Patchwork [PULL,06/24] xilinx_spips: Trash LQ page cache on mode change

login
register
mail settings
Submitter Peter Maydell
Date June 3, 2013, 4:30 p.m.
Message ID <1370277021-26129-7-git-send-email-peter.maydell@linaro.org>
Download mbox | patch
Permalink /patch/248352/
State New
Headers show

Comments

Peter Maydell - June 3, 2013, 4:30 p.m.
From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Invalidate the LQSPI cached page when transitioning into LQSPI mode.
Otherwise there is a possibility that the controller will return stale
data to the guest when transitioning back to LQ_MODE after a page
program.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Message-id: 677490a6ee1953fe5d366e599d665de645ac84db.1369117359.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/xilinx_spips.c |   25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

Patch

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 86f33ef..cf4c43e 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -165,6 +165,8 @@  typedef struct {
 typedef struct XilinxSPIPSClass {
     SysBusDeviceClass parent_class;
 
+    const MemoryRegionOps *reg_ops;
+
     uint32_t rx_fifo_size;
     uint32_t tx_fifo_size;
 } XilinxSPIPSClass;
@@ -462,6 +464,25 @@  static const MemoryRegionOps spips_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static void xilinx_qspips_write(void *opaque, hwaddr addr,
+                                uint64_t value, unsigned size)
+{
+    XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
+
+    xilinx_spips_write(opaque, addr, value, size);
+    addr >>= 2;
+
+    if (addr == R_LQSPI_CFG) {
+        q->lqspi_cached_addr = ~0ULL;
+    }
+}
+
+static const MemoryRegionOps qspips_ops = {
+    .read = xilinx_spips_read,
+    .write = xilinx_qspips_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 #define LQSPI_CACHE_SIZE 1024
 
 static uint64_t
@@ -565,7 +586,7 @@  static void xilinx_spips_realize(DeviceState *dev, Error **errp)
         sysbus_init_irq(sbd, &s->cs_lines[i]);
     }
 
-    memory_region_init_io(&s->iomem, &spips_ops, s, "spi", R_MAX*4);
+    memory_region_init_io(&s->iomem, xsc->reg_ops, s, "spi", R_MAX*4);
     sysbus_init_mmio(sbd, &s->iomem);
 
     s->irqline = -1;
@@ -629,6 +650,7 @@  static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
     XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
 
     dc->realize = xilinx_qspips_realize;
+    xsc->reg_ops = &qspips_ops;
     xsc->rx_fifo_size = RXFF_A_Q;
     xsc->tx_fifo_size = TXFF_A_Q;
 }
@@ -643,6 +665,7 @@  static void xilinx_spips_class_init(ObjectClass *klass, void *data)
     dc->props = xilinx_spips_properties;
     dc->vmsd = &vmstate_xilinx_spips;
 
+    xsc->reg_ops = &spips_ops;
     xsc->rx_fifo_size = RXFF_A;
     xsc->tx_fifo_size = TXFF_A;
 }