summaryrefslogtreecommitdiff
path: root/Core/CORE_DXE/Partition
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_DXE/Partition')
-rw-r--r--Core/CORE_DXE/Partition/ElTorito.c470
-rw-r--r--Core/CORE_DXE/Partition/ElTorito.h264
-rw-r--r--Core/CORE_DXE/Partition/Gpt.c606
-rw-r--r--Core/CORE_DXE/Partition/Gpt.h161
-rw-r--r--Core/CORE_DXE/Partition/Mbr.c407
-rw-r--r--Core/CORE_DXE/Partition/Mbr.h171
-rw-r--r--Core/CORE_DXE/Partition/Partition.c1006
-rw-r--r--Core/CORE_DXE/Partition/Partition.cif16
-rw-r--r--Core/CORE_DXE/Partition/Partition.h188
-rw-r--r--Core/CORE_DXE/Partition/Partition.sdl4
10 files changed, 3293 insertions, 0 deletions
diff --git a/Core/CORE_DXE/Partition/ElTorito.c b/Core/CORE_DXE/Partition/ElTorito.c
new file mode 100644
index 0000000..749ba74
--- /dev/null
+++ b/Core/CORE_DXE/Partition/ElTorito.c
@@ -0,0 +1,470 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.c 21 8/28/12 3:14p Pats $
+//
+// $Revision: 21 $
+//
+// $Date: 8/28/12 3:14p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.c $
+//
+// 21 8/28/12 3:14p Pats
+// [TAG] EIP99287
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Problem booting certain HDD emulation ElTorito CD/DVD's.
+// [RootCause] If the CD has ElTorito and ISO9660 partitions, the block
+// sizeread will be the ISO9660 block size, but the ElTorito partition
+// needs the HDD block size
+// [Solution] Set block size to HDD block size if HDD emulation detected.
+// [Files] Eltorito.c
+//
+// 20 5/10/12 5:54a Rameshr
+// [TAG] EIP88924
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] UEFI 2.3.1 SCT block io read test fail
+// [RootCause] If the CD has two Boot image , two blockio will be
+// installed by Partition driver. But the second blockIo , LastBlock value
+// is wrong
+// [Solution] 2nd logical blockIO LastBlock size calculation corrected.
+// [Files] Eltorito.c
+//
+// 19 9/27/11 7:43p Yul
+// [TAG] EIP69053
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System cannot boot to WINPE from CD/DVD.
+// [RootCause] Blocksize change
+// [Solution] Blocksize change
+// [Files] EIOorito.c
+//
+// 18 5/10/11 11:21a Pats
+// [TAG] - EIP 57859
+// [Category]- BUG FIX
+// [Severity]- Normal
+// [Symptom] - On EFI shell, though CD media is recognized as a Block
+// device, is not recognized as a File system.
+// [RootCause] - Blocksize change from EIP 30719.
+// [Solution] - Removed change from EIP 30719.
+// [Files] - ElTorito.c
+//
+// 17 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 16 10/20/09 5:02p Felixp
+// Check for a block I/O device errors is added in
+// ElToritoCreateChildHandle function.
+//
+// 14 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 13 4/23/09 11:54a Oleksiyy
+// Memory free error fix
+//
+// 12 2/19/09 1:02p Artems
+// EIP 19052 Minor improvement to support CD burned with Windows Explorer
+//
+// 11 1/16/09 3:02p Felixp
+// New Feature:
+// CD-ROM handling code is updated to create additional logical instance
+// of the Bock I/O protocol
+// based on primary volume descriptor of the CR-ROM.
+// The instance is used by the ISO 9660 file systems driver
+// (separate eModule. Not part of the Core) to implement file system
+// protocol.
+// The new parittion driver funcionality is only enabled when ISO 9660
+// file systems driver
+// ($/Source/Modules/FsIso9660) is included into the project.
+//
+// 10 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 9 4/24/07 5:31p Robert
+// Updated Headers to compile with CHM creation
+//
+// 8 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 7 8/24/06 12:34p Felixp
+// x64 support (fixes for warnings/errors)
+//
+// 5 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 5/05/05 5:07p Robert
+// When reading the data for the Volume Descriptor. There was no check
+// for the Status of the Read Blocks call. If this returned an error then it
+// was continuing on. Now it exits when an error is found
+//
+// 2 2/11/05 6:13p Felixp
+// Code optimized by using DPAddNode instead of DPAdd
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 3 12/21/04 4:53p Markw
+// Modified device path defines for consistency.
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ElTorito.c
+//
+// Description: EFI El Torito Partition Support Functions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//=============================================================================
+// Includes
+#include "Partition.h"
+#include "ElTorito.h"
+#include "mbr.h"
+
+extern BOOLEAN Iso9660FileSystemSupportEnabled;
+EFI_GUID VendorDpGuid = AMI_ISO9660_MEDIA_GUID;
+
+//=============================================================================
+// Local Variables
+
+//=============================================================================
+// Function Definitions
+
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: ElToritoCreateChildHandle
+//
+// Description: Searches CDROM disk for El Torito bootable partitions
+// and creates a child handle for each one found
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output:
+//
+// Returns:
+// EFI_SUCCESS - Partition found
+// EFI_INVALID_MEDIA - a parameter passed in or in the data structure
+// is invalid
+// EFI_NO_MEDIA - No partitions found
+// EFI_OUT_OF RESOURCES - Not enough resources to allocate memory
+//
+// Referrals: ReadBlocks AllocatePool MemCmp FreePool Div64 SetMem
+// CreateChildHandle DPAddNode SET_NODE_LENGTH
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS ElToritoCreateChildHandle (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ PARTITION_DATA PData, DData;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ BOOT_RECORD_DESC *VolDesc = NULL;
+ EL_TORITO_ENTRIES *Entry = NULL, *StartEntry = NULL;
+ CDROM_DEVICE_PATH CdDp;
+ UINT32 BlockSize;
+ UINT16 Checksum;
+ UINT16 *Temp = NULL;
+ UINTN Idx;
+ UINT32 VolSize;
+ UINT32 Sectors;
+ UINTN BootEntry;
+ UINTN Dummy;
+
+ AMI_ISO9660_DEVICE_PATH VendorDp;
+ PRIMARY_VOLUME_DESC_HEADER *PrimVolDesc;
+
+
+// TODO: The El Torito spec says that the Boot Record Volume only exists on the last session
+// we need to find the last session on the CD
+
+ // Verify that the CDROM is using the correct block size
+ if (BlockIo->Media->BlockSize != CDROM_BLOCK_SIZE)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Allocate memory for the Boot Record Volume
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &VolDesc);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ // CDROM Spec says sector 16 contains the Primary Volume descriptor
+ Lba = CDROM_BOOT_PRI_VOL_DESCRIPTOR_SECTOR;
+
+ Status = BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, VolDesc );
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check for valid volume descriptor signature
+ if (MemCmp (VolDesc->IsoId, "CD001", 5))
+ {
+ gBS->FreePool(VolDesc);
+ return EFI_INVALID_PARAMETER;
+ }
+
+//***********************************************************************
+// Add Logical partition for ISO 9660 support
+//***********************************************************************
+ PrimVolDesc = (PRIMARY_VOLUME_DESC_HEADER *)VolDesc;
+ BlockSize = CDROM_BLOCK_SIZE;
+
+ //Set Vendor device path
+ VendorDp.Dp.Header.Type = MEDIA_DEVICE_PATH;
+ VendorDp.Dp.Header.SubType = MEDIA_VENDOR_DP;
+ VendorDp.Dp.Guid = VendorDpGuid;
+ VendorDp.VolumeSize = PrimVolDesc->VolSpaceSize;
+ VendorDp.Root = PrimVolDesc->Root;
+ MemCpy(VendorDp.VolumeLabel, PrimVolDesc->VolId, 32);
+ SET_NODE_LENGTH(&VendorDp.Dp.Header,sizeof(AMI_ISO9660_DEVICE_PATH));
+
+
+ // clear the data structure
+ gBS->SetMem(&DData, sizeof(PARTITION_DATA), 0);
+
+ // create new device path
+ DData.DevPath = DPAddNode(DevicePath, &(VendorDp.Dp.Header));
+
+ // save pertinent info
+ DData.Handle = NULL;
+ DData.ParentBlockIo = BlockIo;
+ DData.ParentDiskIo = DiskIo;
+ DData.StartingLba = 0;
+ DData.EndingLba = BlockIo->Media->LastBlock;
+
+ // Store Parent Handle
+ DData.ParentHandle = ControllerHandle;
+
+//***********************************************************************
+// End of ISO 9660 support
+//***********************************************************************
+
+ // Get the Volume Space Size from Primary Volume Descriptor,
+ // the 32-bit numerical value is stored in Both-Little and Big Endian
+ VolSize = VolDesc->VolSpaceSize[0];
+
+
+ // El Torito Spec says sector 17 contains the Boot Record
+ // Volume: Read and verify the data
+ Lba = CDROM_BOOT_REC_VOL_DESCRIPTOR_SECTOR;
+
+ Status = BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, VolDesc );
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Validate the info in the Boot Record
+ if ((VolDesc->BootIndicator != 0) || ( MemCmp (VolDesc->IsoId, "CD001", 5)) ||
+ (VolDesc->Version != 1) || (MemCmp(VolDesc->Identifier, EL_TORITO_SPEC, 23) ) )
+ {
+ // not a valid boot Record
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // There is a valid boot record. move on to the Boot catalog
+ Lba = VolDesc->BootCatalog;
+
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &StartEntry);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Now load the Boot Catalog and find all the partitions
+ BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, StartEntry );
+
+ // get pointer to the first entry in the Boot Record
+ Entry = (EL_TORITO_ENTRIES *)StartEntry;
+
+ if ((Entry->ValEntry.HeaderId != 1) || (Entry->ValEntry.Sig != 0xaa55))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ gBS->FreePool(StartEntry);
+ StartEntry = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Now Calculate checksum
+ Checksum = 0;
+ Temp = (UINT16 *)Entry;
+
+ for (Idx = 0; Idx < 16; Idx++)
+ Checksum += Temp[Idx];
+
+ // if the checksum is not 0 then the Boot catalog is considered invalid
+ if (Checksum)
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ gBS->FreePool(StartEntry);
+ StartEntry = NULL;
+ goto EndOfEltorito;
+ }
+
+ // The checksum is zero so here we go
+
+ // Find and install the Boot entries
+ // loop through the boot catalog looking for bootable entries
+ // start at the second entry in the boot catalog,
+ // the first is the validation entry
+ Entry++;
+
+ for ( Idx = 0, BootEntry = 0; Idx < ((CDROM_BLOCK_SIZE/ sizeof(EL_TORITO_ENTRIES)) - 1);
+ Idx++, Entry++)
+ {
+ // if it isn't bootable, get next entry
+ if (Entry->DefaultEntry.BootId != CDROM_BOOTABLE)
+ continue;
+
+
+ BlockSize = BlockIo->Media->BlockSize;
+ if( (BlockSize == 0) || (BlockSize == 0xFFFFFFFF) ) {
+ BlockSize = 512;
+ }
+ TRACE((TRACE_DXE_CORE, "BlockSize is %d, MediaID is %d\n", BlockSize, BlockIo->Media->MediaId));
+
+ Sectors = Entry->DefaultEntry.SectorCount;
+ TRACE((TRACE_DXE_CORE, "Sector count is %d\n", Sectors));
+ TRACE((TRACE_DXE_CORE, "Media Type is %d\n", Entry->DefaultEntry.MediaType));
+
+ // use this switch to set the Partition Size
+ switch (Entry->DefaultEntry.MediaType)
+ {
+ case FLOPPY_144:
+ Sectors = FLOPPY_144_SIZE_LBA;
+ break;
+ case FLOPPY_288:
+ Sectors = FLOPPY_288_SIZE_LBA;
+ break;
+ case FLOPPY_12:
+ Sectors = FLOPPY_12_SIZE_LBA;
+ break;
+
+ case NO_EMULATION:
+ BlockSize = CDROM_BLOCK_SIZE;
+ break;
+
+ case HARD_DRIVE:
+ BlockSize = 512;
+ break;
+ default:
+ continue;
+ }
+
+
+ if ((Idx != 0) && (BootEntry == 0))
+ BootEntry++;
+
+ CdDp.BootEntry = (UINT32) BootEntry++;
+
+ CdDp.PartitionStart = Entry->DefaultEntry.LoadLba;
+
+ if (Sectors < 2)
+ CdDp.PartitionSize = (VolSize > BlockIo->Media->LastBlock + 1) ?
+ (UINT32)(BlockIo->Media->LastBlock - CdDp.PartitionStart + 1) :
+ (UINT32)(VolSize - CdDp.PartitionStart);
+
+ else
+ CdDp.PartitionSize = Div64(Sectors* BlockSize + BlockIo->Media->BlockSize - 1,
+ BlockIo->Media->BlockSize, &Dummy );
+
+ // set up the device path for the partition
+ CdDp.Header.Type = MEDIA_DEVICE_PATH;
+ CdDp.Header.SubType = MEDIA_CDROM_DP;
+ SET_NODE_LENGTH(&CdDp.Header,sizeof(CDROM_DEVICE_PATH));
+
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // create new device path
+ PData.DevPath = DPAddNode(DevicePath, &CdDp.Header);
+
+ // save pertinent info
+ PData.Handle = NULL;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+ PData.StartingLba = CdDp.PartitionStart;
+ PData.EndingLba = CdDp.PartitionStart + CdDp.PartitionSize - 1;
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockSize);
+ }
+
+EndOfEltorito:
+
+ if (VolDesc != NULL) gBS->FreePool(VolDesc);
+
+ if (StartEntry != NULL) gBS->FreePool(StartEntry);
+
+ if (Iso9660FileSystemSupportEnabled)
+ {
+ Status = CreateChildHandle(This, &DData, CDROM_BLOCK_SIZE);
+ }
+
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/ElTorito.h b/Core/CORE_DXE/Partition/ElTorito.h
new file mode 100644
index 0000000..ebbd7ba
--- /dev/null
+++ b/Core/CORE_DXE/Partition/ElTorito.h
@@ -0,0 +1,264 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.h 5 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 5 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.h $
+//
+// 5 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 4 1/16/09 3:02p Felixp
+// New Feature:
+// CD-ROM handling code is updated to create additional logical instance
+// of the Bock I/O protocol
+// based on primary volume descriptor of the CR-ROM.
+// The instance is used by the ISO 9660 file systems driver
+// (separate eModule. Not part of the Core) to implement file system
+// protocol.
+// The new parittion driver funcionality is only enabled when ISO 9660
+// file systems driver
+// ($/Source/Modules/FsIso9660) is included into the project.
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <ElTorito.h>
+//
+// Description: EFI El Torito Partition Generic Driver Header.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EL_TORITO_H__
+#define __EL_TORITO_H__
+
+#define CDROM_BOOT_PRI_VOL_DESCRIPTOR_SECTOR 16
+#define CDROM_BOOT_REC_VOL_DESCRIPTOR_SECTOR 17
+
+#define CDROM_BLOCK_SIZE 2048
+
+#define CDROM_BOOTABLE 0x88
+
+
+#define NO_EMULATION 0x00
+#define FLOPPY_12 0x01
+#define FLOPPY_144 0x02
+#define FLOPPY_288 0x03
+#define HARD_DRIVE 0x04
+
+
+#define HD_BLOCK_SIZE 512
+#define FLOPPY_144_SIZE_LBA 720
+#define FLOPPY_288_SIZE_LBA 1440
+#define FLOPPY_12_SIZE_LBA 615
+
+#define EL_TORITO_SPEC "EL TORITO SPECIFICATION"
+
+// {BA7C46D1-9C5E-4fc8-943D-1A491F23FE01}
+#define AMI_ISO9660_MEDIA_GUID \
+ { 0xba7c46d1, 0x9c5e, 0x4fc8, 0x94, 0x3d, 0x1a, 0x49, 0x1f, 0x23, 0xfe, 0x1 }
+
+
+//<AMI_GHDR_START>
+//------------------------------------------------------------------
+// Name: Data_Structures
+//
+// Description:
+// Data Structures needed for El Torito
+//
+// BOOT_RECORD - Data Structure definition of a boot record
+// that is contained within an El Torito Disk
+//
+// EL_TORITO_ENTRIES - A union of possible structs that could be
+// contained within an entry on the disk
+//
+//------------------------------------------------------------------
+//<AMI_GHDR_END>
+#pragma pack(1)
+
+typedef struct _BOOT_RECORD
+{
+ UINT8 BootIndicator;
+ CHAR8 IsoId[5];
+ UINT8 Version;
+ CHAR8 Identifier[32];
+ UINT8 Unused[32];
+ UINT32 BootCatalog;
+ UINT8 Unused2[5];
+ UINT32 VolSpaceSize[2];
+} BOOT_RECORD_DESC;
+
+
+
+typedef union
+{
+ struct
+ {
+ UINT8 HeaderId;
+ UINT8 PlatformId;
+ UINT16 Res0;
+ CHAR8 Id[24];
+ UINT16 Checksum;
+ UINT16 Sig;
+ } ValEntry;
+
+
+ struct
+ {
+ UINT8 BootId;
+ UINT8 MediaType;
+ UINT16 LoadSegment;
+ UINT8 SystemType;
+ UINT8 Unused;
+ UINT16 SectorCount;
+ UINT32 LoadLba;
+ } DefaultEntry;
+
+
+ struct
+ {
+ UINT8 HeaderId;
+ UINT8 PlatformId;
+ UINT16 NumSectionEntries;
+ CHAR8 IdString[28];
+ } SecHeader;
+
+
+ struct
+ {
+ UINT8 BootId;
+ UINT8 MediaType;
+ UINT16 LoadSegment;
+ UINT8 SystemType;
+ UINT8 Unused;
+ UINT16 SectorCount;
+ UINT32 LoadLba;
+ UINT8 SelectionType;
+ UINT8 Criteria[19];
+ } SecEntry;
+
+} EL_TORITO_ENTRIES;
+
+typedef struct
+{
+ UINT8 VolDescType;
+ CHAR8 StdId[5];
+ UINT8 VolDescVer;
+} VOLUME_DESCRIPTOR_HEADER;
+
+typedef struct
+{
+ UINT32 Year;
+ UINT16 Month;
+ UINT16 Day;
+ UINT16 Hour;
+ UINT16 Minute;
+ UINT16 Second;
+ UINT16 HSecond;
+ INT8 Offset;
+} CD_DATE_TIME;
+
+typedef struct
+{
+ UINT8 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+ INT8 Offset;
+} FILE_DATE_TIME;
+
+typedef struct
+{
+ UINT8 RecordLength;
+ UINT8 ExtAttrRecLength;
+ UINT64 StartLba;
+ UINT64 DataLength;
+ FILE_DATE_TIME RecTime;
+ UINT8 Flags;
+ UINT8 FileUnitSize;
+ UINT8 InterleaveGap;
+ UINT32 VolSeqNum;
+ UINT8 FileIdLength;
+ UINT8 FileId[1];
+} ROOT_DIR_HEADER;
+
+typedef struct
+{
+ VOLUME_DESCRIPTOR_HEADER Header;
+ UINT8 Flags;
+ CHAR8 SysId[32];
+ CHAR8 VolId[32];
+ UINT64 Unused;
+ UINT64 VolSpaceSize;
+ CHAR8 EscSeq[32];
+ UINT32 VolSetSize;
+ UINT32 VolSeqNum;
+ UINT32 LBlockSize;
+ UINT64 PathTblSize;
+ UINT32 LPathTbl1;
+ UINT32 LPathTbl2;
+ UINT32 MPathTbl1;
+ UINT32 MPathTbl2;
+ ROOT_DIR_HEADER Root;
+ CHAR8 VolSetId[128];
+ CHAR8 PublisherId[128];
+ CHAR8 DataPrepId[128];
+ CHAR8 ApplicationId[128];
+ CHAR8 CopyrightFileId[37];
+ CHAR8 AbstractFileId[37];
+ CHAR8 BiblioFileId[37];
+ CD_DATE_TIME CreationTime;
+ CD_DATE_TIME ModifyTime;
+ CD_DATE_TIME ExpireTime;
+ CD_DATE_TIME EffectiveTime;
+ UINT8 FileStrucVer;
+ UINT8 Unused1;
+} PRIMARY_VOLUME_DESC_HEADER;
+
+typedef struct
+{
+ VENDOR_DEVICE_PATH Dp;
+ UINT64 VolumeSize;
+ ROOT_DIR_HEADER Root;
+ CHAR8 VolumeLabel[32];
+} AMI_ISO9660_DEVICE_PATH;
+
+#pragma pack()
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Gpt.c b/Core/CORE_DXE/Partition/Gpt.c
new file mode 100644
index 0000000..3a1fe92
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Gpt.c
@@ -0,0 +1,606 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.c 16 7/19/12 10:26a Artems $
+//
+// $Revision: 16 $
+//
+// $Date: 7/19/12 10:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.c $
+//
+// 16 7/19/12 10:26a Artems
+// [TAG] EIP94126
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] GPT system recovery can't work and backup GPT partition
+// will also be destroyed after GPT recovery.
+// [RootCause] Incorrect LBA used to restore GPT partition
+// [Solution] Use correct LBA
+// [Files] Gpt.c
+//
+// 15 5/02/11 5:57p Artems
+// EIP 59571: New partition driver functionality as per UEFI spec v.2.3.1
+//
+// 14 11/23/10 4:43p Vyacheslava
+// [TAG] EIP45145
+// [Category] New Feature
+// [Description] A new feature has done by Cire Lin: We're did the code
+// for repairing GPT table. If CRC checking fails then it will run
+// CopyGpt() to repair GPT table.
+//
+// 13 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 12 2/04/10 2:07p Oleksiyy
+// Minor fixes
+//
+// 11 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 10 4/03/09 5:24p Oleksiyy
+// EIP 20879: Linux GPT discovering logic improvement.
+//
+// 9 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 8 4/24/07 6:07p Robert
+// Update for CHM compliance
+//
+// 7 4/12/07 7:04p Robert
+// Coding Standard Updates
+//
+// 6 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 5 10/10/06 3:22p Yakovlevs
+// Bug fixes. The GPT Partition Driver working now.
+//
+// 4 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 2/11/05 6:14p Felixp
+// - Code optimized by using DPAddNode instead of DPAdd
+// - bug fixes
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Gpt.c
+//
+// Description: EFI GPT Partition Generic Driver.
+// This file detects whether or not the system has a GPT format
+// for the drive and sets up all partitions on the drive
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+// Includes
+#include "Partition.h"
+#include "Gpt.h"
+#include "Mbr.h"
+
+//-----------------------------------------------------------------------------
+// global variables
+
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: AdjustBufferSize
+//
+// Description: Calculates correct Buffer size for BlockIO trasfer
+//
+// Input: EFI_BLOCK_IO_PROTOCOL *BlockIo BlockIo Protocol Interface
+// UINTN *BufferSize Pointer To the Size Needed
+//
+// Output: Modifies Buffer Size to reflect correct number of bytes
+//
+// Returns: Nothing
+//
+// Referrals:
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+VOID AdjustBufferSize(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN OUT UINTN *BufferSize)
+{
+ UINTN sz;
+
+ // Calculate the size of trazaction
+ sz=BlockIo->Media->BlockSize * (*BufferSize/BlockIo->Media->BlockSize);
+
+ if (*BufferSize % BlockIo->Media->BlockSize) sz+=BlockIo->Media->BlockSize;
+
+ *BufferSize=sz;
+}
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: CopyGpt
+//
+// Description: Copies a valid GPT to the location of an invalid one
+//
+// Input:
+// BlockIo - pointer to the BlockIo partition so we can read and write
+// to the Block Device
+// DiskIo - Unused at this time
+// Destination - Pointer to where the valid GPT will be copied
+// Source - Pointer to a valid GPT
+//
+// Output: None - A valid GPT will be written to the Destination address
+//
+// Returns: None
+//
+// Referrals: CopyMem ReadBlocks CalculateCrc32 AllocatePool AdjustBufferSize
+// WriteBlocks FreePool
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+VOID CopyGpt(
+ EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ EFI_DISK_IO_PROTOCOL *DiskIo,
+ GPT_HEADER *Destination,
+ GPT_HEADER *Source
+)
+{
+ EFI_STATUS Status;
+ UINT8 *EntryArray;
+ EFI_LBA EntryLba;
+ UINTN Size;
+ UINT32 Crc32;
+
+ // Calculate Buffer Size for Enrty array
+ Size = Source->NumberOfPartitionEntries * Source->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo, &Size);
+
+ if (Source->MyLba == 1)
+ EntryLba = Source->LastUsableLba + 1;
+ else
+ EntryLba = Source->AlternateLba + 1;
+
+ // Copy the GPT Header
+ gBS->CopyMem( Destination, Source, sizeof(GPT_HEADER) );
+
+ Destination->MyLba = Source->AlternateLba;
+ Destination->AlternateLba = Source->MyLba;
+ Destination->PartitionEntryLba = EntryLba;
+ Destination->Crc32 = 0;
+ Destination->Header.CRC32 = 0;
+
+ // Allocate Memory for Source Patrition Table Array
+ Status = gBS->AllocatePool( EfiBootServicesData, Size, &EntryArray );
+
+ // Zero it out
+ gBS->SetMem( EntryArray, Size, 0 );
+
+ // Read Source's Partition Table Entry Array to the buffer
+ Status = BlockIo->ReadBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Source->PartitionEntryLba,
+ Size,
+ EntryArray
+ );
+
+ // Calculate CRC32 of GIUID Partition Table Entry Array
+ gBS->CalculateCrc32(
+ (UINT8*)EntryArray,
+ Source->NumberOfPartitionEntries * Source->SizeOfPartitionEntry,
+ &Crc32
+ );
+ Destination->Crc32 = Crc32;
+
+ gBS->CalculateCrc32(
+ (UINT8*)Destination,
+ sizeof(GPT_HEADER),
+ &Crc32
+ );
+ Destination->Header.CRC32 = Crc32;
+
+
+ // Write to Destination Partition Header Block
+ Status = BlockIo->WriteBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Destination->MyLba,
+ BlockIo->Media->BlockSize,
+ Destination
+ );
+
+ // Write Destination Partition Table Entry Array
+ Status = BlockIo->WriteBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Destination->PartitionEntryLba,
+ Size,
+ EntryArray
+ );
+
+ gBS->FreePool(EntryArray);
+}
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: ValidateGptHeader
+//
+// Description: Checks if the GPT table is valid
+//
+// Input:
+// BlockIo - Pointer to the Parent BlockIo instance
+// GptHeader - Pointer to a memory area that contains the GPT header
+// to validate
+// HdrLoc - Header location
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - GPT is valid
+// EFI_INVALID_PARAMETER - checks to see if the CRC, signature, and Header
+// Location are vlaid
+// EFI_OUT_OF_RESOURCES - Not enough free memory to allocate to read the
+// GPT entry table
+//
+// Referrals: CalculateCrc32 MemCmp AdjustBufferSize AllocatePool ReadBlocks
+// FreePool
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS ValidateGptHeader(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN GPT_HEADER *GptHeader,
+ IN EFI_LBA HdrLoc
+)
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINT32 Temp32;
+ UINTN Size;
+ PARTITION_ENTRY *GptEntryTable;
+
+
+ // Get CRC of the Partition Header
+ Temp32 = GptHeader->Header.CRC32;
+ GptHeader->Header.CRC32 = 0;
+
+ gBS->CalculateCrc32((UINT8*)GptHeader, sizeof(GPT_HEADER), &Crc);
+ GptHeader->Header.CRC32 = Crc;
+
+ // Check calculated CRC
+ // Check signature
+ // Check that MyLBA parameter points to the location of the current Header
+ if (MemCmp(EFI_GPT_HEADER_ID, &GptHeader->Header.Signature, sizeof(UINT64))
+ || (Temp32 != Crc)
+ || (GptHeader->MyLba != HdrLoc) )
+ return EFI_INVALID_PARAMETER;
+
+ // Calculate the size of trasaction
+ Size = GptHeader->NumberOfPartitionEntries *
+ GptHeader->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo,&Size);
+
+ // allocate memory for the Entry array
+ Status = gBS->AllocatePool( EfiBootServicesData, Size, &GptEntryTable);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ // get the data from the entry array
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ GptHeader->PartitionEntryLba,
+ Size, GptEntryTable);
+
+ // calculate the CRC value for the entry array
+ gBS->CalculateCrc32((UINT8*)GptEntryTable,
+ GptHeader->NumberOfPartitionEntries*
+ GptHeader->SizeOfPartitionEntry, &Crc);
+
+ // the the allocated memory
+ if (GptEntryTable != NULL ) gBS->FreePool(GptEntryTable);
+
+ // check if the CRC that was calculated matches the value that was stored
+ if (Crc != GptHeader->Crc32) return EFI_INVALID_PARAMETER;
+
+ // All checks passed, the GPT is valid
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: VerifyPartionTables
+//
+// Description: Check if either GPT is valid. if only one is then fix the other
+// if both are bad, then it is not a valid GPT system. return error
+//
+// Input:
+// BlockIo - pointer to the BlockIo partition so we can read and write
+// to the Block Device
+// DiskIo - Unused at this time
+//
+// Output:
+// GPT - pointer to a memory space for one GPT
+//
+// Returns: EFI_SUCCESS - If a valid GPT is found
+// EFI_UNSUPPORTED - if no valid GPT is found
+// EFI_OUT_OF_RESOURCES - not enough allocateable memory is available
+//
+// Referrals: AllocatePool ReadBlocks FreePool AdjustBufferSize
+// ValidateGPTHeader CopyGPT CopyMem
+//
+// Notes
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS VerifyPartionTables(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ OUT GPT_HEADER *Gpt
+)
+{
+ EFI_STATUS Status;
+ GPT_HEADER *Primary = NULL;
+ GPT_HEADER *Secondary = NULL;
+ MASTER_BOOT_RECORD *Pmbr = NULL;
+ UINTN Size;
+ UINT8 i, FoundPP = 0;
+
+ // Allocate a buffer for the Protective MBR
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &Pmbr);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ // Read the Protective MBR from LBA #0
+ Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, 0,
+ BlockIo->Media->BlockSize, Pmbr);
+
+ if (EFI_ERROR (Status))
+ {
+ gBS->FreePool(Pmbr);
+ return Status;
+ }
+
+ for (i=0; i < 4; i++)
+
+ // See if Protective MBR is valid and if not free allocated memory and return EFI_UNSUPPORTED
+ if ((Pmbr->PartRec[i].BootIndicator == 0x00) && (Pmbr->PartRec[i].OSType == 0xee) &&
+ (Pmbr->PartRec[i].StartingLba == 1)) FoundPP++;
+
+ if (FoundPP == 0)
+ {
+ gBS->FreePool(Pmbr);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Allocate memory to hold the data for the Primary and Secondary GPT headers
+ // Allocate Primary
+ Size=sizeof(GPT_HEADER);
+ AdjustBufferSize(BlockIo, &Size);
+
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &Primary);
+
+ // if error is returned, exit with No resources available
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Pmbr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Allocate for secondary header
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &Secondary);
+
+ // if error, free memory allocated for primary and then exit with no resources available
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Read primary and backup table
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 1, Size, Primary);
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, BlockIo->Media->LastBlock, Size, Secondary);
+
+ // read primary header from the block device and verify if it is valid
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Primary, 1)))
+ {
+ // if primary is not valid, check secondary to see if it is valid
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Secondary, BlockIo->Media->LastBlock)))
+ {
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ gBS->FreePool(Secondary);
+ return EFI_UNSUPPORTED;
+ }
+
+ // if secondary table is good, copy to primary
+ else
+ {
+ CopyGpt(BlockIo, DiskIo, Primary, Secondary);
+ }
+ }
+
+ // if primary is good, check secondary
+ else
+ {
+ // if secondary is bad, copy primary to secondary
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Secondary, BlockIo->Media->LastBlock)))
+ {
+ CopyGpt(BlockIo, DiskIo, Secondary, Primary);
+ }
+ }
+
+ // now that both tables are fixed, copy to GPT output variable and exit
+ gBS->CopyMem(Gpt, Primary, sizeof(GPT_HEADER));
+
+ // before we exit free all memory allocation and exit with success
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ gBS->FreePool(Secondary);
+
+ return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: GPTDiscoverPartitions
+//
+// Description: Searches GPT Table for partitions
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// other - Driver not loaded
+//
+// Referrals: AllocatePool FreePool VerifyPartionTables AdjustBufferSize
+// MemCmp SetMem CopyMem CreateChildHandle SET_NODE_LENGTH
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS GptDiscoverPartitions (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_STATUS Status;
+ GPT_HEADER *Gpt = NULL;
+ UINT8 *EntryArray = NULL;
+ PARTITION_ENTRY *PartEntry=NULL;
+ HARDDRIVE_DEVICE_PATH HdDp;
+ PARTITION_DATA PData;
+ UINTN Idx;
+ UINTN Size;
+
+
+ // Allocate memory for a valid GPT partiton header
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(GPT_HEADER), &Gpt);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+// EFI_DEADLOOP();
+ // verify that the GPT headers on this BlockIo device are valid
+ if (EFI_ERROR(VerifyPartionTables(BlockIo, DiskIo, Gpt )) )
+ {
+ gBS->FreePool(Gpt);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // If this gets executed, then the Headers are valid and the Entry array
+ // has the correct CRC value
+ // Now parse through the Entry Array and create instances for each
+ // partition on the media
+ // Check Entry Table Crc
+ Size = Gpt->NumberOfPartitionEntries * Gpt->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo, &Size);
+
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &EntryArray);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Gpt);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ Gpt->PartitionEntryLba, Size, EntryArray);
+
+ for (Idx = 0; Idx < Gpt->NumberOfPartitionEntries; Idx++)
+ {
+ PartEntry = (PARTITION_ENTRY *)(EntryArray + Idx * Gpt->SizeOfPartitionEntry);
+
+ // Check to see if this is an unused partition
+ if (!(MemCmp(&PartEntry->PartitionTypeGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID))))
+ continue; // This is an unused partition
+
+ if(PartEntry->Attributes & 0x2) //bit 1 of Attributes set?
+ continue; //no BlockIo for this partition - UEFI spec 2.3.1 p.5.3.3 table 19
+
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // set up the device path for the partition
+ HdDp.Header.Type = MEDIA_DEVICE_PATH;
+ HdDp.Header.SubType = MEDIA_HARDDRIVE_DP;
+ SET_NODE_LENGTH(&HdDp.Header,sizeof(HARDDRIVE_DEVICE_PATH));
+
+ // Idx is 0 based so add one so that partitionNumber is 1 based
+ HdDp.PartitionNumber = (UINT32) Idx + 1;
+ HdDp.PartitionStart = PartEntry->StartingLba;
+ HdDp.PartitionSize = PartEntry->EndingLba - PartEntry->StartingLba + 1;
+ gBS->CopyMem(&HdDp.Signature, &PartEntry->UniquePartitionGuid,
+ sizeof(EFI_GUID));
+ HdDp.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
+ HdDp.SignatureType = SIGNATURE_TYPE_GUID;
+
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // save pertinent info
+ PData.Handle = NULL;
+ PData.ParentHandle = ControllerHandle;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+ PData.StartingLba = PartEntry->StartingLba;
+ PData.EndingLba = PartEntry->EndingLba;
+ gBS->CopyMem(&PData.PartGuid, &PartEntry->PartitionTypeGuid,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ }
+
+ gBS->FreePool(Gpt);
+ gBS->FreePool(EntryArray);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Gpt.h b/Core/CORE_DXE/Partition/Gpt.h
new file mode 100644
index 0000000..120b90a
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Gpt.h
@@ -0,0 +1,161 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.h 6 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 6 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.h $
+//
+// 6 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 5 1/08/08 4:37p Robert
+//
+// 4 1/08/08 4:00p Robert
+//
+// 3 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 2 4/24/07 6:06p Robert
+// Update for CHM compliance
+//
+// 1 1/28/05 1:17p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <GPT.h>
+//
+// Description: EFI GPT Partition Generic Driver Header.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#pragma pack(1)
+
+#define EFI_GPT_HEADER_ID "EFI PART"
+
+// GUID Partition Table Header
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: GPT_HEADER
+//
+// Description: Data Structure definition of the GPT table
+//
+// Fields:
+// Header - EFI_TABLE_HEADER - defines generic EFI header information
+// MyLba - EFI_LBA - The LBA that contains this GPT data structure
+// AlternateLba - EFI_LBA - The LBA that contains the alternative GPT
+// data structure
+// FirstUsableLba - EFI_LBA - the first logical block that can be used
+// in a partition that is defined by the GPT
+// LastUsableLba - EFI_LBA - the last logical block that can be used
+// in a partition that is defined by the GPT
+// DiskGuid - EFI_GUID - Unique GUID to identify this hard drive
+// PartitionEntryLba - EFI_LBA - the starting LBA of the GUID Partition
+// Entry Array
+// NumberOfPartitionEntries - UINT32 - the number of partition entries
+// in the Array
+// SizeOfPartitionEntry - UINT32 - the size of each partition entry
+// Crc32 - UINT32 - crc value of the entire GPT block
+//
+// Referral:
+// EFI_TABLE_HEADER EFI_LBA EFI_GUID
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct
+{
+ EFI_TABLE_HEADER Header;
+ EFI_LBA MyLba;
+ EFI_LBA AlternateLba;
+ EFI_LBA FirstUsableLba;
+ EFI_LBA LastUsableLba;
+ EFI_GUID DiskGuid;
+ EFI_LBA PartitionEntryLba;
+ UINT32 NumberOfPartitionEntries;
+ UINT32 SizeOfPartitionEntry;
+ UINT32 Crc32;
+} GPT_HEADER;
+
+// GPT Partition Entry
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: PARTITION_ENTRY
+//
+// Description: Data Structure definition of a partion entry in the GPT table
+//
+// Fields:
+// PartitionTypeGuid - EFI_GUID - contains GUID that defines that type
+// of GUID
+// UniquePartitionGuid - EFI_GUID - contains unique GUID for each
+// partition
+// StartingLba - EFI_LBA - first LBA of the partition
+// EndingLba - EFI_LBA - last logical block address
+// Attributes - UINT64 - UEFI defined attributes
+// Bit 0 - Partition is required for platform to function
+// Bits 1 - 47 - undefined
+// Bits 48 - 64 - reserved for GUID specific use
+// PartitionName[36] - CHAR16 - unicode string containing the name of
+// the partition
+//
+// Referral:
+// EFI_LBA
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct
+{
+ EFI_GUID PartitionTypeGuid;
+ EFI_GUID UniquePartitionGuid;
+ EFI_LBA StartingLba;
+ EFI_LBA EndingLba;
+ UINT64 Attributes;
+ CHAR16 PartitionName[36];
+} PARTITION_ENTRY;
+
+
+#pragma pack()
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Mbr.c b/Core/CORE_DXE/Partition/Mbr.c
new file mode 100644
index 0000000..7ccdae8
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Mbr.c
@@ -0,0 +1,407 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.c 12 4/16/10 4:24p Pats $
+//
+// $Revision: 12 $
+//
+// $Date: 4/16/10 4:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.c $
+//
+// 12 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 11 2/04/10 3:03p Oleksiyy
+// EIP 31633 Minor Fix
+//
+// 10 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 9 11/13/08 6:10p Felixp
+// Bug fix in MbrCreateChildHandle: unsed part of the signature (12 bytes)
+// in hard driver device path was never initialized.
+//
+// 8 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 7 4/25/07 11:52a Robert
+// Updated for CHM and coding standard commpliance
+//
+// 5 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 7/12/05 5:01p Robert
+// The Free BSD operating system created a partition that referenced
+// itself. This was not checked for in the partition driver so an
+// infinite loop was created.
+// this reference now causes an error condition..
+//
+// 2 2/11/05 6:13p Felixp
+// Code optimized by using DPAddNode instead of DPAdd
+//
+// 6 12/21/04 4:54p Markw
+// Modified device path defines for consistency.
+//
+// 5 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Mbr.c
+//
+// Description: EFI Mbr Partition Generic Driver. This file finds all
+// the partitions defined in the MBR found on a Device
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//-----------------------------------------------------------------------------
+// Includes
+#include "partition.h"
+#include "mbr.h"
+
+
+//-----------------------------------------------------------------------------
+// Global Variables
+EFI_GUID gMbrPartition = EFI_PART_TYPE_LEGACY_MBR_GUID;
+
+
+
+//-----------------------------------------------------------------------------
+// Function Prototypes
+
+
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: CheckValidMbr
+//
+// Description: Makes sure the Master Boot Record has valid partitions
+//
+// Input:
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *Mbr - pointer to a data structure that contains the MBR for
+// the current drive
+//
+// Output: None
+//
+// Returns:
+// TRUE - MBR is valid
+// FALSE - MBR is invalid
+//
+// Referrals: ReadBlocks
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+BOOLEAN CheckValidMbr(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN MASTER_BOOT_RECORD *Mbr
+)
+{
+ EFI_STATUS Status;
+ EFI_LBA EndLba;
+ UINT8 PartitionFound = 0;
+ UINT8 Idx;
+ UINT8 Loop2;
+
+ // read the first block of the Harddrive
+ Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0,
+ BlockIo->Media->BlockSize, Mbr);
+
+ if (Mbr->Sig != MBR_SIGNATURE)
+ return FALSE;
+
+ // check for valid LBA range for all the partitions
+ for (Idx = 0; Idx < NUM_MBR_PARTITIONS; Idx++)
+ {
+ // ignore partitions whose OSType or Size is zero
+ if ((Mbr->PartRec[Idx].OSType == 0)
+ || (Mbr->PartRec[Idx].SizeInLba == 0))
+ continue;
+
+ if (Mbr->PartRec[Idx].StartingLba == 0)
+ continue;
+
+ PartitionFound++;
+
+ EndLba = Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba - 1;
+
+ // check to make sure the partition does not exceed the length
+ // of the disk
+ if (EndLba > BlockIo->Media->LastBlock)
+ return FALSE;
+
+ // Now loop through all partitions to make sure they don't overlap
+ for (Loop2 = Idx+1; Loop2 < NUM_MBR_PARTITIONS; Loop2++)
+ {
+ // ignore partitions whose OSType or Size is zero
+ if ((Mbr->PartRec[Loop2].OSType == 0)
+ || (Mbr->PartRec[Loop2].SizeInLba == 0))
+ continue;
+
+ // check for overlapping partitions
+ if ( EndLba >= Mbr->PartRec[Loop2].StartingLba )
+ return FALSE;
+ }
+ }
+
+ if (PartitionFound)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: MbrCreateChildHandle
+//
+// Description: Searches Master Boot Record for partitions
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// other - Driver not loaded
+//
+// Referrals: AllocatePool FreePool CheckValidMbr SetMem ReadBlocks
+// CopyMem CreateChildHandle SET_NODE_LENGTH
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+EFI_STATUS MbrCreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_STATUS Status;
+ MASTER_BOOT_RECORD *Mbr = NULL;
+ MASTER_BOOT_RECORD *ExtPart = NULL;
+ UINT8 Idx;
+ UINT32 PartitionExists = 0;
+ PARTITION_DATA PData;
+ EFI_GUID *PartType = NULL;
+ EFI_LBA Lba;
+ HARDDRIVE_DEVICE_PATH HdDp;
+
+
+ // allocate memory for the MBR and then read the data from the disk
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize, &Mbr);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ // check to see if the current drive has a valid MBR and a valid
+ // partition on the drive
+ if (CheckValidMbr(BlockIo, Mbr) == FALSE)
+ {
+ gBS->FreePool(Mbr);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // To get here there is a valid partition
+ // create a handle for the partitions
+
+ // set up the device path header for the partition
+ HdDp.Header.Type = MEDIA_DEVICE_PATH;
+ HdDp.Header.SubType = MEDIA_HARDDRIVE_DP;
+ SET_NODE_LENGTH(&HdDp.Header,sizeof(HARDDRIVE_DEVICE_PATH));
+
+ // Loop through the partitions
+ for (Idx=0; Idx < NUM_MBR_PARTITIONS; Idx++)
+ {
+ // skip over empty partitions
+ if ((Mbr->PartRec[Idx].OSType == 0)
+ || (Mbr->PartRec[Idx].SizeInLba == 0))
+ continue;
+
+ // Take care of repetative data assignment
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // set up the device path for the partition
+ HdDp.MBRType = MBR_TYPE_MASTER_BOOT_RECORD;
+ HdDp.SignatureType = SIGNATURE_TYPE_MBR;
+ pBS->SetMem(&HdDp.Signature,sizeof(HdDp.Signature),0);
+ PData.Handle = NULL;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+
+
+ // Now that a valid partition is found process it
+ // TODO: are there any other types of extended partitions
+ // if so, add them to this if statement
+ if ((Mbr->PartRec[Idx].OSType == EXTENDED_PARTITION) ||
+ (Mbr->PartRec[Idx].OSType == WIN95_EXTENDED_PARTITION))
+ {
+ // process the logical partitions that may or may not exist
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize, &ExtPart);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Mbr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // defines where to start reading the next MBR/partition
+ // table from
+ Lba = Mbr->PartRec[Idx].StartingLba;
+
+ // loop through logical partitions: any number of
+ // possible partitions
+ while (TRUE)
+ {
+ // if the table points back to itself, exit
+ if ( Lba == 0)
+ break;
+
+ // get Partition table from the first block of the device
+ Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ Lba, BlockIo->Media->BlockSize, ExtPart);
+
+ // check to see if the disk was read
+ // Also check for All logical partitions having an OSType
+ // of 0x05 or EXTENDED_PARTITION
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Mbr);
+ gBS->FreePool(ExtPart);
+ return Status;
+ }
+
+ // make sure this is a valid partition
+ if (ExtPart->PartRec[0].OSType == NO_PARTITION)
+ break;
+
+ // check for problems that make the partition invalid
+ if ((Lba + ExtPart->PartRec[0].SizeInLba) >
+ (Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba))
+ break;
+
+ // register the Partition
+ HdDp.PartitionNumber = ++PartitionExists;
+
+ // notice that the start of the partition is after the
+ // partition table
+ HdDp.PartitionStart = ExtPart->PartRec[0].StartingLba + Lba;
+ HdDp.PartitionSize = ExtPart->PartRec[0].SizeInLba;
+ gBS->CopyMem(&HdDp.Signature, &ExtPart->UniqueMbrSig,
+ sizeof(UINT32));
+ PData.StartingLba = HdDp.PartitionStart;
+ PData.EndingLba = HdDp.PartitionStart
+ + ExtPart->PartRec[0].SizeInLba - 1;
+
+ // create device path
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // if the OSType member is 0xEF this variable set.
+ // otherwise it is left as 0
+ if (ExtPart->PartRec[0].OSType == EFI_SYSTEM_PARTITION)
+ gBS->CopyMem(&PData.PartGuid, &gMbrPartition,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ // check to see if the next partition is an extended partition
+ if ((ExtPart->PartRec[1].OSType != EXTENDED_PARTITION) &&
+ (ExtPart->PartRec[1].OSType != WIN95_EXTENDED_PARTITION) )
+ break;
+
+ // get set up for the next partition. The Starting Lba
+ // address is a relative address inside the extended
+ // partition add the starting address of the extended
+ // partition to get the actual LBA where it starts
+ Lba = ExtPart->PartRec[1].StartingLba
+ + Mbr->PartRec[Idx].StartingLba;
+ }
+ }
+
+ else // process primary partition
+ {
+ // set up the device path for the partition
+ HdDp.PartitionNumber = ++PartitionExists;
+ HdDp.PartitionStart = Mbr->PartRec[Idx].StartingLba;
+ HdDp.PartitionSize = Mbr->PartRec[Idx].SizeInLba;
+ gBS->CopyMem(HdDp.Signature, &Mbr->UniqueMbrSig, sizeof(UINT32));
+
+ // create device path
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // save pertinent info
+ PData.StartingLba = Mbr->PartRec[Idx].StartingLba;
+ PData.EndingLba = Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba - 1;
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // if the OSType member is 0xEF is this variable set.
+ // otherwise it is left as 0
+ if (Mbr->PartRec[Idx].OSType == 0xEF)
+ gBS->CopyMem(&PData.PartGuid, &gMbrPartition,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ }
+ }
+
+ gBS->FreePool(Mbr);
+ gBS->FreePool(ExtPart);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Mbr.h b/Core/CORE_DXE/Partition/Mbr.h
new file mode 100644
index 0000000..2aa5123
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Mbr.h
@@ -0,0 +1,171 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.h 7 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 7 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.h $
+//
+// 7 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 6 1/08/08 3:10p Robert
+//
+// 5 1/08/08 3:08p Robert
+//
+// 4 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 3 4/25/07 11:53a Robert
+// Updated for CHM and Coding Standard Compliance
+//
+// 2 4/24/05 12:45a Felixp
+// Definitions of SIGNATURE_TYPE_xxx macroses removed since they are
+// already defined in DevicePath.h
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <Mbr.h>
+//
+// Description: EFI Mbr Partition Generic Driver Header. This header
+// contains Data structures and Definitions needed to recognize
+// partitions in an MBR
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _MBR_H
+#define _MBR_H
+
+#define MBR_SIGNATURE 0xaa55
+#define NUM_MBR_PARTITIONS 4
+
+// Type definitions for the Hard drive device path
+#define MBR_TYPE_MASTER_BOOT_RECORD 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+// Needed Partition Type definitions for MBR
+#define NO_PARTITION 0x0
+#define EXTENDED_PARTITION 0x05
+#define WIN95_EXTENDED_PARTITION 0x0f
+
+
+//<AMI_GHDR_START>
+//------------------------------------------------------------------
+// Name: Data_Structures
+//
+// Description:
+// Data Structures needed for MBR
+//
+// MASTER_BOOT_RECORD - Data Structure definition of the
+// MBR located in the first block on an MBR drive
+//
+// MBR_PARTITION - Data Structure definition for each
+// partition in the MBR
+//
+//------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+#pragma pack(1)
+
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: MBR_PARTITION
+//
+// Description: Data Structure that defines a partition within the MBR
+//
+// Fields:
+// BootIndicator - UINT8 - indicates whether this partition is bootable
+// StartHead - UINT8 - unused in EFI
+// StartSector - UINT8 - unused in EFI
+// StartTrack - UINT8 - unused in EFI
+// OSType - UINT8 - defines type of the partition
+// EndHead - UINT8 - unused in EFI
+// EndSector - UINT8 - unused in EFI
+// EndTrack - UINT8 - unused in EFI
+// StartingLba - UINT32 - LBA where the partiton starts on the hard drive
+// SizeInLba - UINT32 - LBA where the partiton ends on the hard drive
+//
+// Referral:
+// None
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _MBR_PARTITION
+{
+ UINT8 BootIndicator;
+ UINT8 StartHead;
+ UINT8 StartSector;
+ UINT8 StartTrack;
+ UINT8 OSType;
+ UINT8 EndHead;
+ UINT8 EndSector;
+ UINT8 EndTrack;
+ UINT32 StartingLba;
+ UINT32 SizeInLba;
+} MBR_PARTITION;
+
+
+// MBR Partition table
+//============================================================================
+// Structure: MASTER_BOOT_RECORD
+//
+// Description: Data Structure that mimicks the structure of a Master Boot
+// Record on a hard drive
+//
+// Fields:
+// BootCode[440] - UINT8 - executable code in the first 440 bytes of a
+// hard drive
+// UniqueMbrSig - UINT32 - Uniques signature associated with the hard
+// drive
+// Unknown - UINT16 - an unknown portion of the data structure
+// PartRec[4] - MBR_PARTITION - an array of partition entries that
+// define the partitions that exist on the hard drive
+// Sig - UINT16 - 0xaa55 - value that indicates this is an MBR
+//
+// Referral:
+// MBR_PARTITION
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _MASTER_BOOT_RECORD
+{
+ UINT8 BootCode[440];
+ UINT32 UniqueMbrSig;
+ UINT16 Unknown;
+ MBR_PARTITION PartRec[4];
+ UINT16 Sig;
+} MASTER_BOOT_RECORD;
+
+
+#pragma pack()
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.c b/Core/CORE_DXE/Partition/Partition.c
new file mode 100644
index 0000000..78cbb10
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.c
@@ -0,0 +1,1006 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.c 21 10/27/11 3:57p Artems $
+//
+// $Revision: 21 $
+//
+// $Date: 10/27/11 3:57p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.c $
+//
+// 21 10/27/11 3:57p Artems
+// EIP 73250: Verified DriverBinding Stop function frees all resources
+// allocated by Start function
+//
+// 20 10/25/11 12:01p Artems
+// EIP 70530: Fixed bugs reported by SCT 2.3.1
+//
+// 19 8/12/11 12:16p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 18 5/02/11 5:58p Artems
+// EIP 59571: Extended partition driver functionality - support of BlockIO
+// protocol version 3
+//
+// 17 2/05/11 3:52p Artems
+// Removed previous check-in changes
+//
+// 16 1/06/11 5:59p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 15 2/04/10 3:06p Oleksiyy
+// EIP 31633 Minor fixes. OpenProtocol error status handling added to
+// DriverBindingStop function.
+//
+// 14 8/28/09 9:10a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 13 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 12 1/16/09 11:25a Felixp
+// Bug fix in the DriverBindingStop function.
+// The stop function was unconditionally closing disk I/O protocol.
+// The protocol should only be closed when no child devices exist.
+//
+// 11 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 10 4/26/07 9:32a Robert
+// Updated for CHM and Coding Standard compliance
+//
+// 8 3/23/07 5:13p Robert
+// More coding standard changes and updated the copyright date
+//
+// 7 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 6 10/10/06 3:43p Yakovlevs
+// Uncommented GPT Partition discovery
+//
+// 5 8/24/06 12:34p Felixp
+// x64 support (fixes for warnings/errors)
+//
+// 3 10/28/05 8:36p Felixp
+// DriverBindingSupported: Device Path test changed from BY_DRIVER to
+// TEST_PROTOCOL
+//
+// 2 2/08/05 12:50p Felixp
+// Bug fix in ReadBlocks and WriteBlocks: attemp to read/write
+// Last LBA on the partition returned EFI_INVALID_PARAMETER
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Partition.c
+//
+// Description: EFI Partition Generic Driver. Provides the Driver
+// Binding protocol and a Block I/O protocol for Partition detection
+// and interaction
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//;-------------------------------------------------------------------------
+// Includes
+#include "partition.h"
+
+
+//;-------------------------------------------------------------------------
+// Global Variables
+EFI_BOOT_SERVICES *gBS;
+EFI_GUID gUnusedPartitionGuid = EFI_PART_TYPE_UNUSED_GUID;
+static EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+
+EFI_STATUS gDevicePathStatus = EFI_SUCCESS;
+EFI_STATUS gDiskIoStatus = EFI_SUCCESS;
+
+//;-------------------------------------------------------------------------
+//GUID Variables
+static EFI_GUID gDevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+EFI_GUID gBlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+EFI_GUID gDiskIoGuid = EFI_DISK_IO_PROTOCOL_GUID;
+
+//;-------------------------------------------------------------------------
+// Function Prototypes
+EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS EFIAPI DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS EFIAPI DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer);
+
+EFI_STATUS Reset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+EFI_STATUS ReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS WriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS FlushBlocks ( IN EFI_BLOCK_IO_PROTOCOL *PartBlockIo);
+
+//;-------------------------------------------------------------------------
+// Protocol Definition
+EFI_BLOCK_IO_PROTOCOL mPartitionBlockIo =
+{
+ EFI_BLOCK_IO_PROTOCOL_REVISION3,
+ NULL,
+ Reset,
+ ReadBlocks,
+ WriteBlocks,
+ FlushBlocks
+};
+
+
+//;-------------------------------------------------------------------------
+// Partition Driver Binding Procol
+EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding =
+{
+ DriverBindingSupported,
+ DriverBindingStart,
+ DriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+
+//;-------------------------------------------------------------------------
+// Function Definitions
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+//Driver Name
+static UINT16 *gDriverName=L"AMI Partition Driver";
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Procedure: ComponentNameGetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Input:
+// 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 Supported Languages. The number of languages supported by a
+// driver is up to the driver writer.
+//
+// Output:
+// 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 thedriver 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.
+//
+// Referrals:
+//
+// Notes:
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: ComponentNameGetDriverName
+//
+// Description: Returns the Driver Name if the language is supported
+//
+// Input:
+// This - Pointer to the instance of this driver
+// Language - Current operating language
+// DriverName - return parameter that will contain the Driver's Name
+//
+// Output: DriverName - return parameter that will contain the Driver's Name
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// EFI_INVALID_PARAMETER - If the Language or DriverName variable is
+// not defined
+// EFI_UNSUPPORTED - If the current laungage is not supported
+//
+// Referrals:
+//
+// Notes:
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName)
+{
+ //Supports only English
+ if (!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName =
+{
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+#endif
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: PartitionEntryPoint
+//
+// Description: Register Driver Binding protocol for this driver.
+//
+// Input:
+// ImageHandle - Identification Handle for the Partition
+// Block I/O driver
+// *SystemTable - Pointer to the EFI System Table
+//
+// Returns:
+// EFI_SUCCESS - Driver Binding Protocol Loaded
+// other - Driver Binding Protocol not loaded
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PartitionEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ gBS = SystemTable->BootServices;
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gPartitionDriverBinding.DriverBindingHandle = NULL;
+ gPartitionDriverBinding.ImageHandle = ImageHandle;
+
+ // Install driver binding protocol here
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gPartitionDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gPartitionDriverBinding,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid, &gComponentName,
+#endif
+ NULL);
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingSupported
+//
+// Description: Test to see if this driver supports ControllerHandle. Any
+// ControllerHandle than contains a BlockIo and DiskIo protocol can be
+// supported.
+//
+// Input:
+// This - Protocol instance pointer.
+// ControllerHandle - Handle of device to test
+// RemainingDevicePath - Not used
+//
+// Output: None
+//
+// 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
+//
+// Referrals: OpenProtocol CloseProtocol
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_STATUS Status;
+
+ // see if the DevicePath is installed on controllerHandle
+ Status = gBS->OpenProtocol(ControllerHandle, &gDevicePathGuid,
+ NULL, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Close the Device Path Protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ // see if the DiskIo has already been started on controllerHandle
+ Status = gBS->OpenProtocol(ControllerHandle, &gDiskIoGuid,
+ &DiskIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Close the DiskIo protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ // Now check for BlockIo Protocol
+ Status = gBS->OpenProtocol(ControllerHandle, &gBlockIoGuid,
+ NULL, This->DriverBindingHandle, ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ // return the status of finding the BlockIo protocol.
+ // if it gets this far the driver supports this device
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingStart
+//
+// 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.
+//
+// Input:
+// This - Protocol instance pointer.
+// ControllerHandle - Handle of device to bind driver to
+// RemainingDevicePath - Not used
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - This driver is added to DeviceHandle
+// other - This driver does not support this device
+//
+// Referrals: OpenProtocol CloseProtocol GptDiscoverPartitions
+// ElToritoCreateChildHandle MbrCreateChildHandle
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS EFIAPI DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ // Open the BlockIo protocol first because we are opening it by
+ // GET_PROTOCOL, if this fails it does not need to be closed. It is
+ // opened by GET_PROTOCOL because DiskIo already opens it BY_DRIVER
+ Status = gBS->OpenProtocol(ControllerHandle, &gBlockIoGuid,
+ &BlockIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ Status = gBS->OpenProtocol(ControllerHandle, &gDevicePathGuid,
+ &ParentDevicePath, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ // Check to see if the Controller has already been started by
+ // another driver
+ // Now open the DiskIo protocol for the controller
+ Status = gBS->OpenProtocol(ControllerHandle, &gDiskIoGuid,
+ &DiskIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR (Status))
+ {
+ // if there is an error, close all opened protocols, only close
+ // this one if
+ // Close the Device Path protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ return Status;
+ }
+
+
+ // parse the devices and create the child handles
+ if (BlockIo->Media->MediaPresent == TRUE)
+ {
+ Status = EFI_NOT_FOUND;
+
+ // search for the children
+ Status = GptDiscoverPartitions(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+
+ if (EFI_ERROR(Status))
+ Status = ElToritoCreateChildHandle(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+
+ if (EFI_ERROR(Status))
+ Status = MbrCreateChildHandle(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+ }
+
+ else
+ Status = EFI_NO_MEDIA;
+
+
+ // Now close all protocols That were not already started
+ if (EFI_ERROR(Status) )
+ {
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingStop
+//
+// Description: Stop this driver on ControllerHandle. Support stoping
+// any child handles created by this driver.
+//
+// Input:
+// This - Protocol instance pointer.
+// DeviceHandle - 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.
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - This driver is removed DeviceHandle
+// other - This driver was not removed from this device
+//
+// Referrals: CloseProtocol OpenProtocol FlushBlocks MemCmp FreePool
+// UninstallMultipleProtocolInterfaces
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS EFIAPI DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+
+ EFI_HANDLE Handle = *ChildHandleBuffer;
+ PARTITION_DATA *Child = NULL;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_GUID *PartType = NULL;
+ BOOLEAN ChildrenLeft = FALSE;
+ EFI_STATUS Status;
+ UINTN Idx = 0;
+
+
+ // Close these protocols if there are no children left
+ if (NumberOfChildren == 0)
+ {
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ return EFI_SUCCESS;
+ }
+
+ // There are children, uninstall protocols and uninstall interfaces,
+ // and free memory
+ while (Idx < NumberOfChildren)
+ {
+ Status = gBS->OpenProtocol(ChildHandleBuffer[Idx], &gBlockIoGuid,
+ (VOID **)&BlockIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(Status))
+ {
+ Idx++;
+ continue;
+ }
+
+ Child = (PARTITION_DATA *)BlockIo;
+
+ // clear all buffers for the current device
+ BlockIo->FlushBlocks(BlockIo);
+
+ // now close all handles
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ChildHandleBuffer[Idx]);
+
+ // look for a non 0 Partition type GUID
+ // if non zero, set the point to the address, otherwise leave pointer
+ // as zero
+ if (MemCmp(&Child->PartGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID)))
+ PartType = &Child->PartGuid;
+
+ // Create the new handle for the child device
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Idx],
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+
+ if (EFI_ERROR(Status))
+ ChildrenLeft = TRUE;
+
+ // free the memory that was allocated for The Child handle and the
+ // device path for the child handle
+
+
+ if (Child->DevPath != NULL)
+ gBS->FreePool(Child->DevPath);
+
+ if (Child->BlockIo.Media != NULL)
+ gBS->FreePool(Child->BlockIo.Media);
+
+ gBS->FreePool(Child);
+
+
+ // Increment Child Handle Pointer
+ Idx++;
+
+ // clear PartGuid pointer for the next child
+ PartType = NULL;
+ }
+
+ // if there are childrem left, exit with error
+ if (ChildrenLeft == TRUE)
+ return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: Reset
+//
+// Description: Reset the parent Block Device.
+//
+// Input:
+// This - Protocol instance pointer.
+// ExtendedVerification - Driver may perform diagnostics on reset.
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - The device was reset.
+// EFI_DEVICE_ERROR - The device is not functioning properly and could
+// not be reset.
+//
+// Referrals: ParentBlockIo->Reset
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Reset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ PARTITION_DATA *PartData;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent's BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ return PartData->ParentBlockIo->Reset(PartData->ParentBlockIo,
+ ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: ReadBlocks
+//
+// Description: Reads blocks from the parent device
+//
+// Input:
+// 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.
+//
+// Output:
+// Buffer - Buffer containing read data
+//
+// Return:
+// 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 match 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.
+//
+// Referrals: Mul64 ReadDisk
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadBlocks ( IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ PARTITION_DATA *PartData;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT64 Start;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ if(MediaId != PartData->BlockIo.Media->MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if(BufferSize == 0)
+ return EFI_SUCCESS;
+
+ if (BufferSize % PartData->BlockIo.Media->BlockSize != 0)
+ return EFI_BAD_BUFFER_SIZE;
+
+ // calculate the byte from which to start the read
+ Start = (Mul64(PartData->StartingLba,
+ PartData->ParentBlockIo->Media->BlockSize) +
+ Mul64(Lba, This->Media->BlockSize));
+
+ // check to see if the read will go beyond the end of the
+ // current partition
+ if ( ((Start + BufferSize - 1) >=
+ Mul64(PartData->EndingLba+1,
+ PartData->ParentBlockIo->Media->BlockSize)) ||
+ (Buffer == NULL))
+ return EFI_INVALID_PARAMETER;
+
+
+ // Make call directly to DiskIo of the device
+
+ DiskIo = PartData->ParentDiskIo;
+
+ return DiskIo->ReadDisk(DiskIo, MediaId, Start, BufferSize, Buffer);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: WriteBlocks
+//
+// Description: Write blocks to the parent device
+//
+// Input:
+// 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
+//
+// Output: None
+//
+// Return:
+// 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_CHANGED - The MediaId does not match 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.
+//
+// Referrals: Mul64 WriteDisk
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+)
+{
+ PARTITION_DATA *PartData;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT64 Start;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ if(MediaId != PartData->BlockIo.Media->MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if (BufferSize % PartData->BlockIo.Media->BlockSize != 0)
+ return EFI_BAD_BUFFER_SIZE;
+
+ // calculated the start address of the write command
+ Start = Mul64(PartData->StartingLba,
+ PartData->ParentBlockIo->Media->BlockSize) +
+ Mul64(Lba, This->Media->BlockSize);
+
+ if ( ((Start + BufferSize - 1) >=
+ Mul64(PartData->EndingLba+1,
+ PartData->ParentBlockIo->Media->BlockSize)) ||
+ (Buffer == NULL))
+ return EFI_INVALID_PARAMETER;
+
+ DiskIo = PartData->ParentDiskIo;
+
+ return DiskIo->WriteDisk(DiskIo, MediaId, Start, BufferSize, Buffer);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: FlushBlocks
+//
+// Description: Flush the parent Block Device.
+//
+// Input: This - Protocol instance pointer.
+//
+// Output: None
+//
+// Return:
+// 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.
+//
+// Referrals: ParentBlockIo->FlushBlocks
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+)
+{
+ PARTITION_DATA *PartData;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PartData = (PARTITION_DATA *) This;
+
+ // return the same value that the device specific BlockIo instance returns
+ return PartData->ParentBlockIo->FlushBlocks(PartData->ParentBlockIo);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: CreateChildHandle
+//
+// Description: Generic create child handle for the partition driver. This
+// should work for GPT, MBR, and El Torito.
+//
+// Input:
+// *This - Pointer to the current instance of the blockIo protocol
+// *PData - a pointer to the start of the private data structure for
+// the partition
+// BlockSize - the blocksize for the partition
+//
+// Output:
+//
+// Return:
+// EFI_SUCCESS - Child created
+// other - no child created
+//
+// Referrals: AllocatePool FreePool CopyMem MemCmp Div64 OpenProtocol
+// InstallMultipleProtocolInterfaces UninstallMultipleProtocolInterfaces
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN PARTITION_DATA *PData,
+ IN UINT32 BlockSize
+)
+{
+ PARTITION_DATA *Child;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_STATUS Status;
+ EFI_GUID *PartType = NULL;
+ UINTN Temp;
+
+
+ // allocate memory for the Child handle
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(PARTITION_DATA), &Child);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(EFI_BLOCK_IO_MEDIA), &Media);
+ if (EFI_ERROR(Status)) {
+ gBS->FreePool(Child);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Copy the data from one location to the other,
+ gBS->CopyMem(Child, PData, sizeof(PARTITION_DATA));
+
+ // get the BlockIo protocol for the partition driver and the
+ // media information from the parent device
+ gBS->CopyMem(&Child->BlockIo, &mPartitionBlockIo, sizeof(EFI_BLOCK_IO_PROTOCOL));
+
+ // just point to the media info for the device, that way we don't have to
+ // worry about changing values
+ Child->BlockIo.Media = Media;
+
+ gBS->CopyMem(Media, PData->ParentBlockIo->Media, sizeof(EFI_BLOCK_IO_MEDIA));
+
+ Media->LogicalPartition = TRUE;
+ Media->BlockSize = BlockSize;
+ Media->IoAlign = 1; //no alignment requirements
+ Media->LowestAlignedLba = 0; //added in Revision 2
+ Media->LogicalBlocksPerPhysicalBlock = 0; //added in Revision 2
+ Media->OptimalTransferLengthGranularity = 0; //added in Revision 3
+
+ // Calculate the last block of the partition
+ Media->LastBlock = Div64( Mul64(PData->EndingLba - PData->StartingLba + 1,
+ Child->ParentBlockIo->Media->BlockSize),
+ BlockSize, &Temp) - 1;
+
+ // look for a non 0 Partition type GUID
+ // if non zero, set the point to the address, otherwise leave
+ // pointer as zero
+ if (MemCmp(&Child->PartGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID)))
+ PartType = &Child->PartGuid;
+
+ // Create the new handle for the child device
+ Child->Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Child->Handle,
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+
+ // Now open the diskIo protocol for the child, if the install multiple
+ // protocol interface returns SUCCESS
+ if (!EFI_ERROR(Status)) {
+ Status = gBS->OpenProtocol ( Child->ParentHandle,
+ &gDiskIoGuid,
+ &Child->ParentDiskIo,
+ This->DriverBindingHandle,
+ Child->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ if (EFI_ERROR(Status)) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ &Child->Handle,
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+ //free all resources
+ gBS->FreePool(Child->DevPath);
+ gBS->FreePool(Media);
+ gBS->FreePool(Child);
+ }
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.cif b/Core/CORE_DXE/Partition/Partition.cif
new file mode 100644
index 0000000..feaa5cb
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Partition"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\Partition\"
+ RefName = "Partition"
+[files]
+"Partition.sdl"
+"ElTorito.c"
+"ElTorito.h"
+"Gpt.c"
+"Gpt.h"
+"Mbr.c"
+"Mbr.h"
+"Partition.c"
+"Partition.h"
+<endComponent>
diff --git a/Core/CORE_DXE/Partition/Partition.h b/Core/CORE_DXE/Partition/Partition.h
new file mode 100644
index 0000000..047cfc8
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.h
@@ -0,0 +1,188 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.h 10 8/12/11 12:16p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 8/12/11 12:16p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.h $
+//
+// 10 8/12/11 12:16p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 9 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 8 1/08/08 2:47p Robert
+//
+// 7 1/08/08 2:47p Robert
+//
+// 6 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 5 4/25/07 12:44p Robert
+// updates for CHM and Coding Standard Compliance
+//
+// 3 4/24/05 12:45a Felixp
+// Definitions of SIGNATURE_TYPE_xxx macroses removed since they are
+// already defined in DevicePath.h
+//
+// 6 12/14/04 6:14p Robert
+// Added component name protocol support
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Partition.h
+//
+// Description: EFI Partition Generic Driver Header. This file
+// contains the GUIDs used by this driver. It also contains
+// Definitions and Data Structures needed by the generic portion of
+// the Partition driver.
+//
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _PARTITION_H
+#define _PARTITION_H
+
+
+#include <AmiDxeLib.h>
+
+// protocols consumed
+#include <protocol\BlockIo.h>
+#include <protocol\DiskIo.h>
+#include <protocol\DevicePath.h>
+#include <protocol\DriverBinding.h>
+#include <Protocol\ComponentName2.h>
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_GUID gUnusedPartitionGuid;
+
+//=============================================================================
+// GUID Definitions
+
+#define EFI_PART_TYPE_UNUSED_GUID \
+ { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \
+ { 0xc12a7328, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b}
+
+#define EFI_PART_TYPE_LEGACY_MBR_GUID \
+ { 0x024dee41, 0x33e7, 0x11d3, 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f}
+
+
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define EFI_SYSTEM_PARTITION 0xef
+
+
+//=============================================================================
+// Structure definitions
+
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: OPCODE_CMD
+//
+// Description: Data Structure definition of the Private data for each instance
+// of the Partition Block I/O driver
+//
+// Fields:
+// BlockIo - EFI_BLOCK_IO_PROTOCOL - Pointer to the EFI_BLOCK_IO_PROTOCOL
+// protocol for this partition
+// Handle - EFI_HANDLE - child handle for this partition
+// ParentBlockIo - EFI_BLOCK_IO_PROTOCOL * - pointer to the
+// EFI_BLOCK_IO_PROTOCOL of the parent device
+// ParentDiskIo - EFI_DISK_IO_PROTOCOL * - pointer to the
+// EFI_DISK_IO_PROTOCOL of the parent device
+// DevPath - EFI_DEVICE_PATH_PROTOCOL * - pointer to the device path
+// for this device
+// StartingLba - EFI_LBA - The starting Lba of the current partition
+// EndingLba - EFI_LBA - The ending Lba of the current partition
+// PartGuid - EFI_GUID - The GUID assigned to the partition
+// ParentHandle - EFI_HANDLE - the handle assigned to the parent device
+//
+// Referral:
+// None
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _PARTITION_DATA
+{
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_HANDLE Handle;
+ EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
+ EFI_DISK_IO_PROTOCOL *ParentDiskIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+
+ EFI_LBA StartingLba;
+ EFI_LBA EndingLba;
+ EFI_GUID PartGuid;
+
+ EFI_HANDLE ParentHandle;
+} PARTITION_DATA;
+
+
+//=============================================================================
+// Function Prototypes
+EFI_STATUS CreateChildHandle(EFI_DRIVER_BINDING_PROTOCOL *This, PARTITION_DATA *PData,
+ UINT32 BlockSize);
+
+EFI_STATUS GptDiscoverPartitions (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+EFI_STATUS ElToritoCreateChildHandle (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+EFI_STATUS MbrCreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.sdl b/Core/CORE_DXE/Partition/Partition.sdl
new file mode 100644
index 0000000..a846251
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.sdl
@@ -0,0 +1,4 @@
+PATH
+ Name = "PARTITION_DIR"
+End
+