]> git.proxmox.com Git - mirror_edk2.git/blame - PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.c
Remove svn:executable on *.c, *.h, *.asm, *.S, *.inf and *.asl*
[mirror_edk2.git] / PcAtChipsetPkg / PciHostBridgeDxe / PciHostBridge.c
CommitLineData
21b404d1 1/** @file\r
2 Pci Host Bridge driver: \r
3 Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation\r
4\r
5 Copyright (c) 2008 - 2009, Intel Corporation<BR> All rights\r
6 reserved. This program and the accompanying materials are\r
7 licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10 \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/ \r
15\r
16#include "PciHostBridge.h"\r
17\r
18//\r
19// Support 64 K IO space\r
20//\r
21#define RES_IO_BASE 0x1000\r
22#define RES_IO_LIMIT 0xFFFF\r
23//\r
24// Support 4G address space\r
25//\r
26#define RES_MEM_BASE_1 0xF8000000\r
27#define RES_MEM_LIMIT_1 (0xFEC00000 - 1)\r
28\r
29//\r
30// Hard code: Root Bridge Number within the host bridge\r
31// Root Bridge's attribute\r
32// Root Bridge's device path\r
33// Root Bridge's resource appeture\r
34//\r
35UINTN RootBridgeNumber[1] = { 1 };\r
36\r
37UINT64 RootBridgeAttribute[1][1] = { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM };\r
38\r
39EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[1][1] = {\r
40 {\r
41 ACPI_DEVICE_PATH,\r
42 ACPI_DP,\r
43 (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),\r
44 (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8),\r
45 EISA_PNP_ID(0x0A03),\r
46 0,\r
47 END_DEVICE_PATH_TYPE,\r
48 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
49 END_DEVICE_PATH_LENGTH,\r
50 0\r
51 }\r
52};\r
53\r
54PCI_ROOT_BRIDGE_RESOURCE_APPETURE mResAppeture[1][1] = {\r
55 {0, 0, 0, 0xffffffff, 0, 1 << 16}\r
56};\r
57\r
58EFI_HANDLE mDriverImageHandle;\r
59\r
60PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {\r
61 PCI_HOST_BRIDGE_SIGNATURE, // Signature\r
62 NULL, // HostBridgeHandle\r
63 0, // RootBridgeNumber\r
64 {NULL, NULL}, // Head\r
65 FALSE, // ResourceSubiteed\r
66 TRUE, // CanRestarted\r
67 {\r
68 NotifyPhase,\r
69 GetNextRootBridge,\r
70 GetAttributes,\r
71 StartBusEnumeration,\r
72 SetBusNumbers,\r
73 SubmitResources,\r
74 GetProposedResources,\r
75 PreprocessController\r
76 }\r
77};\r
78\r
79//\r
80// Implementation\r
81//\r
82EFI_STATUS\r
83EFIAPI\r
84InitializePciHostBridge (\r
85 IN EFI_HANDLE ImageHandle,\r
86 IN EFI_SYSTEM_TABLE *SystemTable\r
87 )\r
88/*++\r
89\r
90Routine Description:\r
91 Entry point of this driver\r
92\r
93Arguments:\r
94\r
95 ImageHandle -\r
96\r
97 SystemTable -\r
98 \r
99Returns:\r
100\r
101--*/\r
102{\r
103 EFI_STATUS Status;\r
104 UINTN Loop1;\r
105 UINTN Loop2;\r
106 PCI_HOST_BRIDGE_INSTANCE *HostBridge;\r
107 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
108 IN EFI_PHYSICAL_ADDRESS BaseAddress;\r
109 IN UINT64 Length;\r
110 \r
111 mDriverImageHandle = ImageHandle;\r
112 \r
113 //\r
114 // Create Host Bridge Device Handle\r
115 //\r
116 for (Loop1 = 0; Loop1 < HOST_BRIDGE_NUMBER; Loop1++) {\r
117 HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);\r
118 if (HostBridge == NULL) {\r
119 return EFI_OUT_OF_RESOURCES;\r
120 }\r
121 \r
122 HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];\r
123 InitializeListHead (&HostBridge->Head);\r
124\r
125 Status = gBS->InstallMultipleProtocolInterfaces (\r
126 &HostBridge->HostBridgeHandle, \r
127 &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,\r
128 NULL\r
129 );\r
130 if (EFI_ERROR (Status)) {\r
131 FreePool (HostBridge);\r
132 return EFI_DEVICE_ERROR;\r
133 }\r
134 \r
135 //\r
136 // Create Root Bridge Device Handle in this Host Bridge\r
137 //\r
138 \r
139 for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {\r
140 PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));\r
141 if (PrivateData == NULL) {\r
142 return EFI_OUT_OF_RESOURCES;\r
143 }\r
144\r
145 PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;\r
146 PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];\r
147\r
148 RootBridgeConstructor (\r
149 &PrivateData->Io, \r
150 HostBridge->HostBridgeHandle, \r
151 RootBridgeAttribute[Loop1][Loop2], \r
152 &mResAppeture[Loop1][Loop2]\r
153 );\r
154 \r
155 Status = gBS->InstallMultipleProtocolInterfaces(\r
156 &PrivateData->Handle, \r
157 &gEfiDevicePathProtocolGuid, PrivateData->DevicePath,\r
158 &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,\r
159 NULL\r
160 );\r
161 if (EFI_ERROR (Status)) {\r
162 FreePool(PrivateData);\r
163 return EFI_DEVICE_ERROR;\r
164 }\r
165 \r
166 InsertTailList (&HostBridge->Head, &PrivateData->Link);\r
167 }\r
168 } \r
169\r
170 Status = gDS->AddIoSpace (\r
171 EfiGcdIoTypeIo, \r
172 RES_IO_BASE, \r
173 RES_IO_LIMIT - RES_IO_BASE + 1\r
174 );\r
175 \r
176 // PCI memory space from 3.75Gbytes->(4GBytes - BIOSFWH local APIC etc)\r
177 Status = gDS->AddMemorySpace (\r
178 EfiGcdMemoryTypeMemoryMappedIo, \r
179 RES_MEM_BASE_1, \r
180 (RES_MEM_LIMIT_1 - RES_MEM_BASE_1 + 1),\r
181 0\r
182 );\r
183 \r
184 BaseAddress = 0x80000000;\r
185 Length = RES_MEM_BASE_1 - BaseAddress;\r
186 Status = gDS->AddMemorySpace (\r
187 EfiGcdMemoryTypeMemoryMappedIo, \r
188 BaseAddress, \r
189 Length,\r
190 0\r
191 );\r
192 \r
193 return EFI_SUCCESS;\r
194}\r
195\r
196\r
197EFI_STATUS\r
198EFIAPI\r
199NotifyPhase(\r
200 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
201 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
202 )\r
203/*++\r
204\r
205Routine Description:\r
206 Enter a certain phase of the PCI enumeration process\r
207\r
208Arguments:\r
209 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance\r
210 Phase -- The phase during enumeration\r
211 \r
212Returns:\r
213\r
214--*/ \r
215{\r
216 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
217 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
218 PCI_RESOURCE_TYPE Index;\r
219 LIST_ENTRY *List;\r
220 EFI_PHYSICAL_ADDRESS BaseAddress;\r
221 UINT64 AddrLen;\r
222 UINTN BitsOfAlignment;\r
223 EFI_STATUS Status;\r
224 EFI_STATUS ReturnStatus;\r
225 \r
226 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
227 \r
228 switch (Phase) {\r
229\r
230 case EfiPciHostBridgeBeginEnumeration:\r
231 if (HostBridgeInstance->CanRestarted) {\r
232 //\r
233 // Reset the Each Root Bridge \r
234 //\r
235 List = HostBridgeInstance->Head.ForwardLink;\r
236 \r
237 while (List != &HostBridgeInstance->Head) {\r
238 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
239 for (Index = TypeIo; Index < TypeMax; Index++) {\r
240 RootBridgeInstance->ResAllocNode[Index].Type = Index;\r
241 RootBridgeInstance->ResAllocNode[Index].Base = 0;\r
242 RootBridgeInstance->ResAllocNode[Index].Length = 0;\r
243 RootBridgeInstance->ResAllocNode[Index].Status = ResNone;\r
244 }\r
245 \r
246 List = List->ForwardLink;\r
247 }\r
248 \r
249 HostBridgeInstance->ResourceSubmited = FALSE;\r
250 HostBridgeInstance->CanRestarted = TRUE;\r
251 } else {\r
252 //\r
253 // Can not restart\r
254 // \r
255 return EFI_NOT_READY;\r
256 } \r
257 break;\r
258\r
259 case EfiPciHostBridgeBeginBusAllocation:\r
260 //\r
261 // No specific action is required here, can perform any chipset specific programing\r
262 //\r
263 HostBridgeInstance->CanRestarted = FALSE;\r
264 return EFI_SUCCESS;\r
265 break;\r
266\r
267 case EfiPciHostBridgeEndBusAllocation:\r
268 //\r
269 // No specific action is required here, can perform any chipset specific programing\r
270 //\r
271 //HostBridgeInstance->CanRestarted = FALSE;\r
272 return EFI_SUCCESS;\r
273 break;\r
274\r
275 case EfiPciHostBridgeBeginResourceAllocation:\r
276 //\r
277 // No specific action is required here, can perform any chipset specific programing\r
278 //\r
279 //HostBridgeInstance->CanRestarted = FALSE;\r
280 return EFI_SUCCESS;\r
281 break;\r
282\r
283 case EfiPciHostBridgeAllocateResources:\r
284 ReturnStatus = EFI_SUCCESS;\r
285 if (HostBridgeInstance->ResourceSubmited) {\r
286 //\r
287 // Take care of the resource dependencies between the root bridges \r
288 //\r
289 List = HostBridgeInstance->Head.ForwardLink;\r
290\r
291 while (List != &HostBridgeInstance->Head) {\r
292 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
293 for (Index = TypeIo; Index < TypeBus; Index++) {\r
294 if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {\r
295 \r
296 AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;\r
297 \r
298 //\r
299 // Get the number of '1' in Alignment.\r
300 //\r
301 BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1;\r
302 \r
303 switch (Index) {\r
304\r
305 case TypeIo: \r
306 //\r
307 // It is impossible for this chipset to align 0xFFFF for IO16\r
308 // So clear it\r
309 //\r
310 if (BitsOfAlignment >= 16) {\r
311 BitsOfAlignment = 0;\r
312 }\r
313 \r
314 Status = gDS->AllocateIoSpace (\r
315 EfiGcdAllocateAnySearchBottomUp, \r
316 EfiGcdIoTypeIo, \r
317 BitsOfAlignment,\r
318 AddrLen,\r
319 &BaseAddress,\r
320 mDriverImageHandle,\r
321 NULL\r
322 );\r
323 \r
324 if (!EFI_ERROR (Status)) {\r
325 RootBridgeInstance->ResAllocNode[Index].Base = (UINTN)BaseAddress;\r
326 RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated; \r
327 } else {\r
328 ReturnStatus = Status; \r
329 if (Status != EFI_OUT_OF_RESOURCES) {\r
330 RootBridgeInstance->ResAllocNode[Index].Length = 0;\r
331 }\r
332 }\r
333\r
334 break;\r
335\r
336\r
337 case TypeMem32:\r
338 //\r
339 // It is impossible for this chipset to align 0xFFFFFFFF for Mem32\r
340 // So clear it \r
341 //\r
342 \r
343 if (BitsOfAlignment >= 32) {\r
344 BitsOfAlignment = 0;\r
345 }\r
346 \r
347 Status = gDS->AllocateMemorySpace (\r
348 EfiGcdAllocateAnySearchBottomUp, \r
349 EfiGcdMemoryTypeMemoryMappedIo, \r
350 BitsOfAlignment,\r
351 AddrLen,\r
352 &BaseAddress,\r
353 mDriverImageHandle,\r
354 NULL\r
355 );\r
356 \r
357 if (!EFI_ERROR (Status)) {\r
358 // We were able to allocate the PCI memory\r
359 RootBridgeInstance->ResAllocNode[Index].Base = (UINTN)BaseAddress;\r
360 RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;\r
361 \r
362 } else {\r
363 // Not able to allocate enough PCI memory\r
364 ReturnStatus = Status; \r
365 \r
366 if (Status != EFI_OUT_OF_RESOURCES) {\r
367 RootBridgeInstance->ResAllocNode[Index].Length = 0;\r
368 } \r
369 ASSERT (FALSE);\r
370 }\r
371 break;\r
372 \r
373 case TypePMem32: \r
374 case TypeMem64: \r
375 case TypePMem64:\r
376 ReturnStatus = EFI_ABORTED;\r
377 break; \r
378 default:\r
379 ASSERT (FALSE);\r
380 break;\r
381 }; //end switch\r
382 }\r
383 }\r
384 \r
385 List = List->ForwardLink;\r
386 }\r
387 \r
388 return ReturnStatus;\r
389\r
390 } else {\r
391 return EFI_NOT_READY;\r
392 }\r
393 break;\r
394\r
395 case EfiPciHostBridgeSetResources:\r
396 break;\r
397\r
398 case EfiPciHostBridgeFreeResources:\r
399 ReturnStatus = EFI_SUCCESS;\r
400 List = HostBridgeInstance->Head.ForwardLink;\r
401 while (List != &HostBridgeInstance->Head) {\r
402 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
403 for (Index = TypeIo; Index < TypeBus; Index++) {\r
404 if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {\r
405 AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;\r
406 BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;\r
407 switch (Index) {\r
408\r
409 case TypeIo: \r
410 Status = gDS->FreeIoSpace (BaseAddress, AddrLen); \r
411 if (EFI_ERROR (Status)) {\r
412 ReturnStatus = Status;\r
413 }\r
414 break;\r
415\r
416 case TypeMem32:\r
417 Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);\r
418 if (EFI_ERROR (Status)) {\r
419 ReturnStatus = Status;\r
420 }\r
421 break;\r
422\r
423 case TypePMem32:\r
424 break;\r
425\r
426 case TypeMem64:\r
427 break;\r
428\r
429 case TypePMem64:\r
430 break; \r
431\r
432 default:\r
433 ASSERT (FALSE);\r
434 break;\r
435\r
436 }; //end switch\r
437 RootBridgeInstance->ResAllocNode[Index].Type = Index;\r
438 RootBridgeInstance->ResAllocNode[Index].Base = 0;\r
439 RootBridgeInstance->ResAllocNode[Index].Length = 0;\r
440 RootBridgeInstance->ResAllocNode[Index].Status = ResNone;\r
441 }\r
442 }\r
443 \r
444 List = List->ForwardLink;\r
445 }\r
446 \r
447 HostBridgeInstance->ResourceSubmited = FALSE;\r
448 HostBridgeInstance->CanRestarted = TRUE; \r
449 return ReturnStatus;\r
450 break;\r
451\r
452 case EfiPciHostBridgeEndResourceAllocation:\r
453 HostBridgeInstance->CanRestarted = FALSE;\r
454 break;\r
455\r
456 default:\r
457 return EFI_INVALID_PARAMETER;\r
458 }; // end switch\r
459 \r
460 return EFI_SUCCESS; \r
461}\r
462\r
463EFI_STATUS\r
464EFIAPI\r
465GetNextRootBridge(\r
466 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
467 IN OUT EFI_HANDLE *RootBridgeHandle\r
468 )\r
469/*++\r
470\r
471Routine Description:\r
472 Return the device handle of the next PCI root bridge that is associated with \r
473 this Host Bridge\r
474\r
475Arguments:\r
476 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
477 RootBridgeHandle -- Returns the device handle of the next PCI Root Bridge. \r
478 On input, it holds the RootBridgeHandle returned by the most \r
479 recent call to GetNextRootBridge().The handle for the first \r
480 PCI Root Bridge is returned if RootBridgeHandle is NULL on input\r
481 \r
482Returns:\r
483\r
484--*/ \r
485{\r
486 BOOLEAN NoRootBridge; \r
487 LIST_ENTRY *List; \r
488 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
489 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
490 \r
491 NoRootBridge = TRUE;\r
492 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
493 List = HostBridgeInstance->Head.ForwardLink;\r
494 \r
495 \r
496 while (List != &HostBridgeInstance->Head) {\r
497 NoRootBridge = FALSE;\r
498 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
499 if (*RootBridgeHandle == NULL) {\r
500 //\r
501 // Return the first Root Bridge Handle of the Host Bridge\r
502 //\r
503 *RootBridgeHandle = RootBridgeInstance->Handle;\r
504 return EFI_SUCCESS;\r
505 } else {\r
506 if (*RootBridgeHandle == RootBridgeInstance->Handle) {\r
507 //\r
508 // Get next if have\r
509 //\r
510 List = List->ForwardLink;\r
511 if (List!=&HostBridgeInstance->Head) {\r
512 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
513 *RootBridgeHandle = RootBridgeInstance->Handle;\r
514 return EFI_SUCCESS; \r
515 } else {\r
516 return EFI_NOT_FOUND;\r
517 }\r
518 }\r
519 }\r
520 \r
521 List = List->ForwardLink;\r
522 } //end while\r
523 \r
524 if (NoRootBridge) {\r
525 return EFI_NOT_FOUND;\r
526 } else {\r
527 return EFI_INVALID_PARAMETER;\r
528 }\r
529}\r
530\r
531EFI_STATUS\r
532EFIAPI\r
533GetAttributes(\r
534 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
535 IN EFI_HANDLE RootBridgeHandle,\r
536 OUT UINT64 *Attributes\r
537 )\r
538/*++\r
539\r
540Routine Description:\r
541 Returns the attributes of a PCI Root Bridge.\r
542\r
543Arguments:\r
544 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
545 RootBridgeHandle -- The device handle of the PCI Root Bridge \r
546 that the caller is interested in\r
547 Attribute -- The pointer to attributes of the PCI Root Bridge \r
548 \r
549Returns:\r
550\r
551--*/ \r
552{\r
553 LIST_ENTRY *List; \r
554 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
555 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
556 \r
557 if (Attributes == NULL) {\r
558 return EFI_INVALID_PARAMETER;\r
559 }\r
560 \r
561 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
562 List = HostBridgeInstance->Head.ForwardLink;\r
563 \r
564 while (List != &HostBridgeInstance->Head) {\r
565 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
566 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
567 *Attributes = RootBridgeInstance->RootBridgeAttrib;\r
568 return EFI_SUCCESS;\r
569 }\r
570 List = List->ForwardLink;\r
571 }\r
572 \r
573 //\r
574 // RootBridgeHandle is not an EFI_HANDLE \r
575 // that was returned on a previous call to GetNextRootBridge()\r
576 //\r
577 return EFI_INVALID_PARAMETER;\r
578}\r
579\r
580EFI_STATUS\r
581EFIAPI\r
582StartBusEnumeration(\r
583 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
584 IN EFI_HANDLE RootBridgeHandle,\r
585 OUT VOID **Configuration\r
586 )\r
587/*++\r
588\r
589Routine Description:\r
590 This is the request from the PCI enumerator to set up \r
591 the specified PCI Root Bridge for bus enumeration process. \r
592\r
593Arguments:\r
594 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
595 RootBridgeHandle -- The PCI Root Bridge to be set up\r
596 Configuration -- Pointer to the pointer to the PCI bus resource descriptor\r
597 \r
598Returns:\r
599\r
600--*/\r
601{\r
602 LIST_ENTRY *List; \r
603 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
604 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
605 VOID *Buffer;\r
606 UINT8 *Temp;\r
607 UINT64 BusStart;\r
608 UINT64 BusEnd;\r
609 \r
610 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
611 List = HostBridgeInstance->Head.ForwardLink;\r
612 \r
613 while (List != &HostBridgeInstance->Head) {\r
614 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
615 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
616 //\r
617 // Set up the Root Bridge for Bus Enumeration\r
618 //\r
619 BusStart = RootBridgeInstance->BusBase;\r
620 BusEnd = RootBridgeInstance->BusLimit;\r
621 //\r
622 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR\r
623 //\r
624 \r
625 Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));\r
626 if (Buffer == NULL) {\r
627 return EFI_OUT_OF_RESOURCES;\r
628 }\r
629 \r
630 Temp = (UINT8 *)Buffer;\r
631 \r
632 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;\r
633 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len = 0x2B;\r
634 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;\r
635 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0; \r
636 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;\r
637 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;\r
638 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;\r
639 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;\r
640 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0; \r
641 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;\r
642 \r
643 Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
644 ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79; \r
645 ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;\r
646 \r
647 *Configuration = Buffer; \r
648 return EFI_SUCCESS;\r
649 }\r
650 List = List->ForwardLink;\r
651 }\r
652 \r
653 return EFI_INVALID_PARAMETER;\r
654}\r
655\r
656EFI_STATUS\r
657EFIAPI\r
658SetBusNumbers(\r
659 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
660 IN EFI_HANDLE RootBridgeHandle,\r
661 IN VOID *Configuration\r
662 )\r
663/*++\r
664\r
665Routine Description:\r
666 This function programs the PCI Root Bridge hardware so that \r
667 it decodes the specified PCI bus range\r
668\r
669Arguments:\r
670 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
671 RootBridgeHandle -- The PCI Root Bridge whose bus range is to be programmed\r
672 Configuration -- The pointer to the PCI bus resource descriptor\r
673 \r
674Returns:\r
675\r
676--*/ \r
677{\r
678 LIST_ENTRY *List; \r
679 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
680 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
681 UINT8 *Ptr;\r
682 UINTN BusStart;\r
683 UINTN BusEnd;\r
684 UINTN BusLen;\r
685 \r
686 if (Configuration == NULL) {\r
687 return EFI_INVALID_PARAMETER;\r
688 }\r
689 \r
690 Ptr = Configuration;\r
691 \r
692 //\r
693 // Check the Configuration is valid\r
694 //\r
695 if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
696 return EFI_INVALID_PARAMETER;\r
697 }\r
698 \r
699 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {\r
700 return EFI_INVALID_PARAMETER;\r
701 }\r
702\r
703 Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
704 if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {\r
705 return EFI_INVALID_PARAMETER;\r
706 }\r
707 \r
708 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
709 List = HostBridgeInstance->Head.ForwardLink;\r
710 \r
711 Ptr = Configuration;\r
712 \r
713 while (List != &HostBridgeInstance->Head) {\r
714 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
715 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
716 BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;\r
717 BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;\r
718 BusEnd = BusStart + BusLen - 1;\r
719 \r
720 if (BusStart > BusEnd) {\r
721 return EFI_INVALID_PARAMETER;\r
722 }\r
723 \r
724 if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {\r
725 return EFI_INVALID_PARAMETER;\r
726 }\r
727 \r
728 //\r
729 // Update the Bus Range\r
730 //\r
731 RootBridgeInstance->ResAllocNode[TypeBus].Base = BusStart;\r
732 RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;\r
733 RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;\r
734 \r
735 //\r
736 // Program the Root Bridge Hardware\r
737 //\r
738 \r
739 return EFI_SUCCESS;\r
740 }\r
741 \r
742 List = List->ForwardLink;\r
743 }\r
744 \r
745 return EFI_INVALID_PARAMETER;\r
746}\r
747\r
748\r
749EFI_STATUS\r
750EFIAPI\r
751SubmitResources(\r
752 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
753 IN EFI_HANDLE RootBridgeHandle,\r
754 IN VOID *Configuration\r
755 )\r
756/*++\r
757\r
758Routine Description:\r
759 Submits the I/O and memory resource requirements for the specified PCI Root Bridge\r
760 \r
761Arguments:\r
762 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
763 RootBridgeHandle -- The PCI Root Bridge whose I/O and memory resource requirements \r
764 are being submitted\r
765 Configuration -- The pointer to the PCI I/O and PCI memory resource descriptor \r
766Returns:\r
767\r
768--*/ \r
769{\r
770 LIST_ENTRY *List; \r
771 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
772 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
773 UINT8 *Temp;\r
774 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
775 UINT64 AddrLen;\r
776 UINT64 Alignment;\r
777 \r
778 //\r
779 // Check the input parameter: Configuration\r
780 //\r
781 if (Configuration == NULL) {\r
782 return EFI_INVALID_PARAMETER;\r
783 }\r
784 \r
785 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
786 List = HostBridgeInstance->Head.ForwardLink;\r
787 \r
788 Temp = (UINT8 *)Configuration;\r
789 while ( *Temp == 0x8A) { \r
790 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;\r
791 }\r
792 if (*Temp != 0x79) {\r
793 return EFI_INVALID_PARAMETER;\r
794 }\r
795 \r
796 Temp = (UINT8 *)Configuration;\r
797 while (List != &HostBridgeInstance->Head) {\r
798 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
799 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
800 while ( *Temp == 0x8A) {\r
801 ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;\r
802\r
803 //\r
804 // Check Address Length\r
805 //\r
806 if (ptr->AddrLen > 0xffffffff) {\r
807 return EFI_INVALID_PARAMETER;\r
808 }\r
809\r
810 //\r
811 // Check address range alignment\r
812 //\r
813 if (ptr->AddrRangeMax >= 0xffffffff || ptr->AddrRangeMax != (GetPowerOfTwo64 (ptr->AddrRangeMax + 1) - 1)) {\r
814 return EFI_INVALID_PARAMETER;\r
815 }\r
816 \r
817 switch (ptr->ResType) {\r
818\r
819 case 0:\r
820 \r
821 //\r
822 // Check invalid Address Sapce Granularity\r
823 //\r
824 if (ptr->AddrSpaceGranularity != 32) {\r
825 return EFI_INVALID_PARAMETER;\r
826 }\r
827 \r
828 //\r
829 // check the memory resource request is supported by PCI root bridge\r
830 //\r
831 if (RootBridgeInstance->RootBridgeAttrib == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM &&\r
832 ptr->SpecificFlag == 0x06) {\r
833 return EFI_INVALID_PARAMETER;\r
834 }\r
835 \r
836 AddrLen = ptr->AddrLen;\r
837 Alignment = ptr->AddrRangeMax;\r
838 if (ptr->AddrSpaceGranularity == 32) {\r
839 if (ptr->SpecificFlag == 0x06) {\r
840 //\r
841 // Apply from GCD\r
842 //\r
843 RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;\r
844 } else {\r
845 RootBridgeInstance->ResAllocNode[TypeMem32].Length = AddrLen;\r
846 RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;\r
847 RootBridgeInstance->ResAllocNode[TypeMem32].Status = ResRequested; \r
848 HostBridgeInstance->ResourceSubmited = TRUE;\r
849 }\r
850 }\r
851\r
852 if (ptr->AddrSpaceGranularity == 64) {\r
853 if (ptr->SpecificFlag == 0x06) {\r
854 RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;\r
855 } else {\r
856 RootBridgeInstance->ResAllocNode[TypeMem64].Status = ResSubmitted;\r
857 }\r
858 }\r
859 break;\r
860\r
861 case 1:\r
862 AddrLen = (UINTN)ptr->AddrLen;\r
863 Alignment = (UINTN)ptr->AddrRangeMax;\r
864 RootBridgeInstance->ResAllocNode[TypeIo].Length = AddrLen;\r
865 RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;\r
866 RootBridgeInstance->ResAllocNode[TypeIo].Status = ResRequested;\r
867 HostBridgeInstance->ResourceSubmited = TRUE; \r
868 break;\r
869\r
870 default:\r
871 break;\r
872 };\r
873 \r
874 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;\r
875 } \r
876 \r
877 return EFI_SUCCESS;\r
878 }\r
879 \r
880 List = List->ForwardLink;\r
881 }\r
882 \r
883 return EFI_INVALID_PARAMETER;\r
884}\r
885\r
886EFI_STATUS\r
887EFIAPI\r
888GetProposedResources(\r
889 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
890 IN EFI_HANDLE RootBridgeHandle,\r
891 OUT VOID **Configuration\r
892 )\r
893/*++\r
894\r
895Routine Description:\r
896 This function returns the proposed resource settings for the specified \r
897 PCI Root Bridge\r
898\r
899Arguments:\r
900 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
901 RootBridgeHandle -- The PCI Root Bridge handle\r
902 Configuration -- The pointer to the pointer to the PCI I/O \r
903 and memory resource descriptor\r
904 \r
905Returns:\r
906\r
907--*/ \r
908{\r
909 LIST_ENTRY *List; \r
910 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
911 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
912 UINTN Index;\r
913 UINTN Number; \r
914 VOID *Buffer; \r
915 UINT8 *Temp;\r
916 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
917 UINT64 ResStatus;\r
918 \r
919 Buffer = NULL;\r
920 Number = 0;\r
921 //\r
922 // Get the Host Bridge Instance from the resource allocation protocol\r
923 //\r
924 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
925 List = HostBridgeInstance->Head.ForwardLink;\r
926 \r
927 //\r
928 // Enumerate the root bridges in this host bridge\r
929 //\r
930 while (List != &HostBridgeInstance->Head) {\r
931 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
932 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
933 for (Index = 0; Index < TypeBus; Index ++) {\r
934 if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {\r
935 Number ++;\r
936 } \r
937 }\r
938 \r
939 if (Number == 0) {\r
940 return EFI_INVALID_PARAMETER;\r
941 }\r
942\r
943 Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));\r
944 if (Buffer == NULL) {\r
945 return EFI_OUT_OF_RESOURCES;\r
946 }\r
947 \r
948 Temp = Buffer;\r
949 for (Index = 0; Index < TypeBus; Index ++) {\r
950 if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {\r
951 ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;\r
952 ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;\r
953 \r
954 switch (Index) {\r
955\r
956 case TypeIo:\r
957 //\r
958 // Io\r
959 //\r
960 ptr->Desc = 0x8A;\r
961 ptr->Len = 0x2B;\r
962 ptr->ResType = 1;\r
963 ptr->GenFlag = 0; \r
964 ptr->SpecificFlag = 0;\r
965 ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;\r
966 ptr->AddrRangeMax = 0;\r
967 ptr->AddrTranslationOffset = \\r
968 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;\r
969 ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;\r
970 break;\r
971\r
972 case TypeMem32:\r
973 //\r
974 // Memory 32\r
975 // \r
976 ptr->Desc = 0x8A;\r
977 ptr->Len = 0x2B;\r
978 ptr->ResType = 0;\r
979 ptr->GenFlag = 0; \r
980 ptr->SpecificFlag = 0;\r
981 ptr->AddrSpaceGranularity = 32;\r
982 ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;\r
983 ptr->AddrRangeMax = 0;\r
984 ptr->AddrTranslationOffset = \\r
985 (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS; \r
986 ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;\r
987 break;\r
988\r
989 case TypePMem32:\r
990 //\r
991 // Prefetch memory 32\r
992 //\r
993 ptr->Desc = 0x8A;\r
994 ptr->Len = 0x2B;\r
995 ptr->ResType = 0;\r
996 ptr->GenFlag = 0; \r
997 ptr->SpecificFlag = 6;\r
998 ptr->AddrSpaceGranularity = 32;\r
999 ptr->AddrRangeMin = 0;\r
1000 ptr->AddrRangeMax = 0;\r
1001 ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; \r
1002 ptr->AddrLen = 0;\r
1003 break;\r
1004\r
1005 case TypeMem64:\r
1006 //\r
1007 // Memory 64\r
1008 //\r
1009 ptr->Desc = 0x8A;\r
1010 ptr->Len = 0x2B;\r
1011 ptr->ResType = 0;\r
1012 ptr->GenFlag = 0; \r
1013 ptr->SpecificFlag = 0;\r
1014 ptr->AddrSpaceGranularity = 64;\r
1015 ptr->AddrRangeMin = 0;\r
1016 ptr->AddrRangeMax = 0;\r
1017 ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; \r
1018 ptr->AddrLen = 0;\r
1019 break;\r
1020\r
1021 case TypePMem64:\r
1022 //\r
1023 // Prefetch memory 64\r
1024 //\r
1025 ptr->Desc = 0x8A;\r
1026 ptr->Len = 0x2B;\r
1027 ptr->ResType = 0;\r
1028 ptr->GenFlag = 0; \r
1029 ptr->SpecificFlag = 6;\r
1030 ptr->AddrSpaceGranularity = 64;\r
1031 ptr->AddrRangeMin = 0;\r
1032 ptr->AddrRangeMax = 0;\r
1033 ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT; \r
1034 ptr->AddrLen = 0;\r
1035 break;\r
1036 };\r
1037 \r
1038 Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
1039 } \r
1040 }\r
1041 \r
1042 ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79; \r
1043 ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;\r
1044 \r
1045 *Configuration = Buffer; \r
1046 \r
1047 return EFI_SUCCESS;\r
1048 }\r
1049 \r
1050 List = List->ForwardLink;\r
1051 }\r
1052 \r
1053 return EFI_INVALID_PARAMETER;\r
1054}\r
1055\r
1056STATIC\r
1057VOID\r
1058UpdateRootBridgeAttributes (\r
1059 IN PCI_ROOT_BRIDGE_INSTANCE *RootBridge,\r
1060 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress\r
1061 )\r
1062{\r
1063 EFI_STATUS Status;\r
1064 PCI_TYPE01 PciConfigurationHeader;\r
1065 UINT64 Attributes;\r
1066\r
1067 //\r
1068 // Read the PCI Configuration Header for the device\r
1069 //\r
1070 Status = RootBridge->Io.Pci.Read (\r
1071 &RootBridge->Io,\r
1072 EfiPciWidthUint16,\r
1073 EFI_PCI_ADDRESS(\r
1074 PciAddress.Bus,\r
1075 PciAddress.Device,\r
1076 PciAddress.Function,\r
1077 0\r
1078 ),\r
1079 sizeof (PciConfigurationHeader) / sizeof (UINT16),\r
1080 &PciConfigurationHeader\r
1081 );\r
1082 if (EFI_ERROR (Status)) {\r
1083 return;\r
1084 }\r
1085\r
1086 Attributes = RootBridge->Attributes;\r
1087\r
1088 //\r
1089 // Look for devices with the VGA Palette Snoop enabled in the COMMAND register of the PCI Config Header\r
1090 //\r
1091 if (PciConfigurationHeader.Hdr.Command & 0x20) {\r
1092 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;\r
1093 }\r
1094\r
1095 //\r
1096 // If the device is a PCI-PCI Bridge, then look at the Subordinate Bus Number\r
1097 //\r
1098 if (IS_PCI_BRIDGE(&PciConfigurationHeader)) {\r
1099 //\r
1100 // Look at the PPB Configuration for legacy decoding attributes\r
1101 //\r
1102 if (PciConfigurationHeader.Bridge.BridgeControl & 0x04) {\r
1103 Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;\r
1104 Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
1105 }\r
1106 if (PciConfigurationHeader.Bridge.BridgeControl & 0x08) {\r
1107 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;\r
1108 Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;\r
1109 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;\r
1110 }\r
1111 } else {\r
1112 //\r
1113 // See if the PCI device is an IDE controller\r
1114 //\r
1115 if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x01 &&\r
1116 PciConfigurationHeader.Hdr.ClassCode[1] == 0x01 ) {\r
1117 if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x80) {\r
1118 Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;\r
1119 Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;\r
1120 }\r
1121 if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x01) {\r
1122 Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;\r
1123 }\r
1124 if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x04) {\r
1125 Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;\r
1126 }\r
1127 }\r
1128\r
1129 //\r
1130 // See if the PCI device is a legacy VGA controller\r
1131 //\r
1132 if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x00 &&\r
1133 PciConfigurationHeader.Hdr.ClassCode[1] == 0x01 ) {\r
1134 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;\r
1135 Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;\r
1136 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;\r
1137 }\r
1138\r
1139 //\r
1140 // See if the PCI device is a standard VGA controller\r
1141 //\r
1142 if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x03 &&\r
1143 PciConfigurationHeader.Hdr.ClassCode[1] == 0x00 ) {\r
1144 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;\r
1145 Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;\r
1146 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;\r
1147 }\r
1148 }\r
1149\r
1150 RootBridge->Attributes = Attributes;\r
1151 RootBridge->Supports = Attributes;\r
1152}\r
1153\r
1154EFI_STATUS\r
1155EFIAPI\r
1156PreprocessController (\r
1157 IN struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,\r
1158 IN EFI_HANDLE RootBridgeHandle,\r
1159 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,\r
1160 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
1161 )\r
1162/*++\r
1163\r
1164Routine Description:\r
1165 This function is called for all the PCI controllers that the PCI \r
1166 bus driver finds. Can be used to Preprogram the controller.\r
1167\r
1168Arguments:\r
1169 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance\r
1170 RootBridgeHandle -- The PCI Root Bridge handle\r
1171 PciBusAddress -- Address of the controller on the PCI bus\r
1172 Phase -- The Phase during resource allocation\r
1173 \r
1174Returns:\r
1175 EFI_SUCCESS\r
1176--*/ \r
1177{\r
1178 PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;\r
1179 PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;\r
1180 LIST_ENTRY *List; \r
1181\r
1182 HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);\r
1183 List = HostBridgeInstance->Head.ForwardLink;\r
1184\r
1185 //\r
1186 // Enumerate the root bridges in this host bridge\r
1187 //\r
1188 while (List != &HostBridgeInstance->Head) {\r
1189 RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);\r
1190 if (RootBridgeHandle == RootBridgeInstance->Handle) {\r
1191 UpdateRootBridgeAttributes (\r
1192 RootBridgeInstance,\r
1193 PciAddress\r
1194 );\r
1195 return EFI_SUCCESS;\r
1196 }\r
1197 List = List->ForwardLink;\r
1198 }\r
1199\r
1200 return EFI_INVALID_PARAMETER;\r
1201}\r