add modules DiskIo, Partition and SecurityStub.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 25 Jun 2007 12:01:28 +0000 (12:01 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 25 Jun 2007 12:01:28 +0000 (12:01 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2732 6f19259b-4bc3-4df7-8a09-765794883524

25 files changed:
MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/MdeModulePkg.nspd
MdeModulePkg/Universal/Disk/DiskIo/Dxe/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/EntryPoint.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/EntryPoint.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Gpt.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Mbr.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.h [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf [new file with mode: 0644]
MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.msa [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf [new file with mode: 0644]
MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa [new file with mode: 0644]

index a22422a..360728d 100644 (file)
 \r
 \r
 [Components.Ia32]\r
-  ${WORKSPACE}\MdeModulePkg\Application\HelloWorld/HelloWorld.inf\r
+  ${WORKSPACE}\MdeModulePkg\Application\HelloWorld\HelloWorld.inf\r
+  ${WORKSPACE}\MdeModulePkg\Universal\Disk\DiskIo\Dxe\DiskIo.inf\r
+  ${WORKSPACE}\MdeModulePkg\Universal\Disk\Partition\Dxe\Partition.inf\r
+  ${WORKSPACE}\MdeModulePkg\Universal\Security\SecurityStub\Dxe\SecurityStub.inf\r
+\r
 \r
index 9777aaf..79287dd 100644 (file)
@@ -23,5 +23,8 @@
   </PackageDefinitions>\r
   <MsaFiles>\r
     <Filename>Application/HelloWorld/HelloWorld.msa</Filename>\r
+    <Filename>Universal/Disk/DiskIo/Dxe/DiskIo.msa</Filename>\r
+    <Filename>Universal/Disk/Partition/Dxe/Partition.msa</Filename>\r
+    <Filename>Universal/Security/SecurityStub/SecurityStub.msa</Filename>\r
   </MsaFiles>\r
 </PackageSurfaceArea>\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/CommonHeader.h b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..8e869fc
--- /dev/null
@@ -0,0 +1,46 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/DiskIo.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+//\r
+// Driver Binding Externs\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gDiskIoComponentName;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c
new file mode 100644 (file)
index 0000000..63bfa7b
--- /dev/null
@@ -0,0 +1,144 @@
+ /*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "DiskIo.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gDiskIoComponentName = {\r
+  DiskIoComponentNameGetDriverName,\r
+  DiskIoComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mDiskIoDriverNameTable[] = {\r
+  {\r
+    "eng",\r
+    (CHAR16 *)L"Generic Disk I/O Driver"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  Arguments:\r
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    Language   - A pointer to a three character ISO 639-2 language identifier.\r
+                 This is the language of the driver name that that the caller \r
+                 is requesting, and it must match one of the languages specified\r
+                 in SupportedLanguages.  The number of languages supported by a \r
+                 driver is up to the driver writer.\r
+    DriverName - A pointer to the Unicode string to return.  This Unicode string\r
+                 is the name of the driver specified by This in the language \r
+                 specified by Language.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This\r
+                            and the language specified by Language was returned \r
+                            in DriverName.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - DriverName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return LookupUnicodeString (\r
+           Language,\r
+           gDiskIoComponentName.SupportedLanguages,\r
+           mDiskIoDriverNameTable,\r
+           DriverName\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the controller\r
+    that is being managed by an EFI Driver.\r
+\r
+  Arguments:\r
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    ControllerHandle - The handle of a controller that the driver specified by \r
+                       This is managing.  This handle specifies the controller \r
+                       whose name is to be returned.\r
+    ChildHandle      - The handle of the child controller to retrieve the name \r
+                       of.  This is an optional parameter that may be NULL.  It \r
+                       will be NULL for device drivers.  It will also be NULL \r
+                       for a bus drivers that wish to retrieve the name of the \r
+                       bus controller.  It will not be NULL for a bus driver \r
+                       that wishes to retrieve the name of a child controller.\r
+    Language         - A pointer to a three character ISO 639-2 language \r
+                       identifier.  This is the language of the controller name \r
+                       that that the caller is requesting, and it must match one\r
+                       of the languages specified in SupportedLanguages.  The \r
+                       number of languages supported by a driver is up to the \r
+                       driver writer.\r
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode\r
+                       string is the name of the controller specified by \r
+                       ControllerHandle and ChildHandle in the language specified\r
+                       by Language from the point of view of the driver specified\r
+                       by This. \r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the user readable name in the \r
+                            language specified by Language for the driver \r
+                            specified by This was returned in DriverName.\r
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing \r
+                            the controller specified by ControllerHandle and \r
+                            ChildHandle.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h
new file mode 100644 (file)
index 0000000..0459ac4
--- /dev/null
@@ -0,0 +1,122 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  DiskIo.h\r
+  \r
+Abstract:\r
+  Private Data definition for Disk IO driver\r
+\r
+--*/\r
+\r
+#ifndef _DISK_IO_H\r
+#define _DISK_IO_H\r
+\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#define DISK_IO_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('d', 's', 'k', 'I')\r
+\r
+#define DATA_BUFFER_BLOCK_NUM           (64)\r
+\r
+typedef struct {\r
+  UINTN                 Signature;\r
+  EFI_DISK_IO_PROTOCOL  DiskIo;\r
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+} DISK_IO_PRIVATE_DATA;\r
+\r
+#define DISK_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gDiskIoDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gDiskIoComponentName;\r
+\r
+//\r
+// Prototypes\r
+// Driver model protocol interface\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                     ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN  EFI_HANDLE                     ControllerHandle,\r
+  IN  UINTN                          NumberOfChildren,\r
+  IN  EFI_HANDLE                     *ChildHandleBuffer\r
+  );\r
+\r
+//\r
+// Disk I/O Protocol Interface\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoReadDisk (\r
+  IN EFI_DISK_IO_PROTOCOL  *This,\r
+  IN UINT32                MediaId,\r
+  IN UINT64                Offset,\r
+  IN UINTN                 BufferSize,\r
+  OUT VOID                 *Buffer\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoWriteDisk (\r
+  IN EFI_DISK_IO_PROTOCOL  *This,\r
+  IN UINT32                MediaId,\r
+  IN UINT64                Offset,\r
+  IN UINTN                 BufferSize,\r
+  IN VOID                  *Buffer\r
+  );\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf
new file mode 100644 (file)
index 0000000..9e08235
--- /dev/null
@@ -0,0 +1,105 @@
+#/** @file\r
+# Component description file for DiskIo module.\r
+#\r
+# DiskIo driver that layers it's self on every Block IO protocol in the system.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DiskIo\r
+  FILE_GUID                      = 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializeDiskIo\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+#  DRIVER_BINDING                =  gDiskIoDriverBinding\r
+#  COMPONENT_NAME                =  gDiskIoComponentName\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  ComponentName.c\r
+  DiskIo.h\r
+  diskio.c\r
+  CommonHeader.h\r
+  EntryPoint.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg\Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  $(WORKSPACE)\MdeModulePkg/MdeModulePkg.dec\r
+  $(WORKSPACE)\MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  BaseLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiDiskIoProtocolGuid                        # PROTOCOL BY_START\r
+  gEfiBlockIoProtocolGuid                       # PROTOCOL TO_START\r
+\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa
new file mode 100644 (file)
index 0000000..f5b93c8
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>DiskIo</ModuleName>\r
+    <ModuleType>UEFI_DRIVER</ModuleType>\r
+    <GuidValue>6B38F7B4-AD98-40e9-9093-ACA2B5A253C4</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for DiskIo module.</Abstract>\r
+    <Description>DiskIo driver that layers it's self on every Block IO protocol in the system.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>DiskIo</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverModelLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>diskio.c</Filename>\r
+    <Filename>DiskIo.h</Filename>\r
+    <Filename>ComponentName.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiDiskIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <DriverBinding>gDiskIoDriverBinding</DriverBinding>\r
+      <ComponentName>gDiskIoComponentName</ComponentName>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/EntryPoint.c b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/EntryPoint.c
new file mode 100644 (file)
index 0000000..6a90a1f
--- /dev/null
@@ -0,0 +1,56 @@
+/**@file\r
+  Entry Point Source file.\r
+\r
+  This file contains the user entry point \r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+/**\r
+  The user Entry Point for module DiskIo. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeDiskIo(\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallAllDriverProtocols (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gDiskIoDriverBinding,\r
+             ImageHandle,\r
+             &gDiskIoComponentName,\r
+             NULL,\r
+             NULL\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c b/MdeModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c
new file mode 100644 (file)
index 0000000..07d5d1e
--- /dev/null
@@ -0,0 +1,734 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  DiskIo.c\r
+\r
+Abstract:\r
+\r
+  DiskIo driver that layers it's self on every Block IO protocol in the system.\r
+  DiskIo converts a block oriented device to a byte oriented device.\r
+\r
+  ReadDisk may have to do reads that are not aligned on sector boundaries.\r
+  There are three cases:\r
+\r
+    UnderRun - The first byte is not on a sector boundary or the read request is\r
+               less than a sector in length.\r
+\r
+    Aligned  - A read of N contiguous sectors.\r
+\r
+    OverRun  - The last byte is not on a sector boundary.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "DiskIo.h"\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {\r
+  DiskIoDriverBindingSupported,\r
+  DiskIoDriverBindingStart,\r
+  DiskIoDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+DISK_IO_PRIVATE_DATA        gDiskIoPrivateDataTemplate = {\r
+  DISK_IO_PRIVATE_DATA_SIGNATURE,\r
+  {\r
+    EFI_DISK_IO_PROTOCOL_REVISION,\r
+    DiskIoReadDisk,\r
+    DiskIoWriteDisk\r
+  },\r
+  NULL\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
+    than contains a BlockIo protocol can be supported.\r
+\r
+  Arguments:\r
+    This                - Protocol instance pointer.\r
+    ControllerHandle    - Handle of device to test.\r
+    RemainingDevicePath - Not used.\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver supports this device.\r
+    EFI_ALREADY_STARTED - This driver is already running on this device.\r
+    other               - This driver does not support this device.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  (VOID **) &BlockIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test.\r
+  //\r
+  gBS->CloseProtocol (\r
+        ControllerHandle,\r
+        &gEfiBlockIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        ControllerHandle\r
+        );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Start this driver on ControllerHandle by opening a Block IO protocol and\r
+    installing a Disk IO protocol on ControllerHandle.\r
+\r
+  Arguments:\r
+    This                - Protocol instance pointer.\r
+    ControllerHandle    - Handle of device to bind driver to.\r
+    RemainingDevicePath - Not used, always produce all possible children.\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver is added to ControllerHandle.\r
+    EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.\r
+    other               - This driver does not support this device.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  DISK_IO_PRIVATE_DATA  *Private;\r
+\r
+  Private = NULL;\r
+\r
+  //\r
+  // Connect to the Block IO interface on ControllerHandle.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  (VOID **) &gDiskIoPrivateDataTemplate.BlockIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Initialize the Disk IO device instance.\r
+  //\r
+  Private = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);\r
+  if (Private == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+  //\r
+  // Install protocol interfaces for the Disk IO device.\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &ControllerHandle,\r
+                  &gEfiDiskIoProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &Private->DiskIo\r
+                  );\r
+\r
+ErrorExit:\r
+  if (EFI_ERROR (Status)) {\r
+\r
+    if (Private != NULL) {\r
+      FreePool (Private);\r
+    }\r
+\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiBlockIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN  EFI_HANDLE                     ControllerHandle,\r
+  IN  UINTN                          NumberOfChildren,\r
+  IN  EFI_HANDLE                     *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Stop this driver on ControllerHandle by removing Disk IO protocol and closing\r
+    the Block IO protocol on ControllerHandle.\r
+\r
+  Arguments:\r
+    This              - Protocol instance pointer.\r
+    ControllerHandle  - Handle of device to stop driver on.\r
+    NumberOfChildren  - Not used.\r
+    ChildHandleBuffer - Not used.\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver is removed ControllerHandle.\r
+    other               - This driver was not removed from this device.\r
+    EFI_UNSUPPORTED\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_DISK_IO_PROTOCOL  *DiskIo;\r
+  DISK_IO_PRIVATE_DATA  *Private;\r
+\r
+  //\r
+  // Get our context back.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiDiskIoProtocolGuid,\r
+                  (VOID **) &DiskIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);\r
+\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  ControllerHandle,\r
+                  &gEfiDiskIoProtocolGuid,\r
+                  &Private->DiskIo\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+\r
+    Status = gBS->CloseProtocol (\r
+                    ControllerHandle,\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    This->DriverBindingHandle,\r
+                    ControllerHandle\r
+                    );\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    FreePool (Private);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoReadDisk (\r
+  IN EFI_DISK_IO_PROTOCOL  *This,\r
+  IN UINT32                MediaId,\r
+  IN UINT64                Offset,\r
+  IN UINTN                 BufferSize,\r
+  OUT VOID                 *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Read BufferSize bytes from Offset into Buffer.\r
+\r
+    Reads may support reads that are not aligned on\r
+    sector boundaries. There are three cases:\r
+\r
+      UnderRun - The first byte is not on a sector boundary or the read request is\r
+                 less than a sector in length.\r
+\r
+      Aligned  - A read of N contiguous sectors.\r
+\r
+      OverRun  - The last byte is not on a sector boundary.\r
+\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    MediaId    - Id of the media, changes every time the media is replaced.\r
+    Offset     - The starting byte offset to read from.\r
+    BufferSize - Size of Buffer.\r
+    Buffer     - Buffer containing read data.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The data was read correctly from the device.\r
+    EFI_DEVICE_ERROR      - The device reported an error while performing the read.\r
+    EFI_NO_MEDIA          - There is no media in the device.\r
+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.\r
+    EFI_INVALID_PARAMETER - The read request contains device addresses that are not\r
+                            valid for the device.\r
+    EFI_OUT_OF_RESOURCES\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  DISK_IO_PRIVATE_DATA  *Private;\r
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+  EFI_BLOCK_IO_MEDIA    *Media;\r
+  UINT32                BlockSize;\r
+  UINT64                Lba;\r
+  UINT64                OverRunLba;\r
+  UINT32                UnderRun;\r
+  UINT32                OverRun;\r
+  BOOLEAN               TransactionComplete;\r
+  UINTN                 WorkingBufferSize;\r
+  UINT8                 *WorkingBuffer;\r
+  UINTN                 Length;\r
+  UINT8                 *Data;\r
+  UINT8                 *PreData;\r
+  UINTN                 IsBufferAligned;\r
+  UINTN                 DataBufferSize;\r
+  BOOLEAN               LastRead;\r
+\r
+  Private   = DISK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  BlockIo   = Private->BlockIo;\r
+  Media     = BlockIo->Media;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (Media->MediaId != MediaId) {\r
+    return EFI_MEDIA_CHANGED;\r
+  }\r
+\r
+  WorkingBuffer     = Buffer;\r
+  WorkingBufferSize = BufferSize;\r
+\r
+  //\r
+  // Allocate a temporary buffer for operation\r
+  //\r
+  DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;\r
+\r
+  if (Media->IoAlign > 1) {\r
+    PreData = AllocatePool (DataBufferSize + Media->IoAlign);\r
+    Data    = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;\r
+  } else {\r
+    PreData = AllocatePool (DataBufferSize);\r
+    Data    = PreData;\r
+  }\r
+\r
+  if (PreData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Lba                 = DivU64x32Remainder (Offset, BlockSize, &UnderRun);\r
+\r
+  Length              = BlockSize - UnderRun;\r
+  TransactionComplete = FALSE;\r
+\r
+  Status              = EFI_SUCCESS;\r
+  if (UnderRun != 0) {\r
+    //\r
+    // Offset starts in the middle of an Lba, so read the entire block.\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        Lba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Length > BufferSize) {\r
+      Length              = BufferSize;\r
+      TransactionComplete = TRUE;\r
+    }\r
+\r
+    CopyMem (WorkingBuffer, Data + UnderRun, Length);\r
+\r
+    WorkingBuffer += Length;\r
+\r
+    WorkingBufferSize -= Length;\r
+    if (WorkingBufferSize == 0) {\r
+      goto Done;\r
+    }\r
+\r
+    Lba += 1;\r
+  }\r
+\r
+  OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);\r
+\r
+  if (!TransactionComplete && WorkingBufferSize >= BlockSize) {\r
+    //\r
+    // If the DiskIo maps directly to a BlockIo device do the read.\r
+    //\r
+    if (OverRun != 0) {\r
+      WorkingBufferSize -= OverRun;\r
+    }\r
+    //\r
+    // Check buffer alignment\r
+    //\r
+    IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);\r
+\r
+    if (Media->IoAlign <= 1 || IsBufferAligned == 0) {\r
+      //\r
+      // Alignment is satisfied, so read them together\r
+      //\r
+      Status = BlockIo->ReadBlocks (\r
+                          BlockIo,\r
+                          MediaId,\r
+                          Lba,\r
+                          WorkingBufferSize,\r
+                          WorkingBuffer\r
+                          );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      WorkingBuffer += WorkingBufferSize;\r
+\r
+    } else {\r
+      //\r
+      // Use the allocated buffer instead of the original buffer\r
+      // to avoid alignment issue.\r
+      // Here, the allocated buffer (8-byte align) can satisfy the alignment\r
+      //\r
+      LastRead = FALSE;\r
+      do {\r
+        if (WorkingBufferSize <= DataBufferSize) {\r
+          //\r
+          // It is the last calling to readblocks in this loop\r
+          //\r
+          DataBufferSize  = WorkingBufferSize;\r
+          LastRead        = TRUE;\r
+        }\r
+\r
+        Status = BlockIo->ReadBlocks (\r
+                            BlockIo,\r
+                            MediaId,\r
+                            Lba,\r
+                            DataBufferSize,\r
+                            Data\r
+                            );\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+\r
+        CopyMem (WorkingBuffer, Data, DataBufferSize);\r
+        WorkingBufferSize -= DataBufferSize;\r
+        WorkingBuffer += DataBufferSize;\r
+        Lba += DATA_BUFFER_BLOCK_NUM;\r
+      } while (!LastRead);\r
+    }\r
+  }\r
+\r
+  if (!TransactionComplete && OverRun != 0) {\r
+    //\r
+    // Last read is not a complete block.\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        OverRunLba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    CopyMem (WorkingBuffer, Data, OverRun);\r
+  }\r
+\r
+Done:\r
+  if (PreData != NULL) {\r
+    FreePool (PreData);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DiskIoWriteDisk (\r
+  IN EFI_DISK_IO_PROTOCOL  *This,\r
+  IN UINT32                MediaId,\r
+  IN UINT64                Offset,\r
+  IN UINTN                 BufferSize,\r
+  IN VOID                  *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Read BufferSize bytes from Offset into Buffer.\r
+\r
+    Writes may require a read modify write to support writes that are not\r
+    aligned on sector boundaries. There are three cases:\r
+\r
+      UnderRun - The first byte is not on a sector boundary or the write request\r
+                 is less than a sector in length. Read modify write is required.\r
+\r
+      Aligned  - A write of N contiguous sectors.\r
+\r
+      OverRun  - The last byte is not on a sector boundary. Read modified write\r
+                 required.\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    MediaId    - Id of the media, changes every time the media is replaced.\r
+    Offset     - The starting byte offset to read from.\r
+    BufferSize - Size of Buffer.\r
+    Buffer     - Buffer containing read data.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The data was written correctly to the device.\r
+    EFI_WRITE_PROTECTED   - The device can not be written to.\r
+    EFI_DEVICE_ERROR      - The device reported an error while performing the write.\r
+    EFI_NO_MEDIA          - There is no media in the device.\r
+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.\r
+    EFI_INVALID_PARAMETER - The write request contains device addresses that are not\r
+                            valid for the device.\r
+    EFI_OUT_OF_RESOURCES\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  DISK_IO_PRIVATE_DATA  *Private;\r
+  EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+  EFI_BLOCK_IO_MEDIA    *Media;\r
+  UINT32                BlockSize;\r
+  UINT64                Lba;\r
+  UINT64                OverRunLba;\r
+  UINT32                UnderRun;\r
+  UINT32                OverRun;\r
+  BOOLEAN               TransactionComplete;\r
+  UINTN                 WorkingBufferSize;\r
+  UINT8                 *WorkingBuffer;\r
+  UINTN                 Length;\r
+  UINT8                 *Data;\r
+  UINT8                 *PreData;\r
+  UINTN                 IsBufferAligned;\r
+  UINTN                 DataBufferSize;\r
+  BOOLEAN               LastWrite;\r
+\r
+  Private   = DISK_IO_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  BlockIo   = Private->BlockIo;\r
+  Media     = BlockIo->Media;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (Media->ReadOnly) {\r
+    return EFI_WRITE_PROTECTED;\r
+  }\r
+\r
+  if (Media->MediaId != MediaId) {\r
+    return EFI_MEDIA_CHANGED;\r
+  }\r
+\r
+  DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;\r
+\r
+  if (Media->IoAlign > 1) {\r
+    PreData = AllocatePool (DataBufferSize + Media->IoAlign);\r
+    Data    = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;\r
+  } else {\r
+    PreData = AllocatePool (DataBufferSize);\r
+    Data    = PreData;\r
+  }\r
+\r
+  if (PreData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  WorkingBuffer       = Buffer;\r
+  WorkingBufferSize   = BufferSize;\r
+\r
+  Lba                 = DivU64x32Remainder (Offset, BlockSize, &UnderRun);\r
+\r
+  Length              = BlockSize - UnderRun;\r
+  TransactionComplete = FALSE;\r
+\r
+  Status              = EFI_SUCCESS;\r
+  if (UnderRun != 0) {\r
+    //\r
+    // Offset starts in the middle of an Lba, so do read modify write.\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        Lba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Length > BufferSize) {\r
+      Length              = BufferSize;\r
+      TransactionComplete = TRUE;\r
+    }\r
+\r
+    CopyMem (Data + UnderRun, WorkingBuffer, Length);\r
+\r
+    Status = BlockIo->WriteBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        Lba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    WorkingBuffer += Length;\r
+    WorkingBufferSize -= Length;\r
+    if (WorkingBufferSize == 0) {\r
+      goto Done;\r
+    }\r
+\r
+    Lba += 1;\r
+  }\r
+\r
+  OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);\r
+\r
+  if (!TransactionComplete && WorkingBufferSize >= BlockSize) {\r
+    //\r
+    // If the DiskIo maps directly to a BlockIo device do the write.\r
+    //\r
+    if (OverRun != 0) {\r
+      WorkingBufferSize -= OverRun;\r
+    }\r
+    //\r
+    // Check buffer alignment\r
+    //\r
+    IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);\r
+\r
+    if (Media->IoAlign <= 1 || IsBufferAligned == 0) {\r
+      //\r
+      // Alignment is satisfied, so write them together\r
+      //\r
+      Status = BlockIo->WriteBlocks (\r
+                          BlockIo,\r
+                          MediaId,\r
+                          Lba,\r
+                          WorkingBufferSize,\r
+                          WorkingBuffer\r
+                          );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      WorkingBuffer += WorkingBufferSize;\r
+\r
+    } else {\r
+      //\r
+      // The buffer parameter is not aligned with the request\r
+      // So use the allocated instead.\r
+      // It can fit almost all the cases.\r
+      //\r
+      LastWrite = FALSE;\r
+      do {\r
+        if (WorkingBufferSize <= DataBufferSize) {\r
+          //\r
+          // It is the last calling to writeblocks in this loop\r
+          //\r
+          DataBufferSize  = WorkingBufferSize;\r
+          LastWrite       = TRUE;\r
+        }\r
+\r
+        CopyMem (Data, WorkingBuffer, DataBufferSize);\r
+        Status = BlockIo->WriteBlocks (\r
+                            BlockIo,\r
+                            MediaId,\r
+                            Lba,\r
+                            DataBufferSize,\r
+                            Data\r
+                            );\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+\r
+        WorkingBufferSize -= DataBufferSize;\r
+        WorkingBuffer += DataBufferSize;\r
+        Lba += DATA_BUFFER_BLOCK_NUM;\r
+      } while (!LastWrite);\r
+    }\r
+  }\r
+\r
+  if (!TransactionComplete && OverRun != 0) {\r
+    //\r
+    // Last bit is not a complete block, so do a read modify write.\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        OverRunLba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    CopyMem (Data, WorkingBuffer, OverRun);\r
+\r
+    Status = BlockIo->WriteBlocks (\r
+                        BlockIo,\r
+                        MediaId,\r
+                        OverRunLba,\r
+                        BlockSize,\r
+                        Data\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (PreData != NULL) {\r
+    FreePool (PreData);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/CommonHeader.h b/MdeModulePkg/Universal/Disk/Partition/Dxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..2b0c0d9
--- /dev/null
@@ -0,0 +1,49 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <Uefi.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/BlockIo.h>\r
+#include <Guid/Gpt.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/DiskIo.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+//\r
+// Driver Binding Externs\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gPartitionComponentName;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c
new file mode 100644 (file)
index 0000000..ab53492
--- /dev/null
@@ -0,0 +1,144 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Partition.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gPartitionComponentName = {\r
+  PartitionComponentNameGetDriverName,\r
+  PartitionComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mPartitionDriverNameTable[] = {\r
+  {\r
+    "eng",\r
+    (CHAR16 *)L"Partition Driver(MBR/GPT/El Torito)"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  Arguments:\r
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    Language   - A pointer to a three character ISO 639-2 language identifier.\r
+                 This is the language of the driver name that that the caller \r
+                 is requesting, and it must match one of the languages specified\r
+                 in SupportedLanguages.  The number of languages supported by a \r
+                 driver is up to the driver writer.\r
+    DriverName - A pointer to the Unicode string to return.  This Unicode string\r
+                 is the name of the driver specified by This in the language \r
+                 specified by Language.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This\r
+                            and the language specified by Language was returned \r
+                            in DriverName.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - DriverName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return LookupUnicodeString (\r
+          Language,\r
+          gPartitionComponentName.SupportedLanguages,\r
+          mPartitionDriverNameTable,\r
+          DriverName\r
+          );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the controller\r
+    that is being managed by an EFI Driver.\r
+\r
+  Arguments:\r
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    ControllerHandle - The handle of a controller that the driver specified by \r
+                       This is managing.  This handle specifies the controller \r
+                       whose name is to be returned.\r
+    ChildHandle      - The handle of the child controller to retrieve the name \r
+                       of.  This is an optional parameter that may be NULL.  It \r
+                       will be NULL for device drivers.  It will also be NULL \r
+                       for a bus drivers that wish to retrieve the name of the \r
+                       bus controller.  It will not be NULL for a bus driver \r
+                       that wishes to retrieve the name of a child controller.\r
+    Language         - A pointer to a three character ISO 639-2 language \r
+                       identifier.  This is the language of the controller name \r
+                       that that the caller is requesting, and it must match one\r
+                       of the languages specified in SupportedLanguages.  The \r
+                       number of languages supported by a driver is up to the \r
+                       driver writer.\r
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode\r
+                       string is the name of the controller specified by \r
+                       ControllerHandle and ChildHandle in the language specified\r
+                       by Language from the point of view of the driver specified\r
+                       by This. \r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the user readable name in the \r
+                            language specified by Language for the driver \r
+                            specified by This was returned in DriverName.\r
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This is not currently managing \r
+                            the controller specified by ControllerHandle and \r
+                            ChildHandle.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c
new file mode 100644 (file)
index 0000000..3b20152
--- /dev/null
@@ -0,0 +1,290 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  ElTorito.c\r
+\r
+Abstract:\r
+\r
+  Decode an El Torito formatted CD-ROM\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Partition.h"\r
+\r
+EFI_STATUS\r
+PartitionInstallElToritoChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Install child handles if the Handle supports El Torito format.\r
+\r
+Arguments:\r
+  This       - Calling context.\r
+  Handle     - Parent Handle\r
+  DiskIo     - Parent DiskIo interface\r
+  BlockIo    - Parent BlockIo interface\r
+  DevicePath - Parent Device Path\r
+\r
+Returns:\r
+  EFI_SUCCESS       - some child handle(s) was added\r
+  EFI_MEDIA_CHANGED - Media changed Detected\r
+  !EFI_SUCCESS      - no child handle was added\r
+\r
+--*/\r
+{\r
+  EFI_STATUS              Status;\r
+  UINT32                  VolDescriptorLba;\r
+  UINT32                  Lba;\r
+  EFI_BLOCK_IO_MEDIA      *Media;\r
+  CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
+  ELTORITO_CATALOG        *Catalog;\r
+  UINTN                   Check;\r
+  UINTN                   Index;\r
+  UINTN                   BootEntry;\r
+  UINTN                   MaxIndex;\r
+  UINT16                  *CheckBuffer;\r
+  CDROM_DEVICE_PATH       CdDev;\r
+  UINT32                  SubBlockSize;\r
+  UINT32                  SectorCount;\r
+  EFI_STATUS              Found;\r
+  UINT32                  VolSpaceSize;\r
+\r
+  Found         = EFI_NOT_FOUND;\r
+  Media         = BlockIo->Media;\r
+  VolSpaceSize  = 0;\r
+\r
+  //\r
+  // CD_ROM has the fixed block size as 2048 bytes\r
+  //\r
+  if (Media->BlockSize != 2048) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);\r
+\r
+  if (VolDescriptor == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
+\r
+  //\r
+  // the ISO-9660 volume descriptor starts at 32k on the media\r
+  // and CD_ROM has the fixed block size as 2048 bytes, so...\r
+  //\r
+  //\r
+  // ((16*2048) / Media->BlockSize) - 1;\r
+  //\r
+  VolDescriptorLba = 15;\r
+  //\r
+  // Loop: handle one volume descriptor per time\r
+  //\r
+  while (TRUE) {\r
+\r
+    VolDescriptorLba += 1;\r
+    if (VolDescriptorLba > Media->LastBlock) {\r
+      //\r
+      // We are pointing past the end of the device so exit\r
+      //\r
+      break;\r
+    }\r
+\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        Media->MediaId,\r
+                        VolDescriptorLba,\r
+                        Media->BlockSize,\r
+                        VolDescriptor\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      Found = Status;\r
+      break;\r
+    }\r
+    //\r
+    // Check for valid volume descriptor signature\r
+    //\r
+    if (VolDescriptor->Type == CDVOL_TYPE_END ||\r
+        CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0\r
+        ) {\r
+      //\r
+      // end of Volume descriptor list\r
+      //\r
+      break;\r
+    }\r
+    //\r
+    // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,\r
+    // the 32-bit numerical values is stored in Both-byte orders\r
+    //\r
+    if (VolDescriptor->Type == CDVOL_TYPE_CODED) {\r
+      VolSpaceSize = VolDescriptor->VolSpaceSize[0];\r
+    }\r
+    //\r
+    // Is it an El Torito volume descriptor?\r
+    //\r
+    if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {\r
+      continue;\r
+    }\r
+    //\r
+    // Read in the boot El Torito boot catalog\r
+    //\r
+    Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);\r
+    if (Lba > Media->LastBlock) {\r
+      continue;\r
+    }\r
+\r
+    Status = BlockIo->ReadBlocks (\r
+                        BlockIo,\r
+                        Media->MediaId,\r
+                        Lba,\r
+                        Media->BlockSize,\r
+                        Catalog\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));\r
+      continue;\r
+    }\r
+    //\r
+    // We don't care too much about the Catalog header's contents, but we do want\r
+    // to make sure it looks like a Catalog header\r
+    //\r
+    if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {\r
+      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));\r
+      continue;\r
+    }\r
+\r
+    Check       = 0;\r
+    CheckBuffer = (UINT16 *) Catalog;\r
+    for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {\r
+      Check += CheckBuffer[Index];\r
+    }\r
+\r
+    if (Check & 0xFFFF) {\r
+      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));\r
+      continue;\r
+    }\r
+\r
+    MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);\r
+    for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {\r
+      //\r
+      // Next entry\r
+      //\r
+      Catalog += 1;\r
+\r
+      //\r
+      // Check this entry\r
+      //\r
+      if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {\r
+        continue;\r
+      }\r
+\r
+      SubBlockSize  = 512;\r
+      SectorCount   = Catalog->Boot.SectorCount;\r
+\r
+      switch (Catalog->Boot.MediaType) {\r
+\r
+      case ELTORITO_NO_EMULATION:\r
+        SubBlockSize = Media->BlockSize;\r
+        break;\r
+\r
+      case ELTORITO_HARD_DISK:\r
+        break;\r
+\r
+      case ELTORITO_12_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x0F;\r
+        break;\r
+\r
+      case ELTORITO_14_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x12;\r
+        break;\r
+\r
+      case ELTORITO_28_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x24;\r
+        break;\r
+\r
+      default:\r
+        DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));\r
+        SectorCount   = 0;\r
+        SubBlockSize  = Media->BlockSize;\r
+        break;\r
+      }\r
+      //\r
+      // Create child device handle\r
+      //\r
+      CdDev.Header.Type     = MEDIA_DEVICE_PATH;\r
+      CdDev.Header.SubType  = MEDIA_CDROM_DP;\r
+      SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));\r
+\r
+      if (Index == 1) {\r
+        //\r
+        // This is the initial/default entry\r
+        //\r
+        BootEntry = 0;\r
+      }\r
+\r
+      CdDev.BootEntry = (UINT32) BootEntry;\r
+      BootEntry++;\r
+      CdDev.PartitionStart = Catalog->Boot.Lba;\r
+      if (SectorCount < 2) {\r
+        //\r
+        // When the SectorCount < 2, set the Partition as the whole CD.\r
+        //\r
+        if (VolSpaceSize > (Media->LastBlock + 1)) {\r
+          CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1);\r
+        } else {\r
+          CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba);\r
+        }\r
+      } else {\r
+        CdDev.PartitionSize = DivU64x32 (\r
+                                MultU64x32 (\r
+                                  SectorCount,\r
+                                  SubBlockSize\r
+                                  ) + Media->BlockSize - 1,\r
+                                Media->BlockSize\r
+                                );\r
+      }\r
+\r
+      Status = PartitionInstallChildHandle (\r
+                This,\r
+                Handle,\r
+                DiskIo,\r
+                BlockIo,\r
+                DevicePath,\r
+                (EFI_DEVICE_PATH_PROTOCOL *) &CdDev,\r
+                Catalog->Boot.Lba,\r
+                Catalog->Boot.Lba + CdDev.PartitionSize - 1,\r
+                SubBlockSize,\r
+                FALSE\r
+                );\r
+      if (!EFI_ERROR (Status)) {\r
+        Found = EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (VolDescriptor);\r
+\r
+  return Found;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/EntryPoint.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/EntryPoint.c
new file mode 100644 (file)
index 0000000..6bcc972
--- /dev/null
@@ -0,0 +1,56 @@
+/**@file\r
+  Entry Point Source file.\r
+\r
+  This file contains the user entry point \r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+/**\r
+  The user Entry Point for module Partition. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePartition(\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallAllDriverProtocols (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gPartitionDriverBinding,\r
+             ImageHandle,\r
+             &gPartitionComponentName,\r
+             NULL,\r
+             NULL\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Gpt.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/Gpt.c
new file mode 100644 (file)
index 0000000..2a8404d
--- /dev/null
@@ -0,0 +1,790 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  Gpt.c\r
+\r
+Abstract:\r
+\r
+  Decode a hard disk partitioned with the GPT scheme in the EFI 1.0\r
+  specification.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Partition.h"\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionValidGptTable (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_LBA                     Lba,\r
+  OUT EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  );\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckGptEntryArrayCRC (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  );\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionRestoreGptTable (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  );\r
+\r
+STATIC\r
+VOID\r
+PartitionCheckGptEntry (\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader,\r
+  IN  EFI_PARTITION_ENTRY         *PartEntry,\r
+  OUT EFI_PARTITION_ENTRY_STATUS  *PEntryStatus\r
+  );\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckCrcAltSize (\r
+  IN UINTN                 MaxSize,\r
+  IN UINTN                 Size,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  );\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckCrc (\r
+  IN UINTN                 MaxSize,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  );\r
+\r
+STATIC\r
+VOID\r
+PartitionSetCrcAltSize (\r
+  IN UINTN                 Size,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  );\r
+\r
+STATIC\r
+VOID\r
+PartitionSetCrc (\r
+  IN OUT EFI_TABLE_HEADER *Hdr\r
+  );\r
+\r
+EFI_STATUS\r
+PartitionInstallGptChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Install child handles if the Handle supports GPT partition structure.\r
+\r
+Arguments:\r
+  This       - Calling context.\r
+  Handle     - Parent Handle\r
+  DiskIo     - Parent DiskIo interface\r
+  BlockIo    - Parent BlockIo interface\r
+  DevicePath - Parent Device Path\r
+\r
+Returns:\r
+  EFI_SUCCESS  - Valid GPT disk\r
+  EFI_MEDIA_CHANGED - Media changed Detected\r
+  !EFI_SUCCESS - Not a valid GPT disk\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINT32                      BlockSize;\r
+  EFI_LBA                     LastBlock;\r
+  MASTER_BOOT_RECORD          *ProtectiveMbr;\r
+  EFI_PARTITION_TABLE_HEADER  *PrimaryHeader;\r
+  EFI_PARTITION_TABLE_HEADER  *BackupHeader;\r
+  EFI_PARTITION_ENTRY         *PartEntry;\r
+  EFI_PARTITION_ENTRY_STATUS  *PEntryStatus;\r
+  UINTN                       Index;\r
+  EFI_STATUS                  GptValid;\r
+  HARDDRIVE_DEVICE_PATH       HdDev;\r
+\r
+  ProtectiveMbr = NULL;\r
+  PrimaryHeader = NULL;\r
+  BackupHeader  = NULL;\r
+  PartEntry     = NULL;\r
+  PEntryStatus  = NULL;\r
+\r
+  BlockSize     = BlockIo->Media->BlockSize;\r
+  LastBlock     = BlockIo->Media->LastBlock;\r
+\r
+  DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));\r
+  DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));\r
+\r
+  GptValid = EFI_NOT_FOUND;\r
+\r
+  //\r
+  // Allocate a buffer for the Protective MBR\r
+  //\r
+  ProtectiveMbr = AllocatePool (BlockSize);\r
+  if (ProtectiveMbr == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Read the Protective MBR from LBA #0\r
+  //\r
+  Status = BlockIo->ReadBlocks (\r
+                      BlockIo,\r
+                      BlockIo->Media->MediaId,\r
+                      0,\r
+                      BlockIo->Media->BlockSize,\r
+                      ProtectiveMbr\r
+                      );\r
+  if (EFI_ERROR (Status)) {\r
+    GptValid = Status;\r
+    goto Done;\r
+  }\r
+  //\r
+  // Verify that the Protective MBR is valid\r
+  //\r
+  if (ProtectiveMbr->Partition[0].BootIndicator != 0x00 ||\r
+      ProtectiveMbr->Partition[0].OSIndicator != PMBR_GPT_PARTITION ||\r
+      UNPACK_UINT32 (ProtectiveMbr->Partition[0].StartingLBA) != 1\r
+      ) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Allocate the GPT structures\r
+  //\r
+  PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));\r
+  if (PrimaryHeader == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER));\r
+\r
+  if (BackupHeader == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check primary and backup partition tables\r
+  //\r
+  if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) {\r
+    DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n"));\r
+\r
+    if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) {\r
+      DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n"));\r
+      goto Done;\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, " Valid backup partition table\n"));\r
+      DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n"));\r
+      if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) {\r
+        DEBUG ((EFI_D_INFO, " Restore primary partition table error\n"));\r
+      }\r
+\r
+      if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) {\r
+        DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));\r
+      }\r
+    }\r
+  } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {\r
+    DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n"));\r
+    DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n"));\r
+    if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) {\r
+      DEBUG ((EFI_D_INFO, " Restore  backup partition table error\n"));\r
+    }\r
+\r
+    if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) {\r
+      DEBUG ((EFI_D_INFO, " Restore backup partition table success\n"));\r
+    }\r
+\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n"));\r
+\r
+  //\r
+  // Read the EFI Partition Entries\r
+  //\r
+  PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY));\r
+  if (PartEntry == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));\r
+    goto Done;\r
+  }\r
+\r
+  Status = DiskIo->ReadDisk (\r
+                    DiskIo,\r
+                    BlockIo->Media->MediaId,\r
+                    MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize),\r
+                    PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),\r
+                    PartEntry\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    GptValid = Status;\r
+    DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));\r
+    goto Done;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, " Partition entries read block success\n"));\r
+\r
+  DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));\r
+\r
+  PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));\r
+  if (PEntryStatus == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check the integrity of partition entries\r
+  //\r
+  PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus);\r
+\r
+  //\r
+  // If we got this far the GPT layout of the disk is valid and we should return true\r
+  //\r
+  GptValid = EFI_SUCCESS;\r
+\r
+  //\r
+  // Create child device handles\r
+  //\r
+  for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {\r
+    if (CompareGuid (&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||\r
+        PEntryStatus[Index].OutOfRange ||\r
+        PEntryStatus[Index].Overlap\r
+        ) {\r
+      //\r
+      // Don't use null EFI Partition Entries or Invalid Partition Entries\r
+      //\r
+      continue;\r
+    }\r
+\r
+    ZeroMem (&HdDev, sizeof (HdDev));\r
+    HdDev.Header.Type     = MEDIA_DEVICE_PATH;\r
+    HdDev.Header.SubType  = MEDIA_HARDDRIVE_DP;\r
+    SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));\r
+\r
+    HdDev.PartitionNumber = (UINT32) Index + 1;\r
+    HdDev.MBRType         = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;\r
+    HdDev.SignatureType   = SIGNATURE_TYPE_GUID;\r
+    HdDev.PartitionStart  = PartEntry[Index].StartingLBA;\r
+    HdDev.PartitionSize   = PartEntry[Index].EndingLBA - PartEntry[Index].StartingLBA + 1;\r
+    CopyMem (HdDev.Signature, &PartEntry[Index].UniquePartitionGUID, sizeof (EFI_GUID));\r
+\r
+    DEBUG ((EFI_D_INFO, " Index : %d\n", Index));\r
+    DEBUG ((EFI_D_INFO, " Start LBA : %x\n", HdDev.PartitionStart));\r
+    DEBUG ((EFI_D_INFO, " End LBA : %x\n", PartEntry[Index].EndingLBA));\r
+    DEBUG ((EFI_D_INFO, " Partition size: %x\n", HdDev.PartitionSize));\r
+    DEBUG ((EFI_D_INFO, " Start : %x", MultU64x32 (PartEntry[Index].StartingLBA, BlockSize)));\r
+    DEBUG ((EFI_D_INFO, " End : %x\n", MultU64x32 (PartEntry[Index].EndingLBA, BlockSize)));\r
+\r
+    Status = PartitionInstallChildHandle (\r
+              This,\r
+              Handle,\r
+              DiskIo,\r
+              BlockIo,\r
+              DevicePath,\r
+              (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
+              PartEntry[Index].StartingLBA,\r
+              PartEntry[Index].EndingLBA,\r
+              BlockSize,\r
+              CompareGuid(&PartEntry[Index].PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)\r
+              );\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n"));\r
+\r
+Done:\r
+  if (ProtectiveMbr != NULL) {\r
+    FreePool (ProtectiveMbr);\r
+  }\r
+  if (PrimaryHeader != NULL) {\r
+    FreePool (PrimaryHeader);\r
+  }\r
+  if (BackupHeader != NULL) {\r
+    FreePool (BackupHeader);\r
+  }\r
+  if (PartEntry != NULL) {\r
+    FreePool (PartEntry);\r
+  }\r
+  if (PEntryStatus != NULL) {\r
+    FreePool (PEntryStatus);\r
+  }\r
+\r
+  return GptValid;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionValidGptTable (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_LBA                     Lba,\r
+  OUT EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if the GPT partition table is valid\r
+\r
+Arguments:\r
+  BlockIo   - Parent BlockIo interface\r
+  DiskIo    - Disk Io protocol.\r
+  Lba       - The starting Lba of the Partition Table\r
+  PartHeader   - Stores the partition table that is read\r
+\r
+Returns:\r
+  TRUE       - The partition table is valid\r
+  FALSE      - The partition table is not valid\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINT32                      BlockSize;\r
+  EFI_PARTITION_TABLE_HEADER  *PartHdr;\r
+\r
+  BlockSize = BlockIo->Media->BlockSize;\r
+\r
+  PartHdr   = AllocateZeroPool (BlockSize);\r
+\r
+  if (PartHdr == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Read the EFI Partition Table Header\r
+  //\r
+  Status = BlockIo->ReadBlocks (\r
+                      BlockIo,\r
+                      BlockIo->Media->MediaId,\r
+                      Lba,\r
+                      BlockSize,\r
+                      PartHdr\r
+                      );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (PartHdr);\r
+    return FALSE;\r
+  }\r
+\r
+  if ((PartHdr->Header.Signature == EFI_PTAB_HEADER_ID) ||\r
+      !PartitionCheckCrc (BlockSize, &PartHdr->Header) ||\r
+      PartHdr->MyLBA != Lba\r
+      ) {\r
+    DEBUG ((EFI_D_INFO, " !Valid efi partition table header\n"));\r
+    FreePool (PartHdr);\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (PartHeader, PartHdr, sizeof (EFI_PARTITION_TABLE_HEADER));\r
+  if (!PartitionCheckGptEntryArrayCRC (BlockIo, DiskIo, PartHeader)) {\r
+    FreePool (PartHdr);\r
+    return FALSE;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, " Valid efi partition table header\n"));\r
+  FreePool (PartHdr);\r
+  return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckGptEntryArrayCRC (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check if the CRC field in the Partition table header is valid\r
+  for Partition entry array\r
+\r
+Arguments:\r
+\r
+  BlockIo   - parent BlockIo interface\r
+  DiskIo    - Disk Io Protocol.\r
+  PartHeader   - Partition table header structure\r
+\r
+Returns:\r
+\r
+  TRUE      - the CRC is valid\r
+  FALSE     - the CRC is invalid\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       *Ptr;\r
+  UINT32      Crc;\r
+  UINTN       Size;\r
+\r
+  //\r
+  // Read the EFI Partition Entries\r
+  //\r
+  Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);\r
+  if (Ptr == NULL) {\r
+    DEBUG ((EFI_D_ERROR, " Allocate pool error\n"));\r
+    return FALSE;\r
+  }\r
+\r
+  Status = DiskIo->ReadDisk (\r
+                    DiskIo,\r
+                    BlockIo->Media->MediaId,\r
+                    MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),\r
+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,\r
+                    Ptr\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (Ptr);\r
+    return FALSE;\r
+  }\r
+\r
+  Size    = PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry;\r
+\r
+  Status  = gBS->CalculateCrc32 (Ptr, Size, &Crc);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "CheckPEntryArrayCRC: Crc calculation failed\n"));\r
+    FreePool (Ptr);\r
+    return FALSE;\r
+  }\r
+\r
+  FreePool (Ptr);\r
+\r
+  return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionRestoreGptTable (\r
+  IN  EFI_BLOCK_IO_PROTOCOL       *BlockIo,\r
+  IN  EFI_DISK_IO_PROTOCOL        *DiskIo,\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Restore Partition Table to its alternate place\r
+  (Primary -> Backup or Backup -> Primary)\r
+\r
+Arguments:\r
+\r
+  BlockIo   - parent BlockIo interface\r
+  DiskIo    - Disk Io Protocol.\r
+  PartHeader   - the source Partition table header structure\r
+\r
+Returns:\r
+\r
+  TRUE      - Restoring succeeds\r
+  FALSE     - Restoring failed\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                  Status;\r
+  UINTN                       BlockSize;\r
+  EFI_PARTITION_TABLE_HEADER  *PartHdr;\r
+  EFI_LBA                     PEntryLBA;\r
+  UINT8                       *Ptr;\r
+\r
+  PartHdr   = NULL;\r
+  Ptr       = NULL;\r
+\r
+  BlockSize = BlockIo->Media->BlockSize;\r
+\r
+  PartHdr   = AllocateZeroPool (BlockSize);\r
+\r
+  if (PartHdr == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Allocate pool error\n"));\r
+    return FALSE;\r
+  }\r
+\r
+  PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \\r
+                             (PartHeader->LastUsableLBA + 1) : \\r
+                             (PRIMARY_PART_HEADER_LBA + 1);\r
+\r
+  CopyMem (PartHdr, PartHeader, sizeof (EFI_PARTITION_TABLE_HEADER));\r
+\r
+  PartHdr->MyLBA              = PartHeader->AlternateLBA;\r
+  PartHdr->AlternateLBA       = PartHeader->MyLBA;\r
+  PartHdr->PartitionEntryLBA  = PEntryLBA;\r
+  PartitionSetCrc ((EFI_TABLE_HEADER *) PartHdr);\r
+\r
+  Status = BlockIo->WriteBlocks (BlockIo, BlockIo->Media->MediaId, PartHdr->MyLBA, BlockSize, PartHdr);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);\r
+  if (Ptr == NULL) {\r
+    DEBUG ((EFI_D_ERROR, " Allocate pool effor\n"));\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  Status = DiskIo->ReadDisk (\r
+                    DiskIo,\r
+                    BlockIo->Media->MediaId,\r
+                    MultU64x32(PartHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),\r
+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,\r
+                    Ptr\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = DiskIo->WriteDisk (\r
+                    DiskIo,\r
+                    BlockIo->Media->MediaId,\r
+                    MultU64x32(PEntryLBA, BlockIo->Media->BlockSize),\r
+                    PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,\r
+                    Ptr\r
+                    );\r
+\r
+Done:\r
+  FreePool (PartHdr);\r
+  FreePool (Ptr);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+STATIC\r
+VOID\r
+PartitionCheckGptEntry (\r
+  IN  EFI_PARTITION_TABLE_HEADER  *PartHeader,\r
+  IN  EFI_PARTITION_ENTRY         *PartEntry,\r
+  OUT EFI_PARTITION_ENTRY_STATUS  *PEntryStatus\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check each partition entry for its range\r
+\r
+Arguments:\r
+\r
+  PartHeader       - the partition table header\r
+  PartEntry        - the partition entry array\r
+  PEntryStatus  - the partition entry status array recording the status of\r
+                  each partition\r
+\r
+Returns:\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EFI_LBA StartingLBA;\r
+  EFI_LBA EndingLBA;\r
+  UINTN   Index1;\r
+  UINTN   Index2;\r
+\r
+  DEBUG ((EFI_D_INFO, " start check partition entries\n"));\r
+  for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {\r
+    if (CompareGuid (&PartEntry[Index1].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {\r
+      continue;\r
+    }\r
+\r
+    StartingLBA = PartEntry[Index1].StartingLBA;\r
+    EndingLBA   = PartEntry[Index1].EndingLBA;\r
+    if (StartingLBA > EndingLBA ||\r
+        StartingLBA < PartHeader->FirstUsableLBA ||\r
+        StartingLBA > PartHeader->LastUsableLBA ||\r
+        EndingLBA < PartHeader->FirstUsableLBA ||\r
+        EndingLBA > PartHeader->LastUsableLBA\r
+        ) {\r
+      PEntryStatus[Index1].OutOfRange = TRUE;\r
+      continue;\r
+    }\r
+\r
+    for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {\r
+\r
+      if (CompareGuid (&PartEntry[Index2].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {\r
+        continue;\r
+      }\r
+\r
+      if (PartEntry[Index2].EndingLBA >= StartingLBA && PartEntry[Index2].StartingLBA <= EndingLBA) {\r
+        //\r
+        // This region overlaps with the Index1'th region\r
+        //\r
+        PEntryStatus[Index1].Overlap  = TRUE;\r
+        PEntryStatus[Index2].Overlap  = TRUE;\r
+        continue;\r
+\r
+      }\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, " End check partition entries\n"));\r
+}\r
+\r
+STATIC\r
+VOID\r
+PartitionSetCrc (\r
+  IN OUT EFI_TABLE_HEADER *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Updates the CRC32 value in the table header\r
+\r
+Arguments:\r
+\r
+  Hdr     - The table to update\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  PartitionSetCrcAltSize (Hdr->HeaderSize, Hdr);\r
+}\r
+\r
+STATIC\r
+VOID\r
+PartitionSetCrcAltSize (\r
+  IN UINTN                 Size,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Updates the CRC32 value in the table header\r
+\r
+Arguments:\r
+\r
+  Size    - The size of the table\r
+  Hdr     - The table to update\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINT32  Crc;\r
+\r
+  Hdr->CRC32 = 0;\r
+  gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);\r
+  Hdr->CRC32 = Crc;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckCrc (\r
+  IN UINTN                 MaxSize,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Checks the CRC32 value in the table header\r
+\r
+Arguments:\r
+\r
+  MaxSize - Max Size limit\r
+  Hdr     - The table to check\r
+\r
+Returns:\r
+\r
+  TRUE if the CRC is OK in the table\r
+\r
+--*/\r
+{\r
+  return PartitionCheckCrcAltSize (MaxSize, Hdr->HeaderSize, Hdr);\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionCheckCrcAltSize (\r
+  IN UINTN                 MaxSize,\r
+  IN UINTN                 Size,\r
+  IN OUT EFI_TABLE_HEADER  *Hdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Checks the CRC32 value in the table header\r
+\r
+Arguments:\r
+\r
+  MaxSize - Max Size Limit\r
+  Size    - The size of the table\r
+  Hdr     - The table to check\r
+\r
+Returns:\r
+\r
+  TRUE if the CRC is OK in the table\r
+\r
+--*/\r
+{\r
+  UINT32      Crc;\r
+  UINT32      OrgCrc;\r
+  EFI_STATUS  Status;\r
+\r
+  Crc = 0;\r
+\r
+  if (Size == 0) {\r
+    //\r
+    // If header size is 0 CRC will pass so return FALSE here\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  if (MaxSize && Size > MaxSize) {\r
+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Size > MaxSize\n"));\r
+    return FALSE;\r
+  }\r
+  //\r
+  // clear old crc from header\r
+  //\r
+  OrgCrc      = Hdr->CRC32;\r
+  Hdr->CRC32  = 0;\r
+\r
+  Status      = gBS->CalculateCrc32 ((UINT8 *) Hdr, Size, &Crc);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc calculation failed\n"));\r
+    return FALSE;\r
+  }\r
+  //\r
+  // set results\r
+  //\r
+  Hdr->CRC32 = Crc;\r
+\r
+  //\r
+  // return status\r
+  //\r
+  DEBUG_CODE_BEGIN ();\r
+    if (OrgCrc != Crc) {\r
+      DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));\r
+    }\r
+  DEBUG_CODE_END ();\r
+\r
+  return (BOOLEAN) (OrgCrc == Crc);\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Mbr.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/Mbr.c
new file mode 100644 (file)
index 0000000..bc08963
--- /dev/null
@@ -0,0 +1,333 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Mbr.c\r
+  \r
+Abstract:\r
+\r
+  Decode a hard disk partitioned with the legacy MBR found on most PC's\r
+\r
+  MBR - Master Boot Record is in the first sector of a partitioned hard disk.\r
+        The MBR supports four partitions per disk. The MBR also contains legacy\r
+        code that is not run on an EFI system. The legacy code reads the \r
+        first sector of the active partition into memory and \r
+\r
+  BPB - Boot(?) Parameter Block is in the first sector of a FAT file system. \r
+        The BPB contains information about the FAT file system. The BPB is \r
+        always on the first sector of a media. The first sector also contains\r
+        the legacy boot strap code.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Partition.h"\r
+\r
+STATIC\r
+BOOLEAN\r
+PartitionValidMbr (\r
+  IN  MASTER_BOOT_RECORD      *Mbr,\r
+  IN  EFI_LBA                 LastLba\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Test to see if the Mbr buffer is a valid MBR\r
+\r
+Arguments:       \r
+  Mbr     - Parent Handle \r
+  LastLba - Last Lba address on the device.\r
+\r
+Returns:\r
+  TRUE  - Mbr is a Valid MBR\r
+  FALSE - Mbr is not a Valid MBR\r
+\r
+--*/\r
+{\r
+  UINT32  StartingLBA;\r
+  UINT32  EndingLBA;\r
+  UINT32  NewEndingLBA;\r
+  INTN    Index1;\r
+  INTN    Index2;\r
+  BOOLEAN MbrValid;\r
+\r
+  if (Mbr->Signature != MBR_SIGNATURE) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // The BPB also has this signature, so it can not be used alone.\r
+  //\r
+  MbrValid = FALSE;\r
+  for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {\r
+    if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {\r
+      continue;\r
+    }\r
+\r
+    MbrValid    = TRUE;\r
+    StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);\r
+    EndingLBA   = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;\r
+    if (EndingLBA > LastLba) {\r
+      //\r
+      // Compatibility Errata:\r
+      //  Some systems try to hide drive space with their INT 13h driver\r
+      //  This does not hide space from the OS driver. This means the MBR\r
+      //  that gets created from DOS is smaller than the MBR created from\r
+      //  a real OS (NT & Win98). This leads to BlockIo->LastBlock being\r
+      //  wrong on some systems FDISKed by the OS.\r
+      //\r
+      // return FALSE since no block devices on a system are implemented\r
+      // with INT 13h\r
+      //\r
+      return FALSE;\r
+    }\r
+\r
+    for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {\r
+      if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {\r
+        continue;\r
+      }\r
+\r
+      NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;\r
+      if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {\r
+        //\r
+        // This region overlaps with the Index1'th region\r
+        //\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Non of the regions overlapped so MBR is O.K.\r
+  //\r
+  return MbrValid;\r
+}\r
+\r
+EFI_STATUS\r
+PartitionInstallMbrChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Install child handles if the Handle supports MBR format.\r
+\r
+Arguments:       \r
+  This       - Calling context.\r
+  Handle     - Parent Handle \r
+  DiskIo     - Parent DiskIo interface\r
+  BlockIo    - Parent BlockIo interface\r
+  DevicePath - Parent Device Path\r
+\r
+Returns:\r
+  EFI_SUCCESS       - If a child handle was added\r
+  EFI_MEDIA_CHANGED - Media changed Detected\r
+       !EFI_SUCCESS      - Not found MBR partition.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                Status;\r
+  MASTER_BOOT_RECORD        *Mbr;\r
+  UINT32                    ExtMbrStartingLba;\r
+  UINTN                     Index;\r
+  HARDDRIVE_DEVICE_PATH     HdDev;\r
+  HARDDRIVE_DEVICE_PATH     ParentHdDev;\r
+  EFI_STATUS                Found;\r
+  UINT32                    PartitionNumber;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;\r
+\r
+  Mbr             = NULL;\r
+  Found           = EFI_NOT_FOUND;\r
+\r
+  Mbr             = AllocatePool (BlockIo->Media->BlockSize);\r
+  if (Mbr == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = BlockIo->ReadBlocks (\r
+                      BlockIo,\r
+                      BlockIo->Media->MediaId,\r
+                      0,\r
+                      BlockIo->Media->BlockSize,\r
+                      Mbr\r
+                      );\r
+  if (EFI_ERROR (Status)) {\r
+    Found = Status;\r
+    goto Done;\r
+  }\r
+  if (!PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // We have a valid mbr - add each partition\r
+  //\r
+  //\r
+  // Get starting and ending LBA of the parent block device.\r
+  //\r
+  LastDevicePathNode = NULL;\r
+  ZeroMem (&ParentHdDev, sizeof (ParentHdDev));\r
+  DevicePathNode = DevicePath;\r
+  while (!EfiIsDevicePathEnd (DevicePathNode)) {\r
+    LastDevicePathNode  = DevicePathNode;\r
+    DevicePathNode      = EfiNextDevicePathNode (DevicePathNode);\r
+  }\r
+\r
+  if (LastDevicePathNode != NULL) {\r
+    if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH &&\r
+        DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP\r
+        ) {\r
+      CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev));\r
+    } else {\r
+      LastDevicePathNode = NULL;\r
+    }\r
+  }\r
+\r
+  PartitionNumber = 1;\r
+\r
+  ZeroMem (&HdDev, sizeof (HdDev));\r
+  HdDev.Header.Type     = MEDIA_DEVICE_PATH;\r
+  HdDev.Header.SubType  = MEDIA_HARDDRIVE_DP;\r
+  SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));\r
+  HdDev.MBRType         = MBR_TYPE_PCAT;\r
+  HdDev.SignatureType   = SIGNATURE_TYPE_MBR;\r
+\r
+  if (LastDevicePathNode == NULL) {\r
+    //\r
+    // This is a MBR, add each partition\r
+    //\r
+    for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {\r
+      if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA) == 0) {\r
+        //\r
+        // Don't use null MBR entries\r
+        //\r
+        continue;\r
+      }\r
+\r
+      if (Mbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION) {\r
+        //\r
+        // This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here.\r
+        //  We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating \r
+        //  this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format\r
+        //  that corrupted the GPT partition. \r
+        //\r
+        continue;\r
+      }\r
+\r
+      HdDev.PartitionNumber = PartitionNumber ++;\r
+      HdDev.PartitionStart  = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA);\r
+      HdDev.PartitionSize   = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA);\r
+      CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (UINT32));\r
+\r
+      Status = PartitionInstallChildHandle (\r
+                This,\r
+                Handle,\r
+                DiskIo,\r
+                BlockIo,\r
+                DevicePath,\r
+                (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
+                HdDev.PartitionStart,\r
+                HdDev.PartitionStart + HdDev.PartitionSize - 1,\r
+                MBR_SIZE,\r
+                (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        Found = EFI_SUCCESS;\r
+      }\r
+    }\r
+  } else {\r
+    //\r
+    // It's an extended partition. Follow the extended partition\r
+    // chain to get all the logical drives\r
+    //\r
+    ExtMbrStartingLba = 0;\r
+\r
+    do {\r
+\r
+      Status = BlockIo->ReadBlocks (\r
+                          BlockIo,\r
+                          BlockIo->Media->MediaId,\r
+                          ExtMbrStartingLba,\r
+                          BlockIo->Media->BlockSize,\r
+                          Mbr\r
+                          );\r
+      if (EFI_ERROR (Status)) {\r
+        Found = Status;\r
+        goto Done;\r
+      }\r
+\r
+      if (Mbr->Partition[0].OSIndicator == 0) {\r
+        break;\r
+      }\r
+\r
+      if ((Mbr->Partition[0].OSIndicator == EXTENDED_DOS_PARTITION) ||\r
+          (Mbr->Partition[0].OSIndicator == EXTENDED_WINDOWS_PARTITION)) {\r
+        ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA);\r
+        continue;\r
+      }\r
+      HdDev.PartitionNumber = PartitionNumber ++;\r
+      HdDev.PartitionStart  = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;\r
+      HdDev.PartitionSize   = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);\r
+      if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) ||\r
+          (HdDev.PartitionStart <= ParentHdDev.PartitionStart)) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      // The signature in EBR(Extended Boot Record) should always be 0.\r
+      //\r
+      *((UINT32 *) &HdDev.Signature[0]) = 0;\r
+\r
+      Status = PartitionInstallChildHandle (\r
+                This,\r
+                Handle,\r
+                DiskIo,\r
+                BlockIo,\r
+                DevicePath,\r
+                (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
+                HdDev.PartitionStart - ParentHdDev.PartitionStart,\r
+                HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,\r
+                MBR_SIZE,\r
+                (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)\r
+                );\r
+      if (!EFI_ERROR (Status)) {\r
+        Found = EFI_SUCCESS;\r
+      }\r
+\r
+      if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) &&\r
+          (Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION)\r
+          ) {\r
+        break;\r
+      }\r
+\r
+      ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA);\r
+      //\r
+      // Don't allow partition to be self referencing\r
+      //\r
+      if (ExtMbrStartingLba == 0) {\r
+        break;\r
+      }\r
+    } while (ExtMbrStartingLba  < ParentHdDev.PartitionSize);\r
+  }\r
+\r
+Done:\r
+  FreePool (Mbr);\r
+\r
+  return Found;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.c b/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.c
new file mode 100644 (file)
index 0000000..63e771e
--- /dev/null
@@ -0,0 +1,706 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  Partition.c\r
+\r
+Abstract:\r
+\r
+  Partition driver that produces logical BlockIo devices from a physical\r
+  BlockIo device. The logical BlockIo devices are based on the format\r
+  of the raw block devices media. Currently "El Torito CD-ROM", Legacy\r
+  MBR, and GPT partition schemes are supported.\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Partition.h"\r
+\r
+//\r
+// Partition Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {\r
+  PartitionDriverBindingSupported,\r
+  PartitionDriverBindingStart,\r
+  PartitionDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+STATIC \r
+PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {\r
+  PartitionInstallGptChildHandles,\r
+  PartitionInstallElToritoChildHandles,\r
+  PartitionInstallMbrChildHandles,\r
+  NULL\r
+};\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
+    than contains a BlockIo and DiskIo protocol can be supported.\r
+\r
+  Arguments:\r
+    This                - Protocol instance pointer.\r
+    ControllerHandle    - Handle of device to test\r
+    RemainingDevicePath - Not used\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver supports this device\r
+    EFI_ALREADY_STARTED - This driver is already running on this device\r
+    EFI_UNSUPPORTED     - This driver does not support this device\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;\r
+  EFI_DISK_IO_PROTOCOL      *DiskIo;\r
+  EFI_DEV_PATH              *Node;\r
+\r
+  if (RemainingDevicePath != NULL) {\r
+    Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+    if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||\r
+        Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||\r
+        DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)\r
+        ) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
+  gBS->CloseProtocol (\r
+        ControllerHandle,\r
+        &gEfiDevicePathProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        ControllerHandle\r
+        );\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiDiskIoProtocolGuid,\r
+                  (VOID **) &DiskIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
+  gBS->CloseProtocol (\r
+        ControllerHandle,\r
+        &gEfiDiskIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        ControllerHandle\r
+        );\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  NULL,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Start this driver on ControllerHandle by opening a Block IO and Disk IO\r
+    protocol, reading Device Path, and creating a child handle with a\r
+    Disk IO and device path protocol.\r
+\r
+  Arguments:\r
+    This                - Protocol instance pointer.\r
+    ControllerHandle    - Handle of device to bind driver to\r
+    RemainingDevicePath - Not used\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver is added to DeviceHandle\r
+    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle\r
+    other               - This driver does not support this device\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_STATUS                OpenStatus;\r
+  EFI_BLOCK_IO_PROTOCOL     *BlockIo;\r
+  EFI_DISK_IO_PROTOCOL      *DiskIo;\r
+  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;\r
+  PARTITION_DETECT_ROUTINE  *Routine;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  (VOID **) &BlockIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Get the Device Path Protocol on ControllerHandle's handle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiDiskIoProtocolGuid,\r
+                  (VOID **) &DiskIo,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiDevicePathProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+    return Status;\r
+  }\r
+\r
+  OpenStatus = Status;\r
+\r
+  //\r
+  // If no media is present, do nothing here.\r
+  //\r
+  Status = EFI_UNSUPPORTED;\r
+  if (BlockIo->Media->MediaPresent) {\r
+    //\r
+    // Try for GPT, then El Torito, and then legacy MBR partition types. If the\r
+    // media supports a given partition type install child handles to represent\r
+    // the partitions described by the media.\r
+    //\r
+    Routine = &mPartitionDetectRoutineTable[0];\r
+    while (*Routine != NULL) {\r
+      Status = (*Routine) (\r
+                   This,\r
+                   ControllerHandle,\r
+                   DiskIo,\r
+                   BlockIo,\r
+                   ParentDevicePath\r
+                   );\r
+      if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED) {\r
+        break;\r
+      }\r
+      Routine++;\r
+    }\r
+  }\r
+  //\r
+  // In the case that the driver is already started (OpenStatus == EFI_ALREADY_STARTED),\r
+  // the DevicePathProtocol and the DiskIoProtocol are not actually opened by the\r
+  // driver. So don't try to close them. Otherwise, we will break the dependency\r
+  // between the controller and the driver set up before.\r
+  //\r
+  if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus) && Status != EFI_MEDIA_CHANGED) {\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiDiskIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiDevicePathProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
+  IN  EFI_HANDLE                    ControllerHandle,\r
+  IN  UINTN                         NumberOfChildren,\r
+  IN  EFI_HANDLE                    *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Stop this driver on ControllerHandle. Support stoping any child handles\r
+    created by this driver.\r
+\r
+  Arguments:\r
+    This              - Protocol instance pointer.\r
+    ControllerHandle  - Handle of device to stop driver on\r
+    NumberOfChildren  - Number of Children in the ChildHandleBuffer\r
+    ChildHandleBuffer - List of handles for the children we need to stop.\r
+\r
+  Returns:\r
+    EFI_SUCCESS         - This driver is removed DeviceHandle\r
+    EFI_DEVICE_ERROR    - This driver was not removed from this device\r
+\r
+--*/\r
+{\r
+  EFI_STATUS              Status;\r
+  UINTN                   Index;\r
+  EFI_BLOCK_IO_PROTOCOL   *BlockIo;\r
+  BOOLEAN                 AllChildrenStopped;\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+  EFI_DISK_IO_PROTOCOL    *DiskIo;\r
+\r
+  if (NumberOfChildren == 0) {\r
+    //\r
+    // Close the bus driver\r
+    //\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiDiskIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+\r
+    gBS->CloseProtocol (\r
+          ControllerHandle,\r
+          &gEfiDevicePathProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          ControllerHandle\r
+          );\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  AllChildrenStopped = TRUE;\r
+  for (Index = 0; Index < NumberOfChildren; Index++) {\r
+    Status = gBS->OpenProtocol (\r
+                    ChildHandleBuffer[Index],\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    (VOID **) &BlockIo,\r
+                    This->DriverBindingHandle,\r
+                    ControllerHandle,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+\r
+      Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);\r
+\r
+      //\r
+      // All Software protocols have be freed from the handle so remove it.\r
+      //\r
+      BlockIo->FlushBlocks (BlockIo);\r
+\r
+      Status = gBS->CloseProtocol (\r
+                      ControllerHandle,\r
+                      &gEfiDiskIoProtocolGuid,\r
+                      This->DriverBindingHandle,\r
+                      ChildHandleBuffer[Index]\r
+                      );\r
+\r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                      ChildHandleBuffer[Index],\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      Private->DevicePath,\r
+                      &gEfiBlockIoProtocolGuid,\r
+                      &Private->BlockIo,\r
+                      Private->EspGuid,\r
+                      NULL,\r
+                      NULL\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        gBS->OpenProtocol (\r
+              ControllerHandle,\r
+              &gEfiDiskIoProtocolGuid,\r
+              (VOID **) &DiskIo,\r
+              This->DriverBindingHandle,\r
+              ChildHandleBuffer[Index],\r
+              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+              );\r
+      } else {\r
+        FreePool (Private->DevicePath);\r
+        FreePool (Private);\r
+      }\r
+\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      AllChildrenStopped = FALSE;\r
+    }\r
+  }\r
+\r
+  if (!AllChildrenStopped) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionReset (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN BOOLEAN                ExtendedVerification\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reset the parent Block Device.\r
+\r
+  Arguments:\r
+    This                 - Protocol instance pointer.\r
+    ExtendedVerification - Driver may perform diagnostics on reset.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The device was reset.\r
+    EFI_DEVICE_ERROR      - The device is not functioning properly and could\r
+                            not be reset.\r
+\r
+--*/\r
+{\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+\r
+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
+\r
+  return Private->ParentBlockIo->Reset (\r
+                                  Private->ParentBlockIo,\r
+                                  ExtendedVerification\r
+                                  );\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionReadBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN UINT32                 MediaId,\r
+  IN EFI_LBA                Lba,\r
+  IN UINTN                  BufferSize,\r
+  OUT VOID                  *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Read by using the Disk IO protocol on the parent device. Lba addresses\r
+    must be converted to byte offsets.\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    MediaId    - Id of the media, changes every time the media is replaced.\r
+    Lba        - The starting Logical Block Address to read from\r
+    BufferSize - Size of Buffer, must be a multiple of device block size.\r
+    Buffer     - Buffer containing read data\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The data was read correctly from the device.\r
+    EFI_DEVICE_ERROR      - The device reported an error while performing the read.\r
+    EFI_NO_MEDIA          - There is no media in the device.\r
+    EFI_MEDIA_CHANGED     - The MediaId does not matched the current device.\r
+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the\r
+                            device.\r
+    EFI_INVALID_PARAMETER - The read request contains device addresses that are not\r
+                            valid for the device.\r
+\r
+--*/\r
+{\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+  UINT64                  Offset;\r
+\r
+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
+\r
+  if (BufferSize % Private->BlockSize != 0) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;\r
+  if (Offset + BufferSize > Private->End) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Because some kinds of partition have different block size from their parent\r
+  // device, we call the Disk IO protocol on the parent device, not the Block IO\r
+  // protocol\r
+  //\r
+  return Private->DiskIo->ReadDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionWriteBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN UINT32                 MediaId,\r
+  IN EFI_LBA                Lba,\r
+  IN UINTN                  BufferSize,\r
+  OUT VOID                  *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Write by using the Disk IO protocol on the parent device. Lba addresses\r
+    must be converted to byte offsets.\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    MediaId    - Id of the media, changes every time the media is replaced.\r
+    Lba        - The starting Logical Block Address to read from\r
+    BufferSize - Size of Buffer, must be a multiple of device block size.\r
+    Buffer     - Buffer containing read data\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The data was written correctly to the device.\r
+    EFI_WRITE_PROTECTED   - The device can not be written to.\r
+    EFI_DEVICE_ERROR      - The device reported an error while performing the write.\r
+    EFI_NO_MEDIA          - There is no media in the device.\r
+    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.\r
+    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the\r
+                            device.\r
+    EFI_INVALID_PARAMETER - The write request contains a LBA that is not\r
+                            valid for the device.\r
+\r
+--*/\r
+{\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+  UINT64                  Offset;\r
+\r
+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
+\r
+  if (BufferSize % Private->BlockSize != 0) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;\r
+  if (Offset + BufferSize > Private->End) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Because some kinds of partition have different block size from their parent\r
+  // device, we call the Disk IO protocol on the parent device, not the Block IO\r
+  // protocol\r
+  //\r
+  return Private->DiskIo->WriteDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionFlushBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Flush the parent Block Device.\r
+\r
+  Arguments:\r
+    This             - Protocol instance pointer.\r
+\r
+  Returns:\r
+    EFI_SUCCESS      - All outstanding data was written to the device\r
+    EFI_DEVICE_ERROR - The device reported an error while writing back the data\r
+    EFI_NO_MEDIA     - There is no media in the device.\r
+\r
+--*/\r
+{\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+\r
+  Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
+\r
+  return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);\r
+}\r
+\r
+EFI_STATUS\r
+PartitionInstallChildHandle (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ParentHandle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *ParentDiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *ParentBlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,\r
+  IN  EFI_LBA                      Start,\r
+  IN  EFI_LBA                      End,\r
+  IN  UINT32                       BlockSize,\r
+  IN  BOOLEAN                      InstallEspGuid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Create a child handle for a logical block device that represents the\r
+  bytes Start to End of the Parent Block IO device.\r
+\r
+Arguments:\r
+  This             - Calling context.\r
+  ParentHandle     - Parent Handle for new child\r
+  ParentDiskIo     - Parent DiskIo interface\r
+  ParentBlockIo    - Parent BlockIo interface\r
+  ParentDevicePath - Parent Device Path\r
+  DevicePathNode   - Child Device Path node\r
+  Start            - Start Block\r
+  End              - End Block\r
+  BlockSize        - Child block size\r
+  InstallEspGuid   - Flag to install EFI System Partition GUID on handle\r
+\r
+Returns:\r
+  EFI_SUCCESS - If a child handle was added\r
+  EFI_OUT_OF_RESOURCES  - A child handle was not added\r
+\r
+--*/\r
+{\r
+  EFI_STATUS              Status;\r
+  PARTITION_PRIVATE_DATA  *Private;\r
+\r
+  Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));\r
+  if (Private == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Private->Signature        = PARTITION_PRIVATE_DATA_SIGNATURE;\r
+\r
+  Private->Start            = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);\r
+  Private->End              = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);\r
+\r
+  Private->BlockSize        = BlockSize;\r
+  Private->ParentBlockIo    = ParentBlockIo;\r
+  Private->DiskIo           = ParentDiskIo;\r
+\r
+  Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
+\r
+  Private->BlockIo.Media    = &Private->Media;\r
+  CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));\r
+  Private->Media.LogicalPartition = TRUE;\r
+  Private->Media.LastBlock = DivU64x32 (\r
+                               MultU64x32 (\r
+                                 End - Start + 1,\r
+                                 ParentBlockIo->Media->BlockSize\r
+                                 ),\r
+                               BlockSize\r
+                               ) - 1;\r
+\r
+  Private->Media.BlockSize      = (UINT32) BlockSize;\r
+\r
+  Private->BlockIo.Reset        = PartitionReset;\r
+  Private->BlockIo.ReadBlocks   = PartitionReadBlocks;\r
+  Private->BlockIo.WriteBlocks  = PartitionWriteBlocks;\r
+  Private->BlockIo.FlushBlocks  = PartitionFlushBlocks;\r
+\r
+  Private->DevicePath           = AppendDevicePathNode (ParentDevicePath, DevicePathNode);\r
+\r
+  if (Private->DevicePath == NULL) {\r
+    FreePool (Private);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (InstallEspGuid) {\r
+    Private->EspGuid = &gEfiPartTypeSystemPartGuid;\r
+  } else {\r
+    //\r
+    // If NULL InstallMultipleProtocolInterfaces will ignore it.\r
+    //\r
+    Private->EspGuid = NULL;\r
+  }\r
+  //\r
+  // Create the new handle\r
+  //\r
+  Private->Handle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Private->Handle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  Private->DevicePath,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  &Private->BlockIo,\r
+                  Private->EspGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Open the Parent Handle for the child\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    ParentHandle,\r
+                    &gEfiDiskIoProtocolGuid,\r
+                    (VOID **) &ParentDiskIo,\r
+                    This->DriverBindingHandle,\r
+                    Private->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+  } else {\r
+    FreePool (Private->DevicePath);\r
+    FreePool (Private);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.h b/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.h
new file mode 100644 (file)
index 0000000..90478a5
--- /dev/null
@@ -0,0 +1,189 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  Partition.h\r
+  \r
+Abstract:\r
+\r
+  Partition driver that produces logical BlockIo devices from a physical \r
+  BlockIo device. The logical BlockIo devices are based on the format\r
+  of the raw block devices media. Currently "El Torito CD-ROM", Legacy \r
+  MBR, and GPT partition schemes are supported.\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef __PARTITION_H__\r
+#define __PARTITION_H__\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <IndustryStandard/Mbr.h>\r
+#include <IndustryStandard/ElTorito.h>\r
+\r
+\r
+//\r
+// Partition private data\r
+//\r
+#define PARTITION_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('P', 'a', 'r', 't')\r
+typedef struct {\r
+  UINT64                    Signature;\r
+\r
+  EFI_HANDLE                Handle;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_BLOCK_IO_PROTOCOL     BlockIo;\r
+  EFI_BLOCK_IO_MEDIA        Media;\r
+\r
+  EFI_DISK_IO_PROTOCOL      *DiskIo;\r
+  EFI_BLOCK_IO_PROTOCOL     *ParentBlockIo;\r
+  UINT64                    Start;\r
+  UINT64                    End;\r
+  UINT32                    BlockSize;\r
+\r
+  EFI_GUID                  *EspGuid;\r
+\r
+} PARTITION_PRIVATE_DATA;\r
+\r
+#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a)  CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gPartitionDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gPartitionComponentName;\r
+\r
+//\r
+// Extract INT32 from char array\r
+//\r
+#define UNPACK_INT32(a) (INT32)( (((UINT8 *) a)[0] <<  0) |    \\r
+                                 (((UINT8 *) a)[1] <<  8) |    \\r
+                                 (((UINT8 *) a)[2] << 16) |    \\r
+                                 (((UINT8 *) a)[3] << 24) )\r
+\r
+//\r
+// Extract UINT32 from char array\r
+//\r
+#define UNPACK_UINT32(a) (UINT32)( (((UINT8 *) a)[0] <<  0) |    \\r
+                                   (((UINT8 *) a)[1] <<  8) |    \\r
+                                   (((UINT8 *) a)[2] << 16) |    \\r
+                                   (((UINT8 *) a)[3] << 24) )\r
+\r
+//\r
+// Function Prototypes\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer\r
+  );\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PartitionComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+EFI_STATUS\r
+PartitionInstallChildHandle (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ParentHandle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *ParentDiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *ParentBlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,\r
+  IN  UINT64                       Start,\r
+  IN  UINT64                       End,\r
+  IN  UINT32                       BlockSize,\r
+  IN  BOOLEAN                      InstallEspGuid\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+PartitionInstallGptChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+PartitionInstallElToritoChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+PartitionInstallMbrChildHandles (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  )\r
+;\r
+\r
+typedef\r
+EFI_STATUS\r
+(*PARTITION_DETECT_ROUTINE) (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,\r
+  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf b/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf
new file mode 100644 (file)
index 0000000..832de94
--- /dev/null
@@ -0,0 +1,125 @@
+#/** @file\r
+# Component description file for Partition module.\r
+#\r
+# Partition driver produces the logical BlockIo device \r
+#  that represents the bytes Start to End of the Parent Block IO \r
+#  device (one partition of physical BlockIo device, \r
+#  which can be one of GPT, MBR, ElTorito partition).\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = Partition\r
+  FILE_GUID                      = 1FA1F39E-FEFF-4aae-BD7B-38A070A3B609\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = InitializePartition\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+#  DRIVER_BINDING                =  gPartitionDriverBinding                      \r
+#  COMPONENT_NAME                =  gPartitionComponentName                      \r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  ComponentName.c\r
+  Mbr.c\r
+  Gpt.c\r
+  ElTorito.c\r
+  Partition.c\r
+  Partition.h\r
+  CommonHeader.h\r
+  EntryPoint.c\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg\Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  DevicePathLib\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  BaseLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gEfiPartTypeUnusedGuid                        # SOMETIMES_CONSUMED\r
+  gEfiPartTypeSystemPartGuid                    # SOMETIMES_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiBlockIoProtocolGuid                       # PROTOCOL BY_START\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL BY_START\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL TO_START\r
+  gEfiDiskIoProtocolGuid                        # PROTOCOL TO_START\r
+  gEfiBlockIoProtocolGuid                       # PROTOCOL TO_START\r
+\r
diff --git a/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.msa b/MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.msa
new file mode 100644 (file)
index 0000000..3ed7fef
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>Partition</ModuleName>\r
+    <ModuleType>UEFI_DRIVER</ModuleType>\r
+    <GuidValue>1FA1F39E-FEFF-4aae-BD7B-38A070A3B609</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for Partition module.</Abstract>\r
+    <Description>Partition driver produces the logical BlockIo device \r
+      that represents the bytes Start to End of the Parent Block IO \r
+      device (one partition of physical BlockIo device, \r
+      which can be one of GPT, MBR, ElTorito partition).</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>Partition</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverModelLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DevicePathLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Partition.h</Filename>\r
+    <Filename>Partition.c</Filename>\r
+    <Filename>ElTorito.c</Filename>\r
+    <Filename>Gpt.c</Filename>\r
+    <Filename>Mbr.c</Filename>\r
+    <Filename>ComponentName.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiDiskIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+      <GuidCName>gEfiPartTypeSystemPartGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="SOMETIMES_CONSUMED">\r
+      <GuidCName>gEfiPartTypeUnusedGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <DriverBinding>gPartitionDriverBinding</DriverBinding>\r
+      <ComponentName>gPartitionComponentName</ComponentName>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..d7df39f
--- /dev/null
@@ -0,0 +1,34 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/Security.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c
new file mode 100644 (file)
index 0000000..37dfad8
--- /dev/null
@@ -0,0 +1,161 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  SecurityStub.c\r
+\r
+Abstract:\r
+  \r
+  This driver supports platform security service\r
+\r
+--*/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "SecurityStub.h"\r
+\r
+//\r
+// Handle for the Security Architectural Protocol instance produced by this driver\r
+//\r
+EFI_HANDLE                  mSecurityArchProtocolHandle = NULL;\r
+\r
+//\r
+// Security Architectural Protocol instance produced by this driver\r
+//\r
+EFI_SECURITY_ARCH_PROTOCOL  mSecurityStub = { \r
+  SecurityStubAuthenticateState \r
+};\r
+\r
+//\r
+// Worker functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityStubAuthenticateState (\r
+  IN EFI_SECURITY_ARCH_PROTOCOL  *This,\r
+  IN UINT32                      AuthenticationStatus,\r
+  IN EFI_DEVICE_PATH_PROTOCOL    *File\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific \r
+  policy from the DXE core response to an attempt to use a file that returns a \r
+  given status for the authentication check from the section extraction protocol.  \r
+\r
+  The possible responses in a given SAP implementation may include locking \r
+  flash upon failure to authenticate, attestation logging for all signed drivers, \r
+  and other exception operations.  The File parameter allows for possible logging \r
+  within the SAP of the driver.\r
+\r
+  If File is NULL, then EFI_INVALID_PARAMETER is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is not safe for the DXE Core to use under any circumstances, \r
+  then EFI_ACCESS_DENIED is returned.\r
+\r
+  If the file specified by File with an authentication status specified by \r
+  AuthenticationStatus is not safe for the DXE Core to use right now, but it \r
+  might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is \r
+  returned.\r
+\r
+Arguments:\r
+\r
+  This                 - The EFI_SECURITY_ARCH_PROTOCOL instance.\r
+\r
+  AuthenticationStatus - This is the authentication type returned from the Section \r
+                         Extraction protocol.  See the Section Extraction Protocol \r
+                         Specification for details on this type.\r
+\r
+  File                 - This is a pointer to the device path of the file that is \r
+                         being dispatched.  This will optionally be used for logging.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS            - The file specified by File did authenticate, and the \r
+                           platform policy dictates that the DXE Core may use File.\r
+\r
+  EFI_INVALID_PARAMETER  - File is NULL.\r
+\r
+  EFI_SECURITY_VIOLATION - The file specified by File did not authenticate, and \r
+                           the platform policy dictates that File should be placed \r
+                           in the untrusted state.   A file may be promoted from \r
+                           the untrusted to the trusted state at a future time \r
+                           with a call to the Trust() DXE Service.\r
+\r
+  EFI_ACCESS_DENIED      - The file specified by File did not authenticate, and \r
+                           the platform policy dictates that File should not be \r
+                           used for any purpose. \r
+\r
+--*/\r
+{\r
+  if (File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityStubInitialize (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize the state information for the Security Architectural Protocol\r
+\r
+Arguments:\r
+\r
+  ImageHandle of the loaded driver\r
+  Pointer to the System Table\r
+\r
+Returns:\r
+\r
+  Status\r
+\r
+  EFI_SUCCESS           - successful installation of the service\r
+  EFI_OUT_OF_RESOURCES  - cannot allocate protocol data structure\r
+  EFI_DEVICE_ERROR      - cannot create the timer service\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Make sure the Security Architectural Protocol is not already installed in the system\r
+  //\r
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiSecurityArchProtocolGuid);\r
+\r
+  //\r
+  // Install the Security Architectural Protocol onto a new handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mSecurityArchProtocolHandle,\r
+                  &gEfiSecurityArchProtocolGuid,\r
+                  &mSecurityStub,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs
new file mode 100644 (file)
index 0000000..88a0d2b
--- /dev/null
@@ -0,0 +1,31 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  SecurityStub.dxs\r
+\r
+Abstract:\r
+\r
+  Dependency expression source file.\r
+  \r
+--*/  \r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include <DxeDepex.h>\r
+\r
+DEPENDENCY_START\r
+  TRUE\r
+DEPENDENCY_END\r
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h
new file mode 100644 (file)
index 0000000..2f4d922
--- /dev/null
@@ -0,0 +1,52 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  SecurityStub.h\r
+\r
+Abstract:\r
+\r
+  Some definitions for Security Architectural Protocol stub driver\r
+\r
+--*/\r
+\r
+#ifndef _SECURITY_STUB_ARCH_PROTOCOL_H\r
+#define _SECURITY_STUB_ARCH_PROTOCOL_H\r
+\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//\r
+// Function prototypes\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityStubAuthenticateState (\r
+  IN EFI_SECURITY_ARCH_PROTOCOL          *This,\r
+  IN UINT32                              AuthenticationStatus,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL           *File\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SecurityStubInitialize (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf
new file mode 100644 (file)
index 0000000..bd90583
--- /dev/null
@@ -0,0 +1,95 @@
+#/** @file\r
+# Component description file for SecurityStub module\r
+#\r
+# This driver supports platform security service.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecurityStub\r
+  FILE_GUID                      = F80697E9-7FD6-4665-8646-88E33EF71DFC\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = SecurityStubInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  SecurityStub.c\r
+  SecurityStub.h\r
+  SecurityStub.dxs\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Includes Section - list of Include locations that are required for\r
+#                    this module.\r
+#\r
+################################################################################\r
+\r
+[Includes]\r
+  $(WORKSPACE)/MdePkg\Include/Library\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiDriverEntryPoint\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiSecurityArchProtocolGuid                  # PROTOCOL ALWAYS_PRODUCED\r
+\r
diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa
new file mode 100644 (file)
index 0000000..7bf5d22
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>SecurityStub</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>F80697E9-7FD6-4665-8646-88E33EF71DFC</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for SecurityStub module</Abstract>\r
+    <Description>This driver supports platform security service.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>SecurityStub</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>SecurityStub.dxs</Filename>\r
+    <Filename>SecurityStub.h</Filename>\r
+    <Filename>SecurityStub.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiSecurityArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>SecurityStubInitialize</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file