Re: [RFC PATCH v7 2/2] hw/misc/sifive_u_otp: Add backend drive support

2020-10-19 Thread Green Wan
Sorry for replying late. I missed this email. I will revise the patch
today. Thanks,

- Green

On Thu, Oct 15, 2020 at 4:01 PM Bin Meng  wrote:
>
> On Thu, Oct 15, 2020 at 12:15 PM Green Wan  wrote:
> >
> > Add '-drive' support to OTP device. Allow users to assign a raw file
> > as OTP image.
> >
> > test commands for 16k otp.img filled with zero:
> >
> > $ dd if=/dev/zero of=./otp.img bs=1k count=16
> > $ ./qemu-system-riscv64 -M sifive_u -m 256M -nographic -bios none \
> > -kernel ../opensbi/build/platform/sifive/fu540/firmware/fw_payload.elf \
> > -d guest_errors -drive if=none,format=raw,file=otp.img
> >
> > Signed-off-by: Green Wan 
> > ---
> >  hw/misc/sifive_u_otp.c | 67 +-
> >  include/hw/misc/sifive_u_otp.h |  2 +
> >  2 files changed, 68 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> > index 565eec082f..60066375ab 100644
> > --- a/hw/misc/sifive_u_otp.c
> > +++ b/hw/misc/sifive_u_otp.c
> > @@ -19,11 +19,14 @@
> >   */
> >
> >  #include "qemu/osdep.h"
> > +#include "qapi/error.h"
> >  #include "hw/qdev-properties.h"
> >  #include "hw/sysbus.h"
> >  #include "qemu/log.h"
> >  #include "qemu/module.h"
> >  #include "hw/misc/sifive_u_otp.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/block-backend.h"
> >
> >  #define WRITTEN_BIT_ON 0x1
> >
> > @@ -54,6 +57,16 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> > addr, unsigned int size)
> >  if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
> >  (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
> >  (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
> > +
> > +/* read from backend */
> > +if (s->blk) {
> > +int32_t buf;
> > +
> > +blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> > +  SIFIVE_U_OTP_FUSE_WORD);
> > +return buf;
> > +}
> > +
> >  return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
> >  } else {
> >  return 0xff;
> > @@ -137,7 +150,7 @@ static void sifive_u_otp_write(void *opaque, hwaddr 
> > addr,
> >  if (s->pwe && !s->pas) {
> >  if (GET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio)) {
> >  qemu_log_mask(LOG_GUEST_ERROR,
> > -  "Error: write idx<%u>, bit<%u>\n",
> > +  "write once error: idx<%u>, bit<%u>\n",
>
> This should be in the patch 1.
>
> >s->pa, s->paio);
> >  break;
> >  }
> > @@ -145,6 +158,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr 
> > addr,
> >  /* write bit data */
> >  SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin);
> >
> > +/* write to backend */
> > +if (s->blk) {
> > +blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> > +   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0);
> > +}
> > +
> >  /* update written bit */
> >  SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON);
> >  }
> > @@ -168,16 +187,48 @@ static const MemoryRegionOps sifive_u_otp_ops = {
> >
> >  static Property sifive_u_otp_properties[] = {
> >  DEFINE_PROP_UINT32("serial", SiFiveUOTPState, serial, 0),
> > +DEFINE_PROP_DRIVE("drive", SiFiveUOTPState, blk),
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> >
>
> Otherwise,
> Reviewed-by: Bin Meng 
> Tested-by: Bin Meng 
>
> You can drop the "RFC" tag in the next version.



Re: [RFC PATCH v7 2/2] hw/misc/sifive_u_otp: Add backend drive support

2020-10-15 Thread Bin Meng
On Thu, Oct 15, 2020 at 12:15 PM Green Wan  wrote:
>
> Add '-drive' support to OTP device. Allow users to assign a raw file
> as OTP image.
>
> test commands for 16k otp.img filled with zero:
>
> $ dd if=/dev/zero of=./otp.img bs=1k count=16
> $ ./qemu-system-riscv64 -M sifive_u -m 256M -nographic -bios none \
> -kernel ../opensbi/build/platform/sifive/fu540/firmware/fw_payload.elf \
> -d guest_errors -drive if=none,format=raw,file=otp.img
>
> Signed-off-by: Green Wan 
> ---
>  hw/misc/sifive_u_otp.c | 67 +-
>  include/hw/misc/sifive_u_otp.h |  2 +
>  2 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> index 565eec082f..60066375ab 100644
> --- a/hw/misc/sifive_u_otp.c
> +++ b/hw/misc/sifive_u_otp.c
> @@ -19,11 +19,14 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qapi/error.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/sysbus.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
>  #include "hw/misc/sifive_u_otp.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/block-backend.h"
>
>  #define WRITTEN_BIT_ON 0x1
>
> @@ -54,6 +57,16 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr 
> addr, unsigned int size)
>  if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
>  (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
>  (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
> +
> +/* read from backend */
> +if (s->blk) {
> +int32_t buf;
> +
> +blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
> +  SIFIVE_U_OTP_FUSE_WORD);
> +return buf;
> +}
> +
>  return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
>  } else {
>  return 0xff;
> @@ -137,7 +150,7 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
>  if (s->pwe && !s->pas) {
>  if (GET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio)) {
>  qemu_log_mask(LOG_GUEST_ERROR,
> -  "Error: write idx<%u>, bit<%u>\n",
> +  "write once error: idx<%u>, bit<%u>\n",

This should be in the patch 1.

>s->pa, s->paio);
>  break;
>  }
> @@ -145,6 +158,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
>  /* write bit data */
>  SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin);
>
> +/* write to backend */
> +if (s->blk) {
> +blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
> +   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0);
> +}
> +
>  /* update written bit */
>  SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON);
>  }
> @@ -168,16 +187,48 @@ static const MemoryRegionOps sifive_u_otp_ops = {
>
>  static Property sifive_u_otp_properties[] = {
>  DEFINE_PROP_UINT32("serial", SiFiveUOTPState, serial, 0),
> +DEFINE_PROP_DRIVE("drive", SiFiveUOTPState, blk),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>

Otherwise,
Reviewed-by: Bin Meng 
Tested-by: Bin Meng 

You can drop the "RFC" tag in the next version.



[RFC PATCH v7 2/2] hw/misc/sifive_u_otp: Add backend drive support

2020-10-14 Thread Green Wan
Add '-drive' support to OTP device. Allow users to assign a raw file
as OTP image.

test commands for 16k otp.img filled with zero:

$ dd if=/dev/zero of=./otp.img bs=1k count=16
$ ./qemu-system-riscv64 -M sifive_u -m 256M -nographic -bios none \
-kernel ../opensbi/build/platform/sifive/fu540/firmware/fw_payload.elf \
-d guest_errors -drive if=none,format=raw,file=otp.img

Signed-off-by: Green Wan 
---
 hw/misc/sifive_u_otp.c | 67 +-
 include/hw/misc/sifive_u_otp.h |  2 +
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
index 565eec082f..60066375ab 100644
--- a/hw/misc/sifive_u_otp.c
+++ b/hw/misc/sifive_u_otp.c
@@ -19,11 +19,14 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "hw/qdev-properties.h"
 #include "hw/sysbus.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "hw/misc/sifive_u_otp.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
 
 #define WRITTEN_BIT_ON 0x1
 
@@ -54,6 +57,16 @@ static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, 
unsigned int size)
 if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
 (s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
 (s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
+
+/* read from backend */
+if (s->blk) {
+int32_t buf;
+
+blk_pread(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD, ,
+  SIFIVE_U_OTP_FUSE_WORD);
+return buf;
+}
+
 return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
 } else {
 return 0xff;
@@ -137,7 +150,7 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
 if (s->pwe && !s->pas) {
 if (GET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio)) {
 qemu_log_mask(LOG_GUEST_ERROR,
-  "Error: write idx<%u>, bit<%u>\n",
+  "write once error: idx<%u>, bit<%u>\n",
   s->pa, s->paio);
 break;
 }
@@ -145,6 +158,12 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
 /* write bit data */
 SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin);
 
+/* write to backend */
+if (s->blk) {
+blk_pwrite(s->blk, s->pa * SIFIVE_U_OTP_FUSE_WORD,
+   >fuse[s->pa], SIFIVE_U_OTP_FUSE_WORD, 0);
+}
+
 /* update written bit */
 SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON);
 }
@@ -168,16 +187,48 @@ static const MemoryRegionOps sifive_u_otp_ops = {
 
 static Property sifive_u_otp_properties[] = {
 DEFINE_PROP_UINT32("serial", SiFiveUOTPState, serial, 0),
+DEFINE_PROP_DRIVE("drive", SiFiveUOTPState, blk),
 DEFINE_PROP_END_OF_LIST(),
 };
 
 static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
 {
 SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
+DriveInfo *dinfo;
 
 memory_region_init_io(>mmio, OBJECT(dev), _u_otp_ops, s,
   TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
+
+dinfo = drive_get_next(IF_NONE);
+if (dinfo) {
+int ret;
+uint64_t perm;
+int filesize;
+BlockBackend *blk;
+
+blk = blk_by_legacy_dinfo(dinfo);
+filesize = SIFIVE_U_OTP_NUM_FUSES * SIFIVE_U_OTP_FUSE_WORD;
+if (blk_getlength(blk) < filesize) {
+error_setg(errp, "OTP drive size < 16K");
+return;
+}
+
+qdev_prop_set_drive_err(dev, "drive", blk, errp);
+
+if (s->blk) {
+perm = BLK_PERM_CONSISTENT_READ |
+   (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
+ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
+if (ret < 0) {
+return;
+}
+
+if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
+error_setg(errp, "failed to read the initial flash content");
+}
+}
+}
 }
 
 static void sifive_u_otp_reset(DeviceState *dev)
@@ -191,6 +242,20 @@ static void sifive_u_otp_reset(DeviceState *dev)
 s->fuse[SIFIVE_U_OTP_SERIAL_ADDR] = s->serial;
 s->fuse[SIFIVE_U_OTP_SERIAL_ADDR + 1] = ~(s->serial);
 
+if (s->blk) {
+/* Put serial number to backend as well*/
+uint32_t serial_data;
+int index = SIFIVE_U_OTP_SERIAL_ADDR;
+
+serial_data = s->serial;
+blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
+   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
+
+serial_data = ~(s->serial);
+blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
+   _data, SIFIVE_U_OTP_FUSE_WORD, 0);
+}
+
 /* Initialize write-once map */
 memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
 }
diff --git a/include/hw/misc/sifive_u_otp.h