From 79840ee114cc723c9872c74916108941d4940cfa Mon Sep 17 00:00:00 2001 From: vanjeff Date: Mon, 25 Jun 2007 12:01:28 +0000 Subject: [PATCH] add modules DiskIo, Partition and SecurityStub. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2732 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/MdeModulePkg.dsc | 6 +- MdeModulePkg/MdeModulePkg.nspd | 3 + .../Universal/Disk/DiskIo/Dxe/CommonHeader.h | 46 + .../Universal/Disk/DiskIo/Dxe/ComponentName.c | 144 ++++ .../Universal/Disk/DiskIo/Dxe/DiskIo.h | 122 +++ .../Universal/Disk/DiskIo/Dxe/DiskIo.inf | 105 +++ .../Universal/Disk/DiskIo/Dxe/DiskIo.msa | 75 ++ .../Universal/Disk/DiskIo/Dxe/EntryPoint.c | 56 ++ .../Universal/Disk/DiskIo/Dxe/diskio.c | 734 ++++++++++++++++ .../Disk/Partition/Dxe/CommonHeader.h | 49 ++ .../Disk/Partition/Dxe/ComponentName.c | 144 ++++ .../Universal/Disk/Partition/Dxe/ElTorito.c | 290 +++++++ .../Universal/Disk/Partition/Dxe/EntryPoint.c | 56 ++ .../Universal/Disk/Partition/Dxe/Gpt.c | 790 ++++++++++++++++++ .../Universal/Disk/Partition/Dxe/Mbr.c | 333 ++++++++ .../Universal/Disk/Partition/Dxe/Partition.c | 706 ++++++++++++++++ .../Universal/Disk/Partition/Dxe/Partition.h | 189 +++++ .../Disk/Partition/Dxe/Partition.inf | 125 +++ .../Disk/Partition/Dxe/Partition.msa | 101 +++ .../Security/SecurityStub/Dxe/CommonHeader.h | 34 + .../Security/SecurityStub/Dxe/SecurityStub.c | 161 ++++ .../SecurityStub/Dxe/SecurityStub.dxs | 31 + .../Security/SecurityStub/Dxe/SecurityStub.h | 52 ++ .../SecurityStub/Dxe/SecurityStub.inf | 95 +++ .../SecurityStub/Dxe/SecurityStub.msa | 56 ++ 25 files changed, 4502 insertions(+), 1 deletion(-) create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/ComponentName.c create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.h create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.inf create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/DiskIo.msa create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/EntryPoint.c create mode 100644 MdeModulePkg/Universal/Disk/DiskIo/Dxe/diskio.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/ComponentName.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/EntryPoint.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Gpt.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Mbr.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.c create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.h create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.inf create mode 100644 MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.msa create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf create mode 100644 MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index a22422ac50..360728d3e0 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -289,5 +289,9 @@ [Components.Ia32] - ${WORKSPACE}\MdeModulePkg\Application\HelloWorld/HelloWorld.inf + ${WORKSPACE}\MdeModulePkg\Application\HelloWorld\HelloWorld.inf + ${WORKSPACE}\MdeModulePkg\Universal\Disk\DiskIo\Dxe\DiskIo.inf + ${WORKSPACE}\MdeModulePkg\Universal\Disk\Partition\Dxe\Partition.inf + ${WORKSPACE}\MdeModulePkg\Universal\Security\SecurityStub\Dxe\SecurityStub.inf + diff --git a/MdeModulePkg/MdeModulePkg.nspd b/MdeModulePkg/MdeModulePkg.nspd index 9777aafdc8..79287dd871 100644 --- a/MdeModulePkg/MdeModulePkg.nspd +++ b/MdeModulePkg/MdeModulePkg.nspd @@ -23,5 +23,8 @@ Application/HelloWorld/HelloWorld.msa + Universal/Disk/DiskIo/Dxe/DiskIo.msa + Universal/Disk/Partition/Dxe/Partition.msa + Universal/Security/SecurityStub/SecurityStub.msa 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 +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +// +// 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 @@ + + + + DiskIo + UEFI_DRIVER + 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4 + 1.0 + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DiskIo + + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiDriverModelLib + + + UefiDriverEntryPoint + + + UefiLib + + + BaseLib + + + BaseMemoryLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + + diskio.c + DiskIo.h + ComponentName.c + + + + + + + gEfiBlockIoProtocolGuid + + + gEfiDiskIoProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + gDiskIoDriverBinding + gDiskIoComponentName + + + 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 +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +// +// 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 +#include + + +// +// 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 @@ + + + + Partition + UEFI_DRIVER + 1FA1F39E-FEFF-4aae-BD7B-38A070A3B609 + 1.0 + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + Partition + + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiDriverModelLib + + + UefiDriverEntryPoint + + + BaseLib + + + UefiLib + + + BaseMemoryLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + DevicePathLib + + + + Partition.h + Partition.c + ElTorito.c + Gpt.c + Mbr.c + ComponentName.c + + + + + + + gEfiBlockIoProtocolGuid + + + gEfiDiskIoProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiDevicePathProtocolGuid + + + gEfiBlockIoProtocolGuid + + + + + gEfiPartTypeSystemPartGuid + + + gEfiPartTypeUnusedGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + gPartitionDriverBinding + gPartitionComponentName + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h new file mode 100644 index 0000000000..d7df39ffcd --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/CommonHeader.h @@ -0,0 +1,34 @@ +/**@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 +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include + +#endif diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c new file mode 100644 index 0000000000..37dfad8cd8 --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.c @@ -0,0 +1,161 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SecurityStub.c + +Abstract: + + This driver supports platform security service + +--*/ + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +#include "SecurityStub.h" + +// +// Handle for the Security Architectural Protocol instance produced by this driver +// +EFI_HANDLE mSecurityArchProtocolHandle = NULL; + +// +// Security Architectural Protocol instance produced by this driver +// +EFI_SECURITY_ARCH_PROTOCOL mSecurityStub = { + SecurityStubAuthenticateState +}; + +// +// Worker functions +// +EFI_STATUS +EFIAPI +SecurityStubAuthenticateState ( + IN EFI_SECURITY_ARCH_PROTOCOL *This, + IN UINT32 AuthenticationStatus, + IN EFI_DEVICE_PATH_PROTOCOL *File + ) +/*++ + +Routine Description: + + The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific + policy from the DXE core response to an attempt to use a file that returns a + given status for the authentication check from the section extraction protocol. + + The possible responses in a given SAP implementation may include locking + flash upon failure to authenticate, attestation logging for all signed drivers, + and other exception operations. The File parameter allows for possible logging + within the SAP of the driver. + + If File is NULL, then EFI_INVALID_PARAMETER is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use under any circumstances, + then EFI_ACCESS_DENIED is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use right now, but it + might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is + returned. + +Arguments: + + This - The EFI_SECURITY_ARCH_PROTOCOL instance. + + AuthenticationStatus - This is the authentication type returned from the Section + Extraction protocol. See the Section Extraction Protocol + Specification for details on this type. + + File - This is a pointer to the device path of the file that is + being dispatched. This will optionally be used for logging. + +Returns: + + EFI_SUCCESS - The file specified by File did authenticate, and the + platform policy dictates that the DXE Core may use File. + + EFI_INVALID_PARAMETER - File is NULL. + + EFI_SECURITY_VIOLATION - The file specified by File did not authenticate, and + the platform policy dictates that File should be placed + in the untrusted state. A file may be promoted from + the untrusted to the trusted state at a future time + with a call to the Trust() DXE Service. + + EFI_ACCESS_DENIED - The file specified by File did not authenticate, and + the platform policy dictates that File should not be + used for any purpose. + +--*/ +{ + if (File == NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SecurityStubInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initialize the state information for the Security Architectural Protocol + +Arguments: + + ImageHandle of the loaded driver + Pointer to the System Table + +Returns: + + Status + + EFI_SUCCESS - successful installation of the service + EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure + EFI_DEVICE_ERROR - cannot create the timer service + +--*/ +{ + EFI_STATUS Status; + + // + // Make sure the Security Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiSecurityArchProtocolGuid); + + // + // Install the Security Architectural Protocol onto a new handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mSecurityArchProtocolHandle, + &gEfiSecurityArchProtocolGuid, + &mSecurityStub, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs new file mode 100644 index 0000000000..88a0d2bbbb --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.dxs @@ -0,0 +1,31 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SecurityStub.dxs + +Abstract: + + Dependency expression source file. + +--*/ + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +#include + +DEPENDENCY_START + TRUE +DEPENDENCY_END diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h new file mode 100644 index 0000000000..2f4d92233a --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.h @@ -0,0 +1,52 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SecurityStub.h + +Abstract: + + Some definitions for Security Architectural Protocol stub driver + +--*/ + +#ifndef _SECURITY_STUB_ARCH_PROTOCOL_H +#define _SECURITY_STUB_ARCH_PROTOCOL_H + + + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Function prototypes +// +EFI_STATUS +EFIAPI +SecurityStubAuthenticateState ( + IN EFI_SECURITY_ARCH_PROTOCOL *This, + IN UINT32 AuthenticationStatus, + IN EFI_DEVICE_PATH_PROTOCOL *File + ) +; + +EFI_STATUS +EFIAPI +SecurityStubInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +#endif diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf new file mode 100644 index 0000000000..bd9058374a --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.inf @@ -0,0 +1,95 @@ +#/** @file +# Component description file for SecurityStub module +# +# This driver supports platform security service. +# 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 = SecurityStub + FILE_GUID = F80697E9-7FD6-4665-8646-88E33EF71DFC + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = SecurityStubInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + SecurityStub.c + SecurityStub.h + SecurityStub.dxs + CommonHeader.h + + +################################################################################ +# +# 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] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiSecurityArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + diff --git a/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa new file mode 100644 index 0000000000..7bf5d22d00 --- /dev/null +++ b/MdeModulePkg/Universal/Security/SecurityStub/Dxe/SecurityStub.msa @@ -0,0 +1,56 @@ + + + + SecurityStub + DXE_DRIVER + F80697E9-7FD6-4665-8646-88E33EF71DFC + 1.0 + Component description file for SecurityStub module + This driver supports platform security service. + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + SecurityStub + + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiBootServicesTableLib + + + UefiDriverEntryPoint + + + + SecurityStub.dxs + SecurityStub.h + SecurityStub.c + + + + + + + gEfiSecurityArchProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + SecurityStubInitialize + + + \ No newline at end of file -- 2.39.2