]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/PciBusNoEnumerationDxe/PciRomTable.c
Fix build issue in linux environment.
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciRomTable.c
CommitLineData
10590588 1/*++\r
2\r
3Copyright (c) 2005 - 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 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
d8bee43c 24#include "PciBus.h"\r
10590588 25\r
26typedef struct {\r
27 EFI_HANDLE ImageHandle;\r
28 UINTN Seg;\r
29 UINT8 Bus;\r
30 UINT8 Dev;\r
31 UINT8 Func;\r
32} EFI_PCI_ROM_IMAGE_MAPPING;\r
33\r
34static UINTN mNumberOfPciRomImages = 0;\r
35static UINTN mMaxNumberOfPciRomImages = 0;\r
36static EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL;\r
37\r
38static CHAR16 mHexDigit[17] = L"0123456789ABCDEF";\r
39\r
40static\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 )\r
49\r
50{\r
51 EFI_PCI_ROM_IMAGE_MAPPING *TempMapping;\r
52\r
53 if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) {\r
54\r
55 mMaxNumberOfPciRomImages += 0x20;\r
56\r
57 TempMapping = NULL;\r
58 TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
59 if (TempMapping == NULL) {\r
60 return ;\r
61 }\r
62\r
63 CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING));\r
64\r
65 if (mRomImageTable != NULL) {\r
66 gBS->FreePool (mRomImageTable);\r
67 }\r
68\r
69 mRomImageTable = TempMapping;\r
70 }\r
71\r
72 mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle;\r
73 mRomImageTable[mNumberOfPciRomImages].Seg = Seg;\r
74 mRomImageTable[mNumberOfPciRomImages].Bus = Bus;\r
75 mRomImageTable[mNumberOfPciRomImages].Dev = Dev;\r
76 mRomImageTable[mNumberOfPciRomImages].Func = Func;\r
77 mNumberOfPciRomImages++;\r
78}\r
79\r
80static\r
81VOID\r
82HexToString (\r
83 CHAR16 *String,\r
84 UINTN Value,\r
85 UINTN Digits\r
86 )\r
87\r
88{\r
89 for (; Digits > 0; Digits--, String++) {\r
90 *String = mHexDigit[((Value >> (4*(Digits-1))) & 0x0f)];\r
91 }\r
92}\r
93\r
94EFI_STATUS\r
95PciRomLoadEfiDriversFromRomImage (\r
96 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
97 IN EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor\r
98 )\r
99/*++\r
100\r
101Routine Description:\r
102 Command entry point. \r
103\r
104Arguments:\r
105 ImageHandle The image handle. \r
106 SystemTable The system table.\r
107\r
108Returns:\r
109 EFI_SUCCESS - The command completed successfully\r
110 EFI_INVALID_PARAMETER - Command usage error\r
111 EFI_UNSUPPORTED - Protocols unsupported\r
112 EFI_OUT_OF_RESOURCES - Out of memory\r
113 Other value - Unknown error\r
114\r
115--*/\r
116{\r
117 VOID *RomBar;\r
118 UINTN RomSize;\r
119 CHAR16 *FileName;\r
120 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
121 PCI_DATA_STRUCTURE *Pcir;\r
122 UINTN ImageIndex;\r
123 UINTN RomBarOffset;\r
124 UINT32 ImageSize;\r
125 UINT16 ImageOffset;\r
126 EFI_HANDLE ImageHandle;\r
127 EFI_STATUS Status;\r
128 EFI_STATUS retStatus;\r
129 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
130 BOOLEAN SkipImage;\r
131 UINT32 DestinationSize;\r
132 UINT32 ScratchSize;\r
133 UINT8 *Scratch;\r
134 VOID *ImageBuffer;\r
135 VOID *DecompressedImageBuffer;\r
136 UINT32 ImageLength;\r
137 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
138\r
139 RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
140 RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
141 FileName = L"PciRom Seg=00000000 Bus=00 Dev=00 Func=00 Image=0000";\r
142\r
143 HexToString (&FileName[11], PciOptionRomDescriptor->Seg, 8);\r
144 HexToString (&FileName[24], PciOptionRomDescriptor->Bus, 2);\r
145 HexToString (&FileName[31], PciOptionRomDescriptor->Dev, 2);\r
146 HexToString (&FileName[39], PciOptionRomDescriptor->Func, 2);\r
147\r
148 ImageIndex = 0;\r
149 retStatus = EFI_NOT_FOUND;\r
150 RomBarOffset = (UINTN) RomBar;\r
151\r
152 do {\r
153\r
154 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
155\r
156 if (EfiRomHeader->Signature != 0xaa55) {\r
157 return retStatus;\r
158 }\r
159\r
160 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
161 ImageSize = Pcir->ImageLength * 512;\r
162\r
163 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
164 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
165\r
166 if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
167 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
168\r
169 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
170 ImageSize = EfiRomHeader->InitializationSize * 512;\r
171\r
172 ImageBuffer = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
173 ImageLength = ImageSize - ImageOffset;\r
174 DecompressedImageBuffer = NULL;\r
175\r
176 //\r
177 // decompress here if needed\r
178 //\r
179 SkipImage = FALSE;\r
180 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
181 SkipImage = TRUE;\r
182 }\r
183\r
184 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
185 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
186 if (EFI_ERROR (Status)) {\r
187 SkipImage = TRUE;\r
188 } else {\r
189 SkipImage = TRUE;\r
190 Status = Decompress->GetInfo (\r
191 Decompress,\r
192 ImageBuffer,\r
193 ImageLength,\r
194 &DestinationSize,\r
195 &ScratchSize\r
196 );\r
197 if (!EFI_ERROR (Status)) {\r
198 DecompressedImageBuffer = NULL;\r
199 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
200 if (DecompressedImageBuffer != NULL) {\r
201 Scratch = AllocatePool (ScratchSize);\r
202 if (Scratch != NULL) {\r
203 Status = Decompress->Decompress (\r
204 Decompress,\r
205 ImageBuffer,\r
206 ImageLength,\r
207 DecompressedImageBuffer,\r
208 DestinationSize,\r
209 Scratch,\r
210 ScratchSize\r
211 );\r
212 if (!EFI_ERROR (Status)) {\r
213 ImageBuffer = DecompressedImageBuffer;\r
214 ImageLength = DestinationSize;\r
215 SkipImage = FALSE;\r
216 }\r
217\r
218 gBS->FreePool (Scratch);\r
219 }\r
220 }\r
221 }\r
222 }\r
223 }\r
224\r
225 if (!SkipImage) {\r
226\r
227 //\r
228 // load image and start image\r
229 //\r
230\r
231 HexToString (&FileName[48], ImageIndex, 4);\r
232 FilePath = FileDevicePath (NULL, FileName);\r
233\r
234 Status = gBS->LoadImage (\r
235 FALSE,\r
236 This->ImageHandle,\r
237 FilePath,\r
238 ImageBuffer,\r
239 ImageLength,\r
240 &ImageHandle\r
241 );\r
242 if (!EFI_ERROR (Status)) {\r
243 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
244 if (!EFI_ERROR (Status)) {\r
245 PciRomAddImageMapping (\r
246 ImageHandle,\r
247 PciOptionRomDescriptor->Seg,\r
248 PciOptionRomDescriptor->Bus,\r
249 PciOptionRomDescriptor->Dev,\r
250 PciOptionRomDescriptor->Func\r
251 );\r
252 retStatus = Status;\r
253 }\r
254 }\r
255 if (FilePath != NULL) {\r
256 gBS->FreePool (FilePath);\r
257 }\r
258 }\r
259\r
260 if (DecompressedImageBuffer != NULL) {\r
261 gBS->FreePool (DecompressedImageBuffer);\r
262 }\r
263\r
264 }\r
265 }\r
266\r
267 RomBarOffset = RomBarOffset + ImageSize;\r
268 ImageIndex++;\r
269 } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomBarOffset - (UINTN) RomBar) < RomSize));\r
270\r
271 return retStatus;\r
272}\r
273\r
274EFI_STATUS\r
275PciRomLoadEfiDriversFromOptionRomTable (\r
276 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
277 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo\r
278 )\r
279/*++\r
280\r
281Routine Description:\r
282\r
283Arguments:\r
284\r
285Returns:\r
286\r
287--*/\r
288{\r
289 EFI_STATUS Status;\r
290 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
291 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
292 UINTN Index;\r
293 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
294 UINT16 MinBus;\r
295 UINT16 MaxBus;\r
296\r
297 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
298 if (EFI_ERROR (Status)) {\r
299 return EFI_NOT_FOUND;\r
300 }\r
301\r
302 Status = EFI_NOT_FOUND;\r
303\r
304 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
305 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
306 if (!PciOptionRomDescriptor->DontLoadEfiRom) {\r
307 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {\r
308 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
309 if (EFI_ERROR (Status)) {\r
310 return Status;\r
311 }\r
312\r
313 PciGetBusRange (Descriptors, &MinBus, &MaxBus, NULL);\r
314 if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {\r
315 Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);\r
316 PciOptionRomDescriptor->DontLoadEfiRom |= 2;\r
317 }\r
318 }\r
319 }\r
320 }\r
321\r
322 return Status;\r
323}\r
324\r
325EFI_STATUS\r
326PciRomGetRomResourceFromPciOptionRomTable (\r
327 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
328 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
329 PCI_IO_DEVICE *PciIoDevice\r
330 )\r
331/*++\r
332\r
333Routine Description:\r
334\r
335Arguments:\r
336\r
337Returns:\r
338\r
339--*/\r
340{\r
341 EFI_STATUS Status;\r
342 EFI_PCI_OPTION_ROM_TABLE *PciOptionRomTable;\r
343 EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
344 UINTN Index;\r
345\r
346 Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
347 if (EFI_ERROR (Status)) {\r
348 return EFI_NOT_FOUND;\r
349 }\r
350\r
351 for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
352 PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
353 if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
354 PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber &&\r
355 PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber &&\r
356 PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
357\r
358 PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
359 PciIoDevice->PciIo.RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
360 }\r
361 }\r
362\r
363 for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
364 if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber &&\r
365 mRomImageTable[Index].Bus == PciIoDevice->BusNumber &&\r
366 mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber &&\r
367 mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {\r
368\r
369 AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
370 }\r
371 }\r
372\r
373 return EFI_SUCCESS;\r
374}\r