summary refs log tree commit diff stats
path: root/hw/spapr_vio.c
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2012-10-06 18:51:36 +0200
committerAurelien Jarno <aurelien@aurel32.net>2012-10-06 18:51:36 +0200
commit6b2f90fbbd31d594238098f46ef63ee307a12f55 (patch)
tree88d98655f3c584a3b7abd7f95c6fa2eeb6163467 /hw/spapr_vio.c
parent1d31fca470648ec66afd8743491bfb5846306341 (diff)
parentef8beb0e94c75984e016e855164361c36e15396c (diff)
downloadfocaccia-qemu-6b2f90fbbd31d594238098f46ef63ee307a12f55.tar.gz
focaccia-qemu-6b2f90fbbd31d594238098f46ef63ee307a12f55.zip
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (35 commits)
  PPC: KVM: Fix BAT put
  PPC: e500: Only expose even TLB sizes in initial TLB
  ppc/pseries: Reset VPA registration on CPU reset
  pseries: Don't test for MSR_PR for hypercalls under KVM
  PPC: e500: calculate initrd_base like dt_base
  PPC: e500: increase DTC_LOAD_PAD
  device tree: simplify dumpdtb code
  fdt: move dumpdtb interpretation code to device_tree.c
  target-ppc: Remove unused power_mode field from cpu state
  pseries: Set hash table size based on RAM size
  pseries: Remove unnecessary locking from PAPR hash table hcalls
  ppc405_uc: Fix buffer overflow
  target-ppc: KVM: Fix some kernel version edge cases for kvmppc_reset_htab()
  pseries: Fix semantics of RTAS int-on, int-off and set-xive functions
  pseries: Rework implementation of TCE bypass
  pseries: Remove never used flags field from spapr vio devices
  pseries: Remove XICS irq type enum type
  pseries: Remove C bitfields from xics code
  pseries: Small cleanup to H_CEDE implementation
  pseries: Fix XICS reset
  ...
Diffstat (limited to 'hw/spapr_vio.c')
-rw-r--r--hw/spapr_vio.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 7ca445216d..848806d3f1 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -316,17 +316,10 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
 
 static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
 {
-    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
-    uint32_t liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
-
     if (dev->dma) {
-        spapr_tce_free(dev->dma);
+        spapr_tce_reset(dev->dma);
     }
-    dev->dma = spapr_tce_new_dma_context(liobn, pc->rtce_window_size);
-
-    dev->crq.qladdr = 0;
-    dev->crq.qsize = 0;
-    dev->crq.qnext = 0;
+    free_crq(dev);
 }
 
 static void rtas_set_tce_bypass(sPAPREnvironment *spapr, uint32_t token,
@@ -348,16 +341,14 @@ static void rtas_set_tce_bypass(sPAPREnvironment *spapr, uint32_t token,
         rtas_st(rets, 0, -3);
         return;
     }
-    if (enable) {
-        spapr_tce_free(dev->dma);
-        dev->dma = NULL;
-    } else {
-        VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
-        uint32_t liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
 
-        dev->dma = spapr_tce_new_dma_context(liobn, pc->rtce_window_size);
+    if (!dev->dma) {
+        rtas_st(rets, 0, -3);
+        return;
     }
 
+    spapr_tce_set_bypass(dev->dma, !!enable);
+
     rtas_st(rets, 0, 0);
 }
 
@@ -409,9 +400,10 @@ static void spapr_vio_busdev_reset(DeviceState *qdev)
     VIOsPAPRDevice *dev = DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
     VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
 
-    if (dev->crq.qsize) {
-        free_crq(dev);
-    }
+    /* Shut down the request queue and TCEs if necessary */
+    spapr_vio_quiesce_one(dev);
+
+    dev->signal_state = 0;
 
     if (pc->reset) {
         pc->reset(dev);
@@ -422,7 +414,6 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
 {
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
     VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
-    uint32_t liobn;
     char *id;
 
     if (dev->reg != -1) {
@@ -464,8 +455,10 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
         return -1;
     }
 
-    liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
-    dev->dma = spapr_tce_new_dma_context(liobn, pc->rtce_window_size);
+    if (pc->rtce_window_size) {
+        uint32_t liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
+        dev->dma = spapr_tce_new_dma_context(liobn, pc->rtce_window_size);
+    }
 
     return pc->init(dev);
 }