- Add write operation to update fuse data bit when PWE bit is on.
- Add array, fuse_wo, to store the 'written' status for all bits
of OTP to block the write operation.
Signed-off-by: Green Wan <green.wan@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/misc/sifive_u_otp.c | 30 +++++++++++++++++++++++++++++-
include/hw/misc/sifive_u_otp.h | 3 +++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
index c2f3c8e129..685c1f8e07 100644
--- a/hw/misc/sifive_u_otp.c
+++ b/hw/misc/sifive_u_otp.c
@@ -25,6 +25,14 @@
#include "qemu/module.h"
#include "hw/misc/sifive_u_otp.h"
+#define WRITTEN_BIT_ON 0x1
+
+#define SET_FUSEARRAY_BIT(map, i, off, bit) \
+ map[i] = bit ? (map[i] | bit << off) : (map[i] & ~(bit << off))
+
+#define GET_FUSEARRAY_BIT(map, i, off) \
+ ((map[i] >> off) & 0x1)
+
static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, unsigned int size)
{
SiFiveUOTPState *s = opaque;
@@ -123,7 +131,24 @@ static void sifive_u_otp_write(void *opaque, hwaddr addr,
s->ptrim = val32;
break;
case SIFIVE_U_OTP_PWE:
- s->pwe = val32;
+ s->pwe = val32 & SIFIVE_U_OTP_PWE_EN;
+
+ /* PWE is enabled. Ignore PAS=1 (no redundancy cell) */
+ 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",
+ s->pa, s->paio);
+ break;
+ }
+
+ /* write bit data */
+ SET_FUSEARRAY_BIT(s->fuse, s->pa, s->paio, s->pdin);
+
+ /* update written bit */
+ SET_FUSEARRAY_BIT(s->fuse_wo, s->pa, s->paio, WRITTEN_BIT_ON);
+ }
+
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%" HWADDR_PRIx
@@ -165,6 +190,9 @@ static void sifive_u_otp_reset(DeviceState *dev)
/* Make a valid content of serial number */
s->fuse[SIFIVE_U_OTP_SERIAL_ADDR] = s->serial;
s->fuse[SIFIVE_U_OTP_SERIAL_ADDR + 1] = ~(s->serial);
+
+ /* Initialize write-once map */
+ memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
}
static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/misc/sifive_u_otp.h b/include/hw/misc/sifive_u_otp.h
index 82c9176c8f..ebffbc1fa5 100644
--- a/include/hw/misc/sifive_u_otp.h
+++ b/include/hw/misc/sifive_u_otp.h
@@ -36,6 +36,8 @@
#define SIFIVE_U_OTP_PTRIM 0x34
#define SIFIVE_U_OTP_PWE 0x38
+#define SIFIVE_U_OTP_PWE_EN (1 << 0)
+
#define SIFIVE_U_OTP_PCE_EN (1 << 0)
#define SIFIVE_U_OTP_PDSTB_EN (1 << 0)
@@ -75,6 +77,7 @@ struct SiFiveUOTPState {
uint32_t ptrim;
uint32_t pwe;
uint32_t fuse[SIFIVE_U_OTP_NUM_FUSES];
+ uint32_t fuse_wo[SIFIVE_U_OTP_NUM_FUSES];
/* config */
uint32_t serial;
};
--
2.17.1
Hi Green, On Mon, Sep 28, 2020 at 6:12 PM Green Wan <green.wan@sifive.com> wrote: > > - Add write operation to update fuse data bit when PWE bit is on. > - Add array, fuse_wo, to store the 'written' status for all bits > of OTP to block the write operation. > > Signed-off-by: Green Wan <green.wan@sifive.com> > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > --- > hw/misc/sifive_u_otp.c | 30 +++++++++++++++++++++++++++++- > include/hw/misc/sifive_u_otp.h | 3 +++ > 2 files changed, 32 insertions(+), 1 deletion(-) > I am not sure how you tested this. I wrote a simple U-Boot command to call U-Boot sifive-otp driver to test the write functionality, but it failed. => misc write otp@10070000 0 80200000 10 => misc read otp@10070000 0 80400000 10 => md 80400000 80400000: ffffffff ffffffff ffffffff ffffffff ................ 80400010: 00000000 00000000 00000000 00000000 ................ 80400020: 00000000 00000000 00000000 00000000 ................ 80400030: 00000000 00000000 00000000 00000000 ................ 80400040: 00000000 00000000 00000000 00000000 ................ 80400050: 00000000 00000000 00000000 00000000 ................ 80400060: 00000000 00000000 00000000 00000000 ................ 80400070: 00000000 00000000 00000000 00000000 ................ 80400080: 00000000 00000000 00000000 00000000 ................ 80400090: 00000000 00000000 00000000 00000000 ................ 804000a0: 00000000 00000000 00000000 00000000 ................ 804000b0: 00000000 00000000 00000000 00000000 ................ 804000c0: 00000000 00000000 00000000 00000000 ................ 804000d0: 00000000 00000000 00000000 00000000 ................ 804000e0: 00000000 00000000 00000000 00000000 ................ 804000f0: 00000000 00000000 00000000 00000000 ................ => misc write otp@10070000 0 80200010 10 => misc read otp@10070000 0 80400010 10 => md 80400000 80400000: ffffffff ffffffff ffffffff ffffffff ................ 80400010: ffffffff ffffffff ffffffff ffffffff ................ 80400020: 00000000 00000000 00000000 00000000 ................ 80400030: 00000000 00000000 00000000 00000000 ................ 80400040: 00000000 00000000 00000000 00000000 ................ 80400050: 00000000 00000000 00000000 00000000 ................ 80400060: 00000000 00000000 00000000 00000000 ................ 80400070: 00000000 00000000 00000000 00000000 ................ 80400080: 00000000 00000000 00000000 00000000 ................ 80400090: 00000000 00000000 00000000 00000000 ................ 804000a0: 00000000 00000000 00000000 00000000 ................ 804000b0: 00000000 00000000 00000000 00000000 ................ 804000c0: 00000000 00000000 00000000 00000000 ................ 804000d0: 00000000 00000000 00000000 00000000 ................ 804000e0: 00000000 00000000 00000000 00000000 ................ 804000f0: 00000000 00000000 00000000 00000000 ................ But it can read the serial number at offset 0x3f0 => misc read otp@10070000 3f0 80400010 10 => md 80400000 80400000: ffffffff ffffffff ffffffff ffffffff ................ 80400010: 00000001 fffffffe ffffffff ffffffff ................ 80400020: 00000000 00000000 00000000 00000000 ................ 80400030: 00000000 00000000 00000000 00000000 ................ 80400040: 00000000 00000000 00000000 00000000 ................ 80400050: 00000000 00000000 00000000 00000000 ................ 80400060: 00000000 00000000 00000000 00000000 ................ 80400070: 00000000 00000000 00000000 00000000 ................ 80400080: 00000000 00000000 00000000 00000000 ................ 80400090: 00000000 00000000 00000000 00000000 ................ 804000a0: 00000000 00000000 00000000 00000000 ................ 804000b0: 00000000 00000000 00000000 00000000 ................ 804000c0: 00000000 00000000 00000000 00000000 ................ 804000d0: 00000000 00000000 00000000 00000000 ................ 804000e0: 00000000 00000000 00000000 00000000 ................ 804000f0: 00000000 00000000 00000000 00000000 ................ Regards, Bin
On Wed, Oct 14, 2020 at 1:37 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Green,
>
> On Mon, Sep 28, 2020 at 6:12 PM Green Wan <green.wan@sifive.com> wrote:
> >
> > - Add write operation to update fuse data bit when PWE bit is on.
> > - Add array, fuse_wo, to store the 'written' status for all bits
> > of OTP to block the write operation.
> >
> > Signed-off-by: Green Wan <green.wan@sifive.com>
> > Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > hw/misc/sifive_u_otp.c | 30 +++++++++++++++++++++++++++++-
> > include/hw/misc/sifive_u_otp.h | 3 +++
> > 2 files changed, 32 insertions(+), 1 deletion(-)
> >
>
> I am not sure how you tested this. I wrote a simple U-Boot command to
> call U-Boot sifive-otp driver to test the write functionality, but it
> failed.
>
> => misc write otp@10070000 0 80200000 10
^^^^^^^^^
Quick ask, how about 'md 80200000'?
I didn't use 'misc write' command. I can check afterward.
> => misc read otp@10070000 0 80400000 10
> => md 80400000
> 80400000: ffffffff ffffffff ffffffff ffffffff ................
> 80400010: 00000000 00000000 00000000 00000000 ................
> 80400020: 00000000 00000000 00000000 00000000 ................
> 80400030: 00000000 00000000 00000000 00000000 ................
> 80400040: 00000000 00000000 00000000 00000000 ................
> 80400050: 00000000 00000000 00000000 00000000 ................
> 80400060: 00000000 00000000 00000000 00000000 ................
> 80400070: 00000000 00000000 00000000 00000000 ................
> 80400080: 00000000 00000000 00000000 00000000 ................
> 80400090: 00000000 00000000 00000000 00000000 ................
> 804000a0: 00000000 00000000 00000000 00000000 ................
> 804000b0: 00000000 00000000 00000000 00000000 ................
> 804000c0: 00000000 00000000 00000000 00000000 ................
> 804000d0: 00000000 00000000 00000000 00000000 ................
> 804000e0: 00000000 00000000 00000000 00000000 ................
> 804000f0: 00000000 00000000 00000000 00000000 ................
> => misc write otp@10070000 0 80200010 10
> => misc read otp@10070000 0 80400010 10
> => md 80400000
> 80400000: ffffffff ffffffff ffffffff ffffffff ................
> 80400010: ffffffff ffffffff ffffffff ffffffff ................
> 80400020: 00000000 00000000 00000000 00000000 ................
> 80400030: 00000000 00000000 00000000 00000000 ................
> 80400040: 00000000 00000000 00000000 00000000 ................
> 80400050: 00000000 00000000 00000000 00000000 ................
> 80400060: 00000000 00000000 00000000 00000000 ................
> 80400070: 00000000 00000000 00000000 00000000 ................
> 80400080: 00000000 00000000 00000000 00000000 ................
> 80400090: 00000000 00000000 00000000 00000000 ................
> 804000a0: 00000000 00000000 00000000 00000000 ................
> 804000b0: 00000000 00000000 00000000 00000000 ................
> 804000c0: 00000000 00000000 00000000 00000000 ................
> 804000d0: 00000000 00000000 00000000 00000000 ................
> 804000e0: 00000000 00000000 00000000 00000000 ................
> 804000f0: 00000000 00000000 00000000 00000000 ................
>
> But it can read the serial number at offset 0x3f0
>
> => misc read otp@10070000 3f0 80400010 10
> => md 80400000
> 80400000: ffffffff ffffffff ffffffff ffffffff ................
> 80400010: 00000001 fffffffe ffffffff ffffffff ................
> 80400020: 00000000 00000000 00000000 00000000 ................
> 80400030: 00000000 00000000 00000000 00000000 ................
> 80400040: 00000000 00000000 00000000 00000000 ................
> 80400050: 00000000 00000000 00000000 00000000 ................
> 80400060: 00000000 00000000 00000000 00000000 ................
> 80400070: 00000000 00000000 00000000 00000000 ................
> 80400080: 00000000 00000000 00000000 00000000 ................
> 80400090: 00000000 00000000 00000000 00000000 ................
> 804000a0: 00000000 00000000 00000000 00000000 ................
> 804000b0: 00000000 00000000 00000000 00000000 ................
> 804000c0: 00000000 00000000 00000000 00000000 ................
> 804000d0: 00000000 00000000 00000000 00000000 ................
> 804000e0: 00000000 00000000 00000000 00000000 ................
> 804000f0: 00000000 00000000 00000000 00000000 ................
>
> Regards,
> Bin
Hi Green, On Wed, Oct 14, 2020 at 3:02 PM Green Wan <green.wan@sifive.com> wrote: > > On Wed, Oct 14, 2020 at 1:37 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > Hi Green, > > > > On Mon, Sep 28, 2020 at 6:12 PM Green Wan <green.wan@sifive.com> wrote: > > > > > > - Add write operation to update fuse data bit when PWE bit is on. > > > - Add array, fuse_wo, to store the 'written' status for all bits > > > of OTP to block the write operation. > > > > > > Signed-off-by: Green Wan <green.wan@sifive.com> > > > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > > > --- > > > hw/misc/sifive_u_otp.c | 30 +++++++++++++++++++++++++++++- > > > include/hw/misc/sifive_u_otp.h | 3 +++ > > > 2 files changed, 32 insertions(+), 1 deletion(-) > > > > > > > I am not sure how you tested this. I wrote a simple U-Boot command to > > call U-Boot sifive-otp driver to test the write functionality, but it > > failed. > > > > => misc write otp@10070000 0 80200000 10 > ^^^^^^^^^ > Quick ask, how about 'md 80200000'? > > I didn't use 'misc write' command. I can check afterward. Note 'misc write' is a new U-Boot command I just added for testing this QEMU functionality. Please use the U-Boot patch below: http://patchwork.ozlabs.org/project/uboot/patch/1602657292-82815-1-git-send-email-bmeng.cn@gmail.com/ > > > => misc read otp@10070000 0 80400000 10 > > => md 80400000 > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > 80400010: 00000000 00000000 00000000 00000000 ................ > > 80400020: 00000000 00000000 00000000 00000000 ................ > > 80400030: 00000000 00000000 00000000 00000000 ................ > > 80400040: 00000000 00000000 00000000 00000000 ................ > > 80400050: 00000000 00000000 00000000 00000000 ................ > > 80400060: 00000000 00000000 00000000 00000000 ................ > > 80400070: 00000000 00000000 00000000 00000000 ................ > > 80400080: 00000000 00000000 00000000 00000000 ................ > > 80400090: 00000000 00000000 00000000 00000000 ................ > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > 804000f0: 00000000 00000000 00000000 00000000 ................ > > => misc write otp@10070000 0 80200010 10 > > => misc read otp@10070000 0 80400010 10 > > => md 80400000 > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > 80400010: ffffffff ffffffff ffffffff ffffffff ................ > > 80400020: 00000000 00000000 00000000 00000000 ................ > > 80400030: 00000000 00000000 00000000 00000000 ................ > > 80400040: 00000000 00000000 00000000 00000000 ................ > > 80400050: 00000000 00000000 00000000 00000000 ................ > > 80400060: 00000000 00000000 00000000 00000000 ................ > > 80400070: 00000000 00000000 00000000 00000000 ................ > > 80400080: 00000000 00000000 00000000 00000000 ................ > > 80400090: 00000000 00000000 00000000 00000000 ................ > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > 804000f0: 00000000 00000000 00000000 00000000 ................ > > > > But it can read the serial number at offset 0x3f0 > > > > => misc read otp@10070000 3f0 80400010 10 > > => md 80400000 > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > 80400010: 00000001 fffffffe ffffffff ffffffff ................ > > 80400020: 00000000 00000000 00000000 00000000 ................ > > 80400030: 00000000 00000000 00000000 00000000 ................ > > 80400040: 00000000 00000000 00000000 00000000 ................ > > 80400050: 00000000 00000000 00000000 00000000 ................ > > 80400060: 00000000 00000000 00000000 00000000 ................ > > 80400070: 00000000 00000000 00000000 00000000 ................ > > 80400080: 00000000 00000000 00000000 00000000 ................ > > 80400090: 00000000 00000000 00000000 00000000 ................ > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > 804000f0: 00000000 00000000 00000000 00000000 ................ Regards, Bin
On Wed, Oct 14, 2020 at 3:17 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > Hi Green, > > On Wed, Oct 14, 2020 at 3:02 PM Green Wan <green.wan@sifive.com> wrote: > > > > On Wed, Oct 14, 2020 at 1:37 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > > > Hi Green, > > > > > > On Mon, Sep 28, 2020 at 6:12 PM Green Wan <green.wan@sifive.com> wrote: > > > > > > > > - Add write operation to update fuse data bit when PWE bit is on. > > > > - Add array, fuse_wo, to store the 'written' status for all bits > > > > of OTP to block the write operation. > > > > > > > > Signed-off-by: Green Wan <green.wan@sifive.com> > > > > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > > > > --- > > > > hw/misc/sifive_u_otp.c | 30 +++++++++++++++++++++++++++++- > > > > include/hw/misc/sifive_u_otp.h | 3 +++ > > > > 2 files changed, 32 insertions(+), 1 deletion(-) > > > > > > > > > > I am not sure how you tested this. I wrote a simple U-Boot command to > > > call U-Boot sifive-otp driver to test the write functionality, but it > > > failed. > > > > > > => misc write otp@10070000 0 80200000 10 > > ^^^^^^^^^ > > Quick ask, how about 'md 80200000'? > > > > I didn't use 'misc write' command. I can check afterward. > > Note 'misc write' is a new U-Boot command I just added for testing > this QEMU functionality. Please use the U-Boot patch below: > http://patchwork.ozlabs.org/project/uboot/patch/1602657292-82815-1-git-send-email-bmeng.cn@gmail.com/ > Thanks for pointing it out. I've found one bug when I revise the macro of the write function and the read is correct. It's my mistake. I will include and rerun this test as well. > > > > > => misc read otp@10070000 0 80400000 10 > > > => md 80400000 > > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > > 80400010: 00000000 00000000 00000000 00000000 ................ > > > 80400020: 00000000 00000000 00000000 00000000 ................ > > > 80400030: 00000000 00000000 00000000 00000000 ................ > > > 80400040: 00000000 00000000 00000000 00000000 ................ > > > 80400050: 00000000 00000000 00000000 00000000 ................ > > > 80400060: 00000000 00000000 00000000 00000000 ................ > > > 80400070: 00000000 00000000 00000000 00000000 ................ > > > 80400080: 00000000 00000000 00000000 00000000 ................ > > > 80400090: 00000000 00000000 00000000 00000000 ................ > > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > > 804000f0: 00000000 00000000 00000000 00000000 ................ > > > => misc write otp@10070000 0 80200010 10 > > > => misc read otp@10070000 0 80400010 10 > > > => md 80400000 > > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > > 80400010: ffffffff ffffffff ffffffff ffffffff ................ > > > 80400020: 00000000 00000000 00000000 00000000 ................ > > > 80400030: 00000000 00000000 00000000 00000000 ................ > > > 80400040: 00000000 00000000 00000000 00000000 ................ > > > 80400050: 00000000 00000000 00000000 00000000 ................ > > > 80400060: 00000000 00000000 00000000 00000000 ................ > > > 80400070: 00000000 00000000 00000000 00000000 ................ > > > 80400080: 00000000 00000000 00000000 00000000 ................ > > > 80400090: 00000000 00000000 00000000 00000000 ................ > > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > > 804000f0: 00000000 00000000 00000000 00000000 ................ > > > > > > But it can read the serial number at offset 0x3f0 > > > > > > => misc read otp@10070000 3f0 80400010 10 > > > => md 80400000 > > > 80400000: ffffffff ffffffff ffffffff ffffffff ................ > > > 80400010: 00000001 fffffffe ffffffff ffffffff ................ > > > 80400020: 00000000 00000000 00000000 00000000 ................ > > > 80400030: 00000000 00000000 00000000 00000000 ................ > > > 80400040: 00000000 00000000 00000000 00000000 ................ > > > 80400050: 00000000 00000000 00000000 00000000 ................ > > > 80400060: 00000000 00000000 00000000 00000000 ................ > > > 80400070: 00000000 00000000 00000000 00000000 ................ > > > 80400080: 00000000 00000000 00000000 00000000 ................ > > > 80400090: 00000000 00000000 00000000 00000000 ................ > > > 804000a0: 00000000 00000000 00000000 00000000 ................ > > > 804000b0: 00000000 00000000 00000000 00000000 ................ > > > 804000c0: 00000000 00000000 00000000 00000000 ................ > > > 804000d0: 00000000 00000000 00000000 00000000 ................ > > > 804000e0: 00000000 00000000 00000000 00000000 ................ > > > 804000f0: 00000000 00000000 00000000 00000000 ................ > > Regards, > Bin
© 2016 - 2026 Red Hat, Inc.