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
++;
114 TODO: Add function description
118 String - TODO: add argument description
119 Value - TODO: add argument description
120 Digits - TODO: add argument description
124 TODO: add return values
128 for (; Digits
> 0; Digits
--, String
++) {
129 *String
= (CHAR16
) ((Value
>> (4 * (Digits
- 1))) & 0x0f);
131 (*String
) += ('A' - 10);
138 PciRomLoadEfiDriversFromRomImage (
139 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
140 IN EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
151 // TODO: This - add argument and description to function comment
152 // TODO: PciOptionRomDescriptor - add argument and description to function comment
157 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
158 PCI_DATA_STRUCTURE
*Pcir
;
163 EFI_HANDLE ImageHandle
;
165 EFI_STATUS retStatus
;
166 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
168 UINT32 DestinationSize
;
172 VOID
*DecompressedImageBuffer
;
174 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
176 RomBar
= (VOID
*) (UINTN
) PciOptionRomDescriptor
->RomAddress
;
177 RomSize
= (UINTN
) PciOptionRomDescriptor
->RomLength
;
178 FileName
= L
"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";
180 HexToString (&FileName
[11], PciOptionRomDescriptor
->Seg
, 8);
181 HexToString (&FileName
[24], PciOptionRomDescriptor
->Bus
, 2);
182 HexToString (&FileName
[31], PciOptionRomDescriptor
->Dev
, 2);
183 HexToString (&FileName
[39], PciOptionRomDescriptor
->Func
, 2);
186 retStatus
= EFI_NOT_FOUND
;
187 RomBarOffset
= (UINTN
) RomBar
;
191 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomBarOffset
;
193 if (EfiRomHeader
->Signature
!= 0xaa55) {
197 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomBarOffset
+ EfiRomHeader
->PcirOffset
);
198 ImageSize
= Pcir
->ImageLength
* 512;
200 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
201 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
203 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
204 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
206 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
207 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
209 ImageBuffer
= (VOID
*) (UINTN
) (RomBarOffset
+ ImageOffset
);
210 ImageLength
= ImageSize
- ImageOffset
;
211 DecompressedImageBuffer
= NULL
;
214 // decompress here if needed
217 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
221 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
222 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
223 if (EFI_ERROR (Status
)) {
227 Status
= Decompress
->GetInfo (
234 if (!EFI_ERROR (Status
)) {
235 DecompressedImageBuffer
= NULL
;
236 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
237 if (DecompressedImageBuffer
!= NULL
) {
238 Scratch
= AllocatePool (ScratchSize
);
239 if (Scratch
!= NULL
) {
240 Status
= Decompress
->Decompress (
244 DecompressedImageBuffer
,
249 if (!EFI_ERROR (Status
)) {
250 ImageBuffer
= DecompressedImageBuffer
;
251 ImageLength
= DestinationSize
;
255 gBS
->FreePool (Scratch
);
265 // load image and start image
268 HexToString (&FileName
[48], ImageIndex
, 4);
269 FilePath
= FileDevicePath (NULL
, FileName
);
271 Status
= gBS
->LoadImage (
279 if (!EFI_ERROR (Status
)) {
280 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
281 if (!EFI_ERROR (Status
)) {
282 PciRomAddImageMapping (
284 PciOptionRomDescriptor
->Seg
,
285 PciOptionRomDescriptor
->Bus
,
286 PciOptionRomDescriptor
->Dev
,
287 PciOptionRomDescriptor
->Func
,
288 PciOptionRomDescriptor
->RomAddress
,
289 PciOptionRomDescriptor
->RomLength
296 if (DecompressedImageBuffer
!= NULL
) {
297 gBS
->FreePool (DecompressedImageBuffer
);
303 RomBarOffset
= RomBarOffset
+ ImageSize
;
305 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomBarOffset
- (UINTN
) RomBar
) < RomSize
));
311 PciRomLoadEfiDriversFromOptionRomTable (
312 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
313 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
324 // TODO: This - add argument and description to function comment
325 // TODO: PciRootBridgeIo - add argument and description to function comment
326 // TODO: EFI_NOT_FOUND - add return value to function comment
329 EFI_PCI_OPTION_ROM_TABLE
*PciOptionRomTable
;
330 EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
;
332 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
336 Status
= EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid
, (VOID
**) &PciOptionRomTable
);
337 if (EFI_ERROR (Status
)) {
338 return EFI_NOT_FOUND
;
341 Status
= EFI_NOT_FOUND
;
343 for (Index
= 0; Index
< PciOptionRomTable
->PciOptionRomCount
; Index
++) {
344 PciOptionRomDescriptor
= &PciOptionRomTable
->PciOptionRomDescriptors
[Index
];
345 if (!PciOptionRomDescriptor
->DontLoadEfiRom
) {
346 if (PciOptionRomDescriptor
->Seg
== PciRootBridgeIo
->SegmentNumber
) {
347 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
348 if (EFI_ERROR (Status
)) {
352 PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
);
353 if ((MinBus
<= PciOptionRomDescriptor
->Bus
) && (PciOptionRomDescriptor
->Bus
<= MaxBus
)) {
354 Status
= PciRomLoadEfiDriversFromRomImage (This
, PciOptionRomDescriptor
);
355 PciOptionRomDescriptor
->DontLoadEfiRom
|= 2;
365 PciRomGetRomResourceFromPciOptionRomTable (
366 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
367 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
368 PCI_IO_DEVICE
*PciIoDevice
379 // TODO: This - add argument and description to function comment
380 // TODO: PciRootBridgeIo - add argument and description to function comment
381 // TODO: PciIoDevice - add argument and description to function comment
382 // TODO: EFI_NOT_FOUND - add return value to function comment
383 // TODO: EFI_SUCCESS - add return value to function comment
386 EFI_PCI_OPTION_ROM_TABLE
*PciOptionRomTable
;
387 EFI_PCI_OPTION_ROM_DESCRIPTOR
*PciOptionRomDescriptor
;
390 Status
= EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid
, (VOID
**) &PciOptionRomTable
);
391 if (EFI_ERROR (Status
)) {
392 return EFI_NOT_FOUND
;
395 for (Index
= 0; Index
< PciOptionRomTable
->PciOptionRomCount
; Index
++) {
396 PciOptionRomDescriptor
= &PciOptionRomTable
->PciOptionRomDescriptors
[Index
];
397 if (PciOptionRomDescriptor
->Seg
== PciRootBridgeIo
->SegmentNumber
&&
398 PciOptionRomDescriptor
->Bus
== PciIoDevice
->BusNumber
&&
399 PciOptionRomDescriptor
->Dev
== PciIoDevice
->DeviceNumber
&&
400 PciOptionRomDescriptor
->Func
== PciIoDevice
->FunctionNumber
) {
402 PciIoDevice
->PciIo
.RomImage
= (VOID
*) (UINTN
) PciOptionRomDescriptor
->RomAddress
;
403 PciIoDevice
->PciIo
.RomSize
= (UINTN
) PciOptionRomDescriptor
->RomLength
;
407 for (Index
= 0; Index
< mNumberOfPciRomImages
; Index
++) {
408 if (mRomImageTable
[Index
].Seg
== PciRootBridgeIo
->SegmentNumber
&&
409 mRomImageTable
[Index
].Bus
== PciIoDevice
->BusNumber
&&
410 mRomImageTable
[Index
].Dev
== PciIoDevice
->DeviceNumber
&&
411 mRomImageTable
[Index
].Func
== PciIoDevice
->FunctionNumber
) {
413 AddDriver (PciIoDevice
, mRomImageTable
[Index
].ImageHandle
);
421 PciRomGetImageMapping (
422 PCI_IO_DEVICE
*PciIoDevice
433 // TODO: PciIoDevice - add argument and description to function comment
434 // TODO: EFI_SUCCESS - add return value to function comment
436 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
439 PciRootBridgeIo
= PciIoDevice
->PciRootBridgeIo
;
441 for (Index
= 0; Index
< mNumberOfPciRomImages
; Index
++) {
442 if (mRomImageTable
[Index
].Seg
== PciRootBridgeIo
->SegmentNumber
&&
443 mRomImageTable
[Index
].Bus
== PciIoDevice
->BusNumber
&&
444 mRomImageTable
[Index
].Dev
== PciIoDevice
->DeviceNumber
&&
445 mRomImageTable
[Index
].Func
== PciIoDevice
->FunctionNumber
) {
447 if (mRomImageTable
[Index
].ImageHandle
!= NULL
) {
448 AddDriver (PciIoDevice
, mRomImageTable
[Index
].ImageHandle
);
450 PciIoDevice
->PciIo
.RomImage
= (VOID
*) (UINTN
) mRomImageTable
[Index
].RomAddress
;
451 PciIoDevice
->PciIo
.RomSize
= (UINTN
) mRomImageTable
[Index
].RomLength
;