]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/FatPei/Eltorito.c
FatPkg: Apply uncrustify changes
[mirror_edk2.git] / FatPkg / FatPei / Eltorito.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/ElTorito.h>\r
12#include "FatLitePeim.h"\r
13\r
14/**\r
15 This function finds Eltorito partitions. Main algorithm\r
16 is ported from DXE partition driver.\r
17\r
18 @param[in] PrivateData The global memory map\r
19 @param[in] ParentBlockDevNo The parent block device\r
20\r
21 @retval TRUE New partitions are detected and logical block devices\r
22 are added to block device array\r
23 @retval FALSE No new partitions are added\r
24\r
25**/\r
26BOOLEAN\r
27FatFindEltoritoPartitions (\r
bcdcc416
MK
28 IN PEI_FAT_PRIVATE_DATA *PrivateData,\r
29 IN UINTN ParentBlockDevNo\r
6aac772c
CC
30 )\r
31{\r
bcdcc416
MK
32 EFI_STATUS Status;\r
33 BOOLEAN Found;\r
34 PEI_FAT_BLOCK_DEVICE *BlockDev;\r
35 PEI_FAT_BLOCK_DEVICE *ParentBlockDev;\r
36 UINT32 VolDescriptorLba;\r
37 UINT32 Lba;\r
38 CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
39 ELTORITO_CATALOG *Catalog;\r
40 UINTN Check;\r
41 UINTN Index;\r
42 UINTN MaxIndex;\r
43 UINT16 *CheckBuffer;\r
44 UINT32 SubBlockSize;\r
45 UINT32 SectorCount;\r
46 UINT32 VolSpaceSize;\r
6aac772c
CC
47\r
48 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
49 return FALSE;\r
50 }\r
51\r
bcdcc416
MK
52 Found = FALSE;\r
53 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
54 VolSpaceSize = 0;\r
6aac772c
CC
55\r
56 //\r
57 // CD_ROM has the fixed block size as 2048 bytes\r
58 //\r
59 if (ParentBlockDev->BlockSize != 2048) {\r
60 return FALSE;\r
61 }\r
62\r
bcdcc416
MK
63 VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *)PrivateData->BlockData;\r
64 Catalog = (ELTORITO_CATALOG *)VolDescriptor;\r
6aac772c
CC
65\r
66 //\r
67 // the ISO-9660 volume descriptor starts at 32k on the media\r
68 // and CD_ROM has the fixed block size as 2048 bytes, so...\r
69 //\r
70 VolDescriptorLba = 15;\r
71 //\r
72 // ((16*2048) / Media->BlockSize) - 1;\r
73 //\r
74 // Loop: handle one volume descriptor per time\r
75 //\r
76 while (TRUE) {\r
6aac772c
CC
77 VolDescriptorLba += 1;\r
78 if (VolDescriptorLba > ParentBlockDev->LastBlock) {\r
79 //\r
80 // We are pointing past the end of the device so exit\r
81 //\r
82 break;\r
83 }\r
84\r
85 Status = FatReadBlock (\r
bcdcc416
MK
86 PrivateData,\r
87 ParentBlockDevNo,\r
88 VolDescriptorLba,\r
89 ParentBlockDev->BlockSize,\r
90 VolDescriptor\r
91 );\r
6aac772c
CC
92 if (EFI_ERROR (Status)) {\r
93 break;\r
94 }\r
bcdcc416 95\r
6aac772c
CC
96 //\r
97 // Check for valid volume descriptor signature\r
98 //\r
bcdcc416
MK
99 if ((VolDescriptor->Unknown.Type == CDVOL_TYPE_END) ||\r
100 (CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0)\r
101 )\r
102 {\r
6aac772c
CC
103 //\r
104 // end of Volume descriptor list\r
105 //\r
106 break;\r
107 }\r
bcdcc416 108\r
6aac772c
CC
109 //\r
110 // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte\r
111 //\r
112 if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {\r
113 VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];\r
114 }\r
bcdcc416 115\r
6aac772c
CC
116 //\r
117 // Is it an El Torito volume descriptor?\r
118 //\r
119 if (CompareMem (\r
120 VolDescriptor->BootRecordVolume.SystemId,\r
121 CDVOL_ELTORITO_ID,\r
122 sizeof (CDVOL_ELTORITO_ID) - 1\r
bcdcc416
MK
123 ) != 0)\r
124 {\r
6aac772c
CC
125 continue;\r
126 }\r
bcdcc416 127\r
6aac772c
CC
128 //\r
129 // Read in the boot El Torito boot catalog\r
130 //\r
131 Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
132 if (Lba > ParentBlockDev->LastBlock) {\r
133 continue;\r
134 }\r
135\r
136 Status = FatReadBlock (\r
bcdcc416
MK
137 PrivateData,\r
138 ParentBlockDevNo,\r
139 Lba,\r
140 ParentBlockDev->BlockSize,\r
141 Catalog\r
142 );\r
6aac772c
CC
143 if (EFI_ERROR (Status)) {\r
144 continue;\r
145 }\r
bcdcc416 146\r
6aac772c
CC
147 //\r
148 // We don't care too much about the Catalog header's contents, but we do want\r
149 // to make sure it looks like a Catalog header\r
150 //\r
bcdcc416 151 if ((Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG) || (Catalog->Catalog.Id55AA != 0xAA55)) {\r
6aac772c
CC
152 continue;\r
153 }\r
154\r
155 Check = 0;\r
bcdcc416 156 CheckBuffer = (UINT16 *)Catalog;\r
6aac772c
CC
157 for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {\r
158 Check += CheckBuffer[Index];\r
159 }\r
160\r
161 if ((Check & 0xFFFF) != 0) {\r
162 continue;\r
163 }\r
164\r
165 MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);\r
166 for (Index = 1; Index < MaxIndex; Index += 1) {\r
167 //\r
168 // Next entry\r
169 //\r
170 Catalog += 1;\r
171\r
172 //\r
173 // Check this entry\r
174 //\r
bcdcc416 175 if ((Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE) || (Catalog->Boot.Lba == 0)) {\r
6aac772c
CC
176 continue;\r
177 }\r
178\r
bcdcc416
MK
179 SubBlockSize = 512;\r
180 SectorCount = Catalog->Boot.SectorCount;\r
6aac772c
CC
181\r
182 switch (Catalog->Boot.MediaType) {\r
bcdcc416
MK
183 case ELTORITO_NO_EMULATION:\r
184 SubBlockSize = ParentBlockDev->BlockSize;\r
185 SectorCount = Catalog->Boot.SectorCount;\r
186 break;\r
187\r
188 case ELTORITO_HARD_DISK:\r
189 break;\r
190\r
191 case ELTORITO_12_DISKETTE:\r
192 SectorCount = 0x50 * 0x02 * 0x0F;\r
193 break;\r
194\r
195 case ELTORITO_14_DISKETTE:\r
196 SectorCount = 0x50 * 0x02 * 0x12;\r
197 break;\r
198\r
199 case ELTORITO_28_DISKETTE:\r
200 SectorCount = 0x50 * 0x02 * 0x24;\r
201 break;\r
202\r
203 default:\r
204 SectorCount = 0;\r
205 SubBlockSize = ParentBlockDev->BlockSize;\r
206 break;\r
6aac772c
CC
207 }\r
208\r
209 if (SectorCount < 2) {\r
bcdcc416 210 SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32)(ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32)(VolSpaceSize - Catalog->Boot.Lba);\r
6aac772c 211 }\r
bcdcc416 212\r
6aac772c
CC
213 //\r
214 // Register this partition\r
215 //\r
216 if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
bcdcc416 217 Found = TRUE;\r
6aac772c 218\r
bcdcc416 219 BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
6aac772c 220\r
bcdcc416
MK
221 BlockDev->BlockSize = SubBlockSize;\r
222 BlockDev->LastBlock = SectorCount - 1;\r
223 BlockDev->IoAlign = ParentBlockDev->IoAlign;\r
224 BlockDev->Logical = TRUE;\r
225 BlockDev->PartitionChecked = FALSE;\r
226 BlockDev->StartingPos = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);\r
227 BlockDev->ParentDevNo = ParentBlockDevNo;\r
6aac772c
CC
228\r
229 PrivateData->BlockDeviceCount++;\r
230 }\r
231 }\r
232 }\r
233\r
234 ParentBlockDev->PartitionChecked = TRUE;\r
235\r
236 return Found;\r
6aac772c 237}\r