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