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