]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciRomTable.c
Removed cross references from PciCf8Lib and PciExpressLib class to PciLib class.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciRomTable.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
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
24#include "pcibus.h"\r
25#include "PciRomTable.h"\r
26\r
27typedef struct {\r
28 EFI_HANDLE ImageHandle;\r
29 UINTN Seg;\r
30 UINT8 Bus;\r
31 UINT8 Dev;\r
32 UINT8 Func;\r
33 UINT64 RomAddress;\r
34 UINT64 RomLength;\r
35} EFI_PCI_ROM_IMAGE_MAPPING;\r
36\r
37static UINTN mNumberOfPciRomImages = 0;\r
38static UINTN mMaxNumberOfPciRomImages = 0;\r
39static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
40\r
41VOID\r
42PciRomAddImageMapping (\r
43 IN EFI_HANDLE ImageHandle,\r
44 IN UINTN Seg,\r
45 IN UINT8 Bus,\r
46 IN UINT8 Dev,\r
47 IN UINT8 Func,\r
48 IN UINT64 RomAddress,\r
49 IN UINT64 RomLength\r
50 )\r
51/*++\r
52\r
53Routine Description:\r
54\r
55 TODO: Add function description\r
56\r
57Arguments:\r
58\r
59 ImageHandle - TODO: add argument description\r
60 Seg - TODO: add argument description\r
61 Bus - TODO: add argument description\r
62 Dev - TODO: add argument description\r
63 Func - TODO: add argument description\r
64 RomAddress - TODO: add argument description\r
65 RomLength - TODO: add argument description\r
66\r
67Returns:\r
68\r
69 TODO: add return values\r
70\r
71--*/\r
72{\r
73 EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
74\r
75 if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
76\r
77 mMaxNumberOfPciRomImages += 0x20;\r
78\r
79 TempMapping = NULL;\r
80 TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
81 if (TempMapping == NULL) {\r
82 return ;\r
83 }\r
84\r
85 CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
86\r
87 if (mRomImageTable != NULL) {\r
88 gBS->FreePool (mRomImageTable);\r
89 }\r
90\r
91 mRomImageTable = TempMapping;\r
92 }\r
93\r
94 mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
95 mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
96 mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
97 mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
98 mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
99 mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress;\r
100 mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength;\r
101 mNumberOfPciRomImages++;\r
102}\r
103\r
104VOID\r
105HexToString (\r
106 CHAR16 *String,\r
107 UINTN Value,\r
108 UINTN Digits\r
109 )\r
110/*++\r
111\r
112Routine Description:\r
113\r
114 TODO: Add function description\r
115\r
116Arguments:\r
117\r
118 String - TODO: add argument description\r
119 Value - TODO: add argument description\r
120 Digits - TODO: add argument description\r
121\r
122Returns:\r
123\r
124 TODO: add return values\r
125\r
126--*/\r
127{\r
128 for (; Digits > 0; Digits--, String++) {\r
129 *String = (CHAR16) ((Value >> (4 * (Digits - 1))) & 0x0f);\r
130 if (*String > 9) {\r
131 (*String) += ('A' - 10);\r
132 } else {\r
133 (*String) += '0';\r
134 }\r
135 }\r
136}\r
137EFI_STATUS\r
138PciRomLoadEfiDriversFromRomImage (\r
139 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
140 IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor\r
141 )\r
142/*++\r
143\r
144Routine Description:\r
145\r
146Arguments:\r
147\r
148Returns:\r
149\r
150--*/\r
151// TODO: This - add argument and description to function comment\r
152// TODO: PciOptionRomDescriptor - add argument and description to function comment\r
153{\r
154 VOID *RomBar;\r
155 UINTN RomSize;\r
156 CHAR16 *FileName;\r
157 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
158 PCI_DATA_STRUCTURE *Pcir;\r
159 UINTN ImageIndex;\r
160 UINTN RomBarOffset;\r
161 UINT32 ImageSize;\r
162 UINT16 ImageOffset;\r
163 EFI_HANDLE ImageHandle;\r
164 EFI_STATUS Status;\r
165 EFI_STATUS retStatus;\r
166 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
167 BOOLEAN SkipImage;\r
168 UINT32 DestinationSize;\r
169 UINT32 ScratchSize;\r
170 UINT8 *Scratch;\r
171 VOID *ImageBuffer;\r
172 VOID *DecompressedImageBuffer;\r
173 UINT32 ImageLength;\r
174 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
175\r
176 RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
177 RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
178 FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";\r
179\r
180 HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);\r
181 HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);\r
182 HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);\r
183 HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);\r
184\r
185 ImageIndex = 0;\r
186 retStatus = EFI_NOT_FOUND;\r
187 RomBarOffset = (UINTN) RomBar;\r
188\r
189 do {\r
190\r
191 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
192\r
193 if (EfiRomHeader->Signature != 0xaa55) {\r
194 return retStatus;\r
195 }\r
196\r
197 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
198 ImageSize = Pcir->ImageLength * 512;\r
199\r
200 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
201 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
202\r
203 if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
204 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
205\r
206 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
207 ImageSize = EfiRomHeader->InitializationSize * 512;\r
208\r
209 ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
210 ImageLength = ImageSize - ImageOffset;\r
211 DecompressedImageBuffer = NULL;\r
212\r
213 //\r
214 // decompress here if needed\r
215 //\r
216 SkipImage = FALSE;\r
217 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
218 SkipImage = TRUE;\r
219 }\r
220\r
221 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
222 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
223 if (EFI_ERROR (Status)) {\r
224 SkipImage = TRUE;\r
225 } else {\r
226 SkipImage = TRUE;\r
227 Status = Decompress->GetInfo (\r
228 Decompress,\r
229 ImageBuffer,\r
230 ImageLength,\r
231 &DestinationSize,\r
232 &ScratchSize\r
233 );\r
234 if (!EFI_ERROR (Status)) {\r
235 DecompressedImageBuffer = NULL;\r
236 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
237 if (DecompressedImageBuffer != NULL) {\r
238 Scratch = AllocatePool (ScratchSize);\r
239 if (Scratch != NULL) {\r
240 Status = Decompress->Decompress (\r
241 Decompress,\r
242 ImageBuffer,\r
243 ImageLength,\r
244 DecompressedImageBuffer,\r
245 DestinationSize,\r
246 Scratch,\r
247 ScratchSize\r
248 );\r
249 if (!EFI_ERROR (Status)) {\r
250 ImageBuffer = DecompressedImageBuffer;\r
251 ImageLength = DestinationSize;\r
252 SkipImage = FALSE;\r
253 }\r
254\r
255 gBS->FreePool (Scratch);\r
256 }\r
257 }\r
258 }\r
259 }\r
260 }\r
261\r
262 if (!SkipImage) {\r
263\r
264 //\r
265 // load image and start image\r
266 //\r
267\r
268 HexToString (&FileName[48], ImageIndex, 4);\r
269 FilePath = FileDevicePath (NULL, FileName);\r
270\r
271 Status = gBS->LoadImage (\r
272 FALSE,\r
273 This->ImageHandle,\r
274 FilePath,\r
275 ImageBuffer,\r
276 ImageLength,\r
277 &ImageHandle\r
278 );\r
279 if (!EFI_ERROR (Status)) {\r
280 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
281 if (!EFI_ERROR (Status)) {\r
282 PciRomAddImageMapping (\r
283 ImageHandle,\r
284 PciOptionRomDescriptor->Seg,\r
285 PciOptionRomDescriptor->Bus,\r
286 PciOptionRomDescriptor->Dev,\r
287 PciOptionRomDescriptor->Func,\r
288 PciOptionRomDescriptor->RomAddress,\r
289 PciOptionRomDescriptor->RomLength\r
290 );\r
291 retStatus = Status;\r
292 }\r
293 }\r
294 }\r
295\r
296 if (DecompressedImageBuffer != NULL) {\r
297 gBS->FreePool (DecompressedImageBuffer);\r
298 }\r
299\r
300 }\r
301 }\r
302\r
303 RomBarOffset = RomBarOffset + ImageSize;\r
304 ImageIndex++;\r
305 } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));\r
306\r
307 return retStatus;\r
308}\r
309\r
310EFI_STATUS\r
311PciRomLoadEfiDriversFromOptionRomTable (\r
312 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
313 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo\r
314 )\r
315/*++\r
316\r
317Routine Description:\r
318\r
319Arguments:\r
320\r
321Returns:\r
322\r
323--*/\r
324// TODO: This - add argument and description to function comment\r
325// TODO: PciRootBridgeIo - add argument and description to function comment\r
326// TODO: EFI_NOT_FOUND - add return value to function comment\r
327{\r
328 EFI_STATUS Status;\r
329 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
330 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
331 UINTN Index;\r
332 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
333 UINT16 MinBus;\r
334 UINT16 MaxBus;\r
335\r
336 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
337 if (EFI_ERROR (Status)) {\r
338 return EFI_NOT_FOUND;\r
339 }\r
340\r
341 Status = EFI_NOT_FOUND;\r
342\r
343 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
344 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
345 if (!PciOptionRomDescriptor->DontLoadEfiRom) {\r
346 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {\r
347 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
348 if (EFI_ERROR (Status)) {\r
349 return Status;\r
350 }\r
351\r
352 PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);\r
353 if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {\r
354 Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);\r
355 PciOptionRomDescriptor->DontLoadEfiRom |= 2;\r
356 }\r
357 }\r
358 }\r
359 }\r
360\r
361 return Status;\r
362}\r
363\r
364EFI_STATUS\r
365PciRomGetRomResourceFromPciOptionRomTable (\r
366 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
367 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
368 PCI_IO_DEVICE *PciIoDevice\r
369 )\r
370/*++\r
371\r
372Routine Description:\r
373\r
374Arguments:\r
375\r
376Returns:\r
377\r
378--*/\r
379// TODO: This - add argument and description to function comment\r
380// TODO: PciRootBridgeIo - add argument and description to function comment\r
381// TODO: PciIoDevice - add argument and description to function comment\r
382// TODO: EFI_NOT_FOUND - add return value to function comment\r
383// TODO: EFI_SUCCESS - add return value to function comment\r
384{\r
385 EFI_STATUS Status;\r
386 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
387 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
388 UINTN Index;\r
389\r
390 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
391 if (EFI_ERROR (Status)) {\r
392 return EFI_NOT_FOUND;\r
393 }\r
394\r
395 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
396 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
397 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
398 PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
399 PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
400 PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
401\r
402 PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
403 PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
404 }\r
405 }\r
406\r
407 for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
408 if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
409 mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
410 mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
411 mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
412\r
413 AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
414 }\r
415 }\r
416\r
417 return EFI_SUCCESS;\r
418}\r
419\r
420EFI_STATUS\r
421PciRomGetImageMapping (\r
422 PCI_IO_DEVICE *PciIoDevice\r
423 )\r
424/*++\r
425\r
426Routine Description:\r
427\r
428Arguments:\r
429\r
430Returns:\r
431\r
432--*/\r
433// TODO: PciIoDevice - add argument and description to function comment\r
434// TODO: EFI_SUCCESS - add return value to function comment\r
435{\r
436 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
437 UINTN Index;\r
438\r
439 PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
440\r
441 for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
442 if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
443 mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
444 mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
445 mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
446\r
447 if (mRomImageTable[Index].ImageHandle != NULL) {\r
448 AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
449 } else {\r
450 PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress;\r
451 PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength;\r
452 }\r
453 }\r
454 }\r
455\r
456 return EFI_SUCCESS;\r
457}\r