diff mbox

[qemu,v13,06/16] spapr_pci: Reset DMA config on PHB reset

Message ID 1456823441-46757-7-git-send-email-aik@ozlabs.ru (mailing list archive)
State New, archived
Headers show

Commit Message

Alexey Kardashevskiy March 1, 2016, 9:10 a.m. UTC
LoPAPR dictates that during system reset all DMA windows must be removed
and the default DMA32 window must be created so does the patch.

At the moment there is just one window supported so no change in
behaviour is expected.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 hw/ppc/spapr_iommu.c   |  2 +-
 hw/ppc/spapr_pci.c     | 29 +++++++++++++++++++++++------
 include/hw/ppc/spapr.h |  1 +
 3 files changed, 25 insertions(+), 7 deletions(-)

Comments

David Gibson March 3, 2016, 3:02 a.m. UTC | #1
On Tue, Mar 01, 2016 at 08:10:31PM +1100, Alexey Kardashevskiy wrote:
> LoPAPR dictates that during system reset all DMA windows must be removed
> and the default DMA32 window must be created so does the patch.
> 
> At the moment there is just one window supported so no change in
> behaviour is expected.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  hw/ppc/spapr_iommu.c   |  2 +-
>  hw/ppc/spapr_pci.c     | 29 +++++++++++++++++++++++------
>  include/hw/ppc/spapr.h |  1 +
>  3 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
> index ba9ddbb..8a88a74 100644
> --- a/hw/ppc/spapr_iommu.c
> +++ b/hw/ppc/spapr_iommu.c
> @@ -279,7 +279,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
>      spapr_tce_table_do_enable(tcet);
>  }
>  
> -static void spapr_tce_table_disable(sPAPRTCETable *tcet)
> +void spapr_tce_table_disable(sPAPRTCETable *tcet)
>  {
>      if (!tcet->enabled) {
>          return;
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 7b40687..ee0fecf 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -825,6 +825,19 @@ static int spapr_phb_dma_window_enable(sPAPRPHBState *sphb,
>      return 0;
>  }
>  
> +static int spapr_phb_dma_window_disable(sPAPRPHBState *sphb, uint32_t liobn)
> +{
> +    sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
> +
> +    if (!tcet) {
> +        return -1;
> +    }
> +
> +    spapr_tce_table_disable(tcet);
> +
> +    return 0;
> +}
> +
>  /* Macros to operate with address in OF binding to PCI */
>  #define b_x(x, p, l)    (((x) & ((1<<(l))-1)) << (p))
>  #define b_n(x)          b_x((x), 31, 1) /* 0 if relocatable */
> @@ -1412,12 +1425,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>      memory_region_add_subregion(&sphb->iommu_root, 0,
>                                  spapr_tce_get_iommu(tcet));
>  
> -    /* Register default 32bit DMA window */
> -    spapr_phb_dma_window_enable(sphb, sphb->dma_liobn,
> -                                SPAPR_TCE_PAGE_SHIFT,
> -                                sphb->dma_win_addr,
> -                                sphb->dma_win_size);
> -
>      sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
>  }
>  
> @@ -1434,6 +1441,16 @@ static int spapr_phb_children_reset(Object *child, void *opaque)
>  
>  static void spapr_phb_reset(DeviceState *qdev)
>  {
> +    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
> +
> +    spapr_phb_dma_window_disable(sphb, sphb->dma_liobn);
> +
> +    /* Register default 32bit DMA window */
> +    spapr_phb_dma_window_enable(sphb, sphb->dma_liobn,
> +                                SPAPR_TCE_PAGE_SHIFT,
> +                                sphb->dma_win_addr,
> +                                sphb->dma_win_size);
> +
>      /* Reset the IOMMU state */
>      object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
>  
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index bdf27ec..8aa0c45 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -571,6 +571,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
>  void spapr_tce_table_enable(sPAPRTCETable *tcet,
>                              uint32_t page_shift, uint64_t bus_offset,
>                              uint32_t nb_table, bool vfio_accel);
> +void spapr_tce_table_disable(sPAPRTCETable *tcet);
>  void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
>  
>  MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
diff mbox

Patch

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ba9ddbb..8a88a74 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -279,7 +279,7 @@  void spapr_tce_table_enable(sPAPRTCETable *tcet,
     spapr_tce_table_do_enable(tcet);
 }
 
-static void spapr_tce_table_disable(sPAPRTCETable *tcet)
+void spapr_tce_table_disable(sPAPRTCETable *tcet)
 {
     if (!tcet->enabled) {
         return;
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7b40687..ee0fecf 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -825,6 +825,19 @@  static int spapr_phb_dma_window_enable(sPAPRPHBState *sphb,
     return 0;
 }
 
+static int spapr_phb_dma_window_disable(sPAPRPHBState *sphb, uint32_t liobn)
+{
+    sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+
+    if (!tcet) {
+        return -1;
+    }
+
+    spapr_tce_table_disable(tcet);
+
+    return 0;
+}
+
 /* Macros to operate with address in OF binding to PCI */
 #define b_x(x, p, l)    (((x) & ((1<<(l))-1)) << (p))
 #define b_n(x)          b_x((x), 31, 1) /* 0 if relocatable */
@@ -1412,12 +1425,6 @@  static void spapr_phb_realize(DeviceState *dev, Error **errp)
     memory_region_add_subregion(&sphb->iommu_root, 0,
                                 spapr_tce_get_iommu(tcet));
 
-    /* Register default 32bit DMA window */
-    spapr_phb_dma_window_enable(sphb, sphb->dma_liobn,
-                                SPAPR_TCE_PAGE_SHIFT,
-                                sphb->dma_win_addr,
-                                sphb->dma_win_size);
-
     sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
 }
 
@@ -1434,6 +1441,16 @@  static int spapr_phb_children_reset(Object *child, void *opaque)
 
 static void spapr_phb_reset(DeviceState *qdev)
 {
+    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
+
+    spapr_phb_dma_window_disable(sphb, sphb->dma_liobn);
+
+    /* Register default 32bit DMA window */
+    spapr_phb_dma_window_enable(sphb, sphb->dma_liobn,
+                                SPAPR_TCE_PAGE_SHIFT,
+                                sphb->dma_win_addr,
+                                sphb->dma_win_size);
+
     /* Reset the IOMMU state */
     object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index bdf27ec..8aa0c45 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -571,6 +571,7 @@  sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
 void spapr_tce_table_enable(sPAPRTCETable *tcet,
                             uint32_t page_shift, uint64_t bus_offset,
                             uint32_t nb_table, bool vfio_accel);
+void spapr_tce_table_disable(sPAPRTCETable *tcet);
 void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
 
 MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);