]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/FatPei/Eltorito.c
FatPkg: Break down Part.c file.
[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
7This program and the accompanying materials are licensed and made available\r
8under the terms and conditions of the BSD License which accompanies this\r
9distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <IndustryStandard/ElTorito.h>\r
18#include "FatLitePeim.h"\r
19\r
20/**\r
21 This function finds Eltorito partitions. Main algorithm\r
22 is ported from DXE partition driver.\r
23\r
24 @param[in] PrivateData The global memory map\r
25 @param[in] ParentBlockDevNo The parent block device\r
26\r
27 @retval TRUE New partitions are detected and logical block devices\r
28 are added to block device array\r
29 @retval FALSE No new partitions are added\r
30\r
31**/\r
32BOOLEAN\r
33FatFindEltoritoPartitions (\r
34 IN PEI_FAT_PRIVATE_DATA *PrivateData,\r
35 IN UINTN ParentBlockDevNo\r
36 )\r
37{\r
38 EFI_STATUS Status;\r
39 BOOLEAN Found;\r
40 PEI_FAT_BLOCK_DEVICE *BlockDev;\r
41 PEI_FAT_BLOCK_DEVICE *ParentBlockDev;\r
42 UINT32 VolDescriptorLba;\r
43 UINT32 Lba;\r
44 CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
45 ELTORITO_CATALOG *Catalog;\r
46 UINTN Check;\r
47 UINTN Index;\r
48 UINTN MaxIndex;\r
49 UINT16 *CheckBuffer;\r
50 UINT32 SubBlockSize;\r
51 UINT32 SectorCount;\r
52 UINT32 VolSpaceSize;\r
53\r
54 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
55 return FALSE;\r
56 }\r
57\r
58 Found = FALSE;\r
59 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
60 VolSpaceSize = 0;\r
61\r
62 //\r
63 // CD_ROM has the fixed block size as 2048 bytes\r
64 //\r
65 if (ParentBlockDev->BlockSize != 2048) {\r
66 return FALSE;\r
67 }\r
68\r
69 VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;\r
70 Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
71\r
72 //\r
73 // the ISO-9660 volume descriptor starts at 32k on the media\r
74 // and CD_ROM has the fixed block size as 2048 bytes, so...\r
75 //\r
76 VolDescriptorLba = 15;\r
77 //\r
78 // ((16*2048) / Media->BlockSize) - 1;\r
79 //\r
80 // Loop: handle one volume descriptor per time\r
81 //\r
82 while (TRUE) {\r
83\r
84 VolDescriptorLba += 1;\r
85 if (VolDescriptorLba > ParentBlockDev->LastBlock) {\r
86 //\r
87 // We are pointing past the end of the device so exit\r
88 //\r
89 break;\r
90 }\r
91\r
92 Status = FatReadBlock (\r
93 PrivateData,\r
94 ParentBlockDevNo,\r
95 VolDescriptorLba,\r
96 ParentBlockDev->BlockSize,\r
97 VolDescriptor\r
98 );\r
99 if (EFI_ERROR (Status)) {\r
100 break;\r
101 }\r
102 //\r
103 // Check for valid volume descriptor signature\r
104 //\r
105 if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||\r
106 CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0\r
107 ) {\r
108 //\r
109 // end of Volume descriptor list\r
110 //\r
111 break;\r
112 }\r
113 //\r
114 // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte\r
115 //\r
116 if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {\r
117 VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];\r
118 }\r
119 //\r
120 // Is it an El Torito volume descriptor?\r
121 //\r
122 if (CompareMem (\r
123 VolDescriptor->BootRecordVolume.SystemId,\r
124 CDVOL_ELTORITO_ID,\r
125 sizeof (CDVOL_ELTORITO_ID) - 1\r
126 ) != 0) {\r
127 continue;\r
128 }\r
129 //\r
130 // Read in the boot El Torito boot catalog\r
131 //\r
132 Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
133 if (Lba > ParentBlockDev->LastBlock) {\r
134 continue;\r
135 }\r
136\r
137 Status = FatReadBlock (\r
138 PrivateData,\r
139 ParentBlockDevNo,\r
140 Lba,\r
141 ParentBlockDev->BlockSize,\r
142 Catalog\r
143 );\r
144 if (EFI_ERROR (Status)) {\r
145 continue;\r
146 }\r
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
151 if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {\r
152 continue;\r
153 }\r
154\r
155 Check = 0;\r
156 CheckBuffer = (UINT16 *) Catalog;\r
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
175 if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {\r
176 continue;\r
177 }\r
178\r
179 SubBlockSize = 512;\r
180 SectorCount = Catalog->Boot.SectorCount;\r
181\r
182 switch (Catalog->Boot.MediaType) {\r
183\r
184 case ELTORITO_NO_EMULATION:\r
185 SubBlockSize = ParentBlockDev->BlockSize;\r
186 SectorCount = Catalog->Boot.SectorCount;\r
187 break;\r
188\r
189 case ELTORITO_HARD_DISK:\r
190 break;\r
191\r
192 case ELTORITO_12_DISKETTE:\r
193 SectorCount = 0x50 * 0x02 * 0x0F;\r
194 break;\r
195\r
196 case ELTORITO_14_DISKETTE:\r
197 SectorCount = 0x50 * 0x02 * 0x12;\r
198 break;\r
199\r
200 case ELTORITO_28_DISKETTE:\r
201 SectorCount = 0x50 * 0x02 * 0x24;\r
202 break;\r
203\r
204 default:\r
205 SectorCount = 0;\r
206 SubBlockSize = ParentBlockDev->BlockSize;\r
207 break;\r
208 }\r
209\r
210 if (SectorCount < 2) {\r
211 SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);\r
212 }\r
213 //\r
214 // Register this partition\r
215 //\r
216 if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
217\r
218 Found = TRUE;\r
219\r
220 BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
221\r
222 BlockDev->BlockSize = SubBlockSize;\r
223 BlockDev->LastBlock = SectorCount - 1;\r
224 BlockDev->IoAlign = ParentBlockDev->IoAlign;\r
225 BlockDev->Logical = TRUE;\r
226 BlockDev->PartitionChecked = FALSE;\r
227 BlockDev->StartingPos = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);\r
228 BlockDev->ParentDevNo = ParentBlockDevNo;\r
229\r
230 PrivateData->BlockDeviceCount++;\r
231 }\r
232 }\r
233 }\r
234\r
235 ParentBlockDev->PartitionChecked = TRUE;\r
236\r
237 return Found;\r
238\r
239}\r