Re: [Qemu-devel] [PATCH v3 2/4] m25p80: initial verion

2012-04-24 Thread Peter Maydell
On 20 April 2012 03:12, Peter A. G. Crosthwaite
peter.crosthwa...@petalogix.com wrote:
 Subject: [PATCH v3 2/4] m25p80: initial verion

 Added device model for m25p80 SPI flash

This commit message could be improved; I'd suggest a summary line of
m25p80: Initial implementation of SPI flash device



 Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com
 ---
 changed from v2:
 updated for SSI slave interface
 used async io (suggested - Stefan Hajnoczi)
 changed from v1:
 converted spi api to modified txrx style
 factored out lots of common code and inlined overly short single call 
 functions.
 undated for txrx style spi interface

  Makefile.target |    1 +
  hw/m25p80.c     |  378 
 +++
  2 files changed, 379 insertions(+), 0 deletions(-)
  create mode 100644 hw/m25p80.c

 diff --git a/Makefile.target b/Makefile.target
 index 84951a0..3f7c38e 100644
 --- a/Makefile.target
 +++ b/Makefile.target
 @@ -326,6 +326,7 @@ obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o 
 mips_fulong2e.o
  obj-microblaze-y = petalogix_s3adsp1800_mmu.o
  obj-microblaze-y += petalogix_ml605_mmu.o
  obj-microblaze-y += microblaze_boot.o
 +obj-microblaze-y += m25p80.o

  obj-microblaze-y += microblaze_pic_cpu.o
  obj-microblaze-y += xilinx_intc.o
 diff --git a/hw/m25p80.c b/hw/m25p80.c
 new file mode 100644
 index 000..e6c1f3b
 --- /dev/null
 +++ b/hw/m25p80.c
 @@ -0,0 +1,378 @@
 +/*
 + * ST M25P80 emulator.

ST M25P80 SPI Flash device. -- don't force readers to go and google
for the part number to find out what it is :-)

 + *
 + * Copyright (C) 2011 Edgar E. Iglesias edgar.igles...@gmail.com
 + * Copyright (C) 2012 Peter A. G. Crosthwaite 
 peter.crosthwa...@petalogix.com
 + * Copyright (C) 2012 PetaLogix
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License as
 + * published by the Free Software Foundation; either version 2 or
 + * (at your option) version 3 of the License.

Do we really want GPL 2 or 3, rather than 2 or later ?

 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License along
 + * with this program; if not, see http://www.gnu.org/licenses/.
 + */
 +
 +#include hw.h
 +#include blockdev.h
 +#include ssi.h
 +#include devices.h
 +
 +#ifdef M25P80_ERR_DEBUG
 +#define DB_PRINT(...) do { \
 +    fprintf(stderr,  : %s: , __func__); \
 +    fprintf(stderr, ## __VA_ARGS__); \
 +    } while (0);
 +#else
 +    #define DB_PRINT(...)
 +#endif
 +
 +enum FlashCMD {
 +    NOP = 0,
 +    PP = 0x2,
 +    READ = 0x3,
 +    WRDI = 0x4,
 +    RDSR = 0x5,
 +    WREN = 0x6,
 +    FAST_READ = 0xb,
 +    SECTOR_ERASE = 0x20,
 +    BLOCK_ERASE32 = 0x52,
 +    JEDEC_READ = 0x9f,
 +    CHIP_ERASE = 0xc7,
 +};
 +
 +enum CMDState {
 +    STATE_IDLE,
 +    STATE_PAGE_PROGRAM,
 +    STATE_READ,
 +    STATE_COLLECTING_DATA,
 +    STATE_READING_DATA,
 +};
 +
 +struct flash {
 +    SSISlave ssidev;
 +    uint32_t r;
 +
 +    BlockDriverState *bdrv;
 +    enum CMDState state;
 +
 +    uint8_t *storage;
 +    uint64_t size;
 +    int pagesize;
 +    int sectorsize;
 +    int blocksize;
 +
 +    uint8_t data[16];
 +    int len;
 +    int pos;
 +    int wrap_read;
 +    int needed_bytes;
 +    enum FlashCMD cmd_in_progress;
 +
 +    int64_t dirty_page;
 +
 +    uint64_t waddr;
 +    int write_enable;
 +};

Missing save/load support (which will cause you to want to turn a lot
of those 'int's into either 'bool' or known-width types).

 +
 +static void bdrv_sync_complete(void *opaque, int ret)
 +{
 +
 +}

Is there really nothing to do here? If so, perhaps a comment explaining
why...

 +
 +static void flash_sync_page(struct flash *s, int page)
 +{
 +    if (s-bdrv) {
 +        int bdrv_sector, nb_sectors;
 +        QEMUIOVector iov;
 +
 +        bdrv_sector = (page * s-pagesize) / 512;
 +        nb_sectors = (s-pagesize + 511) / 512;

There's a DIV_ROUND_UP macro, if you like:
  nb_sectors = DIV_ROUND_UP(s-pagesize, BDRV_SECTOR_SIZE);
(though it isn't really used much in qemu currently.)

 +        qemu_iovec_init(iov, 1);
 +        qemu_iovec_add(iov, s-storage + bdrv_sector * 512,
 +                                                    nb_sectors * 512);

Lots of hardcoded 512 here and elsewhere, you probably mean
BDRV_SECTOR_SIZE.

 +        bdrv_aio_writev(s-bdrv, bdrv_sector, iov, nb_sectors,
 +                                                bdrv_sync_complete, NULL);
 +    }
 +}
 +
 +static inline void flash_sync_area(struct flash *s, int64_t off, int64_t len)
 +{
 +    int64_t start, end;
 +
 +    if (!s-bdrv) {
 +        return;
 +    }
 +
 +    start = off / 512;
 +    end = (off + len) / 512;

This rounds down so you 

Re: [Qemu-devel] [PATCH v3 2/4] m25p80: initial verion

2012-04-20 Thread Stefan Hajnoczi
On Fri, Apr 20, 2012 at 3:12 AM, Peter A. G. Crosthwaite
peter.crosthwa...@petalogix.com wrote:
 +static inline void flash_sync_area(struct flash *s, int64_t off, int64_t len)
 +{
 +    int64_t start, end;
 +
 +    if (!s-bdrv) {
 +        return;
 +    }
 +
 +    start = off / 512;
 +    end = (off + len) / 512;
 +    bdrv_write(s-bdrv, start, s-storage + (start * 512), end - start);

Is it possible to use bdrv_aio_write() like in flash_sync_page()?

Stefan



[Qemu-devel] [PATCH v3 2/4] m25p80: initial verion

2012-04-19 Thread Peter A. G. Crosthwaite
Added device model for m25p80 SPI flash

Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com
---
changed from v2:
updated for SSI slave interface
used async io (suggested - Stefan Hajnoczi)
changed from v1:
converted spi api to modified txrx style
factored out lots of common code and inlined overly short single call functions.
undated for txrx style spi interface

 Makefile.target |1 +
 hw/m25p80.c |  378 +++
 2 files changed, 379 insertions(+), 0 deletions(-)
 create mode 100644 hw/m25p80.c

diff --git a/Makefile.target b/Makefile.target
index 84951a0..3f7c38e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -326,6 +326,7 @@ obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o 
mips_fulong2e.o
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 obj-microblaze-y += petalogix_ml605_mmu.o
 obj-microblaze-y += microblaze_boot.o
+obj-microblaze-y += m25p80.o
 
 obj-microblaze-y += microblaze_pic_cpu.o
 obj-microblaze-y += xilinx_intc.o
diff --git a/hw/m25p80.c b/hw/m25p80.c
new file mode 100644
index 000..e6c1f3b
--- /dev/null
+++ b/hw/m25p80.c
@@ -0,0 +1,378 @@
+/*
+ * ST M25P80 emulator.
+ *
+ * Copyright (C) 2011 Edgar E. Iglesias edgar.igles...@gmail.com
+ * Copyright (C) 2012 Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com
+ * Copyright (C) 2012 PetaLogix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see http://www.gnu.org/licenses/.
+ */
+
+#include hw.h
+#include blockdev.h
+#include ssi.h
+#include devices.h
+
+#ifdef M25P80_ERR_DEBUG
+#define DB_PRINT(...) do { \
+fprintf(stderr,  : %s: , __func__); \
+fprintf(stderr, ## __VA_ARGS__); \
+} while (0);
+#else
+#define DB_PRINT(...)
+#endif
+
+enum FlashCMD {
+NOP = 0,
+PP = 0x2,
+READ = 0x3,
+WRDI = 0x4,
+RDSR = 0x5,
+WREN = 0x6,
+FAST_READ = 0xb,
+SECTOR_ERASE = 0x20,
+BLOCK_ERASE32 = 0x52,
+JEDEC_READ = 0x9f,
+CHIP_ERASE = 0xc7,
+};
+
+enum CMDState {
+STATE_IDLE,
+STATE_PAGE_PROGRAM,
+STATE_READ,
+STATE_COLLECTING_DATA,
+STATE_READING_DATA,
+};
+
+struct flash {
+SSISlave ssidev;
+uint32_t r;
+
+BlockDriverState *bdrv;
+enum CMDState state;
+
+uint8_t *storage;
+uint64_t size;
+int pagesize;
+int sectorsize;
+int blocksize;
+
+uint8_t data[16];
+int len;
+int pos;
+int wrap_read;
+int needed_bytes;
+enum FlashCMD cmd_in_progress;
+
+int64_t dirty_page;
+
+uint64_t waddr;
+int write_enable;
+};
+
+static void bdrv_sync_complete(void *opaque, int ret)
+{
+
+}
+
+static void flash_sync_page(struct flash *s, int page)
+{
+if (s-bdrv) {
+int bdrv_sector, nb_sectors;
+QEMUIOVector iov;
+
+bdrv_sector = (page * s-pagesize) / 512;
+nb_sectors = (s-pagesize + 511) / 512;
+qemu_iovec_init(iov, 1);
+qemu_iovec_add(iov, s-storage + bdrv_sector * 512,
+nb_sectors * 512);
+bdrv_aio_writev(s-bdrv, bdrv_sector, iov, nb_sectors,
+bdrv_sync_complete, NULL);
+}
+}
+
+static inline void flash_sync_area(struct flash *s, int64_t off, int64_t len)
+{
+int64_t start, end;
+
+if (!s-bdrv) {
+return;
+}
+
+start = off / 512;
+end = (off + len) / 512;
+bdrv_write(s-bdrv, start, s-storage + (start * 512), end - start);
+}
+
+static void flash_sector_erase(struct flash *s, int sector)
+{
+if (!s-write_enable) {
+DB_PRINT(write with write protect!\n);
+}
+memset(s-storage + sector, 0xff, s-sectorsize);
+flash_sync_area(s, sector, s-sectorsize);
+}
+
+static void flash_block_erase32k(struct flash *s, int addr)
+{
+if (!s-write_enable) {
+DB_PRINT(write with write protect!\n);
+}
+memset(s-storage + addr, 0xff, 32 * 1024);
+flash_sync_area(s, addr, 32 * 1024);
+}
+
+static void flash_chip_erase(struct flash *s)
+{
+if (!s-write_enable) {
+DB_PRINT(write with write protect!\n);
+}
+memset(s-storage, 0xff, s-size);
+flash_sync_area(s, 0, s-size);
+}
+
+static inline void flash_sync_dirty(struct flash *s, int64_t newpage)
+{
+if (s-dirty_page = 0  s-dirty_page != newpage) {
+flash_sync_page(s, s-dirty_page);
+s-dirty_page = newpage;
+}
+}
+
+static inline
+void flash_write8(struct flash *s, uint64_t