3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Option Rom Support for PCI Bus Driver
25 #include "PciRomTable.h"
28 EFI_HANDLE ImageHandle
;
35 } EFI_PCI_ROM_IMAGE_MAPPING
;
37 static UINTN mNumberOfPciRomImages
= 0;
38 static UINTN mMaxNumberOfPciRomImages
= 0;
39 static EFI_PCI_ROM_IMAGE_MAPPING
*mRomImageTable
= NULL
;
42 PciRomAddImageMapping (
43 IN EFI_HANDLE ImageHandle
,
55 TODO: Add function description
59 ImageHandle - TODO: add argument description
60 Seg - TODO: add argument description
61 Bus - TODO: add argument description
62 Dev - TODO: add argument description
63 Func - TODO: add argument description
64 RomAddress - TODO: add argument description
65 RomLength - TODO: add argument description
69 TODO: add return values
73 EFI_PCI_ROM_IMAGE_MAPPING
*TempMapping
;
75 if (mNumberOfPciRomImages
>= mMaxNumberOfPciRomImages
) {
77 mMaxNumberOfPciRomImages
+= 0x20;
80 TempMapping
= AllocatePool (mMaxNumberOfPciRomImages
* sizeof (EFI_PCI_ROM_IMAGE_MAPPING
));
81 if (TempMapping
== NULL
) {
85 CopyMem (TempMapping
, mRomImageTable
, mNumberOfPciRomImages
* sizeof (EFI_PCI_ROM_IMAGE_MAPPING
));
87 if (mRomImageTable
!= NULL
) {
88 gBS
->FreePool (mRomImageTable
);
91 mRomImageTable
= TempMapping
;
94 mRomImageTable
[mNumberOfPciRomImages
].ImageHandle
= ImageHandle
;
95 mRomImageTable
[mNumberOfPciRomImages
].Seg
= Seg
;
96 mRomImageTable
[mNumberOfPciRomImages
].Bus
= Bus
;
97 mRomImageTable
[mNumberOfPciRomImages
].Dev
= Dev
;
98 mRomImageTable
[mNumberOfPciRomImages
].Func
= Func
;
99 mRomImageTable
[mNumberOfPciRomImages
].RomAddress
= RomAddress
;
100 mRomImageTable
[mNumberOfPciRomImages
].RomLength
= RomLength
;
101 mNumberOfPciRomImages
++;
115 TODO: Add function description
119 String - TODO: add argument description
120 Value - TODO: add argument description
121 Digits - TODO: add argument description
125 TODO: add return values
129 for (; Digits
> 0; Digits
--, String
++) {
130 *String
= (CHAR16
) ((Value
>> (4 * (Digits
- 1))) & 0x0f);
132 (*String
) += ('A' - 10);
141 PciRomLoadEfiDriversFromRomImage (
142 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
143 IN EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
154 // TODO: This - add argument and description to function comment
155 // TODO: PciOptionRomDescriptor - add argument and description to function comment
160 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
161 PCI_DATA_STRUCTURE
*Pcir
;
166 EFI_HANDLE ImageHandle
;
168 EFI_STATUS retStatus
;
169 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
171 UINT32 DestinationSize
;
175 VOID
*DecompressedImageBuffer
;
177 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
179 RomBar
= (VOID
*) (UINTN
) PciOptionRomDescriptor
->RomAddress
;
180 RomSize
= (UINTN
) PciOptionRomDescriptor
->RomLength
;
181 FileName
= L
"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";
183 HexToString (&FileName
[11], PciOptionRomDescriptor
->Seg
, 8);
184 HexToString (&FileName
[24], PciOptionRomDescriptor
->Bus
, 2);
185 HexToString (&FileName
[31], PciOptionRomDescriptor
->Dev
, 2);
186 HexToString (&FileName
[39], PciOptionRomDescriptor
->Func
, 2);
189 retStatus
= EFI_NOT_FOUND
;
190 RomBarOffset
= (UINTN
) RomBar
;
194 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomBarOffset
;
196 if (EfiRomHeader
->Signature
!= 0xaa55) {
200 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomBarOffset
+ EfiRomHeader
->PcirOffset
);
201 ImageSize
= Pcir
->ImageLength
* 512;
203 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
204 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
206 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
207 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
209 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
210 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
212 ImageBuffer
= (VOID
*) (UINTN
) (RomBarOffset
+ ImageOffset
);
213 ImageLength
= ImageSize
- ImageOffset
;
214 DecompressedImageBuffer
= NULL
;
217 // decompress here if needed
220 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
224 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
225 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
226 if (EFI_ERROR (Status
)) {
230 Status
= Decompress
->GetInfo (
237 if (!EFI_ERROR (Status
)) {
238 DecompressedImageBuffer
= NULL
;
239 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
240 if (DecompressedImageBuffer
!= NULL
) {
241 Scratch
= AllocatePool (ScratchSize
);
242 if (Scratch
!= NULL
) {
243 Status
= Decompress
->Decompress (
247 DecompressedImageBuffer
,
252 if (!EFI_ERROR (Status
)) {
253 ImageBuffer
= DecompressedImageBuffer
;
254 ImageLength
= DestinationSize
;
258 gBS
->FreePool (Scratch
);
268 // load image and start image
271 HexToString (&FileName
[48], ImageIndex
, 4);
272 FilePath
= FileDevicePath (NULL
, FileName
);
274 Status
= gBS
->LoadImage (
282 if (!EFI_ERROR (Status
)) {
283 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
284 if (!EFI_ERROR (Status
)) {
285 PciRomAddImageMapping (
287 PciOptionRomDescriptor
->Seg
,
288 PciOptionRomDescriptor
->Bus
,
289 PciOptionRomDescriptor
->Dev
,
290 PciOptionRomDescriptor
->Func
,
291 PciOptionRomDescriptor
->RomAddress
,
292 PciOptionRomDescriptor
->RomLength
299 if (DecompressedImageBuffer
!= NULL
) {
300 gBS
->FreePool (DecompressedImageBuffer
);
306 RomBarOffset
= RomBarOffset
+ ImageSize
;
308 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
315 PciRomLoadEfiDriversFromOptionRomTable (
316 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
317 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
328 // TODO: This - add argument and description to function comment
329 // TODO: PciRootBridgeIo - add argument and description to function comment
330 // TODO: EFI_NOT_FOUND - add return value to function comment
333 EFI_PCI_OPTION_ROM_TABLE
*PciOptionRomTable
;
334 EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
;
336 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
340 Status
= EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid
, (VOID
**) &PciOptionRomTable
);
341 if (EFI_ERROR (Status
)) {
342 return EFI_NOT_FOUND
;
345 Status
= EFI_NOT_FOUND
;
347 for (Index
= 0; Index
< PciOptionRomTable
->PciOptionRomCount
; Index
++) {
348 PciOptionRomDescriptor
= &PciOptionRomTable
->PciOptionRomDescriptors
[Index
];
349 if (!PciOptionRomDescriptor
->DontLoadEfiRom
) {
350 if (PciOptionRomDescriptor
->Seg
== PciRootBridgeIo
->SegmentNumber
) {
351 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
352 if (EFI_ERROR (Status
)) {
356 PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
);
357 if ((MinBus
<= PciOptionRomDescriptor
->Bus
) && (PciOptionRomDescriptor
->Bus
<= MaxBus
)) {
358 Status
= PciRomLoadEfiDriversFromRomImage (This
, PciOptionRomDescriptor
);
359 PciOptionRomDescriptor
->DontLoadEfiRom
|= 2;
369 PciRomGetRomResourceFromPciOptionRomTable (
370 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
371 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
372 PCI_IO_DEVICE
*PciIoDevice
383 // TODO: This - add argument and description to function comment
384 // TODO: PciRootBridgeIo - add argument and description to function comment
385 // TODO: PciIoDevice - add argument and description to function comment
386 // TODO: EFI_NOT_FOUND - add return value to function comment
387 // TODO: EFI_SUCCESS - add return value to function comment
390 EFI_PCI_OPTION_ROM_TABLE
*PciOptionRomTable
;
391 EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
;
394 Status
= EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid
, (VOID
**) &PciOptionRomTable
);
395 if (EFI_ERROR (Status
)) {
396 return EFI_NOT_FOUND
;
399 for (Index
= 0; Index
< PciOptionRomTable
->PciOptionRomCount
; Index
++) {
400 PciOptionRomDescriptor
= &PciOptionRomTable
->PciOptionRomDescriptors
[Index
];
401 if (PciOptionRomDescriptor
->Seg
== PciRootBridgeIo
->SegmentNumber
&&
402 PciOptionRomDescriptor
->Bus
== PciIoDevice
->BusNumber
&&
403 PciOptionRomDescriptor
->Dev
== PciIoDevice
->DeviceNumber
&&
404 PciOptionRomDescriptor
->Func
== PciIoDevice
->FunctionNumber
) {
406 PciIoDevice
->PciIo
.RomImage
= (VOID
*) (UINTN
) PciOptionRomDescriptor
->RomAddress
;
407 PciIoDevice
->PciIo
.RomSize
= (UINTN
) PciOptionRomDescriptor
->RomLength
;
411 for (Index
= 0; Index
< mNumberOfPciRomImages
; Index
++) {
412 if (mRomImageTable
[Index
].Seg
== PciRootBridgeIo
->SegmentNumber
&&
413 mRomImageTable
[Index
].Bus
== PciIoDevice
->BusNumber
&&
414 mRomImageTable
[Index
].Dev
== PciIoDevice
->DeviceNumber
&&
415 mRomImageTable
[Index
].Func
== PciIoDevice
->FunctionNumber
) {
417 AddDriver (PciIoDevice
, mRomImageTable
[Index
].ImageHandle
);
425 PciRomGetImageMapping (
426 PCI_IO_DEVICE
*PciIoDevice
437 // TODO: PciIoDevice - add argument and description to function comment
438 // TODO: EFI_SUCCESS - add return value to function comment
440 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
443 PciRootBridgeIo
= PciIoDevice
->PciRootBridgeIo
;
445 for (Index
= 0; Index
< mNumberOfPciRomImages
; Index
++) {
446 if (mRomImageTable
[Index
].Seg
== PciRootBridgeIo
->SegmentNumber
&&
447 mRomImageTable
[Index
].Bus
== PciIoDevice
->BusNumber
&&
448 mRomImageTable
[Index
].Dev
== PciIoDevice
->DeviceNumber
&&
449 mRomImageTable
[Index
].Func
== PciIoDevice
->FunctionNumber
) {
451 if (mRomImageTable
[Index
].ImageHandle
!= NULL
) {
452 AddDriver (PciIoDevice
, mRomImageTable
[Index
].ImageHandle
);
454 PciIoDevice
->PciIo
.RomImage
= (VOID
*) (UINTN
) mRomImageTable
[Index
].RomAddress
;
455 PciIoDevice
->PciIo
.RomSize
= (UINTN
) mRomImageTable
[Index
].RomLength
;