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