20#define EFI_SIZE_TO_BLOCKS(a, blocksize) (((a) / (blocksize)) + (((a) % (blocksize)) ? 1 : 0))
48 GptHdrCrc = PartHeader->Header.CRC32;
53 PartHeader->Header.CRC32 = 0;
60 PartHeader->Header.CRC32 = GptHdrCrc;
62 return (GptHdrCrc == Crc);
85 Size = (
UINTN)
MultU64x32 (PartHeader->NumberOfPartitionEntries, PartHeader->SizeOfPartitionEntry);
88 return (BOOLEAN)(PartHeader->PartitionEntryArrayCRC32 == Crc);
107 IN BOOLEAN IsPrimaryHeader,
115 UINT64 PartitionEntryArraySize;
116 UINT64 PartitionEntryBlockNumb;
117 UINT32 EntryArraySizeRemainder;
119 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
121 if (IsPrimaryHeader) {
124 Lba = ParentBlockDev->LastBlock;
129 (PartHdr->MyLBA != Lba) ||
133 DEBUG ((DEBUG_ERROR,
"Invalid efi partition table header\n"));
140 if (PartHdr->NumberOfPartitionEntries >
DivU64x32 (MAX_UINTN, PartHdr->SizeOfPartitionEntry)) {
141 DEBUG ((DEBUG_ERROR,
"Memory overflow in GPT Entry Array\n"));
145 PartitionEntryArraySize =
MultU64x32 (PartHdr->NumberOfPartitionEntries, PartHdr->SizeOfPartitionEntry);
146 EntryArraySizeRemainder = 0;
147 PartitionEntryBlockNumb =
DivU64x32Remainder (PartitionEntryArraySize, ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
148 if (EntryArraySizeRemainder != 0) {
149 PartitionEntryBlockNumb++;
152 if (IsPrimaryHeader) {
153 EntryArrayLastLba = PartHdr->FirstUsableLBA;
155 EntryArrayLastLba = ParentBlockDev->LastBlock;
161 if (PartHdr->PartitionEntryLBA + PartitionEntryBlockNumb > EntryArrayLastLba) {
162 DEBUG ((DEBUG_ERROR,
"GPT Partition Entry Array Error!\n"));
163 DEBUG ((DEBUG_ERROR,
"PartitionEntryArraySize = %lu.\n", PartitionEntryArraySize));
164 DEBUG ((DEBUG_ERROR,
"PartitionEntryLBA = %lu.\n", PartHdr->PartitionEntryLBA));
165 DEBUG ((DEBUG_ERROR,
"PartitionEntryBlockNumb = %lu.\n", PartitionEntryBlockNumb));
166 DEBUG ((DEBUG_ERROR,
"EntryArrayLastLba = %lu.\n", EntryArrayLastLba));
195 UINT64 PartitionEntryArraySize;
196 UINT64 PartitionEntryBlockNumb;
197 UINT32 EntryArraySizeRemainder;
210 PartitionEntryBuffer =
NULL;
211 PartitionEntryStatus =
NULL;
213 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
216 PartitionEntryArraySize =
MultU64x32 (PartHdr->NumberOfPartitionEntries, PartHdr->SizeOfPartitionEntry);
217 EntryArraySizeRemainder = 0;
218 PartitionEntryBlockNumb =
DivU64x32Remainder (PartitionEntryArraySize, ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
219 if (EntryArraySizeRemainder != 0) {
220 PartitionEntryBlockNumb++;
223 PartitionEntryArraySize =
MultU64x32 (PartitionEntryBlockNumb, ParentBlockDev->BlockSize);
226 if (PartitionEntryBuffer ==
NULL) {
227 DEBUG ((DEBUG_ERROR,
"Allocate memory error!\n"));
232 if (PartitionEntryStatus ==
NULL) {
233 DEBUG ((DEBUG_ERROR,
"Allocate memory error!\n"));
242 PartHdr->PartitionEntryLBA,
243 (
UINTN)PartitionEntryArraySize,
246 if (EFI_ERROR (Status)) {
247 DEBUG ((DEBUG_ERROR,
"Read partition entry array error!\n"));
252 DEBUG ((DEBUG_ERROR,
"Partition entries CRC check fail\n"));
256 for (Index1 = 0; Index1 < PartHdr->NumberOfPartitionEntries; Index1++) {
257 Entry = (
EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntryBuffer + Index1 * PartHdr->SizeOfPartitionEntry);
258 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
262 StartingLBA = Entry->StartingLBA;
263 EndingLBA = Entry->EndingLBA;
264 if ((StartingLBA > EndingLBA) ||
265 (StartingLBA < PartHdr->FirstUsableLBA) ||
266 (StartingLBA > PartHdr->LastUsableLBA) ||
267 (EndingLBA < PartHdr->FirstUsableLBA) ||
268 (EndingLBA > PartHdr->LastUsableLBA)
271 PartitionEntryStatus[Index1].OutOfRange =
TRUE;
275 if ((Entry->Attributes & BIT1) != 0) {
279 PartitionEntryStatus[Index1].OsSpecific =
TRUE;
282 for (Index2 = Index1 + 1; Index2 < PartHdr->NumberOfPartitionEntries; Index2++) {
283 Entry = (
EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntryBuffer + Index2 * PartHdr->SizeOfPartitionEntry);
284 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
288 if ((Entry->EndingLBA >= StartingLBA) && (Entry->StartingLBA <= EndingLBA)) {
292 PartitionEntryStatus[Index1].Overlap =
TRUE;
293 PartitionEntryStatus[Index2].Overlap =
TRUE;
299 for (Index = 0; Index < PartHdr->NumberOfPartitionEntries; Index++) {
300 if (
CompareGuid (&PartitionEntryBuffer[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
301 PartitionEntryStatus[Index].OutOfRange ||
302 PartitionEntryStatus[Index].Overlap ||
303 PartitionEntryStatus[Index].OsSpecific)
312 if (PrivateData->BlockDeviceCount >= PEI_FAT_MAX_BLOCK_DEVICE) {
317 BlockDevPtr = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
319 BlockDevPtr->BlockSize = ParentBlockDev->BlockSize;
320 BlockDevPtr->LastBlock = PartitionEntryBuffer[Index].
EndingLBA;
321 BlockDevPtr->IoAlign = ParentBlockDev->IoAlign;
322 BlockDevPtr->Logical =
TRUE;
323 BlockDevPtr->PartitionChecked =
FALSE;
325 PartitionEntryBuffer[Index].StartingLBA,
326 ParentBlockDev->BlockSize
328 BlockDevPtr->ParentDevNo = ParentBlockDevNo;
330 PrivateData->BlockDeviceCount++;
332 DEBUG ((DEBUG_INFO,
"Find GPT Partition [0x%lx", PartitionEntryBuffer[Index].StartingLBA));
333 DEBUG ((DEBUG_INFO,
", 0x%lx]\n", BlockDevPtr->LastBlock));
334 DEBUG ((DEBUG_INFO,
" BlockSize %x\n", BlockDevPtr->BlockSize));
338 if (PartitionEntryBuffer !=
NULL) {
342 if (PartitionEntryStatus !=
NULL) {
376 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
382 GptHeaderLBA = ParentBlockDev->LastBlock;
389 ParentBlockDev->BlockSize,
392 if (EFI_ERROR (Status)) {
429 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
438 ParentBlockDev->BlockSize,
441 if (EFI_ERROR (Status)) {
442 DEBUG ((DEBUG_ERROR,
"GPT Error When Read Protective Mbr From Partition!\n"));
446 if (ProtectiveMbr->Signature != MBR_SIGNATURE) {
447 DEBUG ((DEBUG_ERROR,
"Protective Mbr Signature is invalid!\n"));
456 for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
458 if ((MbrPartition->BootIndicator == 0x00) &&
459 (MbrPartition->StartSector == 0x02) &&
460 (MbrPartition->OSIndicator == PMBR_GPT_PARTITION) &&
461 (UNPACK_UINT32 (MbrPartition->StartingLBA) == 1)
468 DEBUG ((DEBUG_ERROR,
"Protective Mbr, All Partition Entry Are Empty!\n"));
494 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
498 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
499 if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {
500 DEBUG ((DEBUG_ERROR,
"Device BlockSize %x exceed FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));
510 DEBUG ((DEBUG_ERROR,
"Primary GPT Header Error, Try to Check Backup GPT Header!\n"));
515 ParentBlockDev->PartitionChecked =
TRUE;
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
UINT32 EFIAPI CalculateCrc32(IN VOID *Buffer, IN UINTN Length)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
EFI_STATUS FatReadBlock(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN BlockDeviceNo, IN EFI_PEI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer)
BOOLEAN PartitionCheckGptHeader(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN ParentBlockDevNo, IN BOOLEAN IsPrimaryHeader, IN EFI_PARTITION_TABLE_HEADER *PartHdr)
BOOLEAN PartitionCheckGptStructure(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN ParentBlockDevNo, IN BOOLEAN IsPrimary)
BOOLEAN PartitionCheckGptEntryArrayCRC(IN EFI_PARTITION_TABLE_HEADER *PartHeader, IN EFI_PARTITION_ENTRY *PartEntry)
BOOLEAN PartitionCheckGptHeaderCRC(IN EFI_PARTITION_TABLE_HEADER *PartHeader)
BOOLEAN PartitionCheckGptEntryArray(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN ParentBlockDevNo, IN EFI_PARTITION_TABLE_HEADER *PartHdr)
BOOLEAN PartitionCheckProtectiveMbr(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN ParentBlockDevNo)
BOOLEAN FatFindGptPartitions(IN PEI_FAT_PRIVATE_DATA *PrivateData, IN UINTN ParentBlockDevNo)
#define DEBUG(Expression)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
#define EFI_SIZE_TO_PAGES(Size)
#define PRIMARY_PART_HEADER_LBA
#define EFI_PTAB_HEADER_ID