]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c
Remove all blanks lines to avoid build errors.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBus / Dxe / PciOptionRomSupport.c
CommitLineData
ead42efc 1/*++\r
2\r
3Copyright (c) 2006 - 2007, 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 PciOptionRomSupport.c\r
15\r
16Abstract:\r
17\r
18 PCI Bus Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "pcibus.h"\r
25#include "PciResourceSupport.h"\r
26\r
27//\r
28// Min Max\r
29//\r
30#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))\r
31#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b))\r
32\r
33\r
34EFI_STATUS\r
35GetOpRomInfo (\r
36 IN PCI_IO_DEVICE *PciIoDevice\r
37 )\r
38/*++\r
39\r
40Routine Description:\r
41\r
42Arguments:\r
43\r
44Returns:\r
45\r
46--*/\r
47// TODO: PciIoDevice - add argument and description to function comment\r
48// TODO: EFI_NOT_FOUND - add return value to function comment\r
49// TODO: EFI_SUCCESS - add return value to function comment\r
50{\r
51 UINT8 RomBarIndex;\r
52 UINT32 AllOnes;\r
53 UINT64 Address;\r
54 EFI_STATUS Status;\r
55 UINT8 Bus;\r
56 UINT8 Device;\r
57 UINT8 Function;\r
58 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
59\r
60 Bus = PciIoDevice->BusNumber;\r
61 Device = PciIoDevice->DeviceNumber;\r
62 Function = PciIoDevice->FunctionNumber;\r
63\r
64 PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
65\r
66 //\r
67 // offset is 0x30 if is not ppb\r
68 //\r
69\r
70 //\r
71 // 0x30\r
72 //\r
73 RomBarIndex = PCI_DEVICE_ROMBAR;\r
74\r
75 if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
76 //\r
77 // if is ppb\r
78 //\r
79\r
80 //\r
81 // 0x38\r
82 //\r
83 RomBarIndex = PCI_BRIDGE_ROMBAR;\r
84 }\r
85 //\r
86 // the bit0 is 0 to prevent the enabling of the Rom address decoder\r
87 //\r
88 AllOnes = 0xfffffffe;\r
89 Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);\r
90\r
91 Status = PciRootBridgeIoWrite (\r
92 PciRootBridgeIo,\r
93 &PciIoDevice->Pci,\r
94 EfiPciWidthUint32,\r
95 Address,\r
96 1,\r
97 &AllOnes\r
98 );\r
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
102\r
103 //\r
104 // read back\r
105 //\r
106 Status = PciRootBridgeIoRead (\r
107 PciRootBridgeIo,\r
108 &PciIoDevice->Pci,\r
109 EfiPciWidthUint32,\r
110 Address,\r
111 1,\r
112 &AllOnes\r
113 );\r
114 if (EFI_ERROR (Status)) {\r
115 return Status;\r
116 }\r
117 //\r
118 // Bits [1, 10] are reserved\r
119 //\r
120 AllOnes &= 0xFFFFF800;\r
121 if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) {\r
122 return EFI_NOT_FOUND;\r
123 }\r
124\r
125 PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1);\r
126 return EFI_SUCCESS;\r
127}\r
128\r
129EFI_STATUS\r
130LoadOpRomImage (\r
131 IN PCI_IO_DEVICE *PciDevice,\r
132 IN UINT64 RomBase\r
133 )\r
134/*++\r
135\r
136Routine Description:\r
137 \r
138 Load option rom image for specified PCI device\r
139\r
140Arguments:\r
141\r
142Returns:\r
143\r
144--*/\r
145// TODO: PciDevice - add argument and description to function comment\r
146// TODO: RomBase - add argument and description to function comment\r
147// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
148// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
149// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
150{\r
151 UINT8 RomBarIndex;\r
152 UINT8 Indicator;\r
153 UINT16 OffsetPcir;\r
154 UINT32 RomBarOffset;\r
155 UINT32 RomBar;\r
156 EFI_STATUS retStatus;\r
157 BOOLEAN FirstCheck;\r
158 UINT8 *Image;\r
159 PCI_EXPANSION_ROM_HEADER *RomHeader;\r
160 PCI_DATA_STRUCTURE *RomPcir;\r
161 UINT64 RomSize;\r
162 UINT64 RomImageSize;\r
163 UINT8 *RomInMemory;\r
164 UINT8 CodeType;\r
165\r
166 RomSize = PciDevice->RomSize;\r
167\r
168 Indicator = 0;\r
169 RomImageSize = 0;\r
170 RomInMemory = NULL;\r
171 CodeType = 0xFF;\r
172\r
173 //\r
174 // Get the RomBarIndex\r
175 //\r
176\r
177 //\r
178 // 0x30\r
179 //\r
180 RomBarIndex = PCI_DEVICE_ROMBAR;\r
181 if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {\r
182 //\r
183 // if is ppb\r
184 //\r
185\r
186 //\r
187 // 0x38\r
188 //\r
189 RomBarIndex = PCI_BRIDGE_ROMBAR;\r
190 }\r
191 //\r
192 // Allocate memory for Rom header and PCIR\r
193 //\r
194 RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));\r
195 if (RomHeader == NULL) {\r
196 return EFI_OUT_OF_RESOURCES;\r
197 }\r
198\r
199 RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));\r
200 if (RomPcir == NULL) {\r
201 gBS->FreePool (RomHeader);\r
202 return EFI_OUT_OF_RESOURCES;\r
203 }\r
204\r
205 RomBar = (UINT32) RomBase;\r
206\r
207 //\r
208 // Enable RomBar\r
209 //\r
210 RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);\r
211\r
212 RomBarOffset = RomBar;\r
213 retStatus = EFI_NOT_FOUND;\r
214 FirstCheck = TRUE;\r
215\r
216 do {\r
217 PciDevice->PciRootBridgeIo->Mem.Read (\r
218 PciDevice->PciRootBridgeIo,\r
219 EfiPciWidthUint8,\r
220 RomBarOffset,\r
221 sizeof (PCI_EXPANSION_ROM_HEADER),\r
222 (UINT8 *) RomHeader\r
223 );\r
224\r
225 if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
226 RomBarOffset = RomBarOffset + 512;\r
227 if (FirstCheck) {\r
228 break;\r
229 } else {\r
230 RomImageSize = RomImageSize + 512;\r
231 continue;\r
232 }\r
233 }\r
234\r
235 FirstCheck = FALSE;\r
236 OffsetPcir = RomHeader->PcirOffset;\r
237 PciDevice->PciRootBridgeIo->Mem.Read (\r
238 PciDevice->PciRootBridgeIo,\r
239 EfiPciWidthUint8,\r
240 RomBarOffset + OffsetPcir,\r
241 sizeof (PCI_DATA_STRUCTURE),\r
242 (UINT8 *) RomPcir\r
243 );\r
244 if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
245 CodeType = PCI_CODE_TYPE_PCAT_IMAGE;\r
246 }\r
247 Indicator = RomPcir->Indicator;\r
248 RomImageSize = RomImageSize + RomPcir->ImageLength * 512;\r
249 RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512;\r
250 } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize));\r
251\r
252 //\r
253 // Some Legacy Cards do not report the correct ImageLength so used the maximum\r
254 // of the legacy length and the PCIR Image Length\r
255 //\r
256 if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
257 RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512));\r
258 }\r
259\r
260 if (RomImageSize > 0) {\r
261 retStatus = EFI_SUCCESS;\r
262 Image = AllocatePool ((UINT32) RomImageSize);\r
263 if (Image == NULL) {\r
264 RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
265 gBS->FreePool (RomHeader);\r
266 gBS->FreePool (RomPcir);\r
267 return EFI_OUT_OF_RESOURCES;\r
268 }\r
269 \r
270 //\r
271 // Copy Rom image into memory\r
272 //\r
273 PciDevice->PciRootBridgeIo->Mem.Read (\r
274 PciDevice->PciRootBridgeIo,\r
275 EfiPciWidthUint8,\r
276 RomBar,\r
277 (UINT32) RomImageSize,\r
278 Image\r
279 );\r
280 RomInMemory = Image;\r
281 }\r
282\r
283 RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
284\r
285 PciDevice->PciIo.RomSize = RomImageSize;\r
286 PciDevice->PciIo.RomImage = RomInMemory;\r
287\r
288 PciRomAddImageMapping (\r
289 NULL,\r
290 PciDevice->PciRootBridgeIo->SegmentNumber,\r
291 PciDevice->BusNumber,\r
292 PciDevice->DeviceNumber,\r
293 PciDevice->FunctionNumber,\r
294 (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
295 PciDevice->PciIo.RomSize\r
296 );\r
297\r
298 //\r
299 // Free allocated memory\r
300 //\r
301 gBS->FreePool (RomHeader);\r
302 gBS->FreePool (RomPcir);\r
303\r
304 return retStatus;\r
305}\r
306\r
307EFI_STATUS\r
308RomDecode (\r
309 IN PCI_IO_DEVICE *PciDevice,\r
310 IN UINT8 RomBarIndex,\r
311 IN UINT32 RomBar,\r
312 IN BOOLEAN Enable\r
313 )\r
314/*++\r
315\r
316Routine Description:\r
317\r
318Arguments:\r
319\r
320Returns:\r
321\r
322--*/\r
323// TODO: PciDevice - add argument and description to function comment\r
324// TODO: RomBarIndex - add argument and description to function comment\r
325// TODO: RomBar - add argument and description to function comment\r
326// TODO: Enable - add argument and description to function comment\r
327// TODO: EFI_SUCCESS - add return value to function comment\r
328{\r
329 UINT32 Value32;\r
330 UINT32 Offset;\r
331 EFI_PCI_IO_PROTOCOL *PciIo;\r
332\r
333 PciIo = &PciDevice->PciIo;\r
334 if (Enable) {\r
335 //\r
336 // Clear all bars\r
337 //\r
338 for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
339 PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);\r
340 }\r
341 \r
342 //\r
343 // set the Rom base address: now is hardcode\r
344 // enable its decoder\r
345 //\r
346 Value32 = RomBar | 0x1;\r
347 PciIoWrite (\r
348 PciIo,\r
349 (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
350 RomBarIndex,\r
351 1,\r
352 &Value32\r
353 );\r
354\r
355 //\r
356 // Programe all upstream bridge\r
357 //\r
358 ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE);\r
359\r
360 //\r
361 // Setting the memory space bit in the function's command register\r
362 //\r
363 PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
364\r
365 } else {\r
366 \r
367 //\r
368 // disable command register decode to memory\r
369 //\r
370 PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
371\r
372 //\r
373 // Destroy the programmed bar in all the upstream bridge.\r
374 //\r
375 ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE);\r
376\r
377 //\r
378 // disable rom decode\r
379 //\r
380 Value32 = 0xFFFFFFFE;\r
381 PciIoWrite (\r
382 PciIo,\r
383 (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32,\r
384 RomBarIndex,\r
385 1,\r
386 &Value32\r
387 );\r
388\r
389 }\r
390\r
391 return EFI_SUCCESS;\r
392\r
393}\r
394\r
395EFI_STATUS\r
396ProcessOpRomImage (\r
397 PCI_IO_DEVICE *PciDevice\r
398 )\r
399/*++\r
400\r
401Routine Description:\r
402\r
403 Process the oprom image.\r
404 \r
405Arguments:\r
406 PciDevice A pointer to a pci device.\r
407\r
408Returns:\r
409\r
410 EFI Status.\r
411 \r
412--*/\r
413{\r
414 UINT8 Indicator;\r
415 UINT32 ImageSize;\r
416 UINT16 ImageOffset;\r
417 VOID *RomBar;\r
418 UINT8 *RomBarOffset;\r
419 EFI_HANDLE ImageHandle;\r
420 EFI_STATUS Status;\r
421 EFI_STATUS retStatus;\r
422 BOOLEAN FirstCheck;\r
423 BOOLEAN SkipImage;\r
424 UINT32 DestinationSize;\r
425 UINT32 ScratchSize;\r
426 UINT8 *Scratch;\r
427 VOID *ImageBuffer;\r
428 VOID *DecompressedImageBuffer;\r
429 UINT32 ImageLength;\r
430 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
431 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
432 PCI_DATA_STRUCTURE *Pcir;\r
433\r
434 Indicator = 0;\r
435\r
436 //\r
437 // Get the Address of the Rom image\r
438 //\r
439 RomBar = PciDevice->PciIo.RomImage;\r
440 RomBarOffset = (UINT8 *) RomBar;\r
441 retStatus = EFI_NOT_FOUND;\r
442 FirstCheck = TRUE;\r
443\r
444 do {\r
445 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
446 if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
447 RomBarOffset = RomBarOffset + 512;\r
448 if (FirstCheck) {\r
449 break;\r
450 } else {\r
451 continue;\r
452 }\r
453 }\r
454\r
455 FirstCheck = FALSE;\r
456 Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);\r
457 ImageSize = (UINT32) (Pcir->ImageLength * 512);\r
458 Indicator = Pcir->Indicator;\r
459\r
460 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
461 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
462\r
463 if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
464 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {\r
465\r
466 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
467 ImageSize = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
468\r
469 ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);\r
470 ImageLength = ImageSize - (UINT32)ImageOffset;\r
471 DecompressedImageBuffer = NULL;\r
472\r
473 //\r
474 // decompress here if needed\r
475 //\r
476 SkipImage = FALSE;\r
477 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
478 SkipImage = TRUE;\r
479 }\r
480\r
481 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
482 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
483 if (EFI_ERROR (Status)) {\r
484 SkipImage = TRUE;\r
485 } else {\r
486 SkipImage = TRUE;\r
487 Status = Decompress->GetInfo (\r
488 Decompress,\r
489 ImageBuffer,\r
490 ImageLength,\r
491 &DestinationSize,\r
492 &ScratchSize\r
493 );\r
494 if (!EFI_ERROR (Status)) {\r
495 DecompressedImageBuffer = NULL;\r
496 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
497 if (DecompressedImageBuffer != NULL) {\r
498 Scratch = AllocatePool (ScratchSize);\r
499 if (Scratch != NULL) {\r
500 Status = Decompress->Decompress (\r
501 Decompress,\r
502 ImageBuffer,\r
503 ImageLength,\r
504 DecompressedImageBuffer,\r
505 DestinationSize,\r
506 Scratch,\r
507 ScratchSize\r
508 );\r
509 if (!EFI_ERROR (Status)) {\r
510 ImageBuffer = DecompressedImageBuffer;\r
511 ImageLength = DestinationSize;\r
512 SkipImage = FALSE;\r
513 }\r
514\r
515 gBS->FreePool (Scratch);\r
516 }\r
517 }\r
518 }\r
519 }\r
520 }\r
521\r
522 if (!SkipImage) {\r
523 //\r
524 // load image and start image\r
525 //\r
526 Status = gBS->LoadImage (\r
527 FALSE,\r
528 gPciBusDriverBinding.DriverBindingHandle,\r
529 PciDevice->Handle,\r
530 ImageBuffer,\r
531 ImageLength,\r
532 &ImageHandle\r
533 );\r
534 if (!EFI_ERROR (Status)) {\r
535 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
536 if (!EFI_ERROR (Status)) {\r
537 AddDriver (PciDevice, ImageHandle);\r
538 PciRomAddImageMapping (\r
539 ImageHandle,\r
540 PciDevice->PciRootBridgeIo->SegmentNumber,\r
541 PciDevice->BusNumber,\r
542 PciDevice->DeviceNumber,\r
543 PciDevice->FunctionNumber,\r
544 (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
545 PciDevice->PciIo.RomSize\r
546 );\r
547 retStatus = EFI_SUCCESS;\r
548 }\r
549 }\r
550 }\r
551\r
552 RomBarOffset = RomBarOffset + ImageSize;\r
553 } else {\r
554 RomBarOffset = RomBarOffset + ImageSize;\r
555 }\r
556 } else {\r
557 RomBarOffset = RomBarOffset + ImageSize;\r
558 }\r
559\r
560 } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
561\r
562 return retStatus;\r
563\r
564}\r