]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/FatPei/Eltorito.c
FatPkg: Replace BSD License with BSD+Patent License
[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
28 IN PEI_FAT_PRIVATE_DATA *PrivateData,\r
29 IN UINTN ParentBlockDevNo\r
30 )\r
31{\r
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
47\r
48 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
49 return FALSE;\r
50 }\r
51\r
52 Found = FALSE;\r
53 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
54 VolSpaceSize = 0;\r
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
63 VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;\r
64 Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
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
77\r
78 VolDescriptorLba += 1;\r
79 if (VolDescriptorLba > ParentBlockDev->LastBlock) {\r
80 //\r
81 // We are pointing past the end of the device so exit\r
82 //\r
83 break;\r
84 }\r
85\r
86 Status = FatReadBlock (\r
87 PrivateData,\r
88 ParentBlockDevNo,\r
89 VolDescriptorLba,\r
90 ParentBlockDev->BlockSize,\r
91 VolDescriptor\r
92 );\r
93 if (EFI_ERROR (Status)) {\r
94 break;\r
95 }\r
96 //\r
97 // Check for valid volume descriptor signature\r
98 //\r
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
103 // end of Volume descriptor list\r
104 //\r
105 break;\r
106 }\r
107 //\r
108 // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte\r
109 //\r
110 if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {\r
111 VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];\r
112 }\r
113 //\r
114 // Is it an El Torito volume descriptor?\r
115 //\r
116 if (CompareMem (\r
117 VolDescriptor->BootRecordVolume.SystemId,\r
118 CDVOL_ELTORITO_ID,\r
119 sizeof (CDVOL_ELTORITO_ID) - 1\r
120 ) != 0) {\r
121 continue;\r
122 }\r
123 //\r
124 // Read in the boot El Torito boot catalog\r
125 //\r
126 Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
127 if (Lba > ParentBlockDev->LastBlock) {\r
128 continue;\r
129 }\r
130\r
131 Status = FatReadBlock (\r
132 PrivateData,\r
133 ParentBlockDevNo,\r
134 Lba,\r
135 ParentBlockDev->BlockSize,\r
136 Catalog\r
137 );\r
138 if (EFI_ERROR (Status)) {\r
139 continue;\r
140 }\r
141 //\r
142 // We don't care too much about the Catalog header's contents, but we do want\r
143 // to make sure it looks like a Catalog header\r
144 //\r
145 if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {\r
146 continue;\r
147 }\r
148\r
149 Check = 0;\r
150 CheckBuffer = (UINT16 *) Catalog;\r
151 for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {\r
152 Check += CheckBuffer[Index];\r
153 }\r
154\r
155 if ((Check & 0xFFFF) != 0) {\r
156 continue;\r
157 }\r
158\r
159 MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);\r
160 for (Index = 1; Index < MaxIndex; Index += 1) {\r
161 //\r
162 // Next entry\r
163 //\r
164 Catalog += 1;\r
165\r
166 //\r
167 // Check this entry\r
168 //\r
169 if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {\r
170 continue;\r
171 }\r
172\r
173 SubBlockSize = 512;\r
174 SectorCount = Catalog->Boot.SectorCount;\r
175\r
176 switch (Catalog->Boot.MediaType) {\r
177\r
178 case ELTORITO_NO_EMULATION:\r
179 SubBlockSize = ParentBlockDev->BlockSize;\r
180 SectorCount = Catalog->Boot.SectorCount;\r
181 break;\r
182\r
183 case ELTORITO_HARD_DISK:\r
184 break;\r
185\r
186 case ELTORITO_12_DISKETTE:\r
187 SectorCount = 0x50 * 0x02 * 0x0F;\r
188 break;\r
189\r
190 case ELTORITO_14_DISKETTE:\r
191 SectorCount = 0x50 * 0x02 * 0x12;\r
192 break;\r
193\r
194 case ELTORITO_28_DISKETTE:\r
195 SectorCount = 0x50 * 0x02 * 0x24;\r
196 break;\r
197\r
198 default:\r
199 SectorCount = 0;\r
200 SubBlockSize = ParentBlockDev->BlockSize;\r
201 break;\r
202 }\r
203\r
204 if (SectorCount < 2) {\r
205 SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);\r
206 }\r
207 //\r
208 // Register this partition\r
209 //\r
210 if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
211\r
212 Found = TRUE;\r
213\r
214 BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
215\r
216 BlockDev->BlockSize = SubBlockSize;\r
217 BlockDev->LastBlock = SectorCount - 1;\r
218 BlockDev->IoAlign = ParentBlockDev->IoAlign;\r
219 BlockDev->Logical = TRUE;\r
220 BlockDev->PartitionChecked = FALSE;\r
221 BlockDev->StartingPos = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);\r
222 BlockDev->ParentDevNo = ParentBlockDevNo;\r
223\r
224 PrivateData->BlockDeviceCount++;\r
225 }\r
226 }\r
227 }\r
228\r
229 ParentBlockDev->PartitionChecked = TRUE;\r
230\r
231 return Found;\r
232\r
233}\r