]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/PciBusNoEnumerationDxe/PciRomTable.c
BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciRomTable.c
CommitLineData
10590588 1/*++\r
2\r
94020bb4 3Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 4This program and the accompanying materials \r
10590588 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 PciRomTable.c\r
15 \r
16Abstract:\r
17\r
18 Option Rom Support for PCI Bus Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
d8bee43c 24#include "PciBus.h"\r
10590588 25\r
26typedef struct {\r
27 EFI_HANDLE ImageHandle;\r
28 UINTN Seg;\r
29 UINT8 Bus;\r
30 UINT8 Dev;\r
31 UINT8 Func;\r
32} EFI_PCI_ROM_IMAGE_MAPPING;\r
33\r
e56dd2ce 34UINTN mNumberOfPciRomImages = 0;\r
35UINTN mMaxNumberOfPciRomImages = 0;\r
36EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
10590588 37\r
e56dd2ce 38CHAR16 mHexDigit[17] = L"0123456789ABCDEF";\r
10590588 39\r
10590588 40VOID\r
41PciRomAddImageMapping (\r
42 IN EFI_HANDLE ImageHandle,\r
43 IN UINTN Seg,\r
44 IN UINT8 Bus,\r
45 IN UINT8 Dev,\r
46 IN UINT8 Func\r
47 )\r
48\r
49{\r
50 EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
51\r
52 if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
53\r
54 mMaxNumberOfPciRomImages += 0x20;\r
55\r
56 TempMapping = NULL;\r
57 TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
58 if (TempMapping == NULL) {\r
59 return ;\r
60 }\r
61\r
62 CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
63\r
64 if (mRomImageTable != NULL) {\r
65 gBS->FreePool (mRomImageTable);\r
66 }\r
67\r
68 mRomImageTable = TempMapping;\r
69 }\r
70\r
71 mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
72 mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
73 mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
74 mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
75 mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
76 mNumberOfPciRomImages++;\r
77}\r
78\r
10590588 79VOID\r
80HexToString (\r
81 CHAR16 *String,\r
82 UINTN Value,\r
83 UINTN Digits\r
84 )\r
85\r
86{\r
87 for (; Digits > 0; Digits--, String++) {\r
88 *String = mHexDigit[((Value >> (4*(Digits-1))) & 0x0f)];\r
89 }\r
90}\r
91\r
92EFI_STATUS\r
93PciRomLoadEfiDriversFromRomImage (\r
94 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
95 IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor\r
96 )\r
97/*++\r
98\r
99Routine Description:\r
100 Command entry point. \r
101\r
102Arguments:\r
103 ImageHandle The image handle. \r
104 SystemTable The system table.\r
105\r
106Returns:\r
107 EFI_SUCCESS - The command completed successfully\r
108 EFI_INVALID_PARAMETER - Command usage error\r
109 EFI_UNSUPPORTED - Protocols unsupported\r
110 EFI_OUT_OF_RESOURCES - Out of memory\r
111 Other value - Unknown error\r
112\r
113--*/\r
114{\r
115 VOID *RomBar;\r
116 UINTN RomSize;\r
117 CHAR16 *FileName;\r
118 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
119 PCI_DATA_STRUCTURE *Pcir;\r
120 UINTN ImageIndex;\r
121 UINTN RomBarOffset;\r
122 UINT32 ImageSize;\r
123 UINT16 ImageOffset;\r
124 EFI_HANDLE ImageHandle;\r
125 EFI_STATUS Status;\r
126 EFI_STATUS retStatus;\r
127 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
128 BOOLEAN SkipImage;\r
129 UINT32 DestinationSize;\r
130 UINT32 ScratchSize;\r
131 UINT8 *Scratch;\r
132 VOID *ImageBuffer;\r
133 VOID *DecompressedImageBuffer;\r
134 UINT32 ImageLength;\r
135 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
94020bb4 136 UINT32 InitializationSize;\r
10590588 137\r
138 RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
139 RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
140 FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";\r
141\r
142 HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);\r
143 HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);\r
144 HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);\r
145 HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);\r
146\r
147 ImageIndex = 0;\r
148 retStatus = EFI_NOT_FOUND;\r
149 RomBarOffset = (UINTN) RomBar;\r
150\r
151 do {\r
152\r
153 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
154\r
94020bb4 155\r
156 if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
10590588 157 return retStatus;\r
158 }\r
159\r
94020bb4 160 //\r
161 // If the pointer to the PCI Data Structure is invalid, no further images can be located. \r
162 // The PCI Data Structure must be DWORD aligned. \r
163 //\r
164 if (EfiRomHeader->PcirOffset == 0 ||\r
165 (EfiRomHeader->PcirOffset & 3) != 0 ||\r
166 RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) {\r
167 break;\r
168 }\r
10590588 169 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
94020bb4 170 //\r
171 // If a valid signature is not present in the PCI Data Structure, no further images can be located.\r
172 //\r
173 if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
174 break;\r
175 }\r
10590588 176 ImageSize = Pcir->ImageLength * 512;\r
94020bb4 177 if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {\r
178 break;\r
179 }\r
10590588 180\r
181 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
94020bb4 182 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&\r
183 ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
184 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {\r
10590588 185\r
94020bb4 186 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
187 InitializationSize = EfiRomHeader->InitializationSize * 512;\r
10590588 188\r
94020bb4 189 if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {\r
10590588 190\r
191 ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
94020bb4 192 ImageLength = InitializationSize - ImageOffset;\r
10590588 193 DecompressedImageBuffer = NULL;\r
194\r
195 //\r
196 // decompress here if needed\r
197 //\r
198 SkipImage = FALSE;\r
199 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
200 SkipImage = TRUE;\r
201 }\r
202\r
203 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
204 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
205 if (EFI_ERROR (Status)) {\r
206 SkipImage = TRUE;\r
207 } else {\r
208 SkipImage = TRUE;\r
209 Status = Decompress->GetInfo (\r
210 Decompress,\r
211 ImageBuffer,\r
212 ImageLength,\r
213 &DestinationSize,\r
214 &ScratchSize\r
215 );\r
216 if (!EFI_ERROR (Status)) {\r
217 DecompressedImageBuffer = NULL;\r
218 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
219 if (DecompressedImageBuffer != NULL) {\r
220 Scratch = AllocatePool (ScratchSize);\r
221 if (Scratch != NULL) {\r
222 Status = Decompress->Decompress (\r
223 Decompress,\r
224 ImageBuffer,\r
225 ImageLength,\r
226 DecompressedImageBuffer,\r
227 DestinationSize,\r
228 Scratch,\r
229 ScratchSize\r
230 );\r
231 if (!EFI_ERROR (Status)) {\r
232 ImageBuffer = DecompressedImageBuffer;\r
233 ImageLength = DestinationSize;\r
234 SkipImage = FALSE;\r
235 }\r
236\r
237 gBS->FreePool (Scratch);\r
238 }\r
239 }\r
240 }\r
241 }\r
242 }\r
243\r
244 if (!SkipImage) {\r
245\r
246 //\r
247 // load image and start image\r
248 //\r
249\r
250 HexToString (&FileName[48], ImageIndex, 4);\r
251 FilePath = FileDevicePath (NULL, FileName);\r
252\r
253 Status = gBS->LoadImage (\r
254 FALSE,\r
255 This->ImageHandle,\r
256 FilePath,\r
257 ImageBuffer,\r
258 ImageLength,\r
259 &ImageHandle\r
260 );\r
261 if (!EFI_ERROR (Status)) {\r
262 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
263 if (!EFI_ERROR (Status)) {\r
264 PciRomAddImageMapping (\r
265 ImageHandle,\r
266 PciOptionRomDescriptor->Seg,\r
267 PciOptionRomDescriptor->Bus,\r
268 PciOptionRomDescriptor->Dev,\r
269 PciOptionRomDescriptor->Func\r
270 );\r
271 retStatus = Status;\r
272 }\r
273 }\r
274 if (FilePath != NULL) {\r
275 gBS->FreePool (FilePath);\r
276 }\r
277 }\r
278\r
279 if (DecompressedImageBuffer != NULL) {\r
280 gBS->FreePool (DecompressedImageBuffer);\r
281 }\r
282\r
283 }\r
284 }\r
285\r
286 RomBarOffset = RomBarOffset + ImageSize;\r
287 ImageIndex++;\r
288 } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));\r
289\r
290 return retStatus;\r
291}\r
292\r
293EFI_STATUS\r
294PciRomLoadEfiDriversFromOptionRomTable (\r
295 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
296 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo\r
297 )\r
298/*++\r
299\r
300Routine Description:\r
301\r
302Arguments:\r
303\r
304Returns:\r
305\r
306--*/\r
307{\r
308 EFI_STATUS Status;\r
309 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
310 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
311 UINTN Index;\r
312 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
313 UINT16 MinBus;\r
314 UINT16 MaxBus;\r
315\r
316 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
317 if (EFI_ERROR (Status)) {\r
318 return EFI_NOT_FOUND;\r
319 }\r
320\r
321 Status = EFI_NOT_FOUND;\r
322\r
323 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
324 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
325 if (!PciOptionRomDescriptor->DontLoadEfiRom) {\r
326 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {\r
327 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
328 if (EFI_ERROR (Status)) {\r
329 return Status;\r
330 }\r
331\r
a5f2a205 332 PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);\r
10590588 333 if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {\r
334 Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);\r
335 PciOptionRomDescriptor->DontLoadEfiRom |= 2;\r
336 }\r
337 }\r
338 }\r
339 }\r
340\r
341 return Status;\r
342}\r
343\r
344EFI_STATUS\r
345PciRomGetRomResourceFromPciOptionRomTable (\r
346 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
347 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
348 PCI_IO_DEVICE *PciIoDevice\r
349 )\r
350/*++\r
351\r
352Routine Description:\r
353\r
354Arguments:\r
355\r
356Returns:\r
357\r
358--*/\r
359{\r
360 EFI_STATUS Status;\r
361 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
362 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
363 UINTN Index;\r
364\r
365 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
366 if (EFI_ERROR (Status)) {\r
367 return EFI_NOT_FOUND;\r
368 }\r
369\r
370 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
371 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
372 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
373 PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
374 PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
375 PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
376\r
377 PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
378 PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
379 }\r
380 }\r
381\r
382 for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
383 if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
384 mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
385 mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
386 mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
387\r
388 AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
389 }\r
390 }\r
391\r
392 return EFI_SUCCESS;\r
393}\r