[PATCH qemu v2 05/10] m25p80: add a m25p80_create_rom() routine

Cédric Le Goater clg at kaod.org
Tue Jun 14 03:16:31 AEST 2016


Some SPI controllers, such as the Aspeed AST2400, have a mode in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.

To emulate such a behavior, we need to have access to the underlying
storage of the flash object. The purpose of the routine is to create a
SPI flash object with a preinitialized storage which can be used by
the object itself but also by a SPI controller to handled the MMIOs.

This seems sufficient to support read only accesses for the
moment. For writes, we would need to externalize flash_write8()
routine certainly.

Signed-off-by: Cédric Le Goater <clg at kaod.org>
---
 hw/block/m25p80.c        | 24 +++++++++++++++++++++++-
 include/hw/block/flash.h |  3 +++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 7c25a6de6544..3a500ed03c1b 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -29,6 +29,7 @@
 #include "qemu/bitops.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "hw/block/flash.h"
 
 #ifndef M25P80_ERR_DEBUG
 #define M25P80_ERR_DEBUG 0
@@ -908,7 +909,10 @@ static void m25p80_realize(DeviceState *dev, Error **errp)
         s->blk = blk_by_legacy_dinfo(dinfo);
         blk_attach_dev_nofail(s->blk, s);
 
-        s->storage = blk_blockalign(s->blk, s->size);
+        /* using an external storage. see m25p80_create_rom() */
+        if (!s->storage) {
+            s->storage = blk_blockalign(s->blk, s->size);
+        }
 
         if (blk_pread(s->blk, 0, s->storage, s->size)) {
             error_setg(errp, "failed to read the initial flash content");
@@ -1005,3 +1009,21 @@ static void m25p80_register_types(void)
 }
 
 type_init(m25p80_register_types)
+
+DeviceState *m25p80_create_rom(SSIBus *bus, const char *type,
+                               MemoryRegion *rom, Error **errp)
+{
+    Error *err = NULL;
+    DeviceState *dev = ssi_create_slave_no_init(bus, type);
+    Flash *s = M25P80(dev);
+
+    s->storage = memory_region_get_ram_ptr(rom);
+
+    object_property_set_bool(OBJECT(dev), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return NULL;
+    }
+
+    return dev;
+}
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
index 50ccbbcf1352..ac143846a77e 100644
--- a/include/hw/block/flash.h
+++ b/include/hw/block/flash.h
@@ -61,4 +61,7 @@ uint8_t ecc_digest(ECCState *s, uint8_t sample);
 void ecc_reset(ECCState *s);
 extern VMStateDescription vmstate_ecc_state;
 
+DeviceState *m25p80_create_rom(SSIBus *bus, const char *type,
+                               MemoryRegion *rom, Error **errp);
+
 #endif
-- 
2.1.4



More information about the openbmc mailing list