All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/12] riscv-to-apply queue
@ 2020-10-23 15:16 Alistair Francis
  2020-10-23 15:16 ` [PULL 01/12] riscv: Convert interrupt logs to use qemu_log_mask() Alistair Francis
                   ` (12 more replies)
  0 siblings, 13 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, Alistair Francis

The following changes since commit 4c5b97bfd0dd54dc27717ae8d1cd10e14eef1430:

  Merge remote-tracking branch 'remotes/kraxel/tags/modules-20201022-pull-request' into staging (2020-10-22 12:33:21 +0100)

are available in the Git repository at:

  git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20201023

for you to fetch changes up to 51b6c1bbc3dd1b139a9e9b021d87bcfd7d82299e:

  hw/misc/sifive_u_otp: Add backend drive support (2020-10-22 12:00:50 -0700)

----------------------------------------------------------------
A collection of RISC-V fixes for the next QEMU release.

This includes:
 - Improvements to logging output
 - Hypervisor instruction fixups
 - The ability to load a noMMU kernel
 - SiFive OTP support

----------------------------------------------------------------
Alistair Francis (5):
      riscv: Convert interrupt logs to use qemu_log_mask()
      hw/riscv: sifive_u: Allow specifying the CPU
      hw/riscv: Return the end address of the loaded firmware
      hw/riscv: Add a riscv_is_32_bit() function
      hw/riscv: Load the kernel after the firmware

Bin Meng (1):
      hw/intc: Move sifive_plic.h to the include directory

Georg Kotheimer (3):
      target/riscv: Fix update of hstatus.SPVP
      target/riscv: Fix update of hstatus.GVA in riscv_cpu_do_interrupt
      target/riscv: Fix implementation of HLVX.WU instruction

Green Wan (2):
      hw/misc/sifive_u_otp: Add write function and write-once protection
      hw/misc/sifive_u_otp: Add backend drive support

Yifei Jiang (1):
      target/riscv: raise exception to HS-mode at get_physical_address

 {hw => include/hw}/intc/sifive_plic.h |  0
 include/hw/misc/sifive_u_otp.h        |  5 ++
 include/hw/riscv/boot.h               | 13 +++--
 include/hw/riscv/sifive_u.h           |  1 +
 target/riscv/cpu.h                    | 10 ++--
 hw/misc/sifive_u_otp.c                | 95 ++++++++++++++++++++++++++++++++++-
 hw/riscv/boot.c                       | 56 +++++++++++++++------
 hw/riscv/opentitan.c                  |  3 +-
 hw/riscv/sifive_e.c                   |  3 +-
 hw/riscv/sifive_u.c                   | 28 ++++++++---
 hw/riscv/spike.c                      | 11 ++--
 hw/riscv/virt.c                       | 11 ++--
 target/riscv/cpu_helper.c             | 50 +++++++++++++-----
 target/riscv/op_helper.c              |  7 ++-
 14 files changed, 238 insertions(+), 55 deletions(-)
 rename {hw => include/hw}/intc/sifive_plic.h (100%)


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PULL 01/12] riscv: Convert interrupt logs to use qemu_log_mask()
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 02/12] hw/intc: Move sifive_plic.h to the include directory Alistair Francis
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Alistair Francis, Philippe Mathieu-Daudé

Currently we log interrupts and exceptions using the trace backend in
riscv_cpu_do_interrupt(). We also log exceptions using the interrupt log
mask (-d int) in riscv_raise_exception().

This patch converts riscv_cpu_do_interrupt() to log both interrupts and
exceptions with the interrupt log mask, so that both are printed when a
user runs QEMU with -d int.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 29a8c766c7c4748d0f2711c3a0abb81208138c5e.1601652179.git.alistair.francis@wdc.com
---
 target/riscv/cpu_helper.c | 8 +++++++-
 target/riscv/op_helper.c  | 1 -
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 904899054d..6c68239a46 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -895,7 +895,13 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     }
 
     trace_riscv_trap(env->mhartid, async, cause, env->pc, tval,
-        riscv_cpu_get_trap_name(cause, async));
+                     riscv_cpu_get_trap_name(cause, async));
+
+    qemu_log_mask(CPU_LOG_INT,
+                  "%s: hart:"TARGET_FMT_ld", async:%d, cause:"TARGET_FMT_lx", "
+                  "epc:0x"TARGET_FMT_lx", tval:0x"TARGET_FMT_lx", desc=%s\n",
+                  __func__, env->mhartid, async, cause, env->pc, tval,
+                  riscv_cpu_get_trap_name(cause, async));
 
     if (env->priv <= PRV_S &&
             cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 9b9ada45a9..e987bd262f 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -29,7 +29,6 @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
                                           uint32_t exception, uintptr_t pc)
 {
     CPUState *cs = env_cpu(env);
-    qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
     cs->exception_index = exception;
     cpu_loop_exit_restore(cs, pc);
 }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 02/12] hw/intc: Move sifive_plic.h to the include directory
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
  2020-10-23 15:16 ` [PULL 01/12] riscv: Convert interrupt logs to use qemu_log_mask() Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 03/12] target/riscv: Fix update of hstatus.SPVP Alistair Francis
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Bin Meng, Alistair Francis, Philippe Mathieu-Daudé

From: Bin Meng <bin.meng@windriver.com>

Since sifive_plic.h is used by hw/intc/sifive_plic.c,
it has to be in the public include directory. Move it.

Fixes: 84fcf3c15111 ("hw/riscv: Move sifive_plic model to hw/intc")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 1602578033-68384-1-git-send-email-bmeng.cn@gmail.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 {hw => include/hw}/intc/sifive_plic.h | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename {hw => include/hw}/intc/sifive_plic.h (100%)

diff --git a/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
similarity index 100%
rename from hw/intc/sifive_plic.h
rename to include/hw/intc/sifive_plic.h
-- 
2.28.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PULL 03/12] target/riscv: Fix update of hstatus.SPVP
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
  2020-10-23 15:16 ` [PULL 01/12] riscv: Convert interrupt logs to use qemu_log_mask() Alistair Francis
  2020-10-23 15:16 ` [PULL 02/12] hw/intc: Move sifive_plic.h to the include directory Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 04/12] target/riscv: Fix update of hstatus.GVA in riscv_cpu_do_interrupt Alistair Francis
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, Alistair Francis, Georg Kotheimer

From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>

When trapping from virt into HS mode, hstatus.SPVP was set to
the value of sstatus.SPP, as according to the specification both
flags should be set to the same value.
However, the assignment of SPVP takes place before SPP itself is
updated, which results in SPVP having an outdated value.

Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20201013151054.396481-1-georg.kotheimer@kernkonzept.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6c68239a46..47d05fe34c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -938,7 +938,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
                 /* Trap into HS mode, from virt */
                 riscv_cpu_swap_hypervisor_regs(env);
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
-                                         get_field(env->mstatus, SSTATUS_SPP));
+                                         env->priv);
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
                                          riscv_cpu_virt_enabled(env));
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 04/12] target/riscv: Fix update of hstatus.GVA in riscv_cpu_do_interrupt
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (2 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 03/12] target/riscv: Fix update of hstatus.SPVP Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 05/12] target/riscv: Fix implementation of HLVX.WU instruction Alistair Francis
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, Alistair Francis, Georg Kotheimer

From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>

The hstatus.GVA bit was not set if the faulting guest virtual address
was zero.

Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20201013173054.451135-1-georg.kotheimer@kernkonzept.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu_helper.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 47d05fe34c..f363c1013c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -852,6 +852,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG);
     target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
     target_ulong deleg = async ? env->mideleg : env->medeleg;
+    bool write_tval = false;
     target_ulong tval = 0;
     target_ulong htval = 0;
     target_ulong mtval2 = 0;
@@ -873,6 +874,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         case RISCV_EXCP_INST_PAGE_FAULT:
         case RISCV_EXCP_LOAD_PAGE_FAULT:
         case RISCV_EXCP_STORE_PAGE_FAULT:
+            write_tval  = true;
             tval = env->badaddr;
             break;
         default:
@@ -910,7 +912,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
 
             if ((riscv_cpu_virt_enabled(env) ||
-                 riscv_cpu_two_stage_lookup(env)) && tval) {
+                 riscv_cpu_two_stage_lookup(env)) && write_tval) {
                 /*
                  * If we are writing a guest virtual address to stval, set
                  * this to 1. If we are trapping to VS we will set this to 0
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 05/12] target/riscv: Fix implementation of HLVX.WU instruction
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (3 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 04/12] target/riscv: Fix update of hstatus.GVA in riscv_cpu_do_interrupt Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 06/12] hw/riscv: sifive_u: Allow specifying the CPU Alistair Francis
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Alistair Francis, Georg Kotheimer,
	Philippe Mathieu-Daudé

From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>

The HLVX.WU instruction is supposed to read a machine word,
but prior to this change it read a byte instead.

Fixes: 8c5362acb57 ("target/riscv: Allow generating hlv/hlvx/hsv instructions")
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20201013172223.443645-1-georg.kotheimer@kernkonzept.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/op_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index e987bd262f..4ce73575a7 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -333,12 +333,12 @@ target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
         riscv_cpu_set_two_stage_lookup(env, true);
 
         switch (memop) {
-        case MO_TEUL:
-            pte = cpu_ldub_data_ra(env, address, GETPC());
-            break;
         case MO_TEUW:
             pte = cpu_lduw_data_ra(env, address, GETPC());
             break;
+        case MO_TEUL:
+            pte = cpu_ldl_data_ra(env, address, GETPC());
+            break;
         default:
             g_assert_not_reached();
         }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 06/12] hw/riscv: sifive_u: Allow specifying the CPU
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (4 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 05/12] target/riscv: Fix implementation of HLVX.WU instruction Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 07/12] hw/riscv: Return the end address of the loaded firmware Alistair Francis
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Palmer Dabbelt, alistair23, Bin Meng, Alistair Francis

Allow the user to specify the main application CPU for the sifive_u
machine.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-id: b8412086c8aea0eff30fb7a17f0acf2943381b6a.1602634524.git.alistair.francis@wdc.com
---
 include/hw/riscv/sifive_u.h |  1 +
 hw/riscv/sifive_u.c         | 18 +++++++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 22e7e6efa1..a9f7b4a084 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -48,6 +48,7 @@ typedef struct SiFiveUSoCState {
     CadenceGEMState gem;
 
     uint32_t serial;
+    char *cpu_type;
 } SiFiveUSoCState;
 
 #define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6ad975d692..5f3ad9bc0f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -424,6 +424,8 @@ static void sifive_u_machine_init(MachineState *machine)
     object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
     object_property_set_uint(OBJECT(&s->soc), "serial", s->serial,
                              &error_abort);
+    object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
+                             &error_abort);
     qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
 
     /* register RAM */
@@ -590,6 +592,11 @@ static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
     mc->init = sifive_u_machine_init;
     mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
     mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
+#if defined(TARGET_RISCV32)
+    mc->default_cpu_type = TYPE_RISCV_CPU_SIFIVE_U34;
+#elif defined(TARGET_RISCV64)
+    mc->default_cpu_type = TYPE_RISCV_CPU_SIFIVE_U54;
+#endif
     mc->default_cpus = mc->min_cpus;
 
     object_class_property_add_bool(oc, "start-in-flash",
@@ -618,7 +625,6 @@ type_init(sifive_u_machine_init_register_types)
 
 static void sifive_u_soc_instance_init(Object *obj)
 {
-    MachineState *ms = MACHINE(qdev_get_machine());
     SiFiveUSoCState *s = RISCV_U_SOC(obj);
 
     object_initialize_child(obj, "e-cluster", &s->e_cluster, TYPE_CPU_CLUSTER);
@@ -636,10 +642,6 @@ static void sifive_u_soc_instance_init(Object *obj)
 
     object_initialize_child(OBJECT(&s->u_cluster), "u-cpus", &s->u_cpus,
                             TYPE_RISCV_HART_ARRAY);
-    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
-    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
-    qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", SIFIVE_U_CPU);
-    qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
 
     object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
     object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
@@ -661,6 +663,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
     int i;
     NICInfo *nd = &nd_table[0];
 
+    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
+    qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
+    qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
+    qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
+
     sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_abort);
     sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_abort);
     /*
@@ -792,6 +799,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
 
 static Property sifive_u_soc_props[] = {
     DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
+    DEFINE_PROP_STRING("cpu-type", SiFiveUSoCState, cpu_type),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 07/12] hw/riscv: Return the end address of the loaded firmware
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (5 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 06/12] hw/riscv: sifive_u: Allow specifying the CPU Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 08/12] hw/riscv: Add a riscv_is_32_bit() function Alistair Francis
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Bin Meng, alistair23, Palmer Dabbelt, Alistair Francis

Instead of returning the unused entry address from riscv_load_firmware()
instead return the end address. Also return the end address from
riscv_find_and_load_firmware().

This tells the caller if a firmware was loaded and how big it is. This
can be used to determine the load address of the next image (usually the
kernel).

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-id: 558cf67162342d65a23262248b040563716628b2.1602634524.git.alistair.francis@wdc.com
---
 include/hw/riscv/boot.h |  8 ++++----
 hw/riscv/boot.c         | 28 +++++++++++++++++-----------
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 451338780a..0acbd8aa6e 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -23,10 +23,10 @@
 #include "exec/cpu-defs.h"
 #include "hw/loader.h"
 
-void riscv_find_and_load_firmware(MachineState *machine,
-                                  const char *default_machine_firmware,
-                                  hwaddr firmware_load_addr,
-                                  symbol_fn_t sym_cb);
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+                                          const char *default_machine_firmware,
+                                          hwaddr firmware_load_addr,
+                                          symbol_fn_t sym_cb);
 char *riscv_find_firmware(const char *firmware_filename);
 target_ulong riscv_load_firmware(const char *firmware_filename,
                                  hwaddr firmware_load_addr,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 21adaae56e..fa699308a0 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -40,12 +40,13 @@
 #define fw_dynamic_info_data(__val)     cpu_to_le64(__val)
 #endif
 
-void riscv_find_and_load_firmware(MachineState *machine,
-                                  const char *default_machine_firmware,
-                                  hwaddr firmware_load_addr,
-                                  symbol_fn_t sym_cb)
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+                                          const char *default_machine_firmware,
+                                          hwaddr firmware_load_addr,
+                                          symbol_fn_t sym_cb)
 {
     char *firmware_filename = NULL;
+    target_ulong firmware_end_addr = firmware_load_addr;
 
     if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {
         /*
@@ -60,9 +61,12 @@ void riscv_find_and_load_firmware(MachineState *machine,
 
     if (firmware_filename) {
         /* If not "none" load the firmware */
-        riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb);
+        firmware_end_addr = riscv_load_firmware(firmware_filename,
+                                                firmware_load_addr, sym_cb);
         g_free(firmware_filename);
     }
+
+    return firmware_end_addr;
 }
 
 char *riscv_find_firmware(const char *firmware_filename)
@@ -91,17 +95,19 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
                                  hwaddr firmware_load_addr,
                                  symbol_fn_t sym_cb)
 {
-    uint64_t firmware_entry;
+    uint64_t firmware_entry, firmware_size, firmware_end;
 
     if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
-                         &firmware_entry, NULL, NULL, NULL,
+                         &firmware_entry, NULL, &firmware_end, NULL,
                          0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
-        return firmware_entry;
+        return firmware_end;
     }
 
-    if (load_image_targphys_as(firmware_filename, firmware_load_addr,
-                               ram_size, NULL) > 0) {
-        return firmware_load_addr;
+    firmware_size = load_image_targphys_as(firmware_filename,
+                                           firmware_load_addr, ram_size, NULL);
+
+    if (firmware_size > 0) {
+        return firmware_load_addr + firmware_size;
     }
 
     error_report("could not load firmware '%s'", firmware_filename);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 08/12] hw/riscv: Add a riscv_is_32_bit() function
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (6 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 07/12] hw/riscv: Return the end address of the loaded firmware Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 09/12] hw/riscv: Load the kernel after the firmware Alistair Francis
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Bin Meng, alistair23, Palmer Dabbelt, Alistair Francis

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-id: 4c6a85dfb6dd470aa79356ebc1b02f479c2758e0.1602634524.git.alistair.francis@wdc.com
---
 include/hw/riscv/boot.h | 2 ++
 hw/riscv/boot.c         | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 0acbd8aa6e..2975ed1a31 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -23,6 +23,8 @@
 #include "exec/cpu-defs.h"
 #include "hw/loader.h"
 
+bool riscv_is_32_bit(MachineState *machine);
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
                                           const char *default_machine_firmware,
                                           hwaddr firmware_load_addr,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index fa699308a0..5dea644f47 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -40,6 +40,15 @@
 #define fw_dynamic_info_data(__val)     cpu_to_le64(__val)
 #endif
 
+bool riscv_is_32_bit(MachineState *machine)
+{
+    if (!strncmp(machine->cpu_type, "rv32", 4)) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
                                           const char *default_machine_firmware,
                                           hwaddr firmware_load_addr,
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 09/12] hw/riscv: Load the kernel after the firmware
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (7 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 08/12] hw/riscv: Add a riscv_is_32_bit() function Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 10/12] target/riscv: raise exception to HS-mode at get_physical_address Alistair Francis
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: Bin Meng, alistair23, Palmer Dabbelt, Alistair Francis

Instead of loading the kernel at a hardcoded start address, let's load
the kernel at the next aligned address after the end of the firmware.

This should have no impact for current users of OpenSBI, but will
allow loading a noMMU kernel at the start of memory.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-id: 46c00c4f15b42feb792090e3d74359e180a6d954.1602634524.git.alistair.francis@wdc.com
---
 include/hw/riscv/boot.h |  3 +++
 hw/riscv/boot.c         | 19 ++++++++++++++-----
 hw/riscv/opentitan.c    |  3 ++-
 hw/riscv/sifive_e.c     |  3 ++-
 hw/riscv/sifive_u.c     | 10 ++++++++--
 hw/riscv/spike.c        | 11 ++++++++---
 hw/riscv/virt.c         | 11 ++++++++---
 7 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 2975ed1a31..0b01988727 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -25,6 +25,8 @@
 
 bool riscv_is_32_bit(MachineState *machine);
 
+target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+                                          target_ulong firmware_end_addr);
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
                                           const char *default_machine_firmware,
                                           hwaddr firmware_load_addr,
@@ -34,6 +36,7 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
                                  hwaddr firmware_load_addr,
                                  symbol_fn_t sym_cb);
 target_ulong riscv_load_kernel(const char *kernel_filename,
+                               target_ulong firmware_end_addr,
                                symbol_fn_t sym_cb);
 hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
                          uint64_t kernel_entry, hwaddr *start);
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 5dea644f47..9b3fe3fb1e 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -33,10 +33,8 @@
 #include <libfdt.h>
 
 #if defined(TARGET_RISCV32)
-# define KERNEL_BOOT_ADDRESS 0x80400000
 #define fw_dynamic_info_data(__val)     cpu_to_le32(__val)
 #else
-# define KERNEL_BOOT_ADDRESS 0x80200000
 #define fw_dynamic_info_data(__val)     cpu_to_le64(__val)
 #endif
 
@@ -49,6 +47,15 @@ bool riscv_is_32_bit(MachineState *machine)
     }
 }
 
+target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
+                                          target_ulong firmware_end_addr) {
+    if (riscv_is_32_bit(machine)) {
+        return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
+    } else {
+        return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB);
+    }
+}
+
 target_ulong riscv_find_and_load_firmware(MachineState *machine,
                                           const char *default_machine_firmware,
                                           hwaddr firmware_load_addr,
@@ -123,7 +130,9 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
     exit(1);
 }
 
-target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb)
+target_ulong riscv_load_kernel(const char *kernel_filename,
+                               target_ulong kernel_start_addr,
+                               symbol_fn_t sym_cb)
 {
     uint64_t kernel_entry;
 
@@ -138,9 +147,9 @@ target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb)
         return kernel_entry;
     }
 
-    if (load_image_targphys_as(kernel_filename, KERNEL_BOOT_ADDRESS,
+    if (load_image_targphys_as(kernel_filename, kernel_start_addr,
                                ram_size, NULL) > 0) {
-        return KERNEL_BOOT_ADDRESS;
+        return kernel_start_addr;
     }
 
     error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 0531bd879b..cc758b78b8 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -75,7 +75,8 @@ static void opentitan_board_init(MachineState *machine)
     }
 
     if (machine->kernel_filename) {
-        riscv_load_kernel(machine->kernel_filename, NULL);
+        riscv_load_kernel(machine->kernel_filename,
+                          memmap[IBEX_DEV_RAM].base, NULL);
     }
 }
 
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index fcfac16816..59bac4cc9a 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -114,7 +114,8 @@ static void sifive_e_machine_init(MachineState *machine)
                           memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
 
     if (machine->kernel_filename) {
-        riscv_load_kernel(machine->kernel_filename, NULL);
+        riscv_load_kernel(machine->kernel_filename,
+                          memmap[SIFIVE_E_DEV_DTIM].base, NULL);
     }
 }
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5f3ad9bc0f..b2472c6627 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -415,6 +415,7 @@ static void sifive_u_machine_init(MachineState *machine)
     MemoryRegion *main_mem = g_new(MemoryRegion, 1);
     MemoryRegion *flash0 = g_new(MemoryRegion, 1);
     target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
+    target_ulong firmware_end_addr, kernel_start_addr;
     uint32_t start_addr_hi32 = 0x00000000;
     int i;
     uint32_t fdt_load_addr;
@@ -474,10 +475,15 @@ static void sifive_u_machine_init(MachineState *machine)
         break;
     }
 
-    riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
+    firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
+                                                     start_addr, NULL);
 
     if (machine->kernel_filename) {
-        kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL);
+        kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+                                                         firmware_end_addr);
+
+        kernel_entry = riscv_load_kernel(machine->kernel_filename,
+                                         kernel_start_addr, NULL);
 
         if (machine->initrd_filename) {
             hwaddr start;
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 3fd152a035..facac6e7d2 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -195,6 +195,7 @@ static void spike_board_init(MachineState *machine)
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *main_mem = g_new(MemoryRegion, 1);
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+    target_ulong firmware_end_addr, kernel_start_addr;
     uint32_t fdt_load_addr;
     uint64_t kernel_entry;
     char *soc_name;
@@ -261,12 +262,16 @@ static void spike_board_init(MachineState *machine)
     memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
                                 mask_rom);
 
-    riscv_find_and_load_firmware(machine, BIOS_FILENAME,
-                                 memmap[SPIKE_DRAM].base,
-                                 htif_symbol_callback);
+    firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
+                                                     memmap[SPIKE_DRAM].base,
+                                                     htif_symbol_callback);
 
     if (machine->kernel_filename) {
+        kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+                                                         firmware_end_addr);
+
         kernel_entry = riscv_load_kernel(machine->kernel_filename,
+                                         kernel_start_addr,
                                          htif_symbol_callback);
 
         if (machine->initrd_filename) {
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 41bd2f38ba..6bfd10dfc7 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -493,6 +493,7 @@ static void virt_machine_init(MachineState *machine)
     char *plic_hart_config, *soc_name;
     size_t plic_hart_config_len;
     target_ulong start_addr = memmap[VIRT_DRAM].base;
+    target_ulong firmware_end_addr, kernel_start_addr;
     uint32_t fdt_load_addr;
     uint64_t kernel_entry;
     DeviceState *mmio_plic, *virtio_plic, *pcie_plic;
@@ -602,11 +603,15 @@ static void virt_machine_init(MachineState *machine)
     memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
                                 mask_rom);
 
-    riscv_find_and_load_firmware(machine, BIOS_FILENAME,
-                                 memmap[VIRT_DRAM].base, NULL);
+    firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
+                                                     start_addr, NULL);
 
     if (machine->kernel_filename) {
-        kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL);
+        kernel_start_addr = riscv_calc_kernel_start_addr(machine,
+                                                         firmware_end_addr);
+
+        kernel_entry = riscv_load_kernel(machine->kernel_filename,
+                                         kernel_start_addr, NULL);
 
         if (machine->initrd_filename) {
             hwaddr start;
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 10/12] target/riscv: raise exception to HS-mode at get_physical_address
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (8 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 09/12] hw/riscv: Load the kernel after the firmware Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 11/12] hw/misc/sifive_u_otp: Add write function and write-once protection Alistair Francis
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Alistair Francis, Yifei Jiang, Yipeng Yin

From: Yifei Jiang <jiangyifei@huawei.com>

VS-stage translation at get_physical_address needs to translate pte
address by G-stage translation. But the G-stage translation error
can not be distinguished from VS-stage translation error in
riscv_cpu_tlb_fill. On migration, destination needs to rebuild pte,
and this G-stage translation error must be handled by HS-mode. So
introduce TRANSLATE_STAGE2_FAIL so that riscv_cpu_tlb_fill could
distinguish and raise it to HS-mode.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20201014101728.848-1-jiangyifei@huawei.com
[ Change by AF:
 - Clarify the fault_pte_addr shift
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h        | 10 +++++++---
 target/riscv/cpu_helper.c | 36 +++++++++++++++++++++++++++---------
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de275782e6..de4705bb57 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -82,9 +82,13 @@ enum {
 
 #define VEXT_VERSION_0_07_1 0x00000701
 
-#define TRANSLATE_PMP_FAIL 2
-#define TRANSLATE_FAIL 1
-#define TRANSLATE_SUCCESS 0
+enum {
+    TRANSLATE_SUCCESS,
+    TRANSLATE_FAIL,
+    TRANSLATE_PMP_FAIL,
+    TRANSLATE_G_STAGE_FAIL
+};
+
 #define MMU_USER_IDX 3
 
 #define MAX_RISCV_PMPS (16)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f363c1013c..4652082df1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -316,6 +316,9 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
  * @physical: This will be set to the calculated physical address
  * @prot: The returned protection attributes
  * @addr: The virtual address to be translated
+ * @fault_pte_addr: If not NULL, this will be set to fault pte address
+ *                  when a error occurs on pte address translation.
+ *                  This will already be shifted to match htval.
  * @access_type: The type of MMU access
  * @mmu_idx: Indicates current privilege level
  * @first_stage: Are we in first stage translation?
@@ -324,6 +327,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
  */
 static int get_physical_address(CPURISCVState *env, hwaddr *physical,
                                 int *prot, target_ulong addr,
+                                target_ulong *fault_pte_addr,
                                 int access_type, int mmu_idx,
                                 bool first_stage, bool two_stage)
 {
@@ -447,11 +451,14 @@ restart:
 
             /* Do the second stage translation on the base PTE address. */
             int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
-                                                 base, MMU_DATA_LOAD,
+                                                 base, NULL, MMU_DATA_LOAD,
                                                  mmu_idx, false, true);
 
             if (vbase_ret != TRANSLATE_SUCCESS) {
-                return vbase_ret;
+                if (fault_pte_addr) {
+                    *fault_pte_addr = (base + idx * ptesize) >> 2;
+                }
+                return TRANSLATE_G_STAGE_FAIL;
             }
 
             pte_addr = vbase + idx * ptesize;
@@ -632,13 +639,13 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     int prot;
     int mmu_idx = cpu_mmu_index(&cpu->env, false);
 
-    if (get_physical_address(env, &phys_addr, &prot, addr, 0, mmu_idx,
+    if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx,
                              true, riscv_cpu_virt_enabled(env))) {
         return -1;
     }
 
     if (riscv_cpu_virt_enabled(env)) {
-        if (get_physical_address(env, &phys_addr, &prot, phys_addr,
+        if (get_physical_address(env, &phys_addr, &prot, phys_addr, NULL,
                                  0, mmu_idx, false, true)) {
             return -1;
         }
@@ -727,19 +734,30 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     if (riscv_cpu_virt_enabled(env) ||
         (riscv_cpu_two_stage_lookup(env) && access_type != MMU_INST_FETCH)) {
         /* Two stage lookup */
-        ret = get_physical_address(env, &pa, &prot, address, access_type,
+        ret = get_physical_address(env, &pa, &prot, address,
+                                   &env->guest_phys_fault_addr, access_type,
                                    mmu_idx, true, true);
 
+        /*
+         * A G-stage exception may be triggered during two state lookup.
+         * And the env->guest_phys_fault_addr has already been set in
+         * get_physical_address().
+         */
+        if (ret == TRANSLATE_G_STAGE_FAIL) {
+            first_stage_error = false;
+            access_type = MMU_DATA_LOAD;
+        }
+
         qemu_log_mask(CPU_LOG_MMU,
                       "%s 1st-stage address=%" VADDR_PRIx " ret %d physical "
                       TARGET_FMT_plx " prot %d\n",
                       __func__, address, ret, pa, prot);
 
-        if (ret != TRANSLATE_FAIL) {
+        if (ret == TRANSLATE_SUCCESS) {
             /* Second stage lookup */
             im_address = pa;
 
-            ret = get_physical_address(env, &pa, &prot2, im_address,
+            ret = get_physical_address(env, &pa, &prot2, im_address, NULL,
                                        access_type, mmu_idx, false, true);
 
             qemu_log_mask(CPU_LOG_MMU,
@@ -768,8 +786,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         }
     } else {
         /* Single stage lookup */
-        ret = get_physical_address(env, &pa, &prot, address, access_type,
-                                   mmu_idx, true, false);
+        ret = get_physical_address(env, &pa, &prot, address, NULL,
+                                   access_type, mmu_idx, true, false);
 
         qemu_log_mask(CPU_LOG_MMU,
                       "%s address=%" VADDR_PRIx " ret %d physical "
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 11/12] hw/misc/sifive_u_otp: Add write function and write-once protection
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (9 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 10/12] target/riscv: raise exception to HS-mode at get_physical_address Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-10-23 15:16 ` [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support Alistair Francis
  2020-10-26 13:16 ` [PULL 00/12] riscv-to-apply queue Peter Maydell
  12 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Bin Meng, Alistair Francis, Green Wan

From: Green Wan <green.wan@sifive.com>

 - 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>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-id: 20201020033732.12921-2-green.wan@sifive.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/misc/sifive_u_otp.h |  3 +++
 hw/misc/sifive_u_otp.c         | 30 +++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)

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;
 };
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
index c2f3c8e129..b9238d64cb 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] & ~(0x1 << 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,
+                              "write once error: 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)
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (10 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 11/12] hw/misc/sifive_u_otp: Add write function and write-once protection Alistair Francis
@ 2020-10-23 15:16 ` Alistair Francis
  2020-11-02 17:49   ` Peter Maydell
  2020-10-26 13:16 ` [PULL 00/12] riscv-to-apply queue Peter Maydell
  12 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-10-23 15:16 UTC (permalink / raw)
  To: qemu-devel, peter.maydell
  Cc: alistair23, Bin Meng, Alistair Francis, Green Wan

From: Green Wan <green.wan@sifive.com>

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 <green.wan@sifive.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20201020033732.12921-3-green.wan@sifive.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/misc/sifive_u_otp.h |  2 ++
 hw/misc/sifive_u_otp.c         | 65 ++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/include/hw/misc/sifive_u_otp.h b/include/hw/misc/sifive_u_otp.h
index ebffbc1fa5..5d0d7df455 100644
--- a/include/hw/misc/sifive_u_otp.h
+++ b/include/hw/misc/sifive_u_otp.h
@@ -46,6 +46,7 @@
 
 #define SIFIVE_U_OTP_PA_MASK        0xfff
 #define SIFIVE_U_OTP_NUM_FUSES      0x1000
+#define SIFIVE_U_OTP_FUSE_WORD      4
 #define SIFIVE_U_OTP_SERIAL_ADDR    0xfc
 
 #define SIFIVE_U_OTP_REG_SIZE       0x1000
@@ -80,6 +81,7 @@ struct SiFiveUOTPState {
     uint32_t fuse_wo[SIFIVE_U_OTP_NUM_FUSES];
     /* config */
     uint32_t serial;
+    BlockBackend *blk;
 };
 
 #endif /* HW_SIFIVE_U_OTP_H */
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
index b9238d64cb..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, &buf,
+                          SIFIVE_U_OTP_FUSE_WORD);
+                return buf;
+            }
+
             return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
         } else {
             return 0xff;
@@ -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,
+                           &s->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(&s->mmio, OBJECT(dev), &sifive_u_otp_ops, s,
                           TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->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,
+                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
+
+        serial_data = ~(s->serial);
+        blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
+                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
+    }
+
     /* Initialize write-once map */
     memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
 }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PULL 00/12] riscv-to-apply queue
  2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
                   ` (11 preceding siblings ...)
  2020-10-23 15:16 ` [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support Alistair Francis
@ 2020-10-26 13:16 ` Peter Maydell
  12 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2020-10-26 13:16 UTC (permalink / raw)
  To: Alistair Francis; +Cc: Alistair Francis, QEMU Developers

On Fri, 23 Oct 2020 at 16:27, Alistair Francis <alistair.francis@wdc.com> wrote:
>
> The following changes since commit 4c5b97bfd0dd54dc27717ae8d1cd10e14eef1430:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/modules-20201022-pull-request' into staging (2020-10-22 12:33:21 +0100)
>
> are available in the Git repository at:
>
>   git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20201023
>
> for you to fetch changes up to 51b6c1bbc3dd1b139a9e9b021d87bcfd7d82299e:
>
>   hw/misc/sifive_u_otp: Add backend drive support (2020-10-22 12:00:50 -0700)
>
> ----------------------------------------------------------------
> A collection of RISC-V fixes for the next QEMU release.
>
> This includes:
>  - Improvements to logging output
>  - Hypervisor instruction fixups
>  - The ability to load a noMMU kernel
>  - SiFive OTP support
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.2
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support
  2020-10-23 15:16 ` [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support Alistair Francis
@ 2020-11-02 17:49   ` Peter Maydell
  2020-11-03 15:41     ` Alistair Francis
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2020-11-02 17:49 UTC (permalink / raw)
  To: Alistair Francis; +Cc: Alistair Francis, Bin Meng, QEMU Developers, Green Wan

On Fri, 23 Oct 2020 at 16:27, Alistair Francis <alistair.francis@wdc.com> wrote:
>
> From: Green Wan <green.wan@sifive.com>
>
> Add '-drive' support to OTP device. Allow users to assign a raw file
> as OTP image.

Hi; Coverity reports some issues with this code (CID 1435959,
CID 1435960, CID 1435961). They're all basically the same thing:
in read, write and reset functions this code calls blk_pread()
or blk_pwrite() but doesn't check the return value, so if the
underlying file operation fails then the guest will be
returned garbage data or have its write thrown away without
either the guest or the user being warned about that.

> @@ -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, &buf,
> +                          SIFIVE_U_OTP_FUSE_WORD);
> +                return buf;
> +            }
> +
>              return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
>          } else {
>              return 0xff;
> @@ -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,
> +                           &s->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 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,
> +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> +
> +        serial_data = ~(s->serial);
> +        blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> +    }
> +
>      /* Initialize write-once map */
>      memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
>  }
> --
> 2.28.0

thanks
-- PMM


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support
  2020-11-02 17:49   ` Peter Maydell
@ 2020-11-03 15:41     ` Alistair Francis
  2020-11-04  8:19       ` Green Wan
  0 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-11-03 15:41 UTC (permalink / raw)
  To: Green Wan; +Cc: Peter Maydell, Bin Meng, Alistair Francis, QEMU Developers

On Mon, Nov 2, 2020 at 9:49 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Fri, 23 Oct 2020 at 16:27, Alistair Francis <alistair.francis@wdc.com> wrote:
> >
> > From: Green Wan <green.wan@sifive.com>
> >
> > Add '-drive' support to OTP device. Allow users to assign a raw file
> > as OTP image.
>
> Hi; Coverity reports some issues with this code (CID 1435959,
> CID 1435960, CID 1435961). They're all basically the same thing:
> in read, write and reset functions this code calls blk_pread()
> or blk_pwrite() but doesn't check the return value, so if the
> underlying file operation fails then the guest will be
> returned garbage data or have its write thrown away without
> either the guest or the user being warned about that.

Green Wan are you able to send a patch to check the error value?

Alistair

>
> > @@ -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, &buf,
> > +                          SIFIVE_U_OTP_FUSE_WORD);
> > +                return buf;
> > +            }
> > +
> >              return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
> >          } else {
> >              return 0xff;
> > @@ -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,
> > +                           &s->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 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,
> > +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > +
> > +        serial_data = ~(s->serial);
> > +        blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> > +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > +    }
> > +
> >      /* Initialize write-once map */
> >      memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
> >  }
> > --
> > 2.28.0
>
> thanks
> -- PMM


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support
  2020-11-03 15:41     ` Alistair Francis
@ 2020-11-04  8:19       ` Green Wan
  0 siblings, 0 replies; 17+ messages in thread
From: Green Wan @ 2020-11-04  8:19 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Bin Meng, Alistair Francis, QEMU Developers

OK, let me do it. I'll send it soon.

On Tue, Nov 3, 2020 at 11:53 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Nov 2, 2020 at 9:49 AM Peter Maydell <peter.maydell@linaro.org> wrote:
> >
> > On Fri, 23 Oct 2020 at 16:27, Alistair Francis <alistair.francis@wdc.com> wrote:
> > >
> > > From: Green Wan <green.wan@sifive.com>
> > >
> > > Add '-drive' support to OTP device. Allow users to assign a raw file
> > > as OTP image.
> >
> > Hi; Coverity reports some issues with this code (CID 1435959,
> > CID 1435960, CID 1435961). They're all basically the same thing:
> > in read, write and reset functions this code calls blk_pread()
> > or blk_pwrite() but doesn't check the return value, so if the
> > underlying file operation fails then the guest will be
> > returned garbage data or have its write thrown away without
> > either the guest or the user being warned about that.
>
> Green Wan are you able to send a patch to check the error value?
>
> Alistair
>
> >
> > > @@ -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, &buf,
> > > +                          SIFIVE_U_OTP_FUSE_WORD);
> > > +                return buf;
> > > +            }
> > > +
> > >              return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
> > >          } else {
> > >              return 0xff;
> > > @@ -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,
> > > +                           &s->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 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,
> > > +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > > +
> > > +        serial_data = ~(s->serial);
> > > +        blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
> > > +                   &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0);
> > > +    }
> > > +
> > >      /* Initialize write-once map */
> > >      memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo));
> > >  }
> > > --
> > > 2.28.0
> >
> > thanks
> > -- PMM


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-11-04  8:20 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-23 15:16 [PULL 00/12] riscv-to-apply queue Alistair Francis
2020-10-23 15:16 ` [PULL 01/12] riscv: Convert interrupt logs to use qemu_log_mask() Alistair Francis
2020-10-23 15:16 ` [PULL 02/12] hw/intc: Move sifive_plic.h to the include directory Alistair Francis
2020-10-23 15:16 ` [PULL 03/12] target/riscv: Fix update of hstatus.SPVP Alistair Francis
2020-10-23 15:16 ` [PULL 04/12] target/riscv: Fix update of hstatus.GVA in riscv_cpu_do_interrupt Alistair Francis
2020-10-23 15:16 ` [PULL 05/12] target/riscv: Fix implementation of HLVX.WU instruction Alistair Francis
2020-10-23 15:16 ` [PULL 06/12] hw/riscv: sifive_u: Allow specifying the CPU Alistair Francis
2020-10-23 15:16 ` [PULL 07/12] hw/riscv: Return the end address of the loaded firmware Alistair Francis
2020-10-23 15:16 ` [PULL 08/12] hw/riscv: Add a riscv_is_32_bit() function Alistair Francis
2020-10-23 15:16 ` [PULL 09/12] hw/riscv: Load the kernel after the firmware Alistair Francis
2020-10-23 15:16 ` [PULL 10/12] target/riscv: raise exception to HS-mode at get_physical_address Alistair Francis
2020-10-23 15:16 ` [PULL 11/12] hw/misc/sifive_u_otp: Add write function and write-once protection Alistair Francis
2020-10-23 15:16 ` [PULL 12/12] hw/misc/sifive_u_otp: Add backend drive support Alistair Francis
2020-11-02 17:49   ` Peter Maydell
2020-11-03 15:41     ` Alistair Francis
2020-11-04  8:19       ` Green Wan
2020-10-26 13:16 ` [PULL 00/12] riscv-to-apply queue Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.