Index: MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h =================================================================== --- MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h (revision 9332) +++ MdeModulePkg/Universal/Disk/PartitionDxe/Partition.h (working copy) @@ -399,6 +399,75 @@ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ); +/** + Install child handles if the Handle supports Apple format. + + @param This Calling context. + @param Handle Parent Handle. + @param DiskIo Parent DiskIo interface. + @param BlockIo Parent BlockIo interface. + @param DevicePath Parent Device Path. + + @retval EFI_SUCCESS A child handle was added. + @retval EFI_MEDIA_CHANGED Media change was detected. + @retval Others MBR partition was not found. + +**/ +EFI_STATUS +PartitionInstallAppleChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Install child handles if the Handle supports Apple format. + + @param This Calling context. + @param Handle Parent Handle. + @param DiskIo Parent DiskIo interface. + @param BlockIo Parent BlockIo interface. + @param DevicePath Parent Device Path. + + @retval EFI_SUCCESS A child handle was added. + @retval EFI_MEDIA_CHANGED Media change was detected. + @retval Others Apple partition was not found. + +**/ +EFI_STATUS +PartitionInstallAppleChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +/** + Install child handles if the Handle supports Apple format. + + @param This Calling context. + @param Handle Parent Handle. + @param DiskIo Parent DiskIo interface. + @param BlockIo Parent BlockIo interface. + @param DevicePath Parent Device Path. + + @retval EFI_SUCCESS A child handle was added. + @retval EFI_MEDIA_CHANGED Media change was detected. + @retval Others Apple partition was not found. + +**/ +EFI_STATUS +PartitionInstallAppleChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + typedef EFI_STATUS (*PARTITION_DETECT_ROUTINE) ( Index: MdeModulePkg/Universal/Disk/PartitionDxe/Apple.c =================================================================== --- MdeModulePkg/Universal/Disk/PartitionDxe/Apple.c (revision 0) +++ MdeModulePkg/Universal/Disk/PartitionDxe/Apple.c (revision 0) @@ -0,0 +1,208 @@ +/** @file + Decode an Apple formatted partition table + + Copyright (c) 2009, Sun Microsystems. +**/ + + +#include "Partition.h" + +#define DPISTRLEN 32 + +#pragma pack(1) +typedef struct APPLE_PT_HEADER { + UINT16 sbSig; /* must be BE 0x4552 */ + UINT16 sbBlkSize; /* block size of device */ + UINT32 sbBlkCount; /* number of blocks on device */ + UINT16 sbDevType; /* device type */ + UINT16 sbDevId; /* device id */ + UINT32 sbData; /* not used */ + UINT16 sbDrvrCount; /* driver descriptor count */ + UINT16 sbMap[247]; /* descriptor map */ +} APPLE_PT_HEADER; + +typedef struct APPLE_PT_ENTRY { + UINT16 signature ; /* must be BE 0x504D for new style PT */ + UINT16 reserved_1 ; + UINT32 map_entries ; /* how many PT entries are there */ + UINT32 pblock_start ; /* first physical block */ + UINT32 pblocks ; /* number of physical blocks */ + char name[DPISTRLEN] ; /* name of partition */ + char type[DPISTRLEN] ; /* type of partition */ + /* Some more data we don't really need */ +} APPLE_PT_ENTRY; +#pragma pack() + +static UINT16 +be16_to_cpu(UINT16 x) +{ + return SwapBytes16(x); +} + +static UINT32 +be32_to_cpu(UINT32 x) +{ + return SwapBytes32(x); +} + + +/** + Install child handles if the Handle supports Apple partition table format. + + @param[in] This Calling context. + @param[in] Handle Parent Handle + @param[in] DiskIo Parent DiskIo interface + @param[in] BlockIo Parent BlockIo interface + @param[in] DevicePath Parent Device Path + + + @retval EFI_SUCCESS Child handle(s) was added + @retval EFI_MEDIA_CHANGED Media changed Detected + @retval other no child handle was added + +**/ +EFI_STATUS +PartitionInstallAppleChildHandles ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_STATUS Status; + UINT32 Lba; + EFI_BLOCK_IO_MEDIA *Media; + VOID *Block; + //UINTN MaxIndex; + /** @todo: wrong, as this PT can be on both HDD or CD */ + CDROM_DEVICE_PATH CdDev; + //EFI_DEVICE_PATH_PROTOCOL Dev; + EFI_STATUS Found; + UINT32 Partition; + UINT32 PartitionEntries; + UINT32 VolSpaceSize; + UINT32 SubBlockSize; + UINT32 BlkPerSec; + + Found = EFI_NOT_FOUND; + Media = BlockIo->Media; + VolSpaceSize = 0; + + Block = AllocatePool ((UINTN) Media->BlockSize); + + if (Block == NULL) { + return EFI_NOT_FOUND; + } + + do { + APPLE_PT_HEADER * Header; + + /* read PT header first */ + Lba = 0; + + Status = DiskIo->ReadDisk ( + DiskIo, + Media->MediaId, + MultU64x32 (Lba, Media->BlockSize), + Media->BlockSize, + Block + ); + if (EFI_ERROR (Status)) + { + Found = Status; + break; + } + + Header = (APPLE_PT_HEADER *)Block; + if (be16_to_cpu(Header->sbSig) != 0x4552) + { + break; + } + SubBlockSize = be16_to_cpu(Header->sbBlkSize); + BlkPerSec = Media->BlockSize / SubBlockSize; + + /* Fail if media block size isn't an exact multiple */ + if (Media->BlockSize != SubBlockSize * BlkPerSec) + { + break; + } + + /* Now iterate over PT entries and install child handles */ + PartitionEntries = 1; + for (Partition = 1; Partition <= PartitionEntries; Partition++) + { + APPLE_PT_ENTRY * Entry; + UINT32 StartLba; + UINT32 SizeLbs; + + Status = DiskIo->ReadDisk ( + DiskIo, + Media->MediaId, + MultU64x32 (Partition, SubBlockSize), + SubBlockSize, + Block + ); + + if (EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + goto done; /* would break, but ... */ + } + + Entry = (APPLE_PT_ENTRY *)Block; + + if (be16_to_cpu(Entry->signature) != 0x504D) + { + Print(L"Not a new PT entry: %x", Entry->signature); + continue; + } + + /* First partition contains partitions count */ + if (Partition == 1) + { + PartitionEntries = be32_to_cpu(Entry->map_entries); + } + + StartLba = be32_to_cpu(Entry->pblock_start); + SizeLbs = be32_to_cpu(Entry->pblocks); + + if (0 && CompareMem("Apple_HFS", Entry->type, 10) == 0) + Print(L"HFS partition (%d of %d) at LBA 0x%x size=%dM\n", + Partition, PartitionEntries, StartLba, + (UINT32)(MultU64x32(SizeLbs, SubBlockSize) / (1024 * 1024))); + + ZeroMem (&CdDev, sizeof (CdDev)); + CdDev.Header.Type = MEDIA_DEVICE_PATH; + CdDev.Header.SubType = MEDIA_CDROM_DP; + SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev)); + + CdDev.BootEntry = 0; + /* Convert from partition to media blocks */ + CdDev.PartitionStart = StartLba / BlkPerSec; /* start, LBA */ + CdDev.PartitionSize = SizeLbs / BlkPerSec; /* size, LBs */ + + Status = PartitionInstallChildHandle ( + This, + Handle, + DiskIo, + BlockIo, + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &CdDev, + CdDev.PartitionStart, + CdDev.PartitionStart + CdDev.PartitionSize - 1, + SubBlockSize, + FALSE + ); + + if (!EFI_ERROR (Status)) { + Found = EFI_SUCCESS; + } + } + + } while (0); + + done: + FreePool (Block); + + return Found; +} Index: MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf =================================================================== --- MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf (revision 9332) +++ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf (working copy) @@ -41,6 +41,7 @@ Mbr.c Gpt.c ElTorito.c + Apple.c Partition.c Partition.h Index: MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c =================================================================== --- MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c (revision 9332) +++ MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c (working copy) @@ -34,6 +34,7 @@ // Prioritized function list to detect partition table. // PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = { + PartitionInstallAppleChildHandles, PartitionInstallGptChildHandles, PartitionInstallElToritoChildHandles, PartitionInstallMbrChildHandles,