]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/FatPei/Mbr.c
FatPkg/FatPei: Fix few typos
[mirror_edk2.git] / FatPkg / FatPei / Mbr.c
CommitLineData
6aac772c
CC
1/** @file\r
2 Routines supporting partition discovery and\r
3 logical device reading\r
4\r
5Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
6\r
eb6cb4ce 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
6aac772c
CC
8\r
9**/\r
10\r
11#include <IndustryStandard/Mbr.h>\r
12#include "FatLitePeim.h"\r
13\r
14/**\r
15 Test to see if the Mbr buffer is a valid MBR\r
16\r
17 @param[in] Mbr Parent Handle\r
18 @param[in] LastLba Last Lba address on the device.\r
19\r
20 @retval TRUE Mbr is a Valid MBR\r
21 @retval FALSE Mbr is not a Valid MBR\r
22\r
23**/\r
24BOOLEAN\r
25PartitionValidMbr (\r
26 IN MASTER_BOOT_RECORD *Mbr,\r
27 IN EFI_PEI_LBA LastLba\r
28 )\r
29{\r
30 UINT32 StartingLBA;\r
31 UINT32 EndingLBA;\r
32 UINT32 NewEndingLBA;\r
33 INTN Index1;\r
34 INTN Index2;\r
35 BOOLEAN MbrValid;\r
36\r
37 if (Mbr->Signature != MBR_SIGNATURE) {\r
38 return FALSE;\r
39 }\r
40 //\r
41 // The BPB also has this signature, so it can not be used alone.\r
42 //\r
43 MbrValid = FALSE;\r
44 for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {\r
45 if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {\r
46 continue;\r
47 }\r
48\r
49 MbrValid = TRUE;\r
50 StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);\r
51 EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;\r
52 if (EndingLBA > LastLba) {\r
53 //\r
7feed950 54 // Compatibility Errata:\r
44c9618a 55 // Some systems try to hide drive space with their INT 13h driver\r
6aac772c
CC
56 // This does not hide space from the OS driver. This means the MBR\r
57 // that gets created from DOS is smaller than the MBR created from\r
58 // a real OS (NT & Win98). This leads to BlockIo->LastBlock being\r
59 // wrong on some systems FDISKed by the OS.\r
60 //\r
61 // return FALSE Because no block devices on a system are implemented\r
62 // with INT 13h\r
63 //\r
64 return FALSE;\r
65 }\r
66\r
67 for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {\r
68 if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {\r
69 continue;\r
70 }\r
71\r
72 NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;\r
73 if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {\r
74 //\r
75 // This region overlaps with the Index1'th region\r
76 //\r
77 return FALSE;\r
78 }\r
79 }\r
80 }\r
81 //\r
82 // Non of the regions overlapped so MBR is O.K.\r
83 //\r
84 return MbrValid;\r
85}\r
86\r
87/**\r
88 This function finds Mbr partitions. Main algorithm\r
89 is ported from DXE partition driver.\r
90\r
91 @param[in] PrivateData The global memory map\r
92 @param[in] ParentBlockDevNo The parent block device\r
93\r
94 @retval TRUE New partitions are detected and logical block devices\r
95 are added to block device array\r
96 @retval FALSE No new partitions are added\r
97\r
98**/\r
99BOOLEAN\r
100FatFindMbrPartitions (\r
101 IN PEI_FAT_PRIVATE_DATA *PrivateData,\r
102 IN UINTN ParentBlockDevNo\r
103 )\r
104{\r
105 EFI_STATUS Status;\r
106 MASTER_BOOT_RECORD *Mbr;\r
107 UINTN Index;\r
108 BOOLEAN Found;\r
109 PEI_FAT_BLOCK_DEVICE *ParentBlockDev;\r
110 PEI_FAT_BLOCK_DEVICE *BlockDev;\r
111\r
112 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
113 return FALSE;\r
114 }\r
115\r
116 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
117\r
118 if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {\r
119 DEBUG((DEBUG_ERROR, "Device BlockSize %x exceeds FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));\r
120 return FALSE;\r
121 }\r
122\r
123 Found = FALSE;\r
124 Mbr = (MASTER_BOOT_RECORD *) PrivateData->BlockData;\r
125\r
126 Status = FatReadBlock (\r
127 PrivateData,\r
128 ParentBlockDevNo,\r
129 0,\r
130 ParentBlockDev->BlockSize,\r
131 Mbr\r
132 );\r
133\r
134 if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {\r
135 goto Done;\r
136 }\r
137 //\r
138 // We have a valid mbr - add each partition\r
139 //\r
140 for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {\r
141 if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {\r
142 //\r
143 // Don't use null MBR entries\r
144 //\r
145 continue;\r
146 }\r
147 //\r
148 // Register this partition\r
149 //\r
150 if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
151\r
152 Found = TRUE;\r
153\r
154 BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
155\r
156 BlockDev->BlockSize = MBR_SIZE;\r
157 BlockDev->LastBlock = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;\r
158 BlockDev->IoAlign = ParentBlockDev->IoAlign;\r
159 BlockDev->Logical = TRUE;\r
160 BlockDev->PartitionChecked = FALSE;\r
161 BlockDev->StartingPos = MultU64x32 (\r
162 UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),\r
163 ParentBlockDev->BlockSize\r
164 );\r
165 BlockDev->ParentDevNo = ParentBlockDevNo;\r
166\r
167 PrivateData->BlockDeviceCount++;\r
168 }\r
169 }\r
170\r
171Done:\r
172\r
173 ParentBlockDev->PartitionChecked = TRUE;\r
174 return Found;\r
175}\r