qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH qemu v14 10/18] spapr_pci: Reset DMA config on PHB r


From: Alexey Kardashevskiy
Subject: [Qemu-devel] [PATCH qemu v14 10/18] spapr_pci: Reset DMA config on PHB reset
Date: Mon, 21 Mar 2016 18:46:58 +1100

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 <address@hidden>
Reviewed-by: David Gibson <address@hidden>
---
 hw/ppc/spapr_iommu.c   |  2 +-
 hw/ppc/spapr_pci.c     | 38 +++++++++++++++++++++++++++++---------
 include/hw/ppc/spapr.h |  1 +
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 481ce3c..dd662da 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -330,7 +330,7 @@ static void spapr_tce_table_do_disable(sPAPRTCETable *tcet)
     tcet->nb_table = 0;
 }
 
-static void spapr_tce_table_disable(sPAPRTCETable *tcet)
+void spapr_tce_table_disable(sPAPRTCETable *tcet)
 {
     if (!tcet->enabled) {
         error_report("Warning: trying to disable already disabled TCE table");
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f1d49d5..1e53dad 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -828,6 +828,19 @@ static void spapr_phb_dma_window_enable(sPAPRPHBState 
*sphb,
     spapr_tce_table_enable(tcet, page_shift, window_addr, nb_table);
 }
 
+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 */
@@ -1332,7 +1345,6 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
     int i;
     PCIBus *bus;
     uint64_t msi_window_size = 4096;
-    Error *local_err = NULL;
     sPAPRTCETable *tcet;
 
     if (sphb->index != (uint32_t)-1) {
@@ -1495,14 +1507,6 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
     memory_region_add_subregion_overlap(&sphb->iommu_root, 0,
                                         spapr_tce_get_iommu(tcet), 0);
 
-    /* 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,
-                                &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-    }
-
     sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
 }
 
@@ -1519,6 +1523,22 @@ static int spapr_phb_children_reset(Object *child, void 
*opaque)
 
 static void spapr_phb_reset(DeviceState *qdev)
 {
+    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
+    sPAPRTCETable *tcet = spapr_tce_find_by_liobn(sphb->dma_liobn);
+    Error *local_err = NULL;
+
+    if (tcet && tcet->enabled) {
+        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,
+                                &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+    }
+
     /* 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 e9cdfe3..471eb4a 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -573,6 +573,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);
+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);
-- 
2.5.0.rc3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]