Re: [edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all devices when entering RT
Looks good. Reviewed-by: jiewen@intel.com > -Original Message- > From: Ni, Ruiyu > Sent: Tuesday, November 7, 2017 10:40 AM > To: Ni, Ruiyu ; edk2-devel@lists.01.org > Cc: Kinney, Michael D ; Michael Turner > ; Yao, Jiewen > Subject: RE: [edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all devices > when entering RT > > Jiewen, > Any comments? > > Thanks/Ray > > > -Original Message- > > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of > > Ruiyu Ni > > Sent: Wednesday, November 1, 2017 12:49 PM > > To: edk2-devel@lists.01.org > > Cc: Kinney, Michael D ; Michael Turner > > ; Yao, Jiewen > > Subject: [edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all > > devices when entering RT > > > > The patch ensures all DMA transactions are blocked after ExitBootService. > > If a platform enables IOMMU before and needs disable IOMMU after > > ExitBootService, the IOMMU should be disabled after PCI bus driver disables > > BME. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Michael Turner > > Signed-off-by: Ruiyu Ni > > Cc: Michael D Kinney > > Cc: Jiewen Yao > > Cc: Jeff Fan > > --- > > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 2 + > > MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 3 + > > MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 86 > > +++ > > 3 files changed, 91 insertions(+) > > > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > > index 55eb3a5a80..79b5b71082 100644 > > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > > @@ -18,6 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > > KIND, EITHER EXPRESS OR IMPLIED. > > > > #include > > > > +#include > > + > > #include > > #include > > #include > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > > index 97608bfcf2..d5b8fab3ca 100644 > > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > > @@ -80,6 +80,9 @@ [LibraryClasses] > >DebugLib > >PeCoffLib > > > > +[Guids] > > + gEfiEventExitBootServicesGuid ## > SOMETIMES_CONSUMES ## > > Event > > + > > [Protocols] > >gEfiPciHotPlugRequestProtocolGuid ## > SOMETIMES_PRODUCES > >gEfiPciIoProtocolGuid ## BY_START > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > > index 97bb971a59..004f2a3b5b 100644 > > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > > @@ -21,6 +21,72 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > > KIND, EITHER EXPRESS OR IMPLIED. > > LIST_ENTRY mPciDevicePool; > > > > /** > > + Disable Bus Master Enable bit in all devices in the list. > > + > > + @param Devices A device list. > > +**/ > > +VOID > > +DisableBmeOnTree ( > > + IN LIST_ENTRY *Devices > > + ) > > +{ > > + LIST_ENTRY *Link; > > + PCI_IO_DEVICE *PciIoDevice; > > + UINT16 Command; > > + > > + for ( Link = GetFirstNode (Devices) > > + ; !IsNull (Devices, Link) > > + ; Link = GetNextNode (Devices, Link) > > + ) { > > +PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link); > > +// > > +// Turn off all children's Bus Master, if any > > +// > > +DisableBmeOnTree (&PciIoDevice->ChildList); > > + > > +// > > +// If this is a device that supports BME, disable BME on this device. > > +// > > +if ((PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) > > { > > + PCI_READ_COMMAND_REGISTER(PciIoDevice, &Command); > > + if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) { > > +Command &= ~EFI_PCI_COMMAND_BUS_MASTER; > > +PCI_SET_COMMAND_REGISTER (PciIoDevice, Command); > > +DEBUG (( > > + DEBUG_INFO," %02x %02x %02x %04x\n", > > + PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, > PciIoDevice- > > >FunctionNumber, > > + Command > > + )); > > + } > &
Re: [edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all devices when entering RT
Jiewen, Any comments? Thanks/Ray > -Original Message- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of > Ruiyu Ni > Sent: Wednesday, November 1, 2017 12:49 PM > To: edk2-devel@lists.01.org > Cc: Kinney, Michael D ; Michael Turner > ; Yao, Jiewen > Subject: [edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all > devices when entering RT > > The patch ensures all DMA transactions are blocked after ExitBootService. > If a platform enables IOMMU before and needs disable IOMMU after > ExitBootService, the IOMMU should be disabled after PCI bus driver disables > BME. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Michael Turner > Signed-off-by: Ruiyu Ni > Cc: Michael D Kinney > Cc: Jiewen Yao > Cc: Jeff Fan > --- > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 2 + > MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 3 + > MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 86 > +++ > 3 files changed, 91 insertions(+) > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > index 55eb3a5a80..79b5b71082 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > @@ -18,6 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > > #include > > +#include > + > #include > #include > #include > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > index 97608bfcf2..d5b8fab3ca 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > @@ -80,6 +80,9 @@ [LibraryClasses] >DebugLib >PeCoffLib > > +[Guids] > + gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## > Event > + > [Protocols] >gEfiPciHotPlugRequestProtocolGuid ## SOMETIMES_PRODUCES >gEfiPciIoProtocolGuid ## BY_START > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > index 97bb971a59..004f2a3b5b 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c > @@ -21,6 +21,72 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > LIST_ENTRY mPciDevicePool; > > /** > + Disable Bus Master Enable bit in all devices in the list. > + > + @param Devices A device list. > +**/ > +VOID > +DisableBmeOnTree ( > + IN LIST_ENTRY *Devices > + ) > +{ > + LIST_ENTRY *Link; > + PCI_IO_DEVICE *PciIoDevice; > + UINT16 Command; > + > + for ( Link = GetFirstNode (Devices) > + ; !IsNull (Devices, Link) > + ; Link = GetNextNode (Devices, Link) > + ) { > +PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link); > +// > +// Turn off all children's Bus Master, if any > +// > +DisableBmeOnTree (&PciIoDevice->ChildList); > + > +// > +// If this is a device that supports BME, disable BME on this device. > +// > +if ((PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) > { > + PCI_READ_COMMAND_REGISTER(PciIoDevice, &Command); > + if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) { > +Command &= ~EFI_PCI_COMMAND_BUS_MASTER; > +PCI_SET_COMMAND_REGISTER (PciIoDevice, Command); > +DEBUG (( > + DEBUG_INFO," %02x %02x %02x %04x\n", > + PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice- > >FunctionNumber, > + Command > + )); > + } > +} > + } > +} > + > +/** > + Exit Boot Services Event notification handler. > + > + Disable Bus Master on any that were enabled during BDS. > + > + @param[in] Event Event whose notification function is being invoked. > + @param[in] Context Pointer to the notification function's context. > + > +**/ > +VOID > +EFIAPI > +OnExitBootServices ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + DEBUG (( > +DEBUG_INFO, > +"PciBus: Disable Bus Master of all devices...\n" > +" Bus# Device# Function# NewCommand\n" > +)); > + DisableBmeOnTree(&mPciDevicePool); > +} > + > +/** >Initialize the PCI devices pool. > > **/ > @@ -29,7 +95,27 @@ InitializePciDevicePool ( >VOID >) > { > + EFI_
[edk2] [PATCH v2] MdeModulePkg/PciBus: Disable BME of all devices when entering RT
The patch ensures all DMA transactions are blocked after ExitBootService. If a platform enables IOMMU before and needs disable IOMMU after ExitBootService, the IOMMU should be disabled after PCI bus driver disables BME. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael Turner Signed-off-by: Ruiyu Ni Cc: Michael D Kinney Cc: Jiewen Yao Cc: Jeff Fan --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 2 + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 3 + MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 86 +++ 3 files changed, 91 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index 55eb3a5a80..79b5b71082 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -18,6 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include + #include #include #include diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf index 97608bfcf2..d5b8fab3ca 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -80,6 +80,9 @@ [LibraryClasses] DebugLib PeCoffLib +[Guids] + gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event + [Protocols] gEfiPciHotPlugRequestProtocolGuid ## SOMETIMES_PRODUCES gEfiPciIoProtocolGuid ## BY_START diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c index 97bb971a59..004f2a3b5b 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c @@ -21,6 +21,72 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. LIST_ENTRY mPciDevicePool; /** + Disable Bus Master Enable bit in all devices in the list. + + @param Devices A device list. +**/ +VOID +DisableBmeOnTree ( + IN LIST_ENTRY *Devices + ) +{ + LIST_ENTRY *Link; + PCI_IO_DEVICE *PciIoDevice; + UINT16 Command; + + for ( Link = GetFirstNode (Devices) + ; !IsNull (Devices, Link) + ; Link = GetNextNode (Devices, Link) + ) { +PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link); +// +// Turn off all children's Bus Master, if any +// +DisableBmeOnTree (&PciIoDevice->ChildList); + +// +// If this is a device that supports BME, disable BME on this device. +// +if ((PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) { + PCI_READ_COMMAND_REGISTER(PciIoDevice, &Command); + if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) { +Command &= ~EFI_PCI_COMMAND_BUS_MASTER; +PCI_SET_COMMAND_REGISTER (PciIoDevice, Command); +DEBUG (( + DEBUG_INFO," %02x %02x %02x %04x\n", + PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, + Command + )); + } +} + } +} + +/** + Exit Boot Services Event notification handler. + + Disable Bus Master on any that were enabled during BDS. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnExitBootServices ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG (( +DEBUG_INFO, +"PciBus: Disable Bus Master of all devices...\n" +" Bus# Device# Function# NewCommand\n" +)); + DisableBmeOnTree(&mPciDevicePool); +} + +/** Initialize the PCI devices pool. **/ @@ -29,7 +95,27 @@ InitializePciDevicePool ( VOID ) { + EFI_EVENT ExitBootServicesEvent; + EFI_STATUS Status; + InitializeListHead (&mPciDevicePool); + + // + // DisableBME on ExitBootServices should be synchonized with any IOMMU ExitBootServices routine. + // DisableBME should be run before the IOMMU protections are disabled. + // One way to do this is to ensure that the IOMMU ExitBootServices callback runs at TPL_CALLBACK. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + OnExitBootServices, + NULL, + &gEfiEventExitBootServicesGuid, + &ExitBootServicesEvent + ); + if (EFI_ERROR (Status)) { +DEBUG ((DEBUG_ERROR, "PciBus: Unable to hook ExitBootServices event - %r\n", Status)); + } } /** -- 2.12.2.windows.2 ___ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel