//\r
LIST_ENTRY mPciDevicePool;\r
\r
-/**\r
- Disable Bus Master Enable bit in all devices in the list.\r
-\r
- @param Devices A device list.\r
-**/\r
-VOID\r
-DisableBmeOnTree (\r
- IN LIST_ENTRY *Devices\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- UINT16 Command;\r
-\r
- for ( Link = GetFirstNode (Devices)\r
- ; !IsNull (Devices, Link)\r
- ; Link = GetNextNode (Devices, Link)\r
- ) {\r
- PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);\r
- //\r
- // Turn off all children's Bus Master, if any\r
- //\r
- DisableBmeOnTree (&PciIoDevice->ChildList);\r
-\r
- //\r
- // If this is a device that supports BME, disable BME on this device.\r
- //\r
- if ((PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) {\r
- PCI_READ_COMMAND_REGISTER(PciIoDevice, &Command);\r
- if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) {\r
- Command &= ~EFI_PCI_COMMAND_BUS_MASTER;\r
- PCI_SET_COMMAND_REGISTER (PciIoDevice, Command);\r
- DEBUG ((\r
- DEBUG_INFO," %02x %02x %02x %04x\n",\r
- PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,\r
- Command\r
- ));\r
- }\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Exit Boot Services Event notification handler.\r
-\r
- Disable Bus Master on any that were enabled during BDS.\r
-\r
- @param[in] Event Event whose notification function is being invoked.\r
- @param[in] Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnExitBootServices (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "PciBus: Disable Bus Master of all devices...\n"\r
- " Bus# Device# Function# NewCommand\n"\r
- ));\r
- DisableBmeOnTree(&mPciDevicePool);\r
-}\r
-\r
/**\r
Initialize the PCI devices pool.\r
\r
VOID\r
)\r
{\r
- EFI_EVENT ExitBootServicesEvent;\r
- EFI_STATUS Status;\r
-\r
InitializeListHead (&mPciDevicePool);\r
-\r
- //\r
- // DisableBME on ExitBootServices should be synchonized with any IOMMU ExitBootServices routine.\r
- // DisableBME should be run before the IOMMU protections are disabled.\r
- // One way to do this is to ensure that the IOMMU ExitBootServices callback runs at TPL_CALLBACK.\r
- //\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- OnExitBootServices,\r
- NULL,\r
- &gEfiEventExitBootServicesGuid,\r
- &ExitBootServicesEvent\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "PciBus: Unable to hook ExitBootServices event - %r\n", Status));\r
- }\r
}\r
\r
/**\r