[PATCH qemu 05/12] ast2400: handle SPI flash Command mode (read only)

Cédric Le Goater clg at kaod.org
Mon May 30 07:19:58 AEST 2016


We can now use directly the m25p80 flash storage to handle memory
accesses when the SPI flash slave is configured in Command mode. Only
read only accesses are handled. Command mode is only required by
U-Boot, Linux does not use it yet.

Handling write accesses would demand more changes to the m25p80 flash
model.

Signed-off-by: Cédric Le Goater <clg at kaod.org>
---
 hw/ssi/aspeed_smc.c         | 18 +++++++++++++++---
 include/hw/ssi/aspeed_smc.h |  2 ++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 4175356141e7..159ab691051d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -28,6 +28,7 @@
 #include "qemu/log.h"
 #include "include/qemu/error-report.h"
 #include "exec/address-spaces.h"
+#include "hw/block/flash.h"
 
 #include "hw/ssi/aspeed_smc.h"
 
@@ -284,8 +285,9 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
             ret = (ret << 8) | ssi_transfer(s->spi, 0x0);
         }
     } else {
-        error_report("%s: flash not in usermode", __func__);
-        ret = -1;
+        for (i = 0; i < size; i++) {
+            ret = (ret << 8) | fl->storage[addr + i];
+        }
     }
 
     return ret;
@@ -330,6 +332,11 @@ static void aspeed_smc_flash_reset(DeviceState *d)
 
 static int aspeed_smc_flash_init(SysBusDevice *sbd)
 {
+    DeviceState *dev = DEVICE(sbd);
+    AspeedSMCFlashState *s = ASPEED_SMC_FLASH(dev);
+
+    s->size = 0;
+    s->storage = NULL;
     return 0;
 }
 
@@ -422,8 +429,13 @@ void aspeed_smc_init_flashes(AspeedSMCState *s, const char *flashtype)
         cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
         sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
 
+        fl->storage = m25p80_get_storage(DEVICE(fl->flash), &fl->size);
+        if (fl->size > aspeed_segments[s->smc_type][i].size) {
+            fl->size = aspeed_segments[s->smc_type][i].size;
+        }
+
         memory_region_init_io(&fl->mmio, new, &aspeed_smc_flash_ops, fl, name,
-                              aspeed_segments[s->smc_type][i].size);
+                              fl->size);
         sysbus_init_mmio(SYS_BUS_DEVICE(new), &fl->mmio);
 
         sysbus_mmio_map(SYS_BUS_DEVICE(new), 0,
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 1625dfb76a63..2615ce9fa8aa 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -38,6 +38,8 @@ typedef struct AspeedSMCFlashState {
 
     MemoryRegion mmio;
     int id;
+    uint32_t size;
+    uint8_t *storage;
     struct AspeedSMCState *controller;
     DeviceState *flash;
 } AspeedSMCFlashState;
-- 
2.1.4



More information about the openbmc mailing list