878ddf1f |
1 | /*++\r |
2 | \r |
3 | Copyright (c) 2006, Intel Corporation \r |
4 | All rights reserved. This program and the accompanying materials \r |
5 | are licensed and made available under the terms and conditions of the BSD License \r |
6 | which accompanies this distribution. The full text of the license may be found at \r |
7 | http://opensource.org/licenses/bsd-license.php \r |
8 | \r |
9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r |
10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r |
11 | \r |
12 | Module Name:\r |
13 | \r |
14 | LightPciLib.c\r |
15 | \r |
16 | Abstract:\r |
17 | \r |
18 | Light PCI Bus Driver Lib file\r |
19 | It abstracts some functions that can be different \r |
20 | between light PCI bus driver and full PCI bus driver\r |
21 | \r |
22 | Revision History\r |
23 | \r |
24 | --*/\r |
25 | \r |
26 | #include "pcibus.h"\r |
27 | \r |
28 | //\r |
29 | // Light PCI bus driver woundn't support hotplug device\r |
30 | // So just return\r |
31 | //\r |
32 | VOID\r |
33 | InstallHotPlugRequestProtocol (\r |
34 | IN EFI_STATUS *Status\r |
35 | )\r |
36 | /*++\r |
37 | \r |
38 | Routine Description:\r |
39 | \r |
40 | \r |
41 | Arguments:\r |
42 | \r |
43 | Returns:\r |
44 | \r |
45 | None\r |
46 | \r |
47 | --*/\r |
48 | // TODO: Status - add argument and description to function comment\r |
49 | {\r |
50 | return ;\r |
51 | }\r |
52 | \r |
53 | //\r |
54 | // Light PCI bus driver woundn't support hotplug device\r |
55 | // So just skip install this GUID\r |
56 | //\r |
57 | VOID\r |
58 | InstallPciHotplugGuid (\r |
59 | IN PCI_IO_DEVICE *PciIoDevice\r |
60 | )\r |
61 | /*++\r |
62 | \r |
63 | Routine Description:\r |
64 | \r |
65 | \r |
66 | Arguments:\r |
67 | \r |
68 | Returns:\r |
69 | \r |
70 | None\r |
71 | \r |
72 | --*/\r |
73 | // TODO: PciIoDevice - add argument and description to function comment\r |
74 | {\r |
75 | return ;\r |
76 | }\r |
77 | \r |
78 | //\r |
79 | // Light PCI bus driver woundn't support hotplug device\r |
80 | // So just skip uninstall the GUID\r |
81 | //\r |
82 | VOID\r |
83 | UninstallPciHotplugGuid (\r |
84 | IN PCI_IO_DEVICE *PciIoDevice\r |
85 | )\r |
86 | /*++\r |
87 | \r |
88 | Routine Description:\r |
89 | \r |
90 | \r |
91 | Arguments:\r |
92 | \r |
93 | Returns:\r |
94 | \r |
95 | None\r |
96 | \r |
97 | --*/\r |
98 | // TODO: PciIoDevice - add argument and description to function comment\r |
99 | {\r |
100 | return ;\r |
101 | }\r |
102 | \r |
103 | //\r |
104 | // Light PCI bus driver woundn't support PCCard\r |
105 | // So it needn't get the bar of CardBus\r |
106 | //\r |
107 | VOID\r |
108 | GetBackPcCardBar (\r |
109 | IN PCI_IO_DEVICE *PciIoDevice\r |
110 | )\r |
111 | /*++\r |
112 | \r |
113 | Routine Description:\r |
114 | \r |
115 | TODO: Add function description\r |
116 | \r |
117 | Arguments:\r |
118 | \r |
119 | PciIoDevice - TODO: add argument description\r |
120 | \r |
121 | Returns:\r |
122 | \r |
123 | TODO: add return values\r |
124 | \r |
125 | --*/\r |
126 | {\r |
127 | return ;\r |
128 | }\r |
129 | \r |
130 | //\r |
131 | // Light PCI bus driver woundn't support resource reallocation\r |
132 | // So just return\r |
133 | //\r |
134 | EFI_STATUS\r |
135 | RemoveRejectedPciDevices (\r |
136 | EFI_HANDLE RootBridgeHandle,\r |
137 | IN PCI_IO_DEVICE *Bridge\r |
138 | )\r |
139 | /*++\r |
140 | \r |
141 | Routine Description:\r |
142 | \r |
143 | TODO: Add function description\r |
144 | \r |
145 | Arguments:\r |
146 | \r |
147 | RootBridgeHandle - TODO: add argument description\r |
148 | Bridge - TODO: add argument description\r |
149 | \r |
150 | Returns:\r |
151 | \r |
152 | EFI_SUCCESS - TODO: Add description for return value\r |
153 | \r |
154 | --*/\r |
155 | {\r |
156 | return EFI_SUCCESS;\r |
157 | }\r |
158 | \r |
159 | //\r |
160 | // Light PCI bus driver woundn't support resource reallocation\r |
161 | // Simplified the code\r |
162 | //\r |
163 | EFI_STATUS\r |
164 | PciHostBridgeResourceAllocator (\r |
165 | IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r |
166 | )\r |
167 | /*++\r |
168 | \r |
169 | Routine Description:\r |
170 | \r |
171 | Arguments:\r |
172 | \r |
173 | Returns:\r |
174 | \r |
175 | None\r |
176 | \r |
177 | --*/\r |
178 | // TODO: PciResAlloc - add argument and description to function comment\r |
179 | // TODO: EFI_NOT_FOUND - add return value to function comment\r |
180 | // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r |
181 | // TODO: EFI_NOT_FOUND - add return value to function comment\r |
182 | // TODO: EFI_SUCCESS - add return value to function comment\r |
183 | {\r |
184 | PCI_IO_DEVICE *RootBridgeDev;\r |
185 | EFI_HANDLE RootBridgeHandle;\r |
186 | VOID *AcpiConfig;\r |
187 | EFI_STATUS Status;\r |
188 | UINT64 IoBase;\r |
189 | UINT64 Mem32Base;\r |
190 | UINT64 PMem32Base;\r |
191 | UINT64 Mem64Base;\r |
192 | UINT64 PMem64Base;\r |
193 | UINT64 MaxOptionRomSize;\r |
194 | PCI_RESOURCE_NODE *IoBridge;\r |
195 | PCI_RESOURCE_NODE *Mem32Bridge;\r |
196 | PCI_RESOURCE_NODE *PMem32Bridge;\r |
197 | PCI_RESOURCE_NODE *Mem64Bridge;\r |
198 | PCI_RESOURCE_NODE *PMem64Bridge;\r |
199 | PCI_RESOURCE_NODE IoPool;\r |
200 | PCI_RESOURCE_NODE Mem32Pool;\r |
201 | PCI_RESOURCE_NODE PMem32Pool;\r |
202 | PCI_RESOURCE_NODE Mem64Pool;\r |
203 | PCI_RESOURCE_NODE PMem64Pool;\r |
204 | REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;\r |
205 | \r |
206 | //\r |
207 | // Initialize resource pool\r |
208 | //\r |
209 | \r |
210 | InitializeResourcePool (&IoPool, PciBarTypeIo16);\r |
211 | InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r |
212 | InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r |
213 | InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r |
214 | InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r |
215 | \r |
216 | RootBridgeDev = NULL;\r |
217 | RootBridgeHandle = 0;\r |
218 | \r |
219 | while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r |
220 | //\r |
221 | // Get RootBridg Device by handle\r |
222 | //\r |
223 | RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r |
224 | \r |
225 | if (RootBridgeDev == NULL) {\r |
226 | return EFI_NOT_FOUND;\r |
227 | }\r |
228 | \r |
229 | //\r |
230 | // Get host bridge handle for status report\r |
231 | //\r |
232 | ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r |
233 | \r |
234 | //\r |
235 | // Create the entire system resource map from the information collected by\r |
236 | // enumerator. Several resource tree was created\r |
237 | //\r |
238 | \r |
239 | IoBridge = CreateResourceNode (\r |
240 | RootBridgeDev,\r |
241 | 0,\r |
242 | 0xFFF,\r |
243 | 0,\r |
244 | PciBarTypeIo16,\r |
245 | PciResUsageTypical\r |
246 | );\r |
247 | \r |
248 | Mem32Bridge = CreateResourceNode (\r |
249 | RootBridgeDev,\r |
250 | 0,\r |
251 | 0xFFFFF,\r |
252 | 0,\r |
253 | PciBarTypeMem32,\r |
254 | PciResUsageTypical\r |
255 | );\r |
256 | \r |
257 | PMem32Bridge = CreateResourceNode (\r |
258 | RootBridgeDev,\r |
259 | 0,\r |
260 | 0xFFFFF,\r |
261 | 0,\r |
262 | PciBarTypePMem32,\r |
263 | PciResUsageTypical\r |
264 | );\r |
265 | \r |
266 | Mem64Bridge = CreateResourceNode (\r |
267 | RootBridgeDev,\r |
268 | 0,\r |
269 | 0xFFFFF,\r |
270 | 0,\r |
271 | PciBarTypeMem64,\r |
272 | PciResUsageTypical\r |
273 | );\r |
274 | \r |
275 | PMem64Bridge = CreateResourceNode (\r |
276 | RootBridgeDev,\r |
277 | 0,\r |
278 | 0xFFFFF,\r |
279 | 0,\r |
280 | PciBarTypePMem64,\r |
281 | PciResUsageTypical\r |
282 | );\r |
283 | \r |
284 | //\r |
285 | // Create resourcemap by going through all the devices subject to this root bridge\r |
286 | //\r |
287 | Status = CreateResourceMap (\r |
288 | RootBridgeDev,\r |
289 | IoBridge,\r |
290 | Mem32Bridge,\r |
291 | PMem32Bridge,\r |
292 | Mem64Bridge,\r |
293 | PMem64Bridge\r |
294 | );\r |
295 | \r |
296 | //\r |
297 | // Get the max ROM size that the root bridge can process\r |
298 | //\r |
299 | RootBridgeDev->RomSize = Mem32Bridge->Length;\r |
300 | \r |
301 | //\r |
302 | // Get Max Option Rom size for current root bridge\r |
303 | //\r |
304 | MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r |
305 | \r |
306 | //\r |
307 | // Enlarger the mem32 resource to accomdate the option rom\r |
308 | // if the mem32 resource is not enough to hold the rom\r |
309 | //\r |
310 | if (MaxOptionRomSize > Mem32Bridge->Length) {\r |
311 | \r |
312 | Mem32Bridge->Length = MaxOptionRomSize;\r |
313 | RootBridgeDev->RomSize = MaxOptionRomSize;\r |
314 | \r |
315 | //\r |
316 | // Alignment should be adjusted as well\r |
317 | //\r |
318 | if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r |
319 | Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r |
320 | }\r |
321 | }\r |
322 | \r |
323 | //\r |
324 | // Based on the all the resource tree, contruct ACPI resource node to\r |
325 | // submit the resource aperture to pci host bridge protocol\r |
326 | //\r |
327 | Status = ConstructAcpiResourceRequestor (\r |
328 | RootBridgeDev,\r |
329 | IoBridge,\r |
330 | Mem32Bridge,\r |
331 | PMem32Bridge,\r |
332 | Mem64Bridge,\r |
333 | PMem64Bridge,\r |
334 | &AcpiConfig\r |
335 | );\r |
336 | \r |
337 | //\r |
338 | // Insert these resource nodes into the database\r |
339 | //\r |
340 | InsertResourceNode (&IoPool, IoBridge);\r |
341 | InsertResourceNode (&Mem32Pool, Mem32Bridge);\r |
342 | InsertResourceNode (&PMem32Pool, PMem32Bridge);\r |
343 | InsertResourceNode (&Mem64Pool, Mem64Bridge);\r |
344 | InsertResourceNode (&PMem64Pool, PMem64Bridge);\r |
345 | \r |
346 | if (Status == EFI_SUCCESS) {\r |
347 | //\r |
348 | // Submit the resource requirement\r |
349 | //\r |
350 | Status = PciResAlloc->SubmitResources (\r |
351 | PciResAlloc,\r |
352 | RootBridgeDev->Handle,\r |
353 | AcpiConfig\r |
354 | );\r |
355 | }\r |
356 | //\r |
357 | // Free acpi resource node\r |
358 | //\r |
359 | if (AcpiConfig) {\r |
360 | gBS->FreePool (AcpiConfig);\r |
361 | }\r |
362 | \r |
363 | if (EFI_ERROR (Status)) {\r |
364 | //\r |
365 | // Destroy all the resource tree\r |
366 | //\r |
367 | DestroyResourceTree (&IoPool);\r |
368 | DestroyResourceTree (&Mem32Pool);\r |
369 | DestroyResourceTree (&PMem32Pool);\r |
370 | DestroyResourceTree (&Mem64Pool);\r |
371 | DestroyResourceTree (&PMem64Pool);\r |
372 | return Status;\r |
373 | }\r |
374 | }\r |
375 | //\r |
376 | // End while\r |
377 | //\r |
378 | \r |
379 | //\r |
380 | // Notify pci bus driver starts to program the resource\r |
381 | //\r |
382 | Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r |
383 | \r |
384 | if (EFI_ERROR (Status)) {\r |
385 | //\r |
386 | // Allocation failed, then return\r |
387 | //\r |
388 | return EFI_OUT_OF_RESOURCES;\r |
389 | }\r |
390 | //\r |
391 | // Raise the EFI_IOB_PCI_RES_ALLOC status code\r |
392 | //\r |
393 | REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r |
394 | EFI_PROGRESS_CODE,\r |
395 | EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r |
396 | (VOID *) &ExtendedData,\r |
397 | sizeof (ExtendedData)\r |
398 | );\r |
399 | \r |
400 | //\r |
401 | // Notify pci bus driver starts to program the resource\r |
402 | //\r |
403 | NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r |
404 | \r |
405 | RootBridgeDev = NULL;\r |
406 | \r |
407 | RootBridgeHandle = 0;\r |
408 | \r |
409 | while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r |
410 | //\r |
411 | // Get RootBridg Device by handle\r |
412 | //\r |
413 | RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r |
414 | \r |
415 | if (RootBridgeDev == NULL) {\r |
416 | return EFI_NOT_FOUND;\r |
417 | }\r |
418 | \r |
419 | //\r |
420 | // Get acpi resource node for all the resource types\r |
421 | //\r |
422 | AcpiConfig = NULL;\r |
423 | Status = PciResAlloc->GetProposedResources (\r |
424 | PciResAlloc,\r |
425 | RootBridgeDev->Handle,\r |
426 | &AcpiConfig\r |
427 | );\r |
428 | \r |
429 | if (EFI_ERROR (Status)) {\r |
430 | return Status;\r |
431 | }\r |
432 | \r |
433 | //\r |
434 | // Get the resource base by interpreting acpi resource node\r |
435 | //\r |
436 | //\r |
437 | GetResourceBase (\r |
438 | AcpiConfig,\r |
439 | &IoBase,\r |
440 | &Mem32Base,\r |
441 | &PMem32Base,\r |
442 | &Mem64Base,\r |
443 | &PMem64Base\r |
444 | );\r |
445 | \r |
446 | //\r |
447 | // Process option rom for this root bridge\r |
448 | //\r |
449 | Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r |
450 | \r |
451 | //\r |
452 | // Create the entire system resource map from the information collected by\r |
453 | // enumerator. Several resource tree was created\r |
454 | //\r |
455 | Status = GetResourceMap (\r |
456 | RootBridgeDev,\r |
457 | &IoBridge,\r |
458 | &Mem32Bridge,\r |
459 | &PMem32Bridge,\r |
460 | &Mem64Bridge,\r |
461 | &PMem64Bridge,\r |
462 | &IoPool,\r |
463 | &Mem32Pool,\r |
464 | &PMem32Pool,\r |
465 | &Mem64Pool,\r |
466 | &PMem64Pool\r |
467 | );\r |
468 | \r |
469 | if (EFI_ERROR (Status)) {\r |
470 | return Status;\r |
471 | }\r |
472 | \r |
473 | //\r |
474 | // Program IO resources\r |
475 | //\r |
476 | ProgramResource (\r |
477 | IoBase,\r |
478 | IoBridge\r |
479 | );\r |
480 | \r |
481 | //\r |
482 | // Program Mem32 resources\r |
483 | //\r |
484 | ProgramResource (\r |
485 | Mem32Base,\r |
486 | Mem32Bridge\r |
487 | );\r |
488 | \r |
489 | //\r |
490 | // Program PMem32 resources\r |
491 | //\r |
492 | ProgramResource (\r |
493 | PMem32Base,\r |
494 | PMem32Bridge\r |
495 | );\r |
496 | \r |
497 | //\r |
498 | // Program Mem64 resources\r |
499 | //\r |
500 | ProgramResource (\r |
501 | Mem64Base,\r |
502 | Mem64Bridge\r |
503 | );\r |
504 | \r |
505 | //\r |
506 | // Program PMem64 resources\r |
507 | //\r |
508 | ProgramResource (\r |
509 | PMem64Base,\r |
510 | PMem64Bridge\r |
511 | );\r |
512 | \r |
513 | if (AcpiConfig != NULL) {\r |
514 | gBS->FreePool (AcpiConfig);\r |
515 | }\r |
516 | }\r |
517 | \r |
518 | //\r |
519 | // Destroy all the resource tree\r |
520 | //\r |
521 | DestroyResourceTree (&IoPool);\r |
522 | DestroyResourceTree (&Mem32Pool);\r |
523 | DestroyResourceTree (&PMem32Pool);\r |
524 | DestroyResourceTree (&Mem64Pool);\r |
525 | DestroyResourceTree (&PMem64Pool);\r |
526 | \r |
527 | //\r |
528 | // Notify the resource allocation phase is to end\r |
529 | //\r |
530 | NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r |
531 | \r |
532 | return EFI_SUCCESS;\r |
533 | }\r |
534 | \r |
535 | EFI_STATUS\r |
536 | PciScanBus (\r |
537 | IN PCI_IO_DEVICE *Bridge,\r |
538 | IN UINT8 StartBusNumber,\r |
539 | OUT UINT8 *SubBusNumber,\r |
540 | OUT UINT8 *PaddedBusRange\r |
541 | )\r |
542 | /*++\r |
543 | \r |
544 | Routine Description:\r |
545 | \r |
546 | This routine is used to assign bus number to the given PCI bus system\r |
547 | \r |
548 | Arguments:\r |
549 | \r |
550 | Returns:\r |
551 | \r |
552 | None\r |
553 | \r |
554 | --*/\r |
555 | // TODO: Bridge - add argument and description to function comment\r |
556 | // TODO: StartBusNumber - add argument and description to function comment\r |
557 | // TODO: SubBusNumber - add argument and description to function comment\r |
558 | // TODO: PaddedBusRange - add argument and description to function comment\r |
559 | // TODO: EFI_DEVICE_ERROR - add return value to function comment\r |
560 | // TODO: EFI_SUCCESS - add return value to function comment\r |
561 | {\r |
562 | EFI_STATUS Status;\r |
563 | PCI_TYPE00 Pci;\r |
564 | UINT8 Device;\r |
565 | UINT8 Func;\r |
566 | UINT64 Address;\r |
567 | UINTN SecondBus;\r |
568 | UINT16 Register;\r |
569 | PCI_IO_DEVICE *PciDevice;\r |
570 | EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r |
571 | \r |
572 | PciRootBridgeIo = Bridge->PciRootBridgeIo;\r |
573 | SecondBus = 0;\r |
574 | Register = 0;\r |
575 | \r |
576 | ResetAllPpbBusReg (Bridge, StartBusNumber);\r |
577 | \r |
578 | for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r |
579 | for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r |
580 | \r |
581 | //\r |
582 | // Check to see whether a pci device is present\r |
583 | //\r |
584 | Status = PciDevicePresent (\r |
585 | PciRootBridgeIo,\r |
586 | &Pci,\r |
587 | StartBusNumber,\r |
588 | Device,\r |
589 | Func\r |
590 | );\r |
591 | \r |
592 | if (!EFI_ERROR (Status) && \r |
593 | (IS_PCI_BRIDGE (&Pci) ||\r |
594 | IS_CARDBUS_BRIDGE (&Pci))) {\r |
595 | \r |
596 | //\r |
597 | // Get the bridge information\r |
598 | //\r |
599 | Status = PciSearchDevice (\r |
600 | Bridge,\r |
601 | &Pci,\r |
602 | StartBusNumber,\r |
603 | Device,\r |
604 | Func,\r |
605 | &PciDevice\r |
606 | );\r |
607 | \r |
608 | if (EFI_ERROR (Status)) {\r |
609 | return Status;\r |
610 | }\r |
611 | \r |
612 | (*SubBusNumber)++;\r |
613 | \r |
614 | SecondBus = (*SubBusNumber);\r |
615 | \r |
616 | Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r |
617 | \r |
618 | Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r |
619 | \r |
620 | Status = PciRootBridgeIo->Pci.Write (\r |
621 | PciRootBridgeIo,\r |
622 | EfiPciWidthUint16,\r |
623 | Address,\r |
624 | 1,\r |
625 | &Register\r |
626 | );\r |
627 | \r |
628 | //\r |
629 | // Initialize SubBusNumber to SecondBus\r |
630 | //\r |
631 | Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r |
632 | Status = PciRootBridgeIo->Pci.Write (\r |
633 | PciRootBridgeIo,\r |
634 | EfiPciWidthUint8,\r |
635 | Address,\r |
636 | 1,\r |
637 | SubBusNumber\r |
638 | );\r |
639 | //\r |
640 | // If it is PPB, resursively search down this bridge\r |
641 | //\r |
642 | if (IS_PCI_BRIDGE (&Pci)) {\r |
643 | //\r |
644 | // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r |
645 | // PCI configuration transaction to go through any PPB\r |
646 | //\r |
647 | Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r |
648 | Register = 0xFF;\r |
649 | Status = PciRootBridgeIo->Pci.Write (\r |
650 | PciRootBridgeIo,\r |
651 | EfiPciWidthUint8,\r |
652 | Address,\r |
653 | 1,\r |
654 | &Register\r |
655 | );\r |
656 | \r |
657 | PreprocessController (\r |
658 | PciDevice,\r |
659 | PciDevice->BusNumber,\r |
660 | PciDevice->DeviceNumber,\r |
661 | PciDevice->FunctionNumber,\r |
662 | EfiPciBeforeChildBusEnumeration\r |
663 | );\r |
664 | \r |
665 | Status = PciScanBus (\r |
666 | PciDevice,\r |
667 | (UINT8) (SecondBus),\r |
668 | SubBusNumber,\r |
669 | PaddedBusRange\r |
670 | );\r |
671 | \r |
672 | if (EFI_ERROR (Status)) {\r |
673 | return EFI_DEVICE_ERROR;\r |
674 | }\r |
675 | }\r |
676 | \r |
677 | //\r |
678 | // Set the current maximum bus number under the PPB\r |
679 | //\r |
680 | \r |
681 | Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r |
682 | \r |
683 | Status = PciRootBridgeIo->Pci.Write (\r |
684 | PciRootBridgeIo,\r |
685 | EfiPciWidthUint8,\r |
686 | Address,\r |
687 | 1,\r |
688 | SubBusNumber\r |
689 | );\r |
690 | \r |
691 | }\r |
692 | \r |
693 | if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r |
694 | \r |
695 | //\r |
696 | // Skip sub functions, this is not a multi function device\r |
697 | //\r |
698 | \r |
699 | Func = PCI_MAX_FUNC;\r |
700 | }\r |
701 | }\r |
702 | }\r |
703 | \r |
704 | return EFI_SUCCESS;\r |
705 | }\r |
706 | \r |
707 | //\r |
708 | // Light PCI bus driver woundn't support P2C\r |
709 | // Return instead\r |
710 | //\r |
711 | EFI_STATUS\r |
712 | PciHostBridgeP2CProcess (\r |
713 | IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r |
714 | )\r |
715 | /*++\r |
716 | \r |
717 | Routine Description:\r |
718 | \r |
719 | Arguments:\r |
720 | \r |
721 | Returns:\r |
722 | \r |
723 | None\r |
724 | \r |
725 | --*/\r |
726 | // TODO: PciResAlloc - add argument and description to function comment\r |
727 | // TODO: EFI_SUCCESS - add return value to function comment\r |
728 | {\r |
729 | return EFI_SUCCESS;\r |
730 | }\r |
731 | \r |
732 | //\r |
733 | // Light PCI bus driver woundn't support hotplug device\r |
734 | // Simplified the code\r |
735 | //\r |
736 | EFI_STATUS\r |
737 | PciHostBridgeEnumerator (\r |
738 | EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r |
739 | )\r |
740 | /*++\r |
741 | \r |
742 | Routine Description:\r |
743 | \r |
744 | This function is used to enumerate the entire host bridge \r |
745 | in a given platform\r |
746 | \r |
747 | Arguments:\r |
748 | \r |
749 | PciResAlloc A pointer to the protocol to allocate resource.\r |
750 | \r |
751 | Returns:\r |
752 | \r |
753 | None\r |
754 | \r |
755 | --*/\r |
756 | // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r |
757 | // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r |
758 | // TODO: EFI_SUCCESS - add return value to function comment\r |
759 | {\r |
760 | EFI_HANDLE RootBridgeHandle;\r |
761 | PCI_IO_DEVICE *RootBridgeDev;\r |
762 | EFI_STATUS Status;\r |
763 | EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r |
764 | UINT16 MinBus;\r |
765 | EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r |
766 | \r |
767 | InitializeHotPlugSupport ();\r |
768 | \r |
769 | //\r |
770 | // Notify the bus allocation phase is about to start\r |
771 | //\r |
772 | NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r |
773 | \r |
774 | RootBridgeHandle = NULL;\r |
775 | while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r |
776 | \r |
777 | //\r |
778 | // if a root bridge instance is found, create root bridge device for it\r |
779 | //\r |
780 | \r |
781 | RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r |
782 | \r |
783 | if (RootBridgeDev == NULL) {\r |
784 | return EFI_OUT_OF_RESOURCES;\r |
785 | }\r |
786 | \r |
787 | //\r |
788 | // Enumerate all the buses under this root bridge\r |
789 | //\r |
790 | \r |
791 | Status = PciRootBridgeEnumerator (\r |
792 | PciResAlloc,\r |
793 | RootBridgeDev\r |
794 | );\r |
795 | \r |
796 | if (EFI_ERROR (Status)) {\r |
797 | return Status;\r |
798 | }\r |
799 | \r |
800 | DestroyRootBridge (RootBridgeDev);\r |
801 | \r |
802 | //\r |
803 | // Error proccess here\r |
804 | //\r |
805 | }\r |
806 | \r |
807 | //\r |
808 | // Notify the bus allocation phase is to end\r |
809 | //\r |
810 | NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r |
811 | \r |
812 | //\r |
813 | // Notify the resource allocation phase is to start\r |
814 | //\r |
815 | NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);\r |
816 | \r |
817 | RootBridgeHandle = NULL;\r |
818 | while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r |
819 | \r |
820 | //\r |
821 | // if a root bridge instance is found, create root bridge device for it\r |
822 | //\r |
823 | \r |
824 | RootBridgeDev = CreateRootBridge (RootBridgeHandle);\r |
825 | \r |
826 | if (RootBridgeDev == NULL) {\r |
827 | return EFI_OUT_OF_RESOURCES;\r |
828 | }\r |
829 | \r |
830 | Status = StartManagingRootBridge (RootBridgeDev);\r |
831 | \r |
832 | if (EFI_ERROR (Status)) {\r |
833 | return Status;\r |
834 | }\r |
835 | \r |
836 | PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;\r |
837 | Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r |
838 | \r |
839 | if (EFI_ERROR (Status)) {\r |
840 | return Status;\r |
841 | }\r |
842 | \r |
843 | Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);\r |
844 | \r |
845 | if (EFI_ERROR (Status)) {\r |
846 | return Status;\r |
847 | }\r |
848 | \r |
849 | //\r |
850 | // Determine root bridge attribute by calling interface of Pcihostbridge\r |
851 | // protocol\r |
852 | //\r |
853 | DetermineRootBridgeAttributes (\r |
854 | PciResAlloc,\r |
855 | RootBridgeDev\r |
856 | );\r |
857 | \r |
858 | //\r |
859 | // Collect all the resource information under this root bridge\r |
860 | // A database that records all the information about pci device subject to this\r |
861 | // root bridge will then be created\r |
862 | //\r |
863 | Status = PciPciDeviceInfoCollector (\r |
864 | RootBridgeDev,\r |
865 | (UINT8) MinBus\r |
866 | );\r |
867 | \r |
868 | if (EFI_ERROR (Status)) {\r |
869 | return Status;\r |
870 | }\r |
871 | \r |
872 | InsertRootBridge (RootBridgeDev);\r |
873 | \r |
874 | //\r |
875 | // Record the hostbridge handle\r |
876 | //\r |
877 | AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);\r |
878 | }\r |
879 | \r |
880 | return EFI_SUCCESS;\r |
881 | }\r |