[Qemu-devel] [PATCH 18/28] riscv: hw: Implement a model for SiFive FU540 OTP

2019-08-05 Thread Bin Meng
This implements a simple model for SiFive FU540 OTP (One-Time
Programmable) Memory interface, primarily for reading out the
stored serial number from the first 1 KiB of the 16 KiB OTP
memory reserved by SiFive for internal use.

Signed-off-by: Bin Meng 
---

 hw/riscv/Makefile.objs  |   1 +
 hw/riscv/sifive_u_otp.c | 194 
 include/hw/riscv/sifive_u_otp.h |  90 +++
 3 files changed, 285 insertions(+)
 create mode 100644 hw/riscv/sifive_u_otp.c
 create mode 100644 include/hw/riscv/sifive_u_otp.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index b95bbd5..fc3c6dd 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_otp.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
diff --git a/hw/riscv/sifive_u_otp.c b/hw/riscv/sifive_u_otp.c
new file mode 100644
index 000..f21d9f4
--- /dev/null
+++ b/hw/riscv/sifive_u_otp.c
@@ -0,0 +1,194 @@
+/*
+ * QEMU SiFive U OTP (One-Time Programmable) Memory interface
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the OTP to emulate register reads made by the SDK BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_u_otp.h"
+
+static uint64_t sifive_otp_read(void *opaque, hwaddr addr, unsigned int size)
+{
+SiFiveOTPState *s = opaque;
+
+switch (addr) {
+case SIFIVE_OTP_PA:
+return s->pa;
+case SIFIVE_OTP_PAIO:
+return s->paio;
+case SIFIVE_OTP_PAS:
+return s->pas;
+case SIFIVE_OTP_PCE:
+return s->pce;
+case SIFIVE_OTP_PCLK:
+return s->pclk;
+case SIFIVE_OTP_PDIN:
+return s->pdin;
+case SIFIVE_OTP_PDOUT:
+if ((s->pce & SIFIVE_OTP_PCE_EN) &&
+(s->pdstb & SIFIVE_OTP_PDSTB_EN) &&
+(s->ptrim & SIFIVE_OTP_PTRIM_EN)) {
+return s->fuse[s->pa & SIFIVE_OTP_PA_MASK];
+} else {
+return 0xff;
+}
+case SIFIVE_OTP_PDSTB:
+return s->pdstb;
+case SIFIVE_OTP_PPROG:
+return s->pprog;
+case SIFIVE_OTP_PTC:
+return s->ptc;
+case SIFIVE_OTP_PTM:
+return s->ptm;
+case SIFIVE_OTP_PTM_REP:
+return s->ptm_rep;
+case SIFIVE_OTP_PTR:
+return s->ptr;
+case SIFIVE_OTP_PTRIM:
+return s->ptrim;
+case SIFIVE_OTP_PWE:
+return s->pwe;
+}
+
+hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+return 0;
+}
+
+static void sifive_otp_write(void *opaque, hwaddr addr,
+ uint64_t val64, unsigned int size)
+{
+SiFiveOTPState *s = opaque;
+
+switch (addr) {
+case SIFIVE_OTP_PA:
+s->pa = (uint32_t) val64 & SIFIVE_OTP_PA_MASK;
+break;
+case SIFIVE_OTP_PAIO:
+s->paio = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PAS:
+s->pas = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PCE:
+s->pce = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PCLK:
+s->pclk = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PDIN:
+s->pdin = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PDOUT:
+/* read-only */
+break;
+case SIFIVE_OTP_PDSTB:
+s->pdstb = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PPROG:
+s->pprog = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PTC:
+s->ptc = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PTM:
+s->ptm = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PTM_REP:
+s->ptm_rep = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PTR:
+s->ptr = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PTRIM:
+s->ptrim = (uint32_t) val64;
+break;
+case SIFIVE_OTP_PWE:
+s->pwe = (uint32_t) val64;
+break;
+defa

[Qemu-devel] [PATCH 11/28] riscv: sifive: Rename sifive_prci.{c, h} to sifive_e_prci.{c, h}

2019-08-05 Thread Bin Meng
Current SiFive PRCI model only works with sifive_e machine, as it
only emulates registers or PRCI block in the FE310 SoC.

Rename the file name to make it clear that it is for sifive_e.

Signed-off-by: Bin Meng 
---

 hw/riscv/Makefile.objs  |  2 +-
 hw/riscv/sifive_e.c |  4 ++--
 hw/riscv/{sifive_prci.c => sifive_e_prci.c} | 14 +++---
 include/hw/riscv/{sifive_prci.h => sifive_e_prci.h} | 14 +++---
 4 files changed, 17 insertions(+), 17 deletions(-)
 rename hw/riscv/{sifive_prci.c => sifive_e_prci.c} (90%)
 rename include/hw/riscv/{sifive_prci.h => sifive_e_prci.h} (82%)

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index eb9d4f9..c859697 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -2,9 +2,9 @@ obj-y += boot.o
 obj-$(CONFIG_SPIKE) += riscv_htif.o
 obj-$(CONFIG_HART) += riscv_hart.o
 obj-$(CONFIG_SIFIVE_E) += sifive_e.o
+obj-$(CONFIG_SIFIVE_E) += sifive_e_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_clint.o
 obj-$(CONFIG_SIFIVE) += sifive_gpio.o
-obj-$(CONFIG_SIFIVE) += sifive_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 2a499d8..2d67670 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -41,9 +41,9 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_e.h"
+#include "hw/riscv/sifive_e_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
@@ -174,7 +174,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
 memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
-sifive_prci_create(memmap[SIFIVE_E_PRCI].base);
+sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
 
 /* GPIO */
 
diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_e_prci.c
similarity index 90%
rename from hw/riscv/sifive_prci.c
rename to hw/riscv/sifive_e_prci.c
index f406682..acb914d 100644
--- a/hw/riscv/sifive_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -1,5 +1,5 @@
 /*
- * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt)
+ * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt)
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
@@ -22,7 +22,7 @@
 #include "hw/sysbus.h"
 #include "qemu/module.h"
 #include "target/riscv/cpu.h"
-#include "hw/riscv/sifive_prci.h"
+#include "hw/riscv/sifive_e_prci.h"
 
 static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -82,10 +82,10 @@ static const MemoryRegionOps sifive_prci_ops = {
 
 static void sifive_prci_init(Object *obj)
 {
-SiFivePRCIState *s = SIFIVE_PRCI(obj);
+SiFivePRCIState *s = SIFIVE_E_PRCI(obj);
 
 memory_region_init_io(>mmio, obj, _prci_ops, s,
-  TYPE_SIFIVE_PRCI, 0x8000);
+  TYPE_SIFIVE_E_PRCI, 0x8000);
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
@@ -97,7 +97,7 @@ static void sifive_prci_init(Object *obj)
 }
 
 static const TypeInfo sifive_prci_info = {
-.name  = TYPE_SIFIVE_PRCI,
+.name  = TYPE_SIFIVE_E_PRCI,
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(SiFivePRCIState),
 .instance_init = sifive_prci_init,
@@ -114,9 +114,9 @@ type_init(sifive_prci_register_types)
 /*
  * Create PRCI device.
  */
-DeviceState *sifive_prci_create(hwaddr addr)
+DeviceState *sifive_e_prci_create(hwaddr addr)
 {
-DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_PRCI);
+DeviceState *dev = qdev_create(NULL, TYPE_SIFIVE_E_PRCI);
 qdev_init_nofail(dev);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
 return dev;
diff --git a/include/hw/riscv/sifive_prci.h b/include/hw/riscv/sifive_e_prci.h
similarity index 82%
rename from include/hw/riscv/sifive_prci.h
rename to include/hw/riscv/sifive_e_prci.h
index bd51c4a..7932fe7 100644
--- a/include/hw/riscv/sifive_prci.h
+++ b/include/hw/riscv/sifive_e_prci.h
@@ -1,5 +1,5 @@
 /*
- * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt) interface
+ * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt) interface
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
@@ -16,8 +16,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef HW_SIFIVE_PRCI_H
-#define HW_SIFIVE_PRCI_H
+#ifndef HW_SIFIVE_E_PRCI_H
+#define HW_SIFIVE_E_PRCI_H
 
 enum {
 SIFIVE_PRCI_HFROSCCFG   = 0x0,
@@ -47,10 +47,10 @@ enum {
 SIFIVE_PRCI_PLLOUTDIV_

[Qemu-devel] [PATCH 01/28] riscv: hw: Remove superfluous "linux, phandle" property

2019-08-05 Thread Bin Meng
"linux,phandle" property is optional. Remove all instances in the
sifive_u and virt machine device tree.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 3 ---
 hw/riscv/virt.c | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 71b8083..ef36948 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -125,7 +125,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", cpu_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -184,7 +183,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -197,7 +195,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
 SIFIVE_U_GEM_CLOCK_FREQ);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", ethclk_phandle);
 ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 25faf3b..00be05a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -170,11 +170,9 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", cpu_phandle);
 intc_phandle = phandle++;
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", intc_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", intc_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -250,7 +248,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
-- 
2.7.4




[Qemu-devel] [PATCH 12/28] riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming

2019-08-05 Thread Bin Meng
It should use SIFIVE_PRCI_HFXOSCCFG_RDY and SIFIVE_PRCI_HFXOSCCFG_EN
for hfxosccfg register programming.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_e_prci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_e_prci.c b/hw/riscv/sifive_e_prci.c
index acb914d..c906f11 100644
--- a/hw/riscv/sifive_e_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -89,7 +89,7 @@ static void sifive_prci_init(Object *obj)
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
-s->hfxosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
+s->hfxosccfg = (SIFIVE_PRCI_HFXOSCCFG_RDY | SIFIVE_PRCI_HFXOSCCFG_EN);
 s->pllcfg = (SIFIVE_PRCI_PLLCFG_REFSEL | SIFIVE_PRCI_PLLCFG_BYPASS |
 SIFIVE_PRCI_PLLCFG_LOCK);
 s->plloutdiv = SIFIVE_PRCI_PLLOUTDIV_DIV1;
-- 
2.7.4




Re: [Qemu-devel] [Qemu-riscv] [PATCH 2/2] riscv: sifive_u: Update the plic hart config to support multicore

2019-08-05 Thread Bin Meng
Hi Fabien,

On Tue, Jul 9, 2019 at 12:31 AM Fabien Chouteau  wrote:
>
> Hi Bin,
>
> Thanks for this patch.
>
> I know I am very late to the game but I have a comment here.
>
> On 17/05/2019 17:51, Bin Meng wrote:
> > +/* create PLIC hart topology configuration string */
> > +plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) * 
> > smp_cpus;
> > +plic_hart_config = g_malloc0(plic_hart_config_len);
> > +for (i = 0; i < smp_cpus; i++) {
> > +if (i != 0) {
> > +strncat(plic_hart_config, ",", plic_hart_config_len);
> > +}
> > +strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
> > +plic_hart_config_len);
> > +plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
> > +}
> > +
>
> This will create up to 4 MS PLIC devices. However on the Unleashed FU540 the 
> PLICs are M,MS,MS,MS,MS because of the monitor hart #0.
>
> This means a different memory layout than the real hardware.
>
> For instance address 0x0C00_2080 will be hart #0 S-Mode interrupt enables in 
> QEMU, instead of #1 M-Mode interrupt enables for the real hardware.
>
> To fix this I suggest to change this loop to:
>
> for (i = 0; i < smp_cpus; i++) {
> if (i != 0) {
> strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG,
> plic_hart_config_len);
> } else {
> strncat(plic_hart_config, "M", plic_hart_config_len);
> }
> plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
> }
>
> This will make hart #0 PLIC in M mode and the others in MS.
>
> What do you think?

Thank you for the suggestion. A patch was created for this:
http://patchwork.ozlabs.org/patch/1142282/

Regards,
Bin



[Qemu-devel] [PATCH 04/28] riscv: hart: Extract hart realize to a separate routine

2019-08-05 Thread Bin Meng
Currently riscv_harts_realize() creates all harts based on the
same cpu type given in the hart array property. With current
implementation it can only create symmetric harts. Exact the
hart realize to a separate routine in preparation for supporting
heterogeneous hart arrays.

Signed-off-by: Bin Meng 
---

 hw/riscv/riscv_hart.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index ca69a1b..3dd1c6a 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -37,26 +37,33 @@ static void riscv_harts_cpu_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
+static void riscv_hart_realize(RISCVHartArrayState *s, int hart,
+   char *cpu_type, Error **errp)
+{
+Error *err = NULL;
+
+object_initialize_child(OBJECT(s), "harts[*]", >harts[hart],
+sizeof(RISCVCPU), cpu_type,
+_abort, NULL);
+s->harts[hart].env.mhartid = hart;
+qemu_register_reset(riscv_harts_cpu_reset, >harts[hart]);
+object_property_set_bool(OBJECT(>harts[hart]), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+}
+
 static void riscv_harts_realize(DeviceState *dev, Error **errp)
 {
 RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
-Error *err = NULL;
 int n;
 
 s->harts = g_new0(RISCVCPU, s->num_harts);
 
 for (n = 0; n < s->num_harts; n++) {
-object_initialize_child(OBJECT(s), "harts[*]", >harts[n],
-sizeof(RISCVCPU), s->cpu_type,
-_abort, NULL);
-s->harts[n].env.mhartid = n;
-qemu_register_reset(riscv_harts_cpu_reset, >harts[n]);
-object_property_set_bool(OBJECT(>harts[n]), true,
- "realized", );
-if (err) {
-error_propagate(errp, err);
-return;
-}
+riscv_hart_realize(s, n, s->cpu_type, errp);
 }
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH 07/28] riscv: sifive_u: Set the minimum number of cpus to 2

2019-08-05 Thread Bin Meng
It is not useful if we only have one management CPU.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 08d406f..206eccc 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -428,6 +428,8 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
  * management CPU.
  */
 mc->max_cpus = 5;
+/* It is not useful if we only have one management CPU */
+mc->min_cpus = 2;
 }
 
 DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
-- 
2.7.4




[Qemu-devel] [PATCH 09/28] riscv: sifive_u: Update UART base addresses

2019-08-05 Thread Bin Meng
This updates the UART base address to match the hardware.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index b235f29..9f05e09 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -60,8 +60,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_MROM] = { 0x1000,0x11000 },
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
-[SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
-[SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
+[SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
+[SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
 };
-- 
2.7.4




[Qemu-devel] [PATCH 17/28] riscv: sifive_u: Change UART node name in device tree

2019-08-05 Thread Bin Meng
OpenSBI for fu540 does DT fix up (see fu540_modify_dt()) by updating
chosen "stdout-path" to point to "/soc/serial@...", and U-Boot will
use this information to locate the serial node and probe its driver.
However currently we generate the UART node name as "/soc/uart@...",
causing U-Boot fail to find the serial node in DT.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 20dee52..8044166 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -273,7 +273,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
-nodename = g_strdup_printf("/soc/uart@%lx",
+nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
-- 
2.7.4




[Qemu-devel] [PATCH 26/28] riscv: hw: Update PLIC device tree

2019-08-05 Thread Bin Meng
This removes "reg-names" and "riscv,max-priority" properties of the
PLIC node from device tree, and updates its compatible string, to
keep in sync with the Linux kernel device tree.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 4 +---
 hw/riscv/virt.c | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index d77b3c3..5ded3a0 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -229,15 +229,13 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 (long)memmap[SIFIVE_U_PLIC].base);
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 1);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,plic-1.0.0");
 qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
 cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_PLIC].base,
 0x0, memmap[SIFIVE_U_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 127f005..f662100 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -237,15 +237,13 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
   FDT_PLIC_ADDR_CELLS);
 qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
   FDT_PLIC_INT_CELLS);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,plic-1.0.0");
 qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
 cells, s->soc.num_harts * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[VIRT_PLIC].base,
 0x0, memmap[VIRT_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
-- 
2.7.4




[Qemu-devel] [PATCH 27/28] riscv: virt: Change create_fdt() to return void

2019-08-05 Thread Bin Meng
There is no need to return fdt at the end of create_fdt() because
it's already saved in s->fdt. Other machines (sifive_u, spike)
don't do it neither.

Signed-off-by: Bin Meng 
---

 hw/riscv/virt.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index f662100..5935ac8 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -112,7 +112,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
0x1800, 0, 0, 0x7);
 }
 
-static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -316,8 +316,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 g_free(nodename);
-
-return fdt;
 }
 
 
@@ -373,7 +371,6 @@ static void riscv_virt_board_init(MachineState *machine)
 size_t plic_hart_config_len;
 int i;
 unsigned int smp_cpus = machine->smp.cpus;
-void *fdt;
 
 /* Initialize SOC */
 object_initialize_child(OBJECT(machine), "soc", >soc, sizeof(s->soc),
@@ -392,7 +389,7 @@ static void riscv_virt_board_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
 memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
@@ -411,9 +408,9 @@ static void riscv_virt_board_init(MachineState *machine)
 hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
);
-qemu_fdt_setprop_cell(fdt, "/chosen",
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
   "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH] hw: net: cadence_gem: Fix build errors in DB_PRINT()

2019-08-05 Thread Bin Meng
When CADENCE_GEM_ERR_DEBUG is turned on, there are several
compilation errors in DB_PRINT(). Fix them.

Signed-off-by: Bin Meng 
---

 hw/net/cadence_gem.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index d412085..7516e8f 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -983,8 +983,9 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 return -1;
 }
 
-DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
-rx_desc_get_buffer(s->rx_desc[q]));
+DB_PRINT("copy %d bytes to " TARGET_FMT_plx "\n",
+ MIN(bytes_to_copy, rxbufsize),
+ rx_desc_get_buffer(s, s->rx_desc[q]));
 
 /* Copy packet data to emulated DMA buffer */
 address_space_write(>dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) +
@@ -1157,7 +1158,7 @@ static void gem_transmit(CadenceGEMState *s)
 if (tx_desc_get_length(desc) > sizeof(tx_packet) -
(p - tx_packet)) {
 DB_PRINT("TX descriptor @ 0x%x too large: size 0x%x space " \
- "0x%x\n", (unsigned)packet_desc_addr,
+ "0x%lx\n", (unsigned)packet_desc_addr,
  (unsigned)tx_desc_get_length(desc),
  sizeof(tx_packet) - (p - tx_packet));
 break;
-- 
2.7.4




[Qemu-devel] [PATCH 00/28] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine

2019-08-05 Thread Bin Meng
As of today, the QEMU 'sifive_u' machine is a special target that does
not boot the upstream OpenSBI/U-Boot firmware images built for the real
SiFive HiFive Unleashed board. Hence OpenSBI supports a special platform
"qemu/sifive_u". For U-Boot, the sifive_fu540_defconfig is referenced
in the OpenSBI doc as its payload, but that does not boot at all due
to various issues in current QEMU 'sifive_u' machine codes.

This series aims to improve the emulation fidelity of sifive_u machine,
so that the upstream OpenSBI, U-Boot and kernel images built for the
SiFive HiFive Unleashed board can be used out of the box without any
special hack.

The major changes are:
- Heterogeneous harts creation supported, so that we can create a CPU
  that exactly mirrors the real hardware: 1 E51 + 4 U54.
- Implemented a PRCI model for FU540
- Implemented an OTP model for FU540, primarily used for storing serial
  number of the board
- Fixed GEM support that was seriously broken on sifive_u
- Synced device tree with upstream Linux kernel on sifive_u
- Adding initramfs loading support on sifive_u

OpenSBI v0.4 image built for sifive/fu540 is included as the default
bios image for 'sifive_u' machine.

The series is tested against OpenSBI v0.4 image for sifive/fu540
paltform, U-Boot v2019.10-rc1 image for sifive_fu540_defconfig,
and Linux kernel v5.3-rc3 image with the following patch:

macb: Update compatibility string for SiFive FU540-C000
https://patchwork.kernel.org/patch/11050003/

OpenSBI + U-Boot, ping/tftpboot with U-Boot MACB driver works well.
For Linux, only checked boot log of MACB probe success without error.


Bin Meng (28):
  riscv: hw: Remove superfluous "linux,phandle" property
  riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell
  riscv: Add a sifive_cpu.h to include both E and U cpu type defines
  riscv: hart: Extract hart realize to a separate routine
  riscv: hart: Support heterogeneous harts population
  riscv: sifive_u: Update hart configuration to reflect the real FU540
SoC
  riscv: sifive_u: Set the minimum number of cpus to 2
  riscv: sifive_u: Update PLIC hart topology configuration string
  riscv: sifive_u: Update UART base addresses
  riscv: sifive_u: Remove the unnecessary include of prci header
  riscv: sifive: Rename sifive_prci.{c,h} to sifive_e_prci.{c,h}
  riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming
  riscv: sifive_e: prci: Update the PRCI register block size
  riscv: sifive: Implement PRCI model for FU540
  riscv: sifive_u: Generate hfclk and rtcclk nodes
  riscv: sifive_u: Add PRCI block to the SoC
  riscv: sifive_u: Change UART node name in device tree
  riscv: hw: Implement a model for SiFive FU540 OTP
  riscv: sifive_u: Instantiate OTP memory with a serial number
  riscv: roms: Update default bios for sifive_u machine
  riscv: sifive_u: Update UART and ethernet node clock properties
  riscv: sifive_u: Generate an aliases node in the device tree
  riscv: sifive: Move sifive_mmio_emulate() to a common place
  riscv: sifive_u: Fix broken GEM support
  riscv: sifive_u: Support loading initramfs
  riscv: hw: Update PLIC device tree
  riscv: virt: Change create_fdt() to return void
  riscv: sifive_u: Update model and compatible strings in device tree

 hw/riscv/Makefile.objs |   4 +-
 hw/riscv/riscv_hart.c  |  75 ++--
 hw/riscv/sifive_e.c|  12 +-
 hw/riscv/{sifive_prci.c => sifive_e_prci.c}|  16 +-
 hw/riscv/sifive_u.c| 181 +--
 hw/riscv/sifive_u_otp.c| 194 +
 hw/riscv/sifive_u_prci.c   | 163 +
 hw/riscv/virt.c|  42 ++---
 include/hw/riscv/sifive_cpu.h  |  39 +
 include/hw/riscv/sifive_e.h|   7 +-
 .../hw/riscv/{sifive_prci.h => sifive_e_prci.h}|  16 +-
 include/hw/riscv/sifive_u.h|  15 +-
 include/hw/riscv/sifive_u_otp.h|  90 ++
 include/hw/riscv/sifive_u_prci.h   | 100 +++
 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin   | Bin 40968 -> 45064 bytes
 roms/Makefile  |   4 +-
 16 files changed, 824 insertions(+), 134 deletions(-)
 rename hw/riscv/{sifive_prci.c => sifive_e_prci.c} (88%)
 create mode 100644 hw/riscv/sifive_u_otp.c
 create mode 100644 hw/riscv/sifive_u_prci.c
 create mode 100644 include/hw/riscv/sifive_cpu.h
 rename include/hw/riscv/{sifive_prci.h => sifive_e_prci.h} (80%)
 create mode 100644 include/hw/riscv/sifive_u_otp.h
 create mode 100644 include/hw/riscv/sifive_u_prci.h

-- 
2.7.4




Re: [Qemu-devel] [Qemu-riscv] [PATCH 2/2] riscv: sifive_u: Update the plic hart config to support multicore

2019-08-05 Thread Bin Meng
Hi Alistair,

On Tue, Jul 16, 2019 at 5:33 AM Alistair Francis  wrote:
>
> On Sat, Jul 13, 2019 at 8:23 PM Bin Meng  wrote:
> >
> > Hi Fabien,
> >
> > On Tue, Jul 9, 2019 at 12:31 AM Fabien Chouteau  
> > wrote:
> > >
> > > Hi Bin,
> > >
> > > Thanks for this patch.
> > >
> > > I know I am very late to the game but I have a comment here.
> > >
> > > On 17/05/2019 17:51, Bin Meng wrote:
> > > > +/* create PLIC hart topology configuration string */
> > > > +plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) * 
> > > > smp_cpus;
> > > > +plic_hart_config = g_malloc0(plic_hart_config_len);
> > > > +for (i = 0; i < smp_cpus; i++) {
> > > > +if (i != 0) {
> > > > +strncat(plic_hart_config, ",", plic_hart_config_len);
> > > > +}
> > > > +strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
> > > > +plic_hart_config_len);
> > > > +plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 
> > > > 1);
> > > > +}
> > > > +
> > >
> > > This will create up to 4 MS PLIC devices. However on the Unleashed FU540 
> > > the PLICs are M,MS,MS,MS,MS because of the monitor hart #0.
> > >
> > > This means a different memory layout than the real hardware.
> > >
> > > For instance address 0x0C00_2080 will be hart #0 S-Mode interrupt enables 
> > > in QEMU, instead of #1 M-Mode interrupt enables for the real hardware.
> >
> > Thanks for the notes! I agree to better match the real hardware, it
> > should be modeled like that. However I am not sure what the original
> > intention was when creating the "sifive_u" machine. Both OpenSBI and
> > U-Boot list sifive_u as a special target, instead of the real
> > Unleashed board hence I assume this is a hypothetical target too, like
> > the "virt", but was created to best match the real Unleashed board
> > though.
>
> I thought (Palmer correct me if I'm wrong) that the sifive_u machine
> *should* match the hardware. The problem is that QEMU doesn't support
> everything that the HW supports which is why U-Boot and OpenSBI have
> their own targets. The goal is to not require special QEMU targets, so
> this is a step in the right direction.
>

I've sent a series that improves the emulation fidelity of sifive_u
machine, so that the upstream OpenSBI, U-Boot and kernel images built
for the SiFive HiFive Unleashed board can be used out of the box
without any special hack.

Please have a look.
http://patchwork.ozlabs.org/project/qemu-devel/list/?series=123386

Regards,
Bin



[Qemu-devel] [PATCH 24/28] riscv: sifive_u: Fix broken GEM support

2019-08-05 Thread Bin Meng
At present the GEM support in sifive_u machine is seriously broken.

- The GEM block register base was set to a weird number (0x100900FC),
  which for no way could work with the cadence_gem model in QEMU.
- The generated DT node for GEM has a "clocks-names" which is an
  invalid property name.

Not like other GEM variants, the FU540-specific GEM has a management
block to control 10/100/1000Mbps link speed changes, that is mapped
to 0x100a. We can simply map it into MMIO space without special
handling using sifive_mmio_emulate().

Update the GEM node compatible string to use the official name used
by the upstream Linux kernel, and add the management block reg base
& size to the  property encoding.

Tested with upstream U-Boot and Linux kernel MACB drivers.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 17 +
 include/hw/riscv/sifive_u.h |  3 ++-
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9945b82..85cd4b5 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
  * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
  *
  * Provides a board compatible with the SiFive Freedom U SDK:
  *
@@ -11,6 +12,7 @@
  * 2) PLIC (Platform Level Interrupt Controller)
  * 3) PRCI (Power, Reset, Clock, Interrupt)
  * 4) OTP (One-Time Programmable) memory with stored serial number
+ * 5) GEM (Gigabit Ethernet Controller) and management block
  *
  * This board currently uses a hardcoded devicetree that indicates five harts.
  *
@@ -68,7 +70,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
-[SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
+[SIFIVE_U_GEM] =  { 0x1009, 0x2000 },
+[SIFIVE_U_GEM_MGMT] = { 0x100a, 0x1000 },
 };
 
 #define SIFIVE_OTP_SERIAL   1
@@ -244,17 +247,20 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "cdns,macb");
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-gem");
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_GEM].base,
-0x0, memmap[SIFIVE_U_GEM].size);
+0x0, memmap[SIFIVE_U_GEM].size,
+0x0, memmap[SIFIVE_U_GEM_MGMT].base,
+0x0, memmap[SIFIVE_U_GEM_MGMT].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
 prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
-qemu_fdt_setprop(fdt, nodename, "clocks-names", ethclk_names,
+qemu_fdt_setprop(fdt, nodename, "clock-names", ethclk_names,
 sizeof(ethclk_names));
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
 qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
@@ -455,6 +461,9 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>gem), 0, memmap[SIFIVE_U_GEM].base);
 sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
plic_gpios[SIFIVE_U_GEM_IRQ]);
+
+sifive_mmio_emulate(system_memory, "riscv.sifive.u.gem-mgmt",
+memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 0461331..e92f1aa 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -56,7 +56,8 @@ enum {
 SIFIVE_U_UART1,
 SIFIVE_U_OTP,
 SIFIVE_U_DRAM,
-SIFIVE_U_GEM
+SIFIVE_U_GEM,
+SIFIVE_U_GEM_MGMT
 };
 
 enum {
-- 
2.7.4




[Qemu-devel] [PATCH 10/28] riscv: sifive_u: Remove the unnecessary include of prci header

2019-08-05 Thread Bin Meng
sifive_u machine does not use PRCI as of today. Remove the prci
header inclusion.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9f05e09..dfcb525 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -40,7 +40,6 @@
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_u.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
-- 
2.7.4




[Qemu-devel] [PATCH 22/28] riscv: sifive_u: Generate an aliases node in the device tree

2019-08-05 Thread Bin Meng
The Linux kernel SiFive UART driver expects an aliases node to be
present in the device tree, from which the driver extracts the port
number from "serial#" in the aliases node.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 061d6d4..9945b82 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -283,6 +283,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 if (cmdline) {
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
+qemu_fdt_add_subnode(fdt, "/aliases");
+qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 g_free(nodename);
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH 08/28] riscv: sifive_u: Update PLIC hart topology configuration string

2019-08-05 Thread Bin Meng
With heterogeneous harts config, the PLIC hart topology configuration
string are "M,MS,.." because of the monitor hart #0.

Suggested-by: Fabien Chouteau 
Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 206eccc..b235f29 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -372,10 +372,11 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 plic_hart_config = g_malloc0(plic_hart_config_len);
 for (i = 0; i < ms->smp.cpus; i++) {
 if (i != 0) {
-strncat(plic_hart_config, ",", plic_hart_config_len);
+strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG,
+plic_hart_config_len);
+} else {
+strncat(plic_hart_config, "M", plic_hart_config_len);
 }
-strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
-plic_hart_config_len);
 plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH 02/28] riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell

2019-08-05 Thread Bin Meng
Some of the properties only have 1 cell so we should use
qemu_fdt_setprop_cell() instead of qemu_fdt_setprop_cells().

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 16 
 hw/riscv/virt.c | 24 
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ef36948..623ee64 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -182,7 +182,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -207,20 +207,20 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_GEM].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
 ethclk_phandle, ethclk_phandle, ethclk_phandle);
 qemu_fdt_setprop(fdt, nodename, "clocks-names", ethclk_names,
 sizeof(ethclk_names));
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 1);
-qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
+qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/uart@%lx",
@@ -232,8 +232,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_UART0].size);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
   SIFIVE_U_CLOCK_FREQ / 2);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 00be05a..127f005 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -233,8 +233,8 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
 (long)memmap[VIRT_PLIC].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells",
-   FDT_PLIC_ADDR_CELLS);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells",
+  FDT_PLIC_ADDR_CELLS);
 qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
   FDT_PLIC_INT_CELLS);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
@@ -247,7 +247,7 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -260,19 +260,19 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 

[Qemu-devel] [PATCH 06/28] riscv: sifive_u: Update hart configuration to reflect the real FU540 SoC

2019-08-05 Thread Bin Meng
The FU540-C000 includes a 64-bit E51 RISC-V core and four 64-bit U54
RISC-V cores. Currently the sifive_u machine only populates 4 U54
cores. Update the max cpu number to 5 to reflect the real hardware,
and pass "cpu-type" to populate heterogeneous harts.

The cpu nodes in the generated DTS have been updated as well.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 37 +++--
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 623ee64..08d406f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,7 +10,7 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  *
- * This board currently uses a hardcoded devicetree that indicates one hart.
+ * This board currently uses a hardcoded devicetree that indicates five harts.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -26,6 +26,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
@@ -117,7 +118,10 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
   SIFIVE_U_CLOCK_FREQ);
-qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+/* cpu 0 is the management hart that does not have mmu */
+if (cpu != 0) {
+qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+}
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
 qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
@@ -157,15 +161,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 
 plic_phandle = phandle++;
-cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
+cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4 - 2);
 for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
-cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
-cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
+/* cpu 0 is the management hart that does not have S-mode */
+if (cpu == 0) {
+cells[0] = cpu_to_be32(intc_phandle);
+cells[1] = cpu_to_be32(IRQ_M_EXT);
+} else {
+cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle);
+cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT);
+cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
+cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT);
+}
 g_free(nodename);
 }
 nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
@@ -315,10 +325,16 @@ static void riscv_sifive_u_soc_init(Object *obj)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
 SiFiveUSoCState *s = RISCV_U_SOC(obj);
+char cpu_type[64];
+
+/* create cpu type representing SiFive FU540 SoC */
+pstrcpy(cpu_type, sizeof(cpu_type), SIFIVE_E_CPU);
+pstrcat(cpu_type, sizeof(cpu_type), ",");
+pstrcat(cpu_type, sizeof(cpu_type), SIFIVE_U_CPU);
 
 object_initialize_child(obj, "cpus", >cpus, sizeof(s->cpus),
 TYPE_RISCV_HART_ARRAY, _abort, NULL);
-object_property_set_str(OBJECT(>cpus), SIFIVE_U_CPU, "cpu-type",
+object_property_set_str(OBJECT(>cpus), cpu_type, "cpu-type",
 _abort);
 object_property_set_int(OBJECT(>cpus), ms->smp.cpus, "num-harts",
 _abort);
@@ -407,10 +423,11 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
 {
 mc->desc = "RISC-V Board compatible with SiFive U SDK";
 mc->init = riscv_sifive_u_init;
-/* The real hardware has 5 CPUs, but one of them is a small embedded power
+/*
+ * The real hardware has 5 CPUs, but one of them is a small embedded power
  * management CPU.
  */
-mc->max_cpus = 4;
+mc->max_cpus = 5;
 }
 
 DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
-- 
2.7.4




[Qemu-devel] [PATCH 21/28] riscv: sifive_u: Update UART and ethernet node clock properties

2019-08-05 Thread Bin Meng
Now that we have added PRCI nodes, update existing UART and ethernet
nodes to use PRCI as their clock sources, to keep in sync with the
Linux kernel device tree.

With above changes, the previously handcrafted "/soc/ethclk" node is
no longer needed. Remove it.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c  | 21 +
 include/hw/riscv/sifive_u.h  |  3 +--
 include/hw/riscv/sifive_u_prci.h | 10 ++
 3 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index b90aa53..061d6d4 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -81,8 +81,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 int cpu;
 uint32_t *cells;
 char *nodename;
-char ethclk_names[] = "pclk\0hclk\0tx_clk";
-uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
+char ethclk_names[] = "pclk\0hclk";
+uint32_t plic_phandle, prci_phandle, phandle = 1;
 uint32_t hfclk_phandle, rtcclk_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
@@ -241,17 +241,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
-ethclk_phandle = phandle++;
-nodename = g_strdup_printf("/soc/ethclk");
-qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
-qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-SIFIVE_U_GEM_CLOCK_FREQ);
-qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
-g_free(nodename);
-
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
@@ -264,7 +253,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
-ethclk_phandle, ethclk_phandle, ethclk_phandle);
+prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
 qemu_fdt_setprop(fdt, nodename, "clocks-names", ethclk_names,
 sizeof(ethclk_names));
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
@@ -284,8 +273,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_UART0].base,
 0x0, memmap[SIFIVE_U_UART0].size);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-  SIFIVE_U_CLOCK_FREQ / 2);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+prci_phandle, PRCI_CLK_TLCLK);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 2f475c5..0461331 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -68,8 +68,7 @@ enum {
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
 SIFIVE_U_HFCLK_FREQ = ,
-SIFIVE_U_RTCCLK_FREQ = 100,
-SIFIVE_U_GEM_CLOCK_FREQ = 12500
+SIFIVE_U_RTCCLK_FREQ = 100
 };
 
 #define SIFIVE_U_PLIC_HART_CONFIG "MS"
diff --git a/include/hw/riscv/sifive_u_prci.h b/include/hw/riscv/sifive_u_prci.h
index f3a4656..640c641 100644
--- a/include/hw/riscv/sifive_u_prci.h
+++ b/include/hw/riscv/sifive_u_prci.h
@@ -87,4 +87,14 @@ typedef struct SiFivePRCIState {
 
 DeviceState *sifive_u_prci_create(hwaddr addr);
 
+/*
+ * Clock indexes for use by Device Tree data and the PRCI driver.
+ *
+ * These values are from sifive-fu540-prci.h in the Linux kernel.
+ */
+#define PRCI_CLK_COREPLL0
+#define PRCI_CLK_DDRPLL 1
+#define PRCI_CLK_GEMGXLPLL  2
+#define PRCI_CLK_TLCLK  3
+
 #endif /* HW_SIFIVE_U_PRCI_H */
-- 
2.7.4




[Qemu-devel] [PATCH 25/28] riscv: sifive_u: Support loading initramfs

2019-08-05 Thread Bin Meng
The loading of initramfs is currently not supported on 'sifive_u'.
Add the support to make '-initrd' command line parameter useful.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 85cd4b5..d77b3c3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -323,7 +323,18 @@ static void riscv_sifive_u_init(MachineState *machine)
  memmap[SIFIVE_U_DRAM].base);
 
 if (machine->kernel_filename) {
-riscv_load_kernel(machine->kernel_filename);
+uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename);
+
+if (machine->initrd_filename) {
+hwaddr start;
+hwaddr end = riscv_load_initrd(machine->initrd_filename,
+   machine->ram_size, kernel_entry,
+   );
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
+  "linux,initrd-start", start);
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
+  end);
+}
 }
 
 /* reset vector */
-- 
2.7.4




[Qemu-devel] [PATCH 14/28] riscv: sifive: Implement PRCI model for FU540

2019-08-05 Thread Bin Meng
This adds a simple PRCI model for FU540 (sifive_u). It has different
register layout from the existing PRCI model for FE310 (sifive_e).

Signed-off-by: Bin Meng 
---

 hw/riscv/Makefile.objs   |   1 +
 hw/riscv/sifive_u_prci.c | 163 +++
 include/hw/riscv/sifive_u_prci.h |  90 +
 3 files changed, 254 insertions(+)
 create mode 100644 hw/riscv/sifive_u_prci.c
 create mode 100644 include/hw/riscv/sifive_u_prci.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index c859697..b95bbd5 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
 obj-$(CONFIG_RISCV_VIRT) += virt.o
diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c
new file mode 100644
index 000..35e5962
--- /dev/null
+++ b/hw/riscv/sifive_u_prci.c
@@ -0,0 +1,163 @@
+/*
+ * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt)
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the PRCI to emulate register reads made by the SDK BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_u_prci.h"
+
+static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
+{
+SiFivePRCIState *s = opaque;
+
+switch (addr) {
+case SIFIVE_PRCI_HFXOSCCFG:
+return s->hfxosccfg;
+case SIFIVE_PRCI_COREPLLCFG0:
+return s->corepllcfg0;
+case SIFIVE_PRCI_DDRPLLCFG0:
+return s->ddrpllcfg0;
+case SIFIVE_PRCI_DDRPLLCFG1:
+return s->ddrpllcfg1;
+case SIFIVE_PRCI_GEMGXLPLLCFG0:
+return s->gemgxlpllcfg0;
+case SIFIVE_PRCI_GEMGXLPLLCFG1:
+return s->gemgxlpllcfg1;
+case SIFIVE_PRCI_CORECLKSEL:
+return s->coreclksel;
+case SIFIVE_PRCI_DEVICESRESET:
+return s->devicesreset;
+case SIFIVE_PRCI_CLKMUXSTATUS:
+return s->clkmuxstatus;
+}
+
+hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+return 0;
+}
+
+static void sifive_prci_write(void *opaque, hwaddr addr,
+  uint64_t val64, unsigned int size)
+{
+SiFivePRCIState *s = opaque;
+
+switch (addr) {
+case SIFIVE_PRCI_HFXOSCCFG:
+s->hfxosccfg = (uint32_t) val64;
+/* OSC stays ready */
+s->hfxosccfg |= SIFIVE_PRCI_HFXOSCCFG_RDY;
+break;
+case SIFIVE_PRCI_COREPLLCFG0:
+s->corepllcfg0 = (uint32_t) val64;
+/* internal feedback */
+s->corepllcfg0 |= SIFIVE_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->corepllcfg0 |= SIFIVE_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_PRCI_DDRPLLCFG0:
+s->ddrpllcfg0 = (uint32_t) val64;
+/* internal feedback */
+s->ddrpllcfg0 |= SIFIVE_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->ddrpllcfg0 |= SIFIVE_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_PRCI_DDRPLLCFG1:
+s->ddrpllcfg1 = (uint32_t) val64;
+break;
+case SIFIVE_PRCI_GEMGXLPLLCFG0:
+s->gemgxlpllcfg0 = (uint32_t) val64;
+ /* internal feedback */
+s->gemgxlpllcfg0 |= SIFIVE_PRCI_PLLCFG0_FSE;
+   /* PLL stays locked */
+s->gemgxlpllcfg0 |= SIFIVE_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_PRCI_GEMGXLPLLCFG1:
+s->gemgxlpllcfg1 = (uint32_t) val64;
+break;
+case SIFIVE_PRCI_CORECLKSEL:
+s->coreclksel = (uint32_t) val64;
+break;
+case SIFIVE_PRCI_DEVICESRESET:
+s->devicesreset = (uint32_t) val64;
+break;
+case SIFIVE_PRCI_CLKMUXSTATUS:
+s->clkmuxstatus = (uint32_t) val64;
+break;
+default:
+hw_error("%s: bad write: addr=0x%x v=0x%x\n",
+ __func__, (int)addr, (int)val64);
+}
+}
+
+static const MemoryRegionOps sifive_prci_ops = {
+.read = sifive_prci_read,
+.write = sifive_prci_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.va

[Qemu-devel] [PATCH 28/28] riscv: sifive_u: Update model and compatible strings in device tree

2019-08-05 Thread Bin Meng
This updates model and compatible strings to use the same strings
as used in the Linux kernel device tree (hifive-unleashed-a00.dts).

Signed-off-by: Bin Meng 

---

 hw/riscv/sifive_u.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5ded3a0..b7d4b4f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -94,8 +94,9 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 exit(1);
 }
 
-qemu_fdt_setprop_string(fdt, "/", "model", "ucbbar,spike-bare,qemu");
-qemu_fdt_setprop_string(fdt, "/", "compatible", "ucbbar,spike-bare-dev");
+qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
+qemu_fdt_setprop_string(fdt, "/", "compatible",
+"sifive,hifive-unleashed-a00");
 qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
 
-- 
2.7.4




[Qemu-devel] [PATCH 03/28] riscv: Add a sifive_cpu.h to include both E and U cpu type defines

2019-08-05 Thread Bin Meng
Group SiFive E and U cpu type defines into one header file.

Signed-off-by: Bin Meng 
---

 include/hw/riscv/sifive_cpu.h | 31 +++
 include/hw/riscv/sifive_e.h   |  7 +--
 include/hw/riscv/sifive_u.h   |  7 +--
 3 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/riscv/sifive_cpu.h

diff --git a/include/hw/riscv/sifive_cpu.h b/include/hw/riscv/sifive_cpu.h
new file mode 100644
index 000..1367996
--- /dev/null
+++ b/include/hw/riscv/sifive_cpu.h
@@ -0,0 +1,31 @@
+/*
+ * SiFive CPU types
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_SIFIVE_CPU_H
+#define HW_SIFIVE_CPU_H
+
+#if defined(TARGET_RISCV32)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
+#elif defined(TARGET_RISCV64)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
+#endif
+
+#endif /* HW_SIFIVE_CPU_H */
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index d175b24..e17cdfd 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -19,6 +19,7 @@
 #ifndef HW_SIFIVE_E_H
 #define HW_SIFIVE_E_H
 
+#include "hw/riscv/sifive_cpu.h"
 #include "hw/riscv/sifive_gpio.h"
 
 #define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
@@ -83,10 +84,4 @@ enum {
 #define SIFIVE_E_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_E_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
-#endif
-
 #endif
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 892f0ee..4abc621 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -20,6 +20,7 @@
 #define HW_SIFIVE_U_H
 
 #include "hw/net/cadence_gem.h"
+#include "hw/riscv/sifive_cpu.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -77,10 +78,4 @@ enum {
 #define SIFIVE_U_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_U_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
-#endif
-
 #endif
-- 
2.7.4




[Qemu-devel] [PATCH 15/28] riscv: sifive_u: Generate hfclk and rtcclk nodes

2019-08-05 Thread Bin Meng
To keep in sync with Linux kernel device tree, generate hfclk and
rtcclk nodes in the device tree, to be referenced by PRCI node.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 23 +++
 include/hw/riscv/sifive_u.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index dfcb525..f619ca6 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -76,6 +76,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char *nodename;
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
 uint32_t plic_phandle, ethclk_phandle, phandle = 1;
+uint32_t hfclk_phandle, rtcclk_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
 if (!fdt) {
@@ -94,6 +95,28 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
 
+hfclk_phandle = phandle++;
+nodename = g_strdup_printf("/hfclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", hfclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "hfclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_HFCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
+rtcclk_phandle = phandle++;
+nodename = g_strdup_printf("/rtcclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", rtcclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "rtcclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_RTCCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/memory@%lx",
 (long)memmap[SIFIVE_U_DRAM].base);
 qemu_fdt_add_subnode(fdt, nodename);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 4abc621..bacd60f 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -65,6 +65,8 @@ enum {
 
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
+SIFIVE_U_HFCLK_FREQ = ,
+SIFIVE_U_RTCCLK_FREQ = 100,
 SIFIVE_U_GEM_CLOCK_FREQ = 12500
 };
 
-- 
2.7.4




[Qemu-devel] [PATCH 23/28] riscv: sifive: Move sifive_mmio_emulate() to a common place

2019-08-05 Thread Bin Meng
sifive_mmio_emulate() is currently only used in the sifive_e machine
codes. It can be helpful for other machines as well.

Change it to an inline routine and move it to sifive_cpu.h, so that
other machines like sifive_u can use it.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_e.c   |  8 
 include/hw/riscv/sifive_cpu.h | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 2d67670..7e0fe7b 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -74,14 +74,6 @@ static const struct MemmapEntry {
 [SIFIVE_E_DTIM] = { 0x8000, 0x4000 }
 };
 
-static void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
- uintptr_t offset, uintptr_t length)
-{
-MemoryRegion *mock_mmio = g_new(MemoryRegion, 1);
-memory_region_init_ram(mock_mmio, NULL, name, length, _fatal);
-memory_region_add_subregion(parent, offset, mock_mmio);
-}
-
 static void riscv_sifive_e_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_e_memmap;
diff --git a/include/hw/riscv/sifive_cpu.h b/include/hw/riscv/sifive_cpu.h
index 1367996..897b8f8 100644
--- a/include/hw/riscv/sifive_cpu.h
+++ b/include/hw/riscv/sifive_cpu.h
@@ -1,5 +1,5 @@
 /*
- * SiFive CPU types
+ * SiFive CPU types and common utilities
  *
  * Copyright (c) 2017 SiFive, Inc.
  * Copyright (c) 2019 Bin Meng 
@@ -28,4 +28,12 @@
 #define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
 #endif
 
+static inline void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
+   uintptr_t offset, uintptr_t length)
+{
+MemoryRegion *mock_mmio = g_new(MemoryRegion, 1);
+memory_region_init_ram(mock_mmio, NULL, name, length, _fatal);
+memory_region_add_subregion(parent, offset, mock_mmio);
+}
+
 #endif /* HW_SIFIVE_CPU_H */
-- 
2.7.4




[Qemu-devel] [PATCH 16/28] riscv: sifive_u: Add PRCI block to the SoC

2019-08-05 Thread Bin Meng
Add PRCI mmio base address and size mappings to sifive_u machine,
and generate the corresponding device tree node.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 21 -
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index f619ca6..20dee52 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -9,6 +9,7 @@
  * 0) UART
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
+ * 3) PRCI (Power, Reset, Clock, Interrupt)
  *
  * This board currently uses a hardcoded devicetree that indicates five harts.
  *
@@ -41,6 +42,7 @@
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_u.h"
+#include "hw/riscv/sifive_u_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
@@ -59,6 +61,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_MROM] = { 0x1000,0x11000 },
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
+[SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
@@ -75,7 +78,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uint32_t *cells;
 char *nodename;
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
-uint32_t plic_phandle, ethclk_phandle, phandle = 1;
+uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t hfclk_phandle, rtcclk_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
@@ -182,6 +185,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
+prci_phandle = phandle++;
+nodename = g_strdup_printf("/soc/clock-controller@%lx",
+(long)memmap[SIFIVE_U_PRCI].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", prci_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x1);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+hfclk_phandle, rtcclk_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_PRCI].base,
+0x0, memmap[SIFIVE_U_PRCI].size);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-prci");
+g_free(nodename);
+
 plic_phandle = phandle++;
 cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4 - 2);
 for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
@@ -421,6 +439,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
 memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
+sifive_u_prci_create(memmap[SIFIVE_U_PRCI].base);
 
 for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
 plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index bacd60f..19d5a6f 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -51,6 +51,7 @@ enum {
 SIFIVE_U_MROM,
 SIFIVE_U_CLINT,
 SIFIVE_U_PLIC,
+SIFIVE_U_PRCI,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
 SIFIVE_U_DRAM,
-- 
2.7.4




[Qemu-devel] [PATCH 05/28] riscv: hart: Support heterogeneous harts population

2019-08-05 Thread Bin Meng
At present we only allow symmetric harts to be created. In order to
support heterogeneous harts like SiFive FU540, update hart array's
"cpu-type" property to allow cpu type to be set per hart, separated
by delimiter ",". The frist cpu type before the delimiter is assigned
to hart 0, and the second cpu type before delimiter is assigned to
hart 1, and so on.

If the total number of cpu types supplied in "cpu-type" property is
less than number of maximum harts, the last cpu type in the property
will be used to populate remaining harts.

Signed-off-by: Bin Meng 
---

 hw/riscv/riscv_hart.c | 48 +---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 3dd1c6a..27093e0 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -58,13 +58,55 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
hart,
 static void riscv_harts_realize(DeviceState *dev, Error **errp)
 {
 RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
-int n;
+char *cpu_types;
+char *first_type, *last_type, *tmp_type;
+int n = 0;
 
 s->harts = g_new0(RISCVCPU, s->num_harts);
 
-for (n = 0; n < s->num_harts; n++) {
-riscv_hart_realize(s, n, s->cpu_type, errp);
+/* we should not touch the original s->cpu_type */
+cpu_types = g_strdup(s->cpu_type);
+
+/*
+ * Expect s->cpu_type property was initialized this way:
+ *
+ * "cpu-type-a": symmetric harts
+ * "cpu-type-a,cpu-type-b,cpu-type-c": heterogeneous harts
+ *
+ * For heterogeneous harts, hart cpu types are separated by delimiter ",".
+ * The frist cpu type before the delimiter is assigned to hart 0, and the
+ * second cpu type before delimiter is assigned to hart 1, and so on.
+ *
+ * If the total number of cpu types is less than s->num_harts, the last
+ * cpu type in s->cpu_type will be used to populate remaining harts.
+ */
+
+first_type = strtok(cpu_types, ",");
+riscv_hart_realize(s, n++, first_type, errp);
+tmp_type = strtok(NULL, ",");
+if (!tmp_type) {
+/* symmetric harts */
+for (; n < s->num_harts; n++) {
+riscv_hart_realize(s, n, first_type, errp);
+   }
+} else {
+/* heterogeneous harts */
+while (tmp_type) {
+if (n >= s->num_harts) {
+break;
+}
+riscv_hart_realize(s, n++, tmp_type, errp);
+last_type = tmp_type;
+tmp_type = strtok(NULL, ",");
+}
+
+/* populate remaining harts using the last cpu type in s->cpu_type */
+for (; n < s->num_harts; n++) {
+riscv_hart_realize(s, n, last_type, errp);
+}
 }
+
+g_free(cpu_types);
 }
 
 static void riscv_harts_class_init(ObjectClass *klass, void *data)
-- 
2.7.4




Re: [Qemu-devel] [Qemu-riscv] [PATCH] riscv: sifive_e: Correct various SoC IP block sizes

2019-08-06 Thread Bin Meng
On Wed, Aug 7, 2019 at 5:06 AM Philippe Mathieu-Daudé  wrote:
>
> On 8/5/19 8:43 AM, Bin Meng wrote:
> > On Mon, Aug 5, 2019 at 2:14 PM Chih-Min Chao  
> > wrote:
> >> On Sat, Aug 3, 2019 at 8:27 AM Bin Meng  wrote:
> >>>
> >>> Some of the SoC IP block sizes are wrong. Correct them according
> >>> to the FE310 manual.
> >>>
> >>> Signed-off-by: Bin Meng 
> >>> ---
> >>>
> >>>  hw/riscv/sifive_e.c | 6 +++---
> >>>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> >>> index 2a499d8..9655847 100644
> >>> --- a/hw/riscv/sifive_e.c
> >>> +++ b/hw/riscv/sifive_e.c
> >>> @@ -53,13 +53,13 @@ static const struct MemmapEntry {
> >>>  hwaddr base;
> >>>  hwaddr size;
> >>>  } sifive_e_memmap[] = {
> >>> -[SIFIVE_E_DEBUG] ={0x0,  0x100 },
> >>> +[SIFIVE_E_DEBUG] ={0x0, 0x1000 },
> >>>  [SIFIVE_E_MROM] = { 0x1000, 0x2000 },
> >>>  [SIFIVE_E_OTP] =  {0x2, 0x2000 },
> >>>  [SIFIVE_E_CLINT] ={  0x200,0x1 },
> >>>  [SIFIVE_E_PLIC] = {  0xc00,  0x400 },
> >>> -[SIFIVE_E_AON] =  { 0x1000, 0x8000 },
> >>> -[SIFIVE_E_PRCI] = { 0x10008000, 0x8000 },
> >>> +[SIFIVE_E_AON] =  { 0x1000, 0x1000 },
> >>> +[SIFIVE_E_PRCI] = { 0x10008000, 0x1000 },
> >>>  [SIFIVE_E_OTP_CTRL] = { 0x1001, 0x1000 },
> >>>  [SIFIVE_E_GPIO0] ={ 0x10012000, 0x1000 },
> >>>  [SIFIVE_E_UART0] ={ 0x10013000, 0x1000 },
> >>> --
> >>> 2.7.4
> >>>
> >>
> >> It seems the modification follows  E310-G002(Hifive1 Rev B) spec and the 
> >> origin is for E310-G000(Hifive1) spec.
> >> There should be some way to specify different board version with different 
> >> memory map or we have policy, always support the latest spec.
>
> I agree with Chao, it would be cleaner to have two different boards
> (machines).
> Since the SoCs are very similar, you could add a 'revision' property and
> use it to select the correct map.
>
> >>
> >
> > Yes, I checked both specs. The older spec says these bigger sizes,
> > however their register sizes fit well in the smaller range as well. So
> > I think the modification works well for both.
>
> This is OK for the PRCI, since sifive_prci_create() does not use
> memmap[SIFIVE_E_PRCI].size.
>
> However the AON case is borderline, since you shrink it from 32KiB to 4KiB.
>
> BTW (not related to this patch) it is odd a function named
> sifive_mmio_emulate() creates a RAM region with memory_region_init_ram()
> and does not use the UnimplementedDevice (see make_unimp_dev() in
> hw/arm/musca.c).

Yes, this sifive_mmio_emulate() issue has been pointed out by Alistair
when reviewing the following patch:
http://patchwork.ozlabs.org/patch/1142293/

Regards,
Bin



Re: [Qemu-devel] [Qemu-riscv] [PATCH] riscv: sifive_e: Correct various SoC IP block sizes

2019-08-06 Thread Bin Meng
On Wed, Aug 7, 2019 at 5:06 AM Philippe Mathieu-Daudé  wrote:
>
> On 8/5/19 8:43 AM, Bin Meng wrote:
> > On Mon, Aug 5, 2019 at 2:14 PM Chih-Min Chao  
> > wrote:
> >> On Sat, Aug 3, 2019 at 8:27 AM Bin Meng  wrote:
> >>>
> >>> Some of the SoC IP block sizes are wrong. Correct them according
> >>> to the FE310 manual.
> >>>
> >>> Signed-off-by: Bin Meng 
> >>> ---
> >>>
> >>>  hw/riscv/sifive_e.c | 6 +++---
> >>>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> >>> index 2a499d8..9655847 100644
> >>> --- a/hw/riscv/sifive_e.c
> >>> +++ b/hw/riscv/sifive_e.c
> >>> @@ -53,13 +53,13 @@ static const struct MemmapEntry {
> >>>  hwaddr base;
> >>>  hwaddr size;
> >>>  } sifive_e_memmap[] = {
> >>> -[SIFIVE_E_DEBUG] ={0x0,  0x100 },
> >>> +[SIFIVE_E_DEBUG] ={0x0, 0x1000 },
> >>>  [SIFIVE_E_MROM] = { 0x1000, 0x2000 },
> >>>  [SIFIVE_E_OTP] =  {0x2, 0x2000 },
> >>>  [SIFIVE_E_CLINT] ={  0x200,0x1 },
> >>>  [SIFIVE_E_PLIC] = {  0xc00,  0x400 },
> >>> -[SIFIVE_E_AON] =  { 0x1000, 0x8000 },
> >>> -[SIFIVE_E_PRCI] = { 0x10008000, 0x8000 },
> >>> +[SIFIVE_E_AON] =  { 0x1000, 0x1000 },
> >>> +[SIFIVE_E_PRCI] = { 0x10008000, 0x1000 },
> >>>  [SIFIVE_E_OTP_CTRL] = { 0x1001, 0x1000 },
> >>>  [SIFIVE_E_GPIO0] ={ 0x10012000, 0x1000 },
> >>>  [SIFIVE_E_UART0] ={ 0x10013000, 0x1000 },
> >>> --
> >>> 2.7.4
> >>>
> >>
> >> It seems the modification follows  E310-G002(Hifive1 Rev B) spec and the 
> >> origin is for E310-G000(Hifive1) spec.
> >> There should be some way to specify different board version with different 
> >> memory map or we have policy, always support the latest spec.
>
> I agree with Chao, it would be cleaner to have two different boards
> (machines).
> Since the SoCs are very similar, you could add a 'revision' property and
> use it to select the correct map.
>

I am not sure if adding two different machines will bring us a lot of
benefits, since the only difference is the SoC revision with different
block sizes.

> >>
> >
> > Yes, I checked both specs. The older spec says these bigger sizes,
> > however their register sizes fit well in the smaller range as well. So
> > I think the modification works well for both.
>
> This is OK for the PRCI, since sifive_prci_create() does not use
> memmap[SIFIVE_E_PRCI].size.
>
> However the AON case is borderline, since you shrink it from 32KiB to 4KiB.
>

AON is not implemented anyway currently. And I checked the FE310 old
spec, its register block size is still within the 4KiB range, so
shrinking the size should be fine for both old and new SoC.

> BTW (not related to this patch) it is odd a function named
> sifive_mmio_emulate() creates a RAM region with memory_region_init_ram()
> and does not use the UnimplementedDevice (see make_unimp_dev() in
> hw/arm/musca.c).
>

Regards,
Bin



[Qemu-devel] [PATCH v3] hw: net: cadence_gem: Fix build errors in DB_PRINT()

2019-08-09 Thread Bin Meng
When CADENCE_GEM_ERR_DEBUG is turned on, there are several
compilation errors in DB_PRINT(). Fix them.

While we are here, update to use appropriate modifiers in
the same DB_PRINT() call.

Signed-off-by: Bin Meng 

---

Changes in v3:
- use PRIx64 as rx_desc_get_buffer() returns uint64_t
- use %u for unsigned
- remove unnecessary cast in DB_PRINT()

Changes in v2:
- use HWADDR_PRIx instead of TARGET_FMT_plx for consistency
- use 'z' modifier to print sizeof(..)

 hw/net/cadence_gem.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index d412085..e26ff98 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -983,8 +983,9 @@ static ssize_t gem_receive(NetClientState *nc, const 
uint8_t *buf, size_t size)
 return -1;
 }
 
-DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
-rx_desc_get_buffer(s->rx_desc[q]));
+DB_PRINT("copy %u bytes to 0x%" PRIx64 "\n",
+ MIN(bytes_to_copy, rxbufsize),
+ rx_desc_get_buffer(s, s->rx_desc[q]));
 
 /* Copy packet data to emulated DMA buffer */
 address_space_write(>dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) +
@@ -1156,9 +1157,9 @@ static void gem_transmit(CadenceGEMState *s)
 
 if (tx_desc_get_length(desc) > sizeof(tx_packet) -
(p - tx_packet)) {
-DB_PRINT("TX descriptor @ 0x%x too large: size 0x%x space " \
- "0x%x\n", (unsigned)packet_desc_addr,
- (unsigned)tx_desc_get_length(desc),
+DB_PRINT("TX descriptor @ 0x%" HWADDR_PRIx \
+ " too large: size 0x%x space 0x%zx\n",
+ packet_desc_addr, tx_desc_get_length(desc),
  sizeof(tx_packet) - (p - tx_packet));
 break;
 }
-- 
2.7.4




[Qemu-devel] [PATCH] riscv: rv32: Root page table address can be larger than 32-bit

2019-07-31 Thread Bin Meng
For RV32, the root page table's PPN has 22 bits hence its address
bits could be larger than the maximum bits that target_ulong is
able to represent. Use hwaddr instead.

Signed-off-by: Bin Meng 
---

 target/riscv/cpu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e32b612..3150a6a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -176,7 +176,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 
 *prot = 0;
 
-target_ulong base;
+hwaddr base;
 int levels, ptidxbits, ptesize, vm, sum;
 int mxr = get_field(env->mstatus, MSTATUS_MXR);
 
@@ -239,7 +239,7 @@ restart:
((1 << ptidxbits) - 1);
 
 /* check that physical address of PTE is legal */
-target_ulong pte_addr = base + idx * ptesize;
+hwaddr pte_addr = base + idx * ptesize;
 
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
-- 
2.7.4




[Qemu-devel] [PATCH] riscv: hmp: Add a command to show virtual memory mappings

2019-07-31 Thread Bin Meng
This adds 'info mem' command for RISC-V, to show virtual memory
mappings that aids debugging.

Rather than showing every valid PTE, the command compacts the
output by merging all contiguous physical address mappings into
one block and only shows the merged block mapping details.

Signed-off-by: Bin Meng 
---

 hmp-commands-info.hx   |   2 +-
 target/riscv/Makefile.objs |   4 +
 target/riscv/monitor.c | 227 +
 3 files changed, 232 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/monitor.c

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index c59444c..257ee7d 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -249,7 +249,7 @@ STEXI
 Show virtual to physical memory mappings.
 ETEXI
 
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_RISCV)
 {
 .name   = "mem",
 .args_type  = "",
diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index b1c79bc..a8ceccd 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1,5 +1,9 @@
 obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o pmp.o
 
+ifeq ($(CONFIG_SOFTMMU),y)
+obj-y += monitor.o
+endif
+
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
 
 decode32-y = $(SRC_PATH)/target/riscv/insn32.decode
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
new file mode 100644
index 000..30560ff
--- /dev/null
+++ b/target/riscv/monitor.c
@@ -0,0 +1,227 @@
+/*
+ * QEMU monitor for RISC-V
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * RISC-V specific monitor commands implementation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "cpu_bits.h"
+#include "monitor/monitor.h"
+#include "monitor/hmp-target.h"
+
+#ifdef TARGET_RISCV64
+#define PTE_HEADER_FIELDS   "vaddrpaddr"\
+"size attr\n"
+#define PTE_HEADER_DELIMITER"  "\
+" ---\n"
+#else
+#define PTE_HEADER_FIELDS   "vaddrpaddrsize attr\n"
+#define PTE_HEADER_DELIMITER"   ---\n"
+#endif
+
+/* Perform linear address sign extension */
+static target_ulong addr_canonical(int va_bits, target_ulong addr)
+{
+#ifdef TARGET_RISCV64
+if (addr & (1UL << (va_bits - 1))) {
+addr |= (hwaddr)-(1L << va_bits);
+}
+#endif
+
+return addr;
+}
+
+static void print_pte_header(Monitor *mon)
+{
+monitor_printf(mon, PTE_HEADER_FIELDS);
+monitor_printf(mon, PTE_HEADER_DELIMITER);
+}
+
+static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr,
+  hwaddr paddr, target_ulong size, int attr)
+{
+/* santity check on vaddr */
+if (vaddr >= (1UL << va_bits)) {
+return;
+}
+
+if (!size) {
+return;
+}
+
+monitor_printf(mon, TARGET_FMT_lx " " TARGET_FMT_plx " " TARGET_FMT_lx
+   " %c%c%c%c%c%c%c\n",
+   addr_canonical(va_bits, vaddr),
+   paddr, size,
+   attr & PTE_R ? 'r' : '-',
+   attr & PTE_W ? 'w' : '-',
+   attr & PTE_X ? 'x' : '-',
+   attr & PTE_U ? 'u' : '-',
+   attr & PTE_G ? 'g' : '-',
+   attr & PTE_A ? 'a' : '-',
+   attr & PTE_D ? 'd' : '-');
+}
+
+static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
+ int level, int ptidxbits, int ptesize, int va_bits,
+ hwaddr *vbase, hwaddr *pbase, hwaddr *last_paddr,
+ target_ulong *last_size, int *last_attr)
+{
+hwaddr pte_addr;
+hwaddr paddr;
+target_ulong pgsize;
+target_ulong pte;
+int ptshift;
+int attr;
+int idx;
+
+if (level < 0) {
+return;
+}
+
+ptshift = level * ptidxbits;
+pgsize = 1UL << (PGSHIFT + ptshift);
+
+for (idx = 0; idx < (1UL << ptidxbits); idx++) {
+pte_addr = base + idx * ptesize;
+cpu_

Re: [Qemu-devel] [PATCH] riscv: rv32: Root page table address can be larger than 32-bit

2019-08-01 Thread Bin Meng
On Thu, Aug 1, 2019 at 10:16 PM Richard Henderson
 wrote:
>
> On 7/31/19 6:53 PM, Bin Meng wrote:
> > I am not sure how (idx * ptesize) could overflow. It represents the
> > offset by a page table which is [0, 4096).
>
> You're right, I mis-read what was going on there.
>
> However, lower down, "target_ulong ppn" needs to be promoted to hwaddr, so 
> that
>
> ppn = pte >> PTE_PPN_SHIFT;
> ...
> base = ppn << PGSHIFT;
>
> does not overflow.  (Which is the part of the page table walk that I thought I
> had gleaned from the patch without actually reading the entire function.)

Ah, yes. ppn should be promoted. Thanks for the review!

Regards,
Bin



Re: [Qemu-devel] [PATCH] riscv: sifive_test: Add reset functionality

2019-07-22 Thread Bin Meng
Hi Palmer,

On Sat, Jul 20, 2019 at 9:47 AM Palmer Dabbelt  wrote:
>
> On Fri, 14 Jun 2019 08:15:51 PDT (-0700), bmeng...@gmail.com wrote:
> > This adds a reset opcode for sifive_test device to trigger a system
> > reset for testing purpose.
> >
> > Signed-off-by: Bin Meng 
> > ---
> >
> >  hw/riscv/sifive_test.c | 4 
> >  include/hw/riscv/sifive_test.h | 3 ++-
> >  2 files changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/riscv/sifive_test.c b/hw/riscv/sifive_test.c
> > index 24a04d7..cd86831 100644
> > --- a/hw/riscv/sifive_test.c
> > +++ b/hw/riscv/sifive_test.c
> > @@ -21,6 +21,7 @@
> >  #include "qemu/osdep.h"
> >  #include "hw/sysbus.h"
> >  #include "qemu/module.h"
> > +#include "sysemu/sysemu.h"
> >  #include "target/riscv/cpu.h"
> >  #include "hw/riscv/sifive_test.h"
> >
> > @@ -40,6 +41,9 @@ static void sifive_test_write(void *opaque, hwaddr addr,
> >  exit(code);
> >  case FINISHER_PASS:
> >  exit(0);
> > +case FINISHER_RESET:
> > +qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> > +return;
> >  default:
> >  break;
> >  }
> > diff --git a/include/hw/riscv/sifive_test.h b/include/hw/riscv/sifive_test.h
> > index 71d4c9f..c186a31 100644
> > --- a/include/hw/riscv/sifive_test.h
> > +++ b/include/hw/riscv/sifive_test.h
> > @@ -34,7 +34,8 @@ typedef struct SiFiveTestState {
> >
> >  enum {
> >  FINISHER_FAIL = 0x,
> > -FINISHER_PASS = 0x
> > +FINISHER_PASS = 0x,
> > +FINISHER_RESET = 0x
> >  };
> >
> >  DeviceState *sifive_test_create(hwaddr addr);
>
> Reviewed-by: Palmer Dabbelt 

Thanks a lot!

> Sorry this took a while, but it's in the hardware now.  I'll merge this, but
> I'm considering it a new feature so it'll be held off a bit.

"but it's in the hardware now", do you mean the code I added (0x)
is now supported by a newer version SiFive test device with compatible
string "sifive,test1", and can actually do the system wide reset?

Regards,
Bin



Re: [PATCH v2 1/2] riscv: hw: Drop "clock-frequency" property of cpu nodes

2019-09-21 Thread Bin Meng
Hi Philippe,

On Sat, Sep 21, 2019 at 4:51 PM Philippe Mathieu-Daudé
 wrote:
>
> Hi Bin,
>
> On 9/21/19 7:41 AM, Bin Meng wrote:
> > The "clock-frequency" property of cpu nodes isn't required. Drop it.
> >
> > This is to keep in sync with Linux kernel commit below:
> > https://patchwork.kernel.org/patch/11133031/
>
> What happens if you run a older kernel that doesn't contain the
> referenced patch?
>

This property has never been required by the kernel since the beginning.

Regards,
Bin



[PATCH v2 1/2] riscv: hw: Drop "clock-frequency" property of cpu nodes

2019-09-20 Thread Bin Meng
The "clock-frequency" property of cpu nodes isn't required. Drop it.

This is to keep in sync with Linux kernel commit below:
https://patchwork.kernel.org/patch/11133031/

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v2:
- drop the one in spike and virt machines too

 hw/riscv/sifive_u.c | 2 --
 hw/riscv/spike.c| 2 --
 hw/riscv/virt.c | 2 --
 include/hw/riscv/sifive_u.h | 1 -
 include/hw/riscv/spike.h| 4 
 include/hw/riscv/virt.h | 4 
 6 files changed, 15 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9f8e84b..02dd761 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -151,8 +151,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa;
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-  SIFIVE_U_CLOCK_FREQ);
 /* cpu 0 is the management hart that does not have mmu */
 if (cpu != 0) {
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index d60415d..8bbffbc 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -102,8 +102,6 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa = riscv_isa_string(>soc.harts[cpu]);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-  SPIKE_CLOCK_FREQ);
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d36f562..1303061 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -161,8 +161,6 @@ static void create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa = riscv_isa_string(>soc.harts[cpu]);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-  VIRT_CLOCK_FREQ);
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e4df298..4850805 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -75,7 +75,6 @@ enum {
 };
 
 enum {
-SIFIVE_U_CLOCK_FREQ = 10,
 SIFIVE_U_HFCLK_FREQ = ,
 SIFIVE_U_RTCCLK_FREQ = 100
 };
diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
index 03d8703..dc77042 100644
--- a/include/hw/riscv/spike.h
+++ b/include/hw/riscv/spike.h
@@ -38,10 +38,6 @@ enum {
 SPIKE_DRAM
 };
 
-enum {
-SPIKE_CLOCK_FREQ = 10
-};
-
 #if defined(TARGET_RISCV32)
 #define SPIKE_V1_09_1_CPU TYPE_RISCV_CPU_RV32GCSU_V1_09_1
 #define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_RV32GCSU_V1_10_0
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 6e5fbe5..68978a1 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -55,10 +55,6 @@ enum {
 VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */
 };
 
-enum {
-VIRT_CLOCK_FREQ = 10
-};
-
 #define VIRT_PLIC_HART_CONFIG "MS"
 #define VIRT_PLIC_NUM_SOURCES 127
 #define VIRT_PLIC_NUM_PRIORITIES 7
-- 
2.7.4




[PATCH v2 2/2] riscv: sifive_u: Add ethernet0 to the aliases node

2019-09-20 Thread Bin Meng
U-Boot expects this alias to be in place in order to fix up the mac
address of the ethernet node.

This is to keep in sync with Linux kernel commit below:
https://patchwork.kernel.org/patch/11133033/

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v2: None

 hw/riscv/sifive_u.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 02dd761..1ac51e3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -270,6 +270,10 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 s->soc.gem.conf.macaddr.a, ETH_ALEN);
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
 qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+
+qemu_fdt_add_subnode(fdt, "/aliases");
+qemu_fdt_setprop_string(fdt, "/aliases", "ethernet0", nodename);
+
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
@@ -297,7 +301,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 
-qemu_fdt_add_subnode(fdt, "/aliases");
 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 
 g_free(nodename);
-- 
2.7.4




Re: [PATCH v1 4/6] riscv/sifive_u: Add the start-in-flash property

2019-09-21 Thread Bin Meng
On Sat, Sep 21, 2019 at 6:12 AM Alistair Francis  wrote:
>
> On Thu, Sep 19, 2019 at 10:15 PM Bin Meng  wrote:
> >
> > On Fri, Sep 20, 2019 at 6:32 AM Alistair Francis
> >  wrote:
> > >
> > > Add a property that when set to true QEMU will jump from the ROM code to
> > > the start of flash memory instead of DRAM which is the default
> > > behaviour.
> > >
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  hw/riscv/sifive_u.c | 27 +++
> > >  include/hw/riscv/sifive_u.h |  2 ++
> > >  2 files changed, 29 insertions(+)
> > >
> > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > > index c3949fb316..b7cd3631cd 100644
> > > --- a/hw/riscv/sifive_u.c
> > > +++ b/hw/riscv/sifive_u.c
> > > @@ -373,6 +373,10 @@ static void riscv_sifive_u_init(MachineState 
> > > *machine)
> > > /* dtb: */
> > >  };
> > >
> > > +if (s->start_in_flash) {
> > > +reset_vec[6] = memmap[SIFIVE_U_FLASH0].base; /* start: .dword 
> > > FLASH0_BASE */
> > > +}
> > > +
> > >  /* copy in the reset vector in little_endian byte order */
> > >  for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> > >  reset_vec[i] = cpu_to_le32(reset_vec[i]);
> > > @@ -544,8 +548,31 @@ static void riscv_sifive_u_soc_realize(DeviceState 
> > > *dev, Error **errp)
> > >  memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
> > >  }
> > >
> > > +static bool virt_get_start_in_flash(Object *obj, Error **errp)
> > > +{
> > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > +
> > > +return s->start_in_flash;
> > > +}
> > > +
> > > +static void virt_set_start_in_flash(Object *obj, bool value, Error 
> > > **errp)
> > > +{
> > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > +
> > > +s->start_in_flash = value;
> > > +}
> > > +
> > >  static void riscv_sifive_u_machine_instance_init(Object *obj)
> > >  {
> > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > +
> > > +s->start_in_flash = false;
> > > +object_property_add_bool(obj, "start-in-flash", 
> > > virt_get_start_in_flash,
> > > + virt_set_start_in_flash, NULL);
> > > +object_property_set_description(obj, "start-in-flash",
> > > +"Set on to tell QEMU's ROM to jump 
> > > to " \
> > > +"flash. Otherwise QEMU will jump to 
> > > DRAM",
> > > +NULL);
> > >
> > >  }
> > >
> > > diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> > > index a921079fbe..2656b43c58 100644
> > > --- a/include/hw/riscv/sifive_u.h
> > > +++ b/include/hw/riscv/sifive_u.h
> > > @@ -57,6 +57,8 @@ typedef struct SiFiveUState {
> > >
> > >  void *fdt;
> > >  int fdt_size;
> > > +
> > > +bool start_in_flash;
> > >  } SiFiveUState;
> > >
> > >  enum {
> >
> > This patch chose a different way from the one used in patch "[v1,6/6]
> > riscv/virt: Jump to pflash if specified":
> >
> > - this patch uses reset_vec[6] while patch [6/6] defines a variable 
> > start_addr
> > - this patch adds a "start-in-flash" property to the machine, while
> > patch [6/6] tests against drive IF_PFLASH
>
> Yes, we do it differently for the sifive_u board as the sifive_u board
> doesn't use pflash so there is no way to know if the user has loaded
> anything into the SPI memory.
>

OK.

> >
> > We should be consistent and I would prefer to use the patch [6/6] way.
> > On Unleashed an SPI flash is mounted so we cannot add a PFlash to
> > sifive_u machine like what was done on virt machine, so we should test
> > IF_MTD instead. Thoughts?
>
> How would we test that?
>
> Right now I am loading the binary in SPI with the -device loader
> option. The machine can't really know what is/isn't loaded there.
>
> It's not ideal, but I don't see a nicer way.

I think we need write a SiFive SPI model to support this in a clean
way. Ideally we should simulate the hardware boot workflow as
documented in the FU540 manual chapter 6 "Boot Process".

Regards,
Bin



Re: [PATCH v1 5/6] riscv/virt: Add the PFlash CFI01 device

2019-09-21 Thread Bin Meng
On Sat, Sep 21, 2019 at 6:16 AM Alistair Francis  wrote:
>
> On Thu, Sep 19, 2019 at 10:15 PM Bin Meng  wrote:
> >
> > On Fri, Sep 20, 2019 at 6:36 AM Alistair Francis
> >  wrote:
> > >
> > > Add the CFI01 PFlash to the RISC-V virt board. This is the same PFlash
> > > from the ARM Virt board and the implementation is based on the ARM Virt
> > > board. This allows users to specify flash files from the command line.
> > >
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  hw/riscv/Kconfig|  1 +
> > >  hw/riscv/virt.c | 81 +
> > >  include/hw/riscv/virt.h |  3 ++
> > >  3 files changed, 85 insertions(+)
> > >
> > > diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> > > index fb19b2df3a..b12660b9f8 100644
> > > --- a/hw/riscv/Kconfig
> > > +++ b/hw/riscv/Kconfig
> > > @@ -36,4 +36,5 @@ config RISCV_VIRT
> > >  select SERIAL
> > >  select VIRTIO_MMIO
> > >  select PCI_EXPRESS_GENERIC_BRIDGE
> > > +select PFLASH_CFI01
> > >  select SIFIVE
> > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > index d36f5625ec..ca002ecea7 100644
> > > --- a/hw/riscv/virt.c
> > > +++ b/hw/riscv/virt.c
> > > @@ -26,6 +26,7 @@
> > >  #include "hw/boards.h"
> > >  #include "hw/loader.h"
> > >  #include "hw/sysbus.h"
> > > +#include "hw/qdev-properties.h"
> > >  #include "hw/char/serial.h"
> > >  #include "target/riscv/cpu.h"
> > >  #include "hw/riscv/riscv_hart.h"
> > > @@ -61,12 +62,72 @@ static const struct MemmapEntry {
> > >  [VIRT_PLIC] ={  0xc00, 0x400 },
> > >  [VIRT_UART0] =   { 0x1000, 0x100 },
> > >  [VIRT_VIRTIO] =  { 0x10001000,0x1000 },
> > > +[VIRT_FLASH] =   { 0x2000, 0x200 },
> > >  [VIRT_DRAM] ={ 0x8000,   0x0 },
> > >  [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
> > >  [VIRT_PCIE_PIO] ={ 0x0300,0x0001 },
> > >  [VIRT_PCIE_ECAM] =   { 0x3000,0x1000 },
> > >  };
> > >
> > > +#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
> > > +
> > > +static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s,
> > > +   const char *name,
> > > +   const char *alias_prop_name)
> > > +{
> > > +/*
> > > + * Create a single flash device.  We use the same parameters as
> > > + * the flash devices on the ARM virt board.
> > > + */
> > > +DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
> > > +
> > > +qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
> > > +qdev_prop_set_uint8(dev, "width", 4);
> > > +qdev_prop_set_uint8(dev, "device-width", 2);
> > > +qdev_prop_set_bit(dev, "big-endian", false);
> > > +qdev_prop_set_uint16(dev, "id0", 0x89);
> > > +qdev_prop_set_uint16(dev, "id1", 0x18);
> > > +qdev_prop_set_uint16(dev, "id2", 0x00);
> > > +qdev_prop_set_uint16(dev, "id3", 0x00);
> > > +qdev_prop_set_string(dev, "name", name);
> >
> > alias_prop_name is unused? ARM virt has 2 more calls in the same function 
> > here.
>
> Yep, you are right. I have removed this.

Any reason of removing this?

>
> >
> > > +
> > > +return PFLASH_CFI01(dev);
> > > +}
> > > +
> > > +static void virt_flash_create(RISCVVirtState *s)
> > > +{
> > > +s->flash[0] = virt_flash_create1(s, "virt.flash0", "pflash0");
> > > +s->flash[1] = virt_flash_create1(s, "virt.flash1", "pflash1");
> >
> > I don't think we should mirror what is used on ARM virt board to
> > create 2 flash for sifive_u. For ARM virt, there are 2 flashes because
> > they need distinguish secure and non-secure. For sifive_u, only one is
> > enough.
>
> I went back and forward about 1 or 2. Two seems more usable as maybe
> someone wants to include two pflash files? The Xilinx machine also has
> two so I'm kind of used to 2, but I'm not really fussed.
>
> Unless anyone else wants two I will change it to 1.

Regards,
Bin



Re: [PATCH v1 3/6] riscv/sifive_u: Manually define the machine

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:34 AM Alistair Francis
 wrote:
>
> Instead of using the DEFINE_MACHINE() macro to define the machine let's
> do it manually. This allows us to specify machine properties.
>
> This patch is no functional change.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 27 +++
>  include/hw/riscv/sifive_u.h |  7 ++-
>  2 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 9c5d791320..c3949fb316 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -310,8 +310,7 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  static void riscv_sifive_u_init(MachineState *machine)
>  {
>  const struct MemmapEntry *memmap = sifive_u_memmap;
> -
> -SiFiveUState *s = g_new0(SiFiveUState, 1);
> +SiFiveUState *s = RISCV_U_MACHINE(machine);
>  MemoryRegion *system_memory = get_system_memory();
>  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
>  MemoryRegion *flash0 = g_new(MemoryRegion, 1);
> @@ -545,8 +544,15 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
> Error **errp)
>  memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
>  }
>
> -static void riscv_sifive_u_machine_init(MachineClass *mc)
> +static void riscv_sifive_u_machine_instance_init(Object *obj)
> +{
> +

nits: remove this blank line

> +}
> +
> +static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
>  {
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
>  mc->desc = "RISC-V Board compatible with SiFive U SDK";
>  mc->init = riscv_sifive_u_init;
>  mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 
> SIFIVE_U_COMPUTE_CPU_COUNT;
> @@ -554,7 +560,20 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
>  mc->default_cpus = mc->min_cpus;
>  }
>
> -DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
> +static const TypeInfo riscv_sifive_u_machine_init_typeinfo = {

nits: riscv_sifive_u_machine_typeinfo (no _init for consistency with others)

> +.name   = MACHINE_TYPE_NAME("sifive_u"),
> +.parent = TYPE_MACHINE,
> +.class_init = riscv_sifive_u_machine_class_init,
> +.instance_init = riscv_sifive_u_machine_instance_init,
> +.instance_size = sizeof(SiFiveUState),
> +};
> +
> +static void riscv_sifive_u_machine_init_register_types(void)
> +{
> +type_register_static(_sifive_u_machine_init_typeinfo);
> +}
> +
> +type_init(riscv_sifive_u_machine_init_register_types)

nits: I would move the machine declaration to after the sifive_u SoC
declaration in this file.

>
>  static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data)
>  {
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 2a08e2a5db..a921079fbe 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -44,12 +44,17 @@ typedef struct SiFiveUSoCState {
>  CadenceGEMState gem;
>  } SiFiveUSoCState;
>
> +#define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
> +#define RISCV_U_MACHINE(obj) \
> +OBJECT_CHECK(SiFiveUState, (obj), TYPE_RISCV_U_MACHINE)
> +
>  typedef struct SiFiveUState {
>  /*< private >*/
> -SysBusDevice parent_obj;
> +MachineState parent_obj;
>
>  /*< public >*/
>  SiFiveUSoCState soc;
> +
>  void *fdt;
>  int fdt_size;
>  } SiFiveUState;
> --

Regards,
Bin



Re: [PATCH v1 2/6] riscv/sifive_u: Add QSPI memory region

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:32 AM Alistair Francis
 wrote:
>
> There doesn't seem to be details on what QSPI the HiFive Unleashed uses.

IMHO, this sentence should be removed as there are details available.
See the hifive-unleashed-a00.dts.

 {
status = "okay";
flash@0 {
compatible = "issi,is25wp256", "jedec,spi-nor";
..

> To allow boot firmware developers to use QEMU to target the Unleashed
> let's add a chunk of memory to represent the QSPI. This can be targeted

nits: to represent the QSPI0 memory-mapped flash

> using QEMU's -device loader command line option.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 8 
>  include/hw/riscv/sifive_u.h | 1 +
>  2 files changed, 9 insertions(+)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index de6e197882..9c5d791320 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -71,6 +71,7 @@ static const struct MemmapEntry {
>  [SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
>  [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
>  [SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
> +[SIFIVE_U_FLASH0] =   { 0x2000,  0x200 },

We should map 256MiB per the manual.

>  [SIFIVE_U_DRAM] = { 0x8000,0x0 },
>  [SIFIVE_U_GEM] =  { 0x1009, 0x2000 },
>  [SIFIVE_U_GEM_MGMT] = { 0x100a, 0x1000 },
> @@ -313,6 +314,7 @@ static void riscv_sifive_u_init(MachineState *machine)
>  SiFiveUState *s = g_new0(SiFiveUState, 1);
>  MemoryRegion *system_memory = get_system_memory();
>  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> +MemoryRegion *flash0 = g_new(MemoryRegion, 1);
>  int i;
>
>  /* Initialize SoC */
> @@ -328,6 +330,12 @@ static void riscv_sifive_u_init(MachineState *machine)
>  memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base,
>  main_mem);
>
> +/* register QSPI0 Flash */
> +memory_region_init_ram(flash0, NULL, "riscv.sifive.u.flash0",
> +   memmap[SIFIVE_U_FLASH0].size, _fatal);
> +memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
> +flash0);
> +
>  /* create device tree */
>  create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 50e3620c02..2a08e2a5db 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -64,6 +64,7 @@ enum {
>  SIFIVE_U_UART0,
>  SIFIVE_U_UART1,
>  SIFIVE_U_OTP,
> +SIFIVE_U_FLASH0,
>  SIFIVE_U_DRAM,
>  SIFIVE_U_GEM,
>  SIFIVE_U_GEM_MGMT
> --

Regards,
Bin



Re: [PATCH v1 1/6] riscv/sifive_u: Add L2-LIM cache memory

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:32 AM Alistair Francis
 wrote:
>
> On reset only a single L2 cache way is enabled, the others are exposed
> as memory that can be used by early boot firmware. This L2 region is
> generally disabled using the WayEnable register at a later stage in the
> boot process. To allow firmware to target QEMU and the HiFive Unleashed
> let's add the L2 LIM (LooselyIntegrated Memory).
>
> Ideally we would want to adjust the size of this chunk of memory as the
> L2 Cache Controller WayEnable register is incremented. Unfortunately I
> don't see a nice way to handle reducing or blocking out the L2 LIM while
> still allowing it be re returned to all enabled from a reset.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 15 +++
>  include/hw/riscv/sifive_u.h |  1 +
>  2 files changed, 16 insertions(+)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 9f8e84bf2e..de6e197882 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -65,6 +65,7 @@ static const struct MemmapEntry {
>  [SIFIVE_U_DEBUG] ={0x0,  0x100 },
>  [SIFIVE_U_MROM] = { 0x1000,0x11000 },
>  [SIFIVE_U_CLINT] ={  0x200,0x1 },
> +[SIFIVE_U_L2LIM] ={  0x800,  0x1e0 },

The size should be 0x200.

>  [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
>  [SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
>  [SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
> @@ -431,6 +432,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
> Error **errp)
>  const struct MemmapEntry *memmap = sifive_u_memmap;
>  MemoryRegion *system_memory = get_system_memory();
>  MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> +MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
>  qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
>  char *plic_hart_config;
>  size_t plic_hart_config_len;
> @@ -459,6 +461,19 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
> Error **errp)
>  memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base,
>  mask_rom);
>
> +/* Add L2-LIM at reset size.

nits: wrong multi-line comment format

> + * This should be reduced in size as the L2 Cache Controller WayEnable
> + * register is incremented. Unfortunately I don't see a nice (or any) way
> + * to handle reducing or blocking out the L2 LIM while still allowing it
> + * be re returned to all enabled after a reset. For the time being, just
> + * leave it enabled all the time. This won't break anything, but will be
> + * too generous to misbehaving guests.
> + */
> +memory_region_init_ram(l2lim_mem, NULL, "riscv.sifive.u.l2lim",
> +   memmap[SIFIVE_U_L2LIM].size, _fatal);
> +memory_region_add_subregion(system_memory, memmap[SIFIVE_U_L2LIM].base,
> +l2lim_mem);
> +
>  /* create PLIC hart topology configuration string */
>  plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) *
> ms->smp.cpus;
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index e4df298c23..50e3620c02 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -58,6 +58,7 @@ enum {
>  SIFIVE_U_DEBUG,
>  SIFIVE_U_MROM,
>  SIFIVE_U_CLINT,
> +SIFIVE_U_L2LIM,
>  SIFIVE_U_PLIC,
>  SIFIVE_U_PRCI,
>  SIFIVE_U_UART0,
> --

Regards,
Bin



Re: [PATCH v1 4/6] riscv/sifive_u: Add the start-in-flash property

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:32 AM Alistair Francis
 wrote:
>
> Add a property that when set to true QEMU will jump from the ROM code to
> the start of flash memory instead of DRAM which is the default
> behaviour.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 27 +++
>  include/hw/riscv/sifive_u.h |  2 ++
>  2 files changed, 29 insertions(+)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index c3949fb316..b7cd3631cd 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -373,6 +373,10 @@ static void riscv_sifive_u_init(MachineState *machine)
> /* dtb: */
>  };
>
> +if (s->start_in_flash) {
> +reset_vec[6] = memmap[SIFIVE_U_FLASH0].base; /* start: .dword 
> FLASH0_BASE */
> +}
> +
>  /* copy in the reset vector in little_endian byte order */
>  for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
>  reset_vec[i] = cpu_to_le32(reset_vec[i]);
> @@ -544,8 +548,31 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
> Error **errp)
>  memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
>  }
>
> +static bool virt_get_start_in_flash(Object *obj, Error **errp)
> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +return s->start_in_flash;
> +}
> +
> +static void virt_set_start_in_flash(Object *obj, bool value, Error **errp)
> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = value;
> +}
> +
>  static void riscv_sifive_u_machine_instance_init(Object *obj)
>  {
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = false;
> +object_property_add_bool(obj, "start-in-flash", virt_get_start_in_flash,
> + virt_set_start_in_flash, NULL);
> +object_property_set_description(obj, "start-in-flash",
> +"Set on to tell QEMU's ROM to jump to " \
> +"flash. Otherwise QEMU will jump to 
> DRAM",
> +NULL);
>
>  }
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index a921079fbe..2656b43c58 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -57,6 +57,8 @@ typedef struct SiFiveUState {
>
>  void *fdt;
>  int fdt_size;
> +
> +bool start_in_flash;
>  } SiFiveUState;
>
>  enum {

This patch chose a different way from the one used in patch "[v1,6/6]
riscv/virt: Jump to pflash if specified":

- this patch uses reset_vec[6] while patch [6/6] defines a variable start_addr
- this patch adds a "start-in-flash" property to the machine, while
patch [6/6] tests against drive IF_PFLASH

We should be consistent and I would prefer to use the patch [6/6] way.
On Unleashed an SPI flash is mounted so we cannot add a PFlash to
sifive_u machine like what was done on virt machine, so we should test
IF_MTD instead. Thoughts?

Regards,
Bin



Re: [PATCH v1 6/6] riscv/virt: Jump to pflash if specified

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:35 AM Alistair Francis
 wrote:
>
> If the user supplied pflash to QEMU then change the reset code to jump
> to the pflash base address instead of the DRAM base address.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/virt.c | 10 +-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index ca002ecea7..ed25cc6761 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -441,6 +441,7 @@ static void riscv_virt_board_init(MachineState *machine)
>  MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
>  char *plic_hart_config;
>  size_t plic_hart_config_len;
> +target_ulong start_addr = memmap[VIRT_DRAM].base;
>  int i;
>  unsigned int smp_cpus = machine->smp.cpus;
>
> @@ -487,6 +488,13 @@ static void riscv_virt_board_init(MachineState *machine)
>  }
>  }
>
> +if (drive_get(IF_PFLASH, 0, 0)) {
> +/* Pflash was supplied, let's overwrite the address we jump to after

nits: wrong multi-line comment format

> + * reset to the base of the flash.
> + */
> +start_addr = virt_memmap[VIRT_FLASH].base;
> +}
> +
>  /* reset vector */
>  uint32_t reset_vec[8] = {
>  0x0297,  /* 1:  auipc  t0, %pcrel_hi(dtb) */
> @@ -499,7 +507,7 @@ static void riscv_virt_board_init(MachineState *machine)
>  #endif
>  0x00028067,  /* jr t0 */
>  0x,
> -memmap[VIRT_DRAM].base,  /* start: .dword memmap[VIRT_DRAM].base 
> */
> +start_addr,  /* start: .dword */
>  0x,
>   /* dtb: */
>  };
> --

Otherwise,
Reviewed-by: Bin Meng 



Re: [PATCH v1 5/6] riscv/virt: Add the PFlash CFI01 device

2019-09-19 Thread Bin Meng
On Fri, Sep 20, 2019 at 6:36 AM Alistair Francis
 wrote:
>
> Add the CFI01 PFlash to the RISC-V virt board. This is the same PFlash
> from the ARM Virt board and the implementation is based on the ARM Virt
> board. This allows users to specify flash files from the command line.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/Kconfig|  1 +
>  hw/riscv/virt.c | 81 +
>  include/hw/riscv/virt.h |  3 ++
>  3 files changed, 85 insertions(+)
>
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index fb19b2df3a..b12660b9f8 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -36,4 +36,5 @@ config RISCV_VIRT
>  select SERIAL
>  select VIRTIO_MMIO
>  select PCI_EXPRESS_GENERIC_BRIDGE
> +select PFLASH_CFI01
>  select SIFIVE
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index d36f5625ec..ca002ecea7 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -26,6 +26,7 @@
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "hw/sysbus.h"
> +#include "hw/qdev-properties.h"
>  #include "hw/char/serial.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/riscv/riscv_hart.h"
> @@ -61,12 +62,72 @@ static const struct MemmapEntry {
>  [VIRT_PLIC] ={  0xc00, 0x400 },
>  [VIRT_UART0] =   { 0x1000, 0x100 },
>  [VIRT_VIRTIO] =  { 0x10001000,0x1000 },
> +[VIRT_FLASH] =   { 0x2000, 0x200 },
>  [VIRT_DRAM] ={ 0x8000,   0x0 },
>  [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
>  [VIRT_PCIE_PIO] ={ 0x0300,0x0001 },
>  [VIRT_PCIE_ECAM] =   { 0x3000,0x1000 },
>  };
>
> +#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
> +
> +static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s,
> +   const char *name,
> +   const char *alias_prop_name)
> +{
> +/*
> + * Create a single flash device.  We use the same parameters as
> + * the flash devices on the ARM virt board.
> + */
> +DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
> +
> +qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
> +qdev_prop_set_uint8(dev, "width", 4);
> +qdev_prop_set_uint8(dev, "device-width", 2);
> +qdev_prop_set_bit(dev, "big-endian", false);
> +qdev_prop_set_uint16(dev, "id0", 0x89);
> +qdev_prop_set_uint16(dev, "id1", 0x18);
> +qdev_prop_set_uint16(dev, "id2", 0x00);
> +qdev_prop_set_uint16(dev, "id3", 0x00);
> +qdev_prop_set_string(dev, "name", name);

alias_prop_name is unused? ARM virt has 2 more calls in the same function here.

> +
> +return PFLASH_CFI01(dev);
> +}
> +
> +static void virt_flash_create(RISCVVirtState *s)
> +{
> +s->flash[0] = virt_flash_create1(s, "virt.flash0", "pflash0");
> +s->flash[1] = virt_flash_create1(s, "virt.flash1", "pflash1");

I don't think we should mirror what is used on ARM virt board to
create 2 flash for sifive_u. For ARM virt, there are 2 flashes because
they need distinguish secure and non-secure. For sifive_u, only one is
enough.

> +}
> +
> +static void virt_flash_map1(PFlashCFI01 *flash,
> +hwaddr base, hwaddr size,
> +MemoryRegion *sysmem)
> +{
> +DeviceState *dev = DEVICE(flash);
> +
> +assert(size % VIRT_FLASH_SECTOR_SIZE == 0);
> +assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
> +qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE);
> +qdev_init_nofail(dev);
> +
> +memory_region_add_subregion(sysmem, base,
> +sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
> +   0));
> +}
> +
> +static void virt_flash_map(RISCVVirtState *s,
> +   MemoryRegion *sysmem)
> +{
> +hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
> +hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
> +
> +virt_flash_map1(s->flash[0], flashbase, flashsize,
> +sysmem);
> +virt_flash_map1(s->flash[1], flashbase + flashsize, flashsize,
> +sysmem);
> +}
> +
>  static void create_pcie_irq_map(void *fdt, char *nodename,
>  uint32_t plic_phandle)
>  {
> @@ -121,6 +182,8 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  char *nodename;
>  uint32_t plic_phandle, phandle = 1;
>  int i;
> +hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
> +hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
>
>  fdt = s->fdt = create_device_tree(>fdt_size);
>  if (!fdt) {
> @@ -316,6 +379,15 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
>  }
>  g_free(nodename);
> +
> +nodename = 

Re: [PATCH v1 1/1] target/riscv: Print CPU and privledge in disas

2019-09-26 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:55 AM Alistair Francis
 wrote:

typo "privledge" in the commit title

>
> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/translate.c | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index adeddb85f6..537af0003e 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -810,7 +810,14 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cpu)
>
>  static void riscv_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
>  {
> +#ifndef CONFIG_USER_ONLY
> +RISCVCPU *rvcpu = RISCV_CPU(cpu);
> +CPURISCVState *env = >env;
> +#endif
>  qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
> +#ifndef CONFIG_USER_ONLY
> +qemu_log("CPU: %d; priv: "TARGET_FMT_ld"\n", cpu->cpu_index, env->priv);

Since this patch wants to be helpful for debugging, would it make more
sense to print out the priv mode string instead of the number, eg:
priv: M.

But I am fine with just printing out the number.

> +#endif
>  log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
>  }

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v2 1/7] riscv/sifive_u: Add L2-LIM cache memory

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:52 AM Alistair Francis
 wrote:
>
> On reset only a single L2 cache way is enabled, the others are exposed
> as memory that can be used by early boot firmware. This L2 region is
> generally disabled using the WayEnable register at a later stage in the
> boot process. To allow firmware to target QEMU and the HiFive Unleashed
> let's add the L2 LIM (LooselyIntegrated Memory).
>
> Ideally we would want to adjust the size of this chunk of memory as the
> L2 Cache Controller WayEnable register is incremented. Unfortunately I
> don't see a nice way to handle reducing or blocking out the L2 LIM while
> still allowing it be re returned to all enabled from a reset.
>
> Signed-off-by: Alistair Francis 
> ---

Please include a changelog in the future. otherwise it's hard to track
what is changed between patch versions.

>  hw/riscv/sifive_u.c | 16 
>  include/hw/riscv/sifive_u.h |  1 +
>  2 files changed, 17 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 5/7] riscv/virt: Manually define the machine

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:51 AM Alistair Francis
 wrote:
>
> Instead of using the DEFINE_MACHINE() macro to define the machine let's
> do it manually. This allows us to use the machine object to create
> RISCVVirtState. This is required to add children and aliases to the
> machine.
>
> This patch is no functional change.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/virt.c | 30 --
>  include/hw/riscv/virt.h |  7 ++-
>  2 files changed, 30 insertions(+), 7 deletions(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v2 2/7] riscv/sifive_u: Add QSPI memory region

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:51 AM Alistair Francis
 wrote:
>
> The HiFive Unleashed uses is25wp256 SPI NOR flash. There is currently no
> model of this in QEMU, so to allow boot firmware developers to use QEMU
> to target the Unleashed let's add a chunk of memory to represent the QSPI0
> memory mapped flash. This can be targeted using QEMU's -device loader
> command line option.
>
> In the future we can look at adding a model for the is25wp256 flash.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 8 
>  include/hw/riscv/sifive_u.h | 1 +
>  2 files changed, 9 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 3/7] riscv/sifive_u: Manually define the machine

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:48 AM Alistair Francis
 wrote:
>
> Instead of using the DEFINE_MACHINE() macro to define the machine let's
> do it manually. This allows us to specify machine properties.
>
> This patch is no functional change.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 44 ++---
>  include/hw/riscv/sifive_u.h |  7 +-
>  2 files changed, 37 insertions(+), 14 deletions(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v2 4/7] riscv/sifive_u: Add the start-in-flash property

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:55 AM Alistair Francis
 wrote:
>
> Add a property that when set to true QEMU will jump from the ROM code to
> the start of flash memory instead of DRAM which is the default
> behaviour.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 27 +++
>  include/hw/riscv/sifive_u.h |  2 ++
>  2 files changed, 29 insertions(+)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index f5741e9a38..33b55d0d5b 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -373,6 +373,10 @@ static void riscv_sifive_u_init(MachineState *machine)
> /* dtb: */
>  };
>
> +if (s->start_in_flash) {
> +reset_vec[6] = memmap[SIFIVE_U_FLASH0].base; /* start: .dword 
> FLASH0_BASE */
> +}

Please change to use the way that patch "[v2,7/7] riscv/virt: Jump to
pflash if specified" does for consistency, ie:

if (s->start_in_flash) {
start_addr = memmap[SIFIVE_U_FLASH0].base; /* start: .dword
FLASH0_BASE */
}

> +
>  /* copy in the reset vector in little_endian byte order */
>  for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
>  reset_vec[i] = cpu_to_le32(reset_vec[i]);
> @@ -432,8 +436,31 @@ static void riscv_sifive_u_soc_init(Object *obj)
>TYPE_CADENCE_GEM);
>  }
>
> +static bool virt_get_start_in_flash(Object *obj, Error **errp)

sifive_u_get_start_in_flash()

> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +return s->start_in_flash;
> +}
> +
> +static void virt_set_start_in_flash(Object *obj, bool value, Error **errp)

sifive_u_set_start_in_flash()

> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = value;
> +}
> +
>  static void riscv_sifive_u_machine_instance_init(Object *obj)
>  {
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = false;
> +object_property_add_bool(obj, "start-in-flash", virt_get_start_in_flash,
> + virt_set_start_in_flash, NULL);
> +object_property_set_description(obj, "start-in-flash",
> +"Set on to tell QEMU's ROM to jump to " \
> +"flash. Otherwise QEMU will jump to 
> DRAM",
> +NULL);
>  }
>
>  static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index a921079fbe..2656b43c58 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -57,6 +57,8 @@ typedef struct SiFiveUState {
>
>  void *fdt;
>  int fdt_size;
> +
> +bool start_in_flash;
>  } SiFiveUState;
>

Regards,
Bin



Re: [PATCH v2 7/7] riscv/virt: Jump to pflash if specified

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:57 AM Alistair Francis
 wrote:
>
> If the user supplied pflash to QEMU then change the reset code to jump
> to the pflash base address instead of the DRAM base address.
>
> Signed-off-by: Alistair Francis 
> Reviewed-by: Bin Meng 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  hw/riscv/virt.c | 11 ++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>

Tested-by: Bin Meng 



Re: [PATCH v2 6/7] riscv/virt: Add the PFlash CFI01 device

2019-09-27 Thread Bin Meng
On Fri, Sep 27, 2019 at 8:57 AM Alistair Francis
 wrote:
>
> Add the CFI01 PFlash to the RISC-V virt board. This is the same PFlash
> from the ARM Virt board and the implementation is based on the ARM Virt
> board. This allows users to specify flash files from the command line.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/Kconfig|  1 +
>  hw/riscv/virt.c | 86 +
>  include/hw/riscv/virt.h |  3 ++
>  3 files changed, 90 insertions(+)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v1 4/6] riscv/sifive_u: Add the start-in-flash property

2019-09-23 Thread Bin Meng
On Tue, Sep 24, 2019 at 1:51 AM Alistair Francis  wrote:
>
> On Sat, Sep 21, 2019 at 7:19 PM Bin Meng  wrote:
> >
> > On Sat, Sep 21, 2019 at 6:12 AM Alistair Francis  
> > wrote:
> > >
> > > On Thu, Sep 19, 2019 at 10:15 PM Bin Meng  wrote:
> > > >
> > > > On Fri, Sep 20, 2019 at 6:32 AM Alistair Francis
> > > >  wrote:
> > > > >
> > > > > Add a property that when set to true QEMU will jump from the ROM code 
> > > > > to
> > > > > the start of flash memory instead of DRAM which is the default
> > > > > behaviour.
> > > > >
> > > > > Signed-off-by: Alistair Francis 
> > > > > ---
> > > > >  hw/riscv/sifive_u.c | 27 +++
> > > > >  include/hw/riscv/sifive_u.h |  2 ++
> > > > >  2 files changed, 29 insertions(+)
> > > > >
> > > > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > > > > index c3949fb316..b7cd3631cd 100644
> > > > > --- a/hw/riscv/sifive_u.c
> > > > > +++ b/hw/riscv/sifive_u.c
> > > > > @@ -373,6 +373,10 @@ static void riscv_sifive_u_init(MachineState 
> > > > > *machine)
> > > > > /* dtb: */
> > > > >  };
> > > > >
> > > > > +if (s->start_in_flash) {
> > > > > +reset_vec[6] = memmap[SIFIVE_U_FLASH0].base; /* start: 
> > > > > .dword FLASH0_BASE */
> > > > > +}
> > > > > +
> > > > >  /* copy in the reset vector in little_endian byte order */
> > > > >  for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> > > > >  reset_vec[i] = cpu_to_le32(reset_vec[i]);
> > > > > @@ -544,8 +548,31 @@ static void 
> > > > > riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
> > > > >  memmap[SIFIVE_U_GEM_MGMT].base, 
> > > > > memmap[SIFIVE_U_GEM_MGMT].size);
> > > > >  }
> > > > >
> > > > > +static bool virt_get_start_in_flash(Object *obj, Error **errp)
> > > > > +{
> > > > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > > > +
> > > > > +return s->start_in_flash;
> > > > > +}
> > > > > +
> > > > > +static void virt_set_start_in_flash(Object *obj, bool value, Error 
> > > > > **errp)
> > > > > +{
> > > > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > > > +
> > > > > +s->start_in_flash = value;
> > > > > +}
> > > > > +
> > > > >  static void riscv_sifive_u_machine_instance_init(Object *obj)
> > > > >  {
> > > > > +SiFiveUState *s = RISCV_U_MACHINE(obj);
> > > > > +
> > > > > +s->start_in_flash = false;
> > > > > +object_property_add_bool(obj, "start-in-flash", 
> > > > > virt_get_start_in_flash,
> > > > > + virt_set_start_in_flash, NULL);
> > > > > +object_property_set_description(obj, "start-in-flash",
> > > > > +"Set on to tell QEMU's ROM to 
> > > > > jump to " \
> > > > > +"flash. Otherwise QEMU will jump 
> > > > > to DRAM",
> > > > > +NULL);
> > > > >
> > > > >  }
> > > > >
> > > > > diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> > > > > index a921079fbe..2656b43c58 100644
> > > > > --- a/include/hw/riscv/sifive_u.h
> > > > > +++ b/include/hw/riscv/sifive_u.h
> > > > > @@ -57,6 +57,8 @@ typedef struct SiFiveUState {
> > > > >
> > > > >  void *fdt;
> > > > >  int fdt_size;
> > > > > +
> > > > > +bool start_in_flash;
> > > > >  } SiFiveUState;
> > > > >
> > > > >  enum {
> > > >
> > > > This patch chose a different way from the one used in patch "[v1,6/6]
> > > > riscv/virt: Jump to pflash if specified":
> > > >
> > > > - this patch uses reset_vec[6] while patch [6/6] defines a variable 
&

[PATCH 1/2] riscv: sifive_u: Drop "clock-frequency" property of cpu nodes

2019-09-20 Thread Bin Meng
The "clock-frequency" property of cpu nodes isn't required. Drop it.

This is to keep in sync with Linux kernel commit below:
https://patchwork.kernel.org/patch/11133031/

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 2 --
 include/hw/riscv/sifive_u.h | 1 -
 2 files changed, 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9f8e84b..02dd761 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -151,8 +151,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa;
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-  SIFIVE_U_CLOCK_FREQ);
 /* cpu 0 is the management hart that does not have mmu */
 if (cpu != 0) {
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e4df298..4850805 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -75,7 +75,6 @@ enum {
 };
 
 enum {
-SIFIVE_U_CLOCK_FREQ = 10,
 SIFIVE_U_HFCLK_FREQ = ,
 SIFIVE_U_RTCCLK_FREQ = 100
 };
-- 
2.7.4




[PATCH 2/2] riscv: sifive_u: Add ethernet0 to the aliases node

2019-09-20 Thread Bin Meng
U-Boot expects this alias to be in place in order to fix up the mac
address of the ethernet node.

This is to keep in sync with Linux kernel commit below:
https://patchwork.kernel.org/patch/11133033/

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 02dd761..1ac51e3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -270,6 +270,10 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 s->soc.gem.conf.macaddr.a, ETH_ALEN);
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
 qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+
+qemu_fdt_add_subnode(fdt, "/aliases");
+qemu_fdt_setprop_string(fdt, "/aliases", "ethernet0", nodename);
+
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
@@ -297,7 +301,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 
-qemu_fdt_add_subnode(fdt, "/aliases");
 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 
 g_free(nodename);
-- 
2.7.4




Re: [PATCH] riscv/virt: Add syscon reboot and poweroff DT nodes

2019-11-11 Thread Bin Meng
On Mon, Nov 11, 2019 at 9:42 PM Anup Patel  wrote:
>
> Correct Palmer's email address.
>
> > -Original Message-
> > From: Anup Patel
> > Sent: Monday, November 11, 2019 7:08 PM
> > To: Peter Maydell ; Palmer Dabbelt
> > ; Alistair Francis ; Sagar
> > Karandikar 
> > Cc: Atish Patra ; Christoph Hellwig ;
> > Anup Patel ; qemu-ri...@nongnu.org; qemu-
> > de...@nongnu.org; Anup Patel 
> > Subject: [PATCH] riscv/virt: Add syscon reboot and poweroff DT nodes
> >
> > The SiFive test device found on virt machine can be used by generic syscon
> > reboot and poweroff drivers available in Linux kernel.
> >
> > This patch updates FDT generation in virt machine so that Linux kernel can
> > probe and use generic syscon drivers.
> >
> > Signed-off-by: Anup Patel 
> > ---
> >  hw/riscv/virt.c | 28 
> >  1 file changed, 24 insertions(+), 4 deletions(-)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index cc8f311e6b..fdfa359713
> > 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -182,11 +182,11 @@ static void create_fdt(RISCVVirtState *s, const
> > struct MemmapEntry *memmap,
> >  uint64_t mem_size, const char *cmdline)  {
> >  void *fdt;
> > -int cpu;
> > +int cpu, i;
> >  uint32_t *cells;
> >  char *nodename;
> > -uint32_t plic_phandle, phandle = 1;
> > -int i;
> > +const char test_compat[] = "sifive,test0\0syscon";
> > +uint32_t plic_phandle, test_phandle, phandle = 1;
> >  hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
> >  hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
> >
> > @@ -356,13 +356,33 @@ static void create_fdt(RISCVVirtState *s, const
> > struct MemmapEntry *memmap,
> >  create_pcie_irq_map(fdt, nodename, plic_phandle);
> >  g_free(nodename);
> >
> > +test_phandle = phandle++;
> >  nodename = g_strdup_printf("/test@%lx",
> >  (long)memmap[VIRT_TEST].base);
> >  qemu_fdt_add_subnode(fdt, nodename);
> > -qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,test0");
> > +qemu_fdt_setprop(fdt, nodename, "compatible",
> > + test_compat, sizeof(test_compat));
> >  qemu_fdt_setprop_cells(fdt, nodename, "reg",
> >  0x0, memmap[VIRT_TEST].base,
> >  0x0, memmap[VIRT_TEST].size);
> > +qemu_fdt_setprop_cell(fdt, nodename, "phandle", test_phandle);
> > +test_phandle = qemu_fdt_get_phandle(fdt, nodename);

Is this necessary?

> > +g_free(nodename);
> > +
> > +nodename = g_strdup_printf("/reboot");
> > +qemu_fdt_add_subnode(fdt, nodename);
> > +qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-
> > reboot");
> > +qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
> > +qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
> > +qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_RESET);
> > +g_free(nodename);
> > +
> > +nodename = g_strdup_printf("/poweroff");
> > +qemu_fdt_add_subnode(fdt, nodename);
> > +qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-
> > poweroff");
> > +qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
> > +qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
> > +qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_PASS);
> >  g_free(nodename);
> >
> >  nodename = g_strdup_printf("/uart@%lx",
> > --

Regards,
Bin



Re: [PATCH for 4.2 v1 1/1] riscv/virt: Increase flash size

2019-11-11 Thread Bin Meng
On Thu, Nov 7, 2019 at 8:54 AM Alistair Francis
 wrote:
>
> Coreboot developers have requested that they have at least 32MB of flash
> to load binaries. We currently have 32MB of flash, but it is split in
> two to allow loading two flash binaries. Let's increase the flash size
> from 32MB to 64MB to ensure we have a single region that is 32MB.
>
> No QEMU release has include flash in the RISC-V virt machine, so this
> isn't a breaking change.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/virt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 



[PATCH] riscv: sifive_u: Add a "serial" property for board serial number

2019-11-16 Thread Bin Meng
At present the board serial number is hard-coded to 1, and passed
to OTP model during initialization. Firmware (FSBL, U-Boot) uses
the serial number to generate a unique MAC address for the on-chip
ethernet controller. When multiple QEMU 'sifive_u' instances are
created and connected to the same subnet, they all have the same
MAC address hence it creates a unusable network.

A new "serial" property is introduced to specify the board serial
number. When not given, the default serial number 1 is used.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 21 -
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 9552abf..e1a5536 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -34,6 +34,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/visitor.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "hw/sysbus.h"
@@ -401,6 +402,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 static void riscv_sifive_u_soc_init(Object *obj)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
+SiFiveUState *us = RISCV_U_MACHINE(ms);
 SiFiveUSoCState *s = RISCV_U_SOC(obj);
 
 object_initialize_child(obj, "e-cluster", >e_cluster,
@@ -433,7 +435,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
   TYPE_SIFIVE_U_PRCI);
 sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
   TYPE_SIFIVE_U_OTP);
-qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
+qdev_prop_set_uint32(DEVICE(>otp), "serial", us->serial);
 sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
   TYPE_CADENCE_GEM);
 }
@@ -452,6 +454,18 @@ static void sifive_u_set_start_in_flash(Object *obj, bool 
value, Error **errp)
 s->start_in_flash = value;
 }
 
+static void sifive_u_get_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
+static void sifive_u_set_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
 static void riscv_sifive_u_machine_instance_init(Object *obj)
 {
 SiFiveUState *s = RISCV_U_MACHINE(obj);
@@ -463,6 +477,11 @@ static void riscv_sifive_u_machine_instance_init(Object 
*obj)
 "Set on to tell QEMU's ROM to jump to " \
 "flash. Otherwise QEMU will jump to DRAM",
 NULL);
+
+s->serial = OTP_SERIAL;
+object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
+sifive_u_set_serial, NULL, >serial, NULL);
+object_property_set_description(obj, "serial", "Board serial number", 
NULL);
 }
 
 static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 82667b5..7cf742e 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -59,6 +59,7 @@ typedef struct SiFiveUState {
 int fdt_size;
 
 bool start_in_flash;
+uint32_t serial;
 } SiFiveUState;
 
 enum {
-- 
2.7.4




[PATCH] riscv: virt: Allow PCI address 0

2019-11-22 Thread Bin Meng
When testing e1000 with the virt machine, e1000's I/O space cannot
be accessed. Debugging shows that the I/O BAR (BAR1) is correctly
written with address 0 plus I/O enable bit, but QEMU's "info pci"
shows that:

  Bus  0, device   1, function 0:
Ethernet controller: PCI device 8086:100e
  ...
  BAR1: I/O at 0x [0x003e].
  ...

It turns out we should set pci_allow_0_address to true to allow 0
PCI address, otherwise pci_bar_address() treats such address as
PCI_BAR_UNMAPPED.

Signed-off-by: Bin Meng 
---

 hw/riscv/virt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 23f340d..411bef5 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -603,6 +603,7 @@ static void riscv_virt_machine_class_init(ObjectClass *oc, 
void *data)
 mc->init = riscv_virt_board_init;
 mc->max_cpus = 8;
 mc->default_cpu_type = VIRT_CPU;
+mc->pci_allow_0_address = true;
 }
 
 static const TypeInfo riscv_virt_machine_typeinfo = {
-- 
2.7.4




Re: [PATCH] riscv: sifive_u: Add a "serial" property for board serial number

2019-11-21 Thread Bin Meng
On Sat, Nov 16, 2019 at 11:08 PM Bin Meng  wrote:
>
> At present the board serial number is hard-coded to 1, and passed
> to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> the serial number to generate a unique MAC address for the on-chip
> ethernet controller. When multiple QEMU 'sifive_u' instances are
> created and connected to the same subnet, they all have the same
> MAC address hence it creates a unusable network.
>
> A new "serial" property is introduced to specify the board serial
> number. When not given, the default serial number 1 is used.
>
> Signed-off-by: Bin Meng 
> ---
>
>  hw/riscv/sifive_u.c | 21 -
>  include/hw/riscv/sifive_u.h |  1 +
>  2 files changed, 21 insertions(+), 1 deletion(-)
>

ping?



Re: [PATCH v4 2/3] target/riscv: Expose "priv" register for GDB for reads

2019-10-15 Thread Bin Meng
On Mon, Oct 14, 2019 at 11:53 PM Jonathan Behrens  wrote:
>
> This patch enables a debugger to read the current privilege level via a 
> virtual
> "priv" register. When compiled with CONFIG_USER_ONLY the register is still
> visible but always reports the value zero.
>
> Signed-off-by: Jonathan Behrens 
> ---
>  configure   |  4 ++--
>  gdb-xml/riscv-32bit-virtual.xml | 11 +++
>  gdb-xml/riscv-64bit-virtual.xml | 11 +++
>  target/riscv/gdbstub.c  | 23 +++
>  4 files changed, 47 insertions(+), 2 deletions(-)
>  create mode 100644 gdb-xml/riscv-32bit-virtual.xml
>  create mode 100644 gdb-xml/riscv-64bit-virtual.xml
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



[PATCH] riscv: Skip checking CSR privilege level in debugger mode

2019-09-20 Thread Bin Meng
If we are in debugger mode, skip the CSR privilege level checking
so that we can read/write all CSRs. Otherwise we get:

(gdb) p/x $mtvec
Could not fetch register "mtvec"; remote failure reply 'E14'

when the hart is currently in S-mode.

Reported-by: Zong Li 
Signed-off-by: Bin Meng 
---

 target/riscv/csr.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f767ad2..974c9c2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -801,7 +801,10 @@ int riscv_csrrw(CPURISCVState *env, int csrno, 
target_ulong *ret_value,
 #if !defined(CONFIG_USER_ONLY)
 int csr_priv = get_field(csrno, 0x300);
 int read_only = get_field(csrno, 0xC00) == 3;
-if ((write_mask && read_only) || (env->priv < csr_priv)) {
+if ((!env->debugger) && (env->priv < csr_priv)) {
+return -1;
+}
+if (write_mask && read_only) {
 return -1;
 }
 #endif
-- 
2.7.4




Re: [PATCH V3] target/riscv: Bugfix reserved bits in PTE for RV64

2019-09-24 Thread Bin Meng
On Wed, Sep 25, 2019 at 12:49 PM  wrote:
>
> From: Guo Ren 
>

nits: the title is probably better to be rephrased to: Ignore reserved
bits when calculating PPN for RV64

> Highest 10 bits of PTE are reserved in riscv-privileged, ref: [1], so we
> need to ignore them. They can not be a part of ppn.

nits: cannot

>
> 1: The RISC-V Instruction Set Manual, Volume II: Privileged Architecture
>4.4 Sv39: Page-Based 39-bit Virtual-Memory System
>4.5 Sv48: Page-Based 48-bit Virtual-Memory System
>
> Signed-off-by: Guo Ren 
> Reviewed-by: Liu Zhiwei 
> ---
>  target/riscv/cpu_bits.h   | 3 +++
>  target/riscv/cpu_helper.c | 4 +++-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> ---
> Changelog V3:

nits: normally we put changelog before the changed file summary above,
and there is no need to put another ---

>  - Use UUL define for PTE_RESERVED.
>  - Keep ppn >> PTE_PPN_SHIFT
>
> Changelog V2:
>  - Bugfix pte destroyed cause boot fail
>  - Change to AND with a mask instead of shifting both directions
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index e998348..cdc62a8 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -470,6 +470,9 @@
>  #define PTE_D   0x080 /* Dirty */
>  #define PTE_SOFT0x300 /* Reserved for Software */
>
> +/* Reserved highest 10 bits in PTE */
> +#define PTE_RESERVED0xFFC0ULL

Can we define the macro for RV32 too, so that (see below)

> +
>  /* Page table PPN shift amount */
>  #define PTE_PPN_SHIFT   10
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 87dd6a6..7e04ff5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -258,10 +258,12 @@ restart:
>  }
>  #if defined(TARGET_RISCV32)
>  target_ulong pte = ldl_phys(cs->as, pte_addr);
> +hwaddr ppn = pte;
>  #elif defined(TARGET_RISCV64)
>  target_ulong pte = ldq_phys(cs->as, pte_addr);
> +hwaddr ppn = pte & ~PTE_RESERVED;
>  #endif
> -hwaddr ppn = pte >> PTE_PPN_SHIFT;
> +ppn = ppn >> PTE_PPN_SHIFT;

we can just do this in this single line?

>
>  if (!(pte & PTE_V)) {
>  /* Invalid PTE */
> --

Regards,
Bin



Re: [PATCH V4] target/riscv: Ignore reserved bits in PTE for RV64

2019-09-25 Thread Bin Meng
On Wed, Sep 25, 2019 at 5:21 PM  wrote:
>
> From: Guo Ren 
>
> Highest 10 bits of PTE are reserved in riscv-privileged, ref: [1], so we
> need to ignore them. They cannot be a part of ppn.
>
> 1: The RISC-V Instruction Set Manual, Volume II: Privileged Architecture
>4.4 Sv39: Page-Based 39-bit Virtual-Memory System
>4.5 Sv48: Page-Based 48-bit Virtual-Memory System
>
> Signed-off-by: Guo Ren 
> Reviewed-by: Liu Zhiwei 
> ---
>  target/riscv/cpu_bits.h   | 7 +++
>  target/riscv/cpu_helper.c | 2 +-
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> Changelog V4:
>  - Change title to Ignore not Bugfix
>  - Use PTE_PPN_MASK for RV32 and RV64
>
> Changelog V3:
>  - Use UUL define for PTE_RESERVED
>  - Keep ppn >> PTE_PPN_SHIFT
>
> Changelog V2:
>  - Bugfix pte destroyed cause boot fail
>  - Change to AND with a mask instead of shifting both directions
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v3 1/3] target/riscv: Tell gdbstub the correct number of CSRs

2019-10-08 Thread Bin Meng
On Tue, Oct 8, 2019 at 8:15 AM Jonathan Behrens  wrote:
>
> If the number of registers reported to the gdbstub code does not match the
> number in the associated XML file, then the register numbers used by the stub
> may get out of sync with a remote GDB instance.

I am not sure how to trigger the out of sync issue. Do you know how?

>
> Signed-off-by: Jonathan Behrens 
> ---
>  target/riscv/gdbstub.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index ded140e8d8..cb5bfd3d50 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -384,7 +384,7 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>  }
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> - 4096, "riscv-32bit-csr.xml", 0);
> + 240, "riscv-32bit-csr.xml", 0);
>  #elif defined(TARGET_RISCV64)
>  if (env->misa & RVF) {
>  gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> @@ -392,6 +392,6 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>  }
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> - 4096, "riscv-64bit-csr.xml", 0);
> + 240, "riscv-64bit-csr.xml", 0);
>  #endif
>  }

The change looks good to me.

Reviewed-by: Bin Meng 



Re: [PATCH v2] target/riscv: Expose "priv" register for GDB

2019-10-08 Thread Bin Meng
Hi Jim,

On Tue, Oct 8, 2019 at 5:17 AM Jim Wilson  wrote:
>
> On 10/4/19 8:16 AM, Jonathan Behrens wrote:
> > diff --git a/gdb-xml/riscv-32bit-cpu.xml b/gdb-xml/riscv-32bit-cpu.xml
> > index 0d07aaec85..d6d76aafd8 100644
> > --- a/gdb-xml/riscv-32bit-cpu.xml
> > +++ b/gdb-xml/riscv-32bit-cpu.xml
> > @@ -44,4 +44,5 @@
> > 
> > 
> > 
> > +  
> >   
>
> Adding this to the cpu register set means that the gdb "info registers"
> command will now list a value for the mysterious undocumented "priv"

My gdb does not list "priv" register after applying this patch.

>>> info registers
ra 0x0  0x0
sp 0x0  0x0
gp 0x0  0x0
tp 0x0  0x0
t0 0x1000   4096
t1 0x0  0
t2 0x0  0
fp 0x0  0x0
s1 0x0  0
a0 0x0  0
a1 0x1020   4128
a2 0x0  0
a3 0x0  0
a4 0x0  0
a5 0x0  0
a6 0x0  0
a7 0x0  0
s2 0x0  0
s3 0x0  0
s4 0x0  0
s5 0x0  0
s6 0x0  0
s7 0x0  0
s8 0x0  0
s9 0x0  0
s100x0  0
s110x0  0
t3 0x0  0
t4 0x0  0
t5 0x0  0
t6 0x0  0
pc 0x1008   0x1008

Anything I was missing?

> register.  That is likely to result in user confusion, and a few gdb bug
> reports.
>
> Gdb incidentally already has support for a virtual priv register.  From
> gdb/riscv-tdep.c:
>
> static const struct riscv_register_feature riscv_virtual_feature =
> {
>   "org.gnu.gdb.riscv.virtual",
>   {
> { RISCV_PRIV_REGNUM, { "priv" }, false }
>   }
> };
>
> So the correct way to fix this is to add a
> gdb-xml/riscv-32bit-virtual.xml file, along with code to handle this new
> xml file and the registers in it.  Likewise for the 64-bit support.
>
> The main advantage of doing things this way is that only people that
> care about the priv register will see it, and this will interoperate
> with other RISC-V debuggers and targets (if any) that already have
> virtual priv register support.

Regards,
Bin



Re: [PATCH v3 4/7] riscv/sifive_u: Add the start-in-flash property

2019-10-09 Thread Bin Meng
On Wed, Oct 9, 2019 at 7:41 AM Alistair Francis
 wrote:
>
> Add a property that when set to true QEMU will jump from the ROM code to
> the start of flash memory instead of DRAM which is the default
> behaviour.
>
> Signed-off-by: Alistair Francis 
> ---
> v3:
>  - Use the start_addr variable instead of editing reset vector
>  - Fix function names
>
>  hw/riscv/sifive_u.c | 30 +-
>  include/hw/riscv/sifive_u.h |  2 ++
>  2 files changed, 31 insertions(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v3 2/3] target/riscv: Expose priv register for GDB for reads

2019-10-08 Thread Bin Meng
On Tue, Oct 8, 2019 at 8:18 AM Jonathan Behrens  wrote:
>
> This patch enables a debugger to read the current privilege level via a 
> virtual
> "priv" register. When compiled with CONFIG_USER_ONLY the register is still
> visible but always reports the value zero.
>
> Signed-off-by: Jonathan Behrens 
> ---
>  configure   |  4 ++--
>  gdb-xml/riscv-32bit-virtual.xml | 11 +++
>  gdb-xml/riscv-64bit-virtual.xml | 11 +++
>  target/riscv/gdbstub.c  | 23 +++
>  4 files changed, 47 insertions(+), 2 deletions(-)
>  create mode 100644 gdb-xml/riscv-32bit-virtual.xml
>  create mode 100644 gdb-xml/riscv-64bit-virtual.xml
>
> diff --git a/configure b/configure
> index 30544f52e6..6118a6a045 100755
> --- a/configure
> +++ b/configure
> @@ -7520,13 +7520,13 @@ case "$target_name" in
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-32bit-csr.xml"
> +gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-32bit-csr.xml riscv-32bit-virtual.xml"
>;;
>riscv64)
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml 
> riscv-64bit-csr.xml"
> +gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml 
> riscv-64bit-csr.xml riscv-64bit-virtual.xml"
>;;
>sh4|sh4eb)
>  TARGET_ARCH=sh4
> diff --git a/gdb-xml/riscv-32bit-virtual.xml b/gdb-xml/riscv-32bit-virtual.xml
> new file mode 100644
> index 00..905f1c555d
> --- /dev/null
> +++ b/gdb-xml/riscv-32bit-virtual.xml
> @@ -0,0 +1,11 @@
> +
> +
> +
> +
> +
> +  
> +
> diff --git a/gdb-xml/riscv-64bit-virtual.xml b/gdb-xml/riscv-64bit-virtual.xml
> new file mode 100644
> index 00..62d86c237b
> --- /dev/null
> +++ b/gdb-xml/riscv-64bit-virtual.xml
> @@ -0,0 +1,11 @@
> +
> +
> +
> +
> +
> +  
> +
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index cb5bfd3d50..33cf7c4c7d 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -373,6 +373,23 @@ static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t 
> *mem_buf, int n)
>  return 0;
>  }
>
> +static int riscv_gdb_get_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
> +{
> +if (n == 0) {
> +#ifdef CONFIG_USER_ONLY
> +return gdb_get_regl(mem_buf, 0);
> +#else
> +return gdb_get_regl(mem_buf, cs->priv);
> +#endif
> +}
> +return 0;
> +}
> +
> +static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
> +{
> +return 0;
> +}
> +
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
>  {
>  RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -385,6 +402,9 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-32bit-csr.xml", 0);
> +
> +gdb_register_coprocessor(cs, riscv_gdb_get_virtual, 
> riscv_gdb_set_virtual,
> + 1, "riscv-32bit-csr.xml", 0);

This should be riscv-32bit-virtual.xml

>  #elif defined(TARGET_RISCV64)
>  if (env->misa & RVF) {
>  gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> @@ -393,5 +413,8 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-64bit-csr.xml", 0);
> +
> +gdb_register_coprocessor(cs, riscv_gdb_get_virtual, 
> riscv_gdb_set_virtual,
> + 1, "riscv-64bit-virtual.xml", 0);
>  #endif
>  }

Regards,
Bin



Re: [PATCH v3 3/3] target/riscv: Make the priv register writable by GDB

2019-10-08 Thread Bin Meng
On Tue, Oct 8, 2019 at 8:20 AM Jonathan Behrens  wrote:
>
> Currently only PRV_U, PRV_S and PRV_M are supported, so this patch ensures 
> that
> the privilege mode is set to one of them. Once support for the H-extension is
> added, this code will also need to properly update the virtualization status
> when switching between VU/VS-modes and M-mode.
>
> Signed-off-by: Jonathan Behrens 
> ---
>  target/riscv/gdbstub.c | 9 +
>  1 file changed, 9 insertions(+)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v2] target/riscv: Expose "priv" register for GDB

2019-10-05 Thread Bin Meng
On Fri, Oct 4, 2019 at 11:18 PM Jonathan Behrens  wrote:
>
> This patch enables a debugger to read and write the current privilege level 
> via
> a special "priv" register. When compiled with CONFIG_USER_ONLY the register is
> still visible but is hardwired to zero.
>
> Signed-off-by: Jonathan Behrens 
> ---
>  gdb-xml/riscv-32bit-cpu.xml |  1 +
>  gdb-xml/riscv-64bit-cpu.xml |  1 +
>  target/riscv/cpu.c  |  2 +-
>  target/riscv/gdbstub.c  | 14 ++
>  4 files changed, 17 insertions(+), 1 deletion(-)
> ---
> Changelog V2:
> - Use PRV_H and PRV_S instead of integer literals
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v1 1/1] riscv/boot: Fix possible memory leak

2019-10-02 Thread Bin Meng
On Thu, Oct 3, 2019 at 5:38 AM Alistair Francis
 wrote:
>
> Coverity (CID 1405786) thinks that there is a possible memory leak as
> we don't guarentee that the memory allocatd from riscv_find_firmware()
> is freed. This is a false positive, but let's tidy up the code to fix
> the warning.
>
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/boot.c | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
>

Reviewed-by: Bin Meng 

Thanks for the patch. I am not sure how I can easily run Coverity to
verify the fix though.

Regards,
Bin



Re: [PATCH] target/riscv: Expose "priv" register for GDB

2019-10-02 Thread Bin Meng
On Wed, Oct 2, 2019 at 10:51 PM Jonathan Behrens  wrote:
>
> This patch enables a debugger to read and write the current privilege level 
> via
> a special "priv" register. When compiled with CONFIG_USER_ONLY the register is
> still visible but is hardwired to zero.
>
> Signed-off-by: Jonathan Behrens 
> ---
>  gdb-xml/riscv-32bit-cpu.xml |  1 +
>  gdb-xml/riscv-64bit-cpu.xml |  1 +
>  target/riscv/cpu.c  |  2 +-
>  target/riscv/gdbstub.c  | 14 ++
>  4 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/gdb-xml/riscv-32bit-cpu.xml b/gdb-xml/riscv-32bit-cpu.xml
> index 0d07aaec85..d6d76aafd8 100644
> --- a/gdb-xml/riscv-32bit-cpu.xml
> +++ b/gdb-xml/riscv-32bit-cpu.xml
> @@ -44,4 +44,5 @@
>
>
>
> +  
>  
> diff --git a/gdb-xml/riscv-64bit-cpu.xml b/gdb-xml/riscv-64bit-cpu.xml
> index b8aa424ae4..0758d1b5fe 100644
> --- a/gdb-xml/riscv-64bit-cpu.xml
> +++ b/gdb-xml/riscv-64bit-cpu.xml
> @@ -44,4 +44,5 @@
>
>
>
> +  
>  
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index f13e298a36..347989858f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -475,7 +475,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> *data)
>  cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
>  cc->gdb_read_register = riscv_cpu_gdb_read_register;
>  cc->gdb_write_register = riscv_cpu_gdb_write_register;
> -cc->gdb_num_core_regs = 33;
> +cc->gdb_num_core_regs = 34;
>  #if defined(TARGET_RISCV32)
>  cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
>  #elif defined(TARGET_RISCV64)
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index ded140e8d8..dc8cb4d26c 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -278,6 +278,12 @@ int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  return gdb_get_regl(mem_buf, env->gpr[n]);
>  } else if (n == 32) {
>  return gdb_get_regl(mem_buf, env->pc);
> +} else if (n == 33) {
> +#ifdef CONFIG_USER_ONLY
> +return gdb_get_regl(mem_buf, 0);
> +#else
> +return gdb_get_regl(mem_buf, env->priv);
> +#endif
>  }
>  return 0;
>  }
> @@ -296,6 +302,14 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  } else if (n == 32) {
>  env->pc = ldtul_p(mem_buf);
>  return sizeof(target_ulong);
> +} else if (n == 33) {
> +#ifndef CONFIG_USER_ONLY
> +env->priv = ldtul_p(mem_buf) & 0x3;
> +if (env->priv == 2) {

Please use PRV_H

> +env->priv = 1;

and PRV_S here

> +}
> +#endif
> +return sizeof(target_ulong);
>  }
>  return 0;
>  }
> --

Regards,
Bin



Re: [U-Boot] U-Boot build for i.MX board won't boot in corresponding QEMU machine

2019-10-03 Thread Bin Meng
+QEMU developers ML

On Thu, Oct 3, 2019 at 7:37 PM Waseem ALKurdi
 wrote:
>
> Dear all,
>
> I'm trying to get mainline U-Boot to boot on mainline QEMU 4.1.0 for the 
> 'sabrelite' board, using the configuration 'mx6qsabrelite_defconfig'.
>
> It's not booting at all. Actually, not a single U-Boot build for an i.MX 
> board would boot, with the exception of 'imx25-pdk'.
>
> I'm compiling U-Boot by un-tarring the source tarball and running the 
> following commands:
>
> $ time 
> CROSS_COMPILE=/path/to/toolchain/arm-2014.05/bin/arm-none-linux-gnueabi- make 
> ARCH=arm clean
> $ time 
> CROSS_COMPILE=/path/to/toolchain/arm-2014.05/bin/arm-none-linux-gnueabi- make 
> ARCH=arm mrproper
> $ time 
> CROSS_COMPILE=/path/to/toolchain/arm-2014.05/bin/arm-none-linux-gnueabi- make 
> ARCH=arm mx6qsabrelite_defconfig
>
> then after the build finishes:
>
> $ qemu-system-arm -M sabrelite -m 512M -kernel 
> ~/Downloads/u-boot-2019.10-rc3/u-boot.imx -monitor stdio
>
> And other variations on this command as well.
> No amount of kernel commandline options or anything would make it boot. What 
> should I do?
>

I suspect mainline QEMU sabrelite machine only supports booting the
Linux kernel directly, but not booting U-Boot.

Regards,
Bin



Re: [PULL] RISC-V Patches for the 5.0 Soft Freeze, Part 2

2020-02-13 Thread Bin Meng
Hi Palmer,

On Thu, Feb 13, 2020 at 1:30 AM Palmer Dabbelt  wrote:
>
> The following changes since commit 81a23caf47956778c5a5056ad656d1ef92bf9659:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' 
> into staging (2020-02-10 17:08:51 +)
>
> are available in the Git repository at:
>
>   g...@github.com:palmer-dabbelt/qemu.git tags/riscv-for-master-5.0-sf2
>
> for you to fetch changes up to 9c8fdcece53e05590441785ab22d91a22da36e29:
>
>   MAINTAINERS: Add maintainer entry for Goldfish RTC (2020-02-10 12:01:39 
> -0800)
>
> 
> RISC-V Patches for the 5.0 Soft Freeze, Part 2
>
> This is a fairly light-weight pull request, but I wanted to send it out to
> avoid the Goldfish stuff getting buried as the next PR should contain the H
> extension implementation.
>
> As far as this PR goes, it contains:
>
> * The addition of syscon device tree nodes for reboot and poweroff, which
>   allows Linux to control QEMU without an additional driver.  The existing
>   device was already compatible with the syscon interface.
> * A fix to our GDB stub to avoid confusing XLEN and FLEN, specifically useful
>   for rv32id-based systems.
> * A device emulation for the Goldfish RTC device, a simple memory-mapped RTC.
> * The addition of the Goldfish RTC device to the RISC-V virt board.
>
> This passes "make check" and boots buildroot for me.
>

This PR is still missing: http://patchwork.ozlabs.org/patch/1199516/

> 
>
> Peter: I'm sending hw/rtc code because it was suggested that the Goldfish
> implementation gets handled via the RISC-V tree as our virt board is the only
> user.  I'm happy to do things differently in the future (maybe send
> goldfish-specific PRs?) if that's better for you.  Just LMK what makes sense, 
> I
> anticipate that this'll be a pretty low traffic device so I'm fine with pretty
> much anything.
>

Regards,
Bin



Re: [PATCH v2 0/4] riscv: Upgrade OpenSBI to v0.6 and add 32-bit sifive_u bios image

2020-02-29 Thread Bin Meng
Hi Palmer,

On Mon, Feb 24, 2020 at 9:40 PM Bin Meng  wrote:
>
>
> This series advances the roms/opensbi submodule to the v0.6 release,
> and builds and captures platform firmware binaries from that release.
>
> A 32-bit sifive_u bios image has also been added, so that we can have
> 32-bit test coverage for SiFive specific drivers that cannot be done
> with the 'virt' machine.
>
> Two GitLab CI jobs are added to build the OpenSBI firmware binaries.
>
> Changes in v2:
> - new patch: Upgrade opensbi from v0.5 to v0.6
> - Update the 32-bit sifive_u bios image to OpenSBI v0.6
> - new patch: Add GitLab jobs to build OpenSBI firmware binaries
>

Would you please take this series for the next PR?

Regards,
Bin



Re: [PATCH v3 1/2] target/riscv: Emulate TIME CSRs for privileged mode

2020-03-01 Thread Bin Meng
On Sun, Feb 2, 2020 at 9:44 PM Anup Patel  wrote:
>
> Currently, TIME CSRs are emulated only for user-only mode. This
> patch add TIME CSRs emulation for privileged mode.
>
> For privileged mode, the TIME CSRs will return value provided
> by rdtime callback which is registered by QEMU machine/platform
> emulation (i.e. CLINT emulation). If rdtime callback is not
> available then the monitor (i.e. OpenSBI) will trap-n-emulate
> TIME CSRs in software.
>
> We see 25+% performance improvement in hackbench numbers when
> TIME CSRs are not trap-n-emulated.
>
> Signed-off-by: Anup Patel 
> Reviewed-by: Alistair Francis 
> ---
>  target/riscv/cpu.h|  5 +++
>  target/riscv/cpu_helper.c |  5 +++
>  target/riscv/csr.c| 86 +--
>  3 files changed, 92 insertions(+), 4 deletions(-)
>

Jonathan has a patch before:
http://patchwork.ozlabs.org/patch/1106480/

The idea in his patch does similar thing according to mcounteren.TM.
But in this patch we seem to control the TIME CSR purely by software.
Is this behavior spec complaint?

Regards,
Bin



Re: [PATCH v1 2/3] riscv/sifive_u: Add a serial property to the sifive_u SoC

2020-03-04 Thread Bin Meng
Hi Alistair,

On Wed, Mar 4, 2020 at 9:37 AM Alistair Francis
 wrote:
>
> At present the board serial number is hard-coded to 1, and passed
> to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> the serial number to generate a unique MAC address for the on-chip
> ethernet controller. When multiple QEMU 'sifive_u' instances are
> created and connected to the same subnet, they all have the same
> MAC address hence it creates a unusable network.
>
> A new "serial" property is introduced to the sifive_u SoC to specify
> the board serial number. When not given, the default serial number
> 1 is used.
>
> Suggested-by: Bin Meng 
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 8 +++-
>  include/hw/riscv/sifive_u.h | 2 ++
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 9a0145b5b4..e52f9d0bd4 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -488,7 +488,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
>TYPE_SIFIVE_U_PRCI);
>  sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
>TYPE_SIFIVE_U_OTP);
> -qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
> +qdev_prop_set_uint32(DEVICE(>otp), "serial", s->serial);
>  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
>TYPE_CADENCE_GEM);
>  }
> @@ -607,10 +607,16 @@ static void riscv_sifive_u_soc_realize(DeviceState 
> *dev, Error **errp)
>  memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
>  }
>
> +static Property riscv_sifive_u_soc_props[] = {
> +DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
> +DEFINE_PROP_END_OF_LIST()

I am not sure how adding another level of property in the SoC could
solve the 'make check' error.

> +};
> +
>  static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(oc);
>
> +device_class_set_props(dc, riscv_sifive_u_soc_props);
>  dc->realize = riscv_sifive_u_soc_realize;
>  /* Reason: Uses serial_hds in realize function, thus can't be used twice 
> */
>  dc->user_creatable = false;
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 82667b5746..a2baa1de5f 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -42,6 +42,8 @@ typedef struct SiFiveUSoCState {
>  SiFiveUPRCIState prci;
>  SiFiveUOTPState otp;
>  CadenceGEMState gem;
> +
> +uint32_t serial;
>  } SiFiveUSoCState;
>
>  #define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
> --

But anyway this patch does not actually work as expected. See below:

$ ./riscv64-softmmu/qemu-system-riscv64 -M sifive_u,serial=3
-nographic -m 2G -bios opensbi_u-boot_sifive_u_64.bin

OpenSBI v0.5 (Oct 31 2019 18:38:50)
   _  _
  / __ \  / |  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |) | |_) || |_
  \/| .__/ \___|_| |_|_/|/_|
| |
|_|

Platform Name  : SiFive Freedom U540
Platform HART Features : RV64ACDFIMSU
Platform Max HARTs : 5
Current Hart   : 1
Firmware Base  : 0x8000
Firmware Size  : 96 KB
Runtime SBI Version: 0.2

PMP0: 0x8000-0x8001 (A)
PMP1: 0x-0x (A,R,W,X)


U-Boot 2019.10 (Oct 31 2019 - 18:38:33 +0800)

CPU:   rv64imafdcsu
Model: SiFive HiFive Unleashed A00
DRAM:  2 GiB
MMC:
In:serial@1001
Out:   serial@1001
Err:   serial@1001
Net:
Warning: ethernet@1009 MAC addresses don't match:
Address in ROM is  52:54:00:12:34:56
Address in environment is  70:b3:d5:92:f0:01
eth0: ethernet@1009
Hit any key to stop autoboot:  0


See this line:
Address in environment is  70:b3:d5:92:f0:01

It should be: 70:b3:d5:92:f0:03 since I specified serial number as 3.

Regards,
Bin



Re: [PATCH v1 1/3] riscv/sifive_u: Fix up file ordering

2020-03-04 Thread Bin Meng
On Wed, Mar 4, 2020 at 9:37 AM Alistair Francis
 wrote:
>
> Split the file into clear machine and SoC sections.
>

Yep, I found functions in this file are a little bit confusing as well ..

> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 107 ++--
>  1 file changed, 54 insertions(+), 53 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 156a003642..9a0145b5b4 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -399,6 +399,60 @@ static void riscv_sifive_u_init(MachineState *machine)

So while we are here, could we rename this to something like:
sifive_u_machine_init()? ie: drop the riscv_ prefix.

>_space_memory);
>  }
>
> +static bool sifive_u_get_start_in_flash(Object *obj, Error **errp)

and sifive_u_machine_get_start_in_flash()? and other functions too?

> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +return s->start_in_flash;
> +}
> +
> +static void sifive_u_set_start_in_flash(Object *obj, bool value, Error 
> **errp)
> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = value;
> +}
> +
> +static void riscv_sifive_u_machine_instance_init(Object *obj)
> +{
> +SiFiveUState *s = RISCV_U_MACHINE(obj);
> +
> +s->start_in_flash = false;
> +object_property_add_bool(obj, "start-in-flash", 
> sifive_u_get_start_in_flash,
> + sifive_u_set_start_in_flash, NULL);
> +object_property_set_description(obj, "start-in-flash",
> +"Set on to tell QEMU's ROM to jump to " \
> +"flash. Otherwise QEMU will jump to 
> DRAM",
> +NULL);
> +}
> +
> +
> +static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
> +{
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +mc->desc = "RISC-V Board compatible with SiFive U SDK";
> +mc->init = riscv_sifive_u_init;
> +mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 
> SIFIVE_U_COMPUTE_CPU_COUNT;
> +mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
> +mc->default_cpus = mc->min_cpus;
> +}
> +
> +static const TypeInfo riscv_sifive_u_machine_typeinfo = {
> +.name   = MACHINE_TYPE_NAME("sifive_u"),
> +.parent = TYPE_MACHINE,
> +.class_init = riscv_sifive_u_machine_class_init,
> +.instance_init = riscv_sifive_u_machine_instance_init,
> +.instance_size = sizeof(SiFiveUState),
> +};
> +
> +static void riscv_sifive_u_machine_init_register_types(void)
> +{
> +type_register_static(_sifive_u_machine_typeinfo);
> +}
> +
> +type_init(riscv_sifive_u_machine_init_register_types)
> +
>  static void riscv_sifive_u_soc_init(Object *obj)

Similarly this can be renamed to: sifive_u_soc_init(), and other soc functions.

>  {
>  MachineState *ms = MACHINE(qdev_get_machine());
> @@ -439,33 +493,6 @@ static void riscv_sifive_u_soc_init(Object *obj)
>TYPE_CADENCE_GEM);
>  }
>
> -static bool sifive_u_get_start_in_flash(Object *obj, Error **errp)
> -{
> -SiFiveUState *s = RISCV_U_MACHINE(obj);
> -
> -return s->start_in_flash;
> -}
> -
> -static void sifive_u_set_start_in_flash(Object *obj, bool value, Error 
> **errp)
> -{
> -SiFiveUState *s = RISCV_U_MACHINE(obj);
> -
> -s->start_in_flash = value;
> -}
> -
> -static void riscv_sifive_u_machine_instance_init(Object *obj)
> -{
> -SiFiveUState *s = RISCV_U_MACHINE(obj);
> -
> -s->start_in_flash = false;
> -object_property_add_bool(obj, "start-in-flash", 
> sifive_u_get_start_in_flash,
> - sifive_u_set_start_in_flash, NULL);
> -object_property_set_description(obj, "start-in-flash",
> -"Set on to tell QEMU's ROM to jump to " \
> -"flash. Otherwise QEMU will jump to 
> DRAM",
> -NULL);
> -}
> -
>  static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
>  {
>  MachineState *ms = MACHINE(qdev_get_machine());
> @@ -603,29 +630,3 @@ static void riscv_sifive_u_soc_register_types(void)
>  }
>
>  type_init(riscv_sifive_u_soc_register_types)
> -
> -static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
> -{
> -MachineClass *mc = MACHINE_CLASS(oc);
> -
> -mc->desc = "RISC-V Board compatible with SiFive U SDK";
> -mc->init = riscv_sifive_u_init;
> -mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 
> SIFIVE_U_COMPUTE_CPU_COUNT;
> -mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
> -mc->default_cpus = mc->min_cpus;
> -}
> -
> -static const TypeInfo riscv_sifive_u_machine_typeinfo = {
> -.name   = MACHINE_TYPE_NAME("sifive_u"),
> -.parent = TYPE_MACHINE,
> -.class_init = riscv_sifive_u_machine_class_init,
> -.instance_init = riscv_sifive_u_machine_instance_init,
> -.instance_size = sizeof(SiFiveUState),
> -};
> 

Re: [PATCH v1 2/3] riscv/sifive_u: Add a serial property to the sifive_u SoC

2020-03-05 Thread Bin Meng
Hi Alistair,

On Thu, Mar 5, 2020 at 7:13 AM Alistair Francis  wrote:
>
> On Wed, Mar 4, 2020 at 6:47 AM Bin Meng  wrote:
> >
> > Hi Alistair,
> >
> > On Wed, Mar 4, 2020 at 9:37 AM Alistair Francis
> >  wrote:
> > >
> > > At present the board serial number is hard-coded to 1, and passed
> > > to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> > > the serial number to generate a unique MAC address for the on-chip
> > > ethernet controller. When multiple QEMU 'sifive_u' instances are
> > > created and connected to the same subnet, they all have the same
> > > MAC address hence it creates a unusable network.
> > >
> > > A new "serial" property is introduced to the sifive_u SoC to specify
> > > the board serial number. When not given, the default serial number
> > > 1 is used.
> > >
> > > Suggested-by: Bin Meng 
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  hw/riscv/sifive_u.c | 8 +++-
> > >  include/hw/riscv/sifive_u.h | 2 ++
> > >  2 files changed, 9 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > > index 9a0145b5b4..e52f9d0bd4 100644
> > > --- a/hw/riscv/sifive_u.c
> > > +++ b/hw/riscv/sifive_u.c
> > > @@ -488,7 +488,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
> > >TYPE_SIFIVE_U_PRCI);
> > >  sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
> > >TYPE_SIFIVE_U_OTP);
> > > -qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
> > > +qdev_prop_set_uint32(DEVICE(>otp), "serial", s->serial);
> > >  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
> > >TYPE_CADENCE_GEM);
> > >  }
> > > @@ -607,10 +607,16 @@ static void riscv_sifive_u_soc_realize(DeviceState 
> > > *dev, Error **errp)
> > >  memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
> > >  }
> > >
> > > +static Property riscv_sifive_u_soc_props[] = {
> > > +DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
> > > +DEFINE_PROP_END_OF_LIST()
> >
> > I am not sure how adding another level of property in the SoC could
> > solve the 'make check' error.
>
> The problem is that you were adding a machine property and then you
> had the SoC reach up to the machine object to get the serial value.
> This isn't correct and is why the tests fail.
>

So looks the failure was due to a check in the test codes only? As I
did not see QEMU crashed during my normal usage.

> This patch series instead adds a property to the machine and the SoC,
> where the machine sets the SoC property.
>

Regards,
Bin



Re: [PATCH v2 2/3] riscv/sifive_u: Add a serial property to the sifive_u SoC

2020-03-05 Thread Bin Meng
On Thu, Mar 5, 2020 at 7:11 AM Alistair Francis
 wrote:
>
> At present the board serial number is hard-coded to 1, and passed
> to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> the serial number to generate a unique MAC address for the on-chip
> ethernet controller. When multiple QEMU 'sifive_u' instances are
> created and connected to the same subnet, they all have the same
> MAC address hence it creates a unusable network.
>
> A new "serial" property is introduced to the sifive_u SoC to specify
> the board serial number. When not given, the default serial number
> 1 is used.
>
> Suggested-by: Bin Meng 
> Signed-off-by: Alistair Francis 
> ---
>  hw/riscv/sifive_u.c | 8 +++-
>  include/hw/riscv/sifive_u.h | 2 ++
>  2 files changed, 9 insertions(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH v1 2/3] riscv/sifive_u: Add a serial property to the sifive_u SoC

2020-03-05 Thread Bin Meng
Hi Alistair,

On Fri, Mar 6, 2020 at 12:53 AM Alistair Francis  wrote:
>
> On Thu, Mar 5, 2020 at 1:31 AM Bin Meng  wrote:
> >
> > Hi Alistair,
> >
> > On Thu, Mar 5, 2020 at 7:13 AM Alistair Francis  
> > wrote:
> > >
> > > On Wed, Mar 4, 2020 at 6:47 AM Bin Meng  wrote:
> > > >
> > > > Hi Alistair,
> > > >
> > > > On Wed, Mar 4, 2020 at 9:37 AM Alistair Francis
> > > >  wrote:
> > > > >
> > > > > At present the board serial number is hard-coded to 1, and passed
> > > > > to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> > > > > the serial number to generate a unique MAC address for the on-chip
> > > > > ethernet controller. When multiple QEMU 'sifive_u' instances are
> > > > > created and connected to the same subnet, they all have the same
> > > > > MAC address hence it creates a unusable network.
> > > > >
> > > > > A new "serial" property is introduced to the sifive_u SoC to specify
> > > > > the board serial number. When not given, the default serial number
> > > > > 1 is used.
> > > > >
> > > > > Suggested-by: Bin Meng 
> > > > > Signed-off-by: Alistair Francis 
> > > > > ---
> > > > >  hw/riscv/sifive_u.c | 8 +++-
> > > > >  include/hw/riscv/sifive_u.h | 2 ++
> > > > >  2 files changed, 9 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > > > > index 9a0145b5b4..e52f9d0bd4 100644
> > > > > --- a/hw/riscv/sifive_u.c
> > > > > +++ b/hw/riscv/sifive_u.c
> > > > > @@ -488,7 +488,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
> > > > >TYPE_SIFIVE_U_PRCI);
> > > > >  sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
> > > > >TYPE_SIFIVE_U_OTP);
> > > > > -qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
> > > > > +qdev_prop_set_uint32(DEVICE(>otp), "serial", s->serial);
> > > > >  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
> > > > >TYPE_CADENCE_GEM);
> > > > >  }
> > > > > @@ -607,10 +607,16 @@ static void 
> > > > > riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
> > > > >  memmap[SIFIVE_U_GEM_MGMT].base, 
> > > > > memmap[SIFIVE_U_GEM_MGMT].size);
> > > > >  }
> > > > >
> > > > > +static Property riscv_sifive_u_soc_props[] = {
> > > > > +DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, 
> > > > > OTP_SERIAL),
> > > > > +DEFINE_PROP_END_OF_LIST()
> > > >
> > > > I am not sure how adding another level of property in the SoC could
> > > > solve the 'make check' error.
> > >
> > > The problem is that you were adding a machine property and then you
> > > had the SoC reach up to the machine object to get the serial value.
> > > This isn't correct and is why the tests fail.
> > >
> >
> > So looks the failure was due to a check in the test codes only? As I
> > did not see QEMU crashed during my normal usage.
>
> No, the bug was in the actual implementation. You were just lucky that
> you didn't see any issues as in your case you could access the machine
> state. The make check probably added the SoC individually and hence
> caught the bug.

That sounds like the difference that caused the crash in the test.
Thanks for helping this!

Regards,
Bin



Re: [PATCH v2] riscv: sifive_u: Add a "serial" property for board serial number

2020-02-24 Thread Bin Meng
Hi Alistair,

On Tue, Feb 25, 2020 at 5:14 AM Alistair Francis  wrote:
>
> On Sun, Feb 16, 2020 at 5:56 AM Bin Meng  wrote:
> >
> > At present the board serial number is hard-coded to 1, and passed
> > to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> > the serial number to generate a unique MAC address for the on-chip
> > ethernet controller. When multiple QEMU 'sifive_u' instances are
> > created and connected to the same subnet, they all have the same
> > MAC address hence it creates a unusable network.
> >
> > A new "serial" property is introduced to specify the board serial
> > number. When not given, the default serial number 1 is used.
> >
> > Signed-off-by: Bin Meng 
> >
> > ---
> >
> > Changes in v2:
> > - Move setting OTP serial number property from riscv_sifive_u_soc_init()
> >   to riscv_sifive_u_soc_realize(), to fix the 'check-qtest-riscv' error.
> >   I am not really sure why doing so could fix the 'make check' error.
> >   The v1 patch worked fine and nothing seems wrong.
> >
> >  hw/riscv/sifive_u.c | 21 -
> >  include/hw/riscv/sifive_u.h |  1 +
> >  2 files changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > index 0e12b3c..ca561d3 100644
> > --- a/hw/riscv/sifive_u.c
> > +++ b/hw/riscv/sifive_u.c
> > @@ -34,6 +34,7 @@
> >  #include "qemu/log.h"
> >  #include "qemu/error-report.h"
> >  #include "qapi/error.h"
> > +#include "qapi/visitor.h"
> >  #include "hw/boards.h"
> >  #include "hw/loader.h"
> >  #include "hw/sysbus.h"
> > @@ -434,7 +435,6 @@ static void riscv_sifive_u_soc_init(Object *obj)
> >TYPE_SIFIVE_U_PRCI);
> >  sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
> >TYPE_SIFIVE_U_OTP);
> > -qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
> >  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
> >TYPE_CADENCE_GEM);
> >  }
> > @@ -453,6 +453,18 @@ static void sifive_u_set_start_in_flash(Object *obj, 
> > bool value, Error **errp)
> >  s->start_in_flash = value;
> >  }
> >
> > +static void sifive_u_get_serial(Object *obj, Visitor *v, const char *name,
> > +void *opaque, Error **errp)
> > +{
> > +visit_type_uint32(v, name, (uint32_t *)opaque, errp);
> > +}
> > +
> > +static void sifive_u_set_serial(Object *obj, Visitor *v, const char *name,
> > +void *opaque, Error **errp)
> > +{
> > +visit_type_uint32(v, name, (uint32_t *)opaque, errp);
>
> This is a little confusing. Maybe it's worth adding a comment that
> opaque is s->serial?

Yes, I can add a comment.

>
> Either that or change opaque to be SiFiveUState *s and then access
> serial via the struct.

Do you mean something like this?

Calling object_property_add() with opaque as NULL, not >serial:

object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
sifive_u_set_serial, NULL, NULL, NULL);

Then in the sifive_u_get_serial() or sifive_u_set_serial(), replace
opaque with RISCV_U_MACHINE(obj)->serial.

Wow, it looks we have designed so flexible APIs :)

>
> > +}
> > +
> >  static void riscv_sifive_u_machine_instance_init(Object *obj)
> >  {
> >  SiFiveUState *s = RISCV_U_MACHINE(obj);
> > @@ -464,11 +476,17 @@ static void 
> > riscv_sifive_u_machine_instance_init(Object *obj)
> >  "Set on to tell QEMU's ROM to jump to 
> > " \
> >  "flash. Otherwise QEMU will jump to 
> > DRAM",
> >  NULL);
> > +
> > +s->serial = OTP_SERIAL;
> > +object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
> > +sifive_u_set_serial, NULL, >serial, NULL);
> > +object_property_set_description(obj, "serial", "Board serial number", 
> > NULL);
> >  }
> >
> >  static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
> >  {
> >  MachineState *ms = MACHINE(qdev_get_machine());
> > +SiFiveUState *us = RISCV_U_MACHINE(ms);
>
> I don't think the Soc should access the machine like this. What if we
> use this Soc on a different machine?
>

Yes, agree. The v1 patch does this in the riscv_sifive_u_init(), but
it could not pass the "make check". See the changelog I mentioned. Do
you know how to fix the "make check" properly? The issue is quite
strange. The v1 patch worked perfectly OK and I did not observe any
crash during my normal use, but with "make check" QEMU RISC-V crashes
with the v1 patch.

> There should be a SoC "serial" property that is set before realise as well.
>

v1 patch: http://patchwork.ozlabs.org/patch/1196127/

Regards,
Bin



[PATCH v2 4/4] gitlab-ci.yml: Add jobs to build OpenSBI firmware binaries

2020-02-24 Thread Bin Meng
Add two GitLab jobs to build the OpenSBI firmware binaries.

The first job builds a Docker image with the packages requisite
to build OpenSBI, and stores this image in the GitLab registry.
The second job pulls the image from the registry and builds the
OpenSBI firmware binaries.

The docker image is only rebuilt if the GitLab YAML or the
Dockerfile is updated. The second job is only built when the
roms/opensbi/ submodule is updated, when a git-ref starts with
'opensbi' or when the last commit contains 'OpenSBI'. The files
generated are archived in the artifacts.zip file.

With OpenSBI v0.6, it took 2 minutes 56 seconds to build
the docker image, and 1 minute 24 seconds to generate the
artifacts.zip with the firmware binaries (filesize: 111KiB).

See: https://gitlab.com/lbmeng/qemu/pipelines/120520138

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Bin Meng 

---

Changes in v2:
- new patch: Add GitLab jobs to build OpenSBI firmware binaries

 .gitlab-ci-opensbi.yml  | 63 +
 .gitlab-ci.d/opensbi/Dockerfile | 33 +
 .gitlab-ci.yml  |  1 +
 3 files changed, 97 insertions(+)
 create mode 100644 .gitlab-ci-opensbi.yml
 create mode 100644 .gitlab-ci.d/opensbi/Dockerfile

diff --git a/.gitlab-ci-opensbi.yml b/.gitlab-ci-opensbi.yml
new file mode 100644
index 000..dd051c0
--- /dev/null
+++ b/.gitlab-ci-opensbi.yml
@@ -0,0 +1,63 @@
+docker-opensbi:
+ stage: build
+ rules: # Only run this job when the Dockerfile is modified
+ - changes:
+   - .gitlab-ci-opensbi.yml
+   - .gitlab-ci.d/opensbi/Dockerfile
+   when: always
+ image: docker:19.03.1
+ services:
+ - docker:19.03.1-dind
+ variables:
+  GIT_DEPTH: 3
+  IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build
+  # We don't use TLS
+  DOCKER_HOST: tcp://docker:2375
+  DOCKER_TLS_CERTDIR: ""
+ before_script:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ script:
+ - docker pull $IMAGE_TAG || true
+ - docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
+--tag $IMAGE_TAG .gitlab-ci.d/opensbi
+ - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
+ - docker push $IMAGE_TAG
+
+build-opensbi:
+ rules: # Only run this job when ...
+ - changes: # ... roms/opensbi/ is modified (submodule updated)
+   - roms/opensbi/*
+   when: always
+ - if: '$CI_COMMIT_REF_NAME =~ /^opensbi/' # or the branch/tag starts with 
'opensbi'
+   when: always
+ - if: '$CI_COMMIT_MESSAGE =~ /opensbi/i' # or last commit description 
contains 'OpenSBI'
+   when: always
+ artifacts:
+   paths: # 'artifacts.zip' will contains the following files:
+   - pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin
+   - pc-bios/opensbi-riscv32-virt-fw_jump.bin
+   - pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
+   - pc-bios/opensbi-riscv64-virt-fw_jump.bin
+   - opensbi32-virt-stdout.log
+   - opensbi32-virt-stderr.log
+   - opensbi64-virt-stdout.log
+   - opensbi64-virt-stderr.log
+   - opensbi32-sifive_u-stdout.log
+   - opensbi32-sifive_u-stderr.log
+   - opensbi64-sifive_u-stdout.log
+   - opensbi64-sifive_u-stderr.log
+ image: $CI_REGISTRY_IMAGE:opensbi-cross-build
+ variables:
+   GIT_DEPTH: 3
+ script: # Clone the required submodules and build OpenSBI
+ - git submodule update --init roms/opensbi
+ - export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
+ - echo "=== Using ${JOBS} simultaneous jobs ==="
+ - make -j${JOBS} -C roms/opensbi clean
+ - make -j${JOBS} -C roms opensbi32-virt 2>&1 1>opensbi32-virt-stdout.log | 
tee -a opensbi32-virt-stderr.log >&2
+ - make -j${JOBS} -C roms/opensbi clean
+ - make -j${JOBS} -C roms opensbi64-virt 2>&1 1>opensbi64-virt-stdout.log | 
tee -a opensbi64-virt-stderr.log >&2
+ - make -j${JOBS} -C roms/opensbi clean
+ - make -j${JOBS} -C roms opensbi32-sifive_u 2>&1 
1>opensbi32-sifive_u-stdout.log | tee -a opensbi32-sifive_u-stderr.log >&2
+ - make -j${JOBS} -C roms/opensbi clean
+ - make -j${JOBS} -C roms opensbi64-sifive_u 2>&1 
1>opensbi64-sifive_u-stdout.log | tee -a opensbi64-sifive_u-stderr.log >&2
diff --git a/.gitlab-ci.d/opensbi/Dockerfile b/.gitlab-ci.d/opensbi/Dockerfile
new file mode 100644
index 000..4ba8a4d
--- /dev/null
+++ b/.gitlab-ci.d/opensbi/Dockerfile
@@ -0,0 +1,33 @@
+#
+# Docker image to cross-compile OpenSBI firmware binaries
+#
+FROM ubuntu:18.04
+
+MAINTAINER Bin Meng 
+
+# Install packages required to build OpenSBI
+RUN apt update \
+&& \
+\
+DEBIAN_FRONTEND=noninteractive \
+apt install --assume-yes --no-install-recommends \
+build-essential \
+ca-certificates \
+git \
+make \
+wget \
+&& \
+\
+rm -rf /var/lib/apt/lists/*
+
+# Manually install the kernel.org "Crosstool" based toolchains for gcc-8.3
+RUN wget -O - \
+
https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bi

[PATCH v2 0/4] riscv: Upgrade OpenSBI to v0.6 and add 32-bit sifive_u bios image

2020-02-24 Thread Bin Meng


This series advances the roms/opensbi submodule to the v0.6 release,
and builds and captures platform firmware binaries from that release.

A 32-bit sifive_u bios image has also been added, so that we can have
32-bit test coverage for SiFive specific drivers that cannot be done
with the 'virt' machine.

Two GitLab CI jobs are added to build the OpenSBI firmware binaries.

Changes in v2:
- new patch: Upgrade opensbi from v0.5 to v0.6
- Update the 32-bit sifive_u bios image to OpenSBI v0.6
- new patch: Add GitLab jobs to build OpenSBI firmware binaries

Bin Meng (4):
  roms: opensbi: Upgrade from v0.5 to v0.6
  roms: opensbi: Add 32-bit firmware image for sifive_u machine
  riscv: sifive_u: Update BIOS_FILENAME for 32-bit
  gitlab-ci.yml: Add jobs to build OpenSBI firmware binaries

 .gitlab-ci-opensbi.yml   |  63 +++
 .gitlab-ci.d/opensbi/Dockerfile  |  33 ++
 .gitlab-ci.yml   |   1 +
 Makefile |   2 +-
 hw/riscv/sifive_u.c  |   6 ++-
 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin | Bin 0 -> 49472 bytes
 pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin 40984 -> 41280 bytes
 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 49160 -> 53760 bytes
 pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin 45064 -> 49664 bytes
 roms/Makefile|   7 +++
 roms/opensbi |   2 +-
 11 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 .gitlab-ci-opensbi.yml
 create mode 100644 .gitlab-ci.d/opensbi/Dockerfile
 create mode 100644 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin

-- 
2.7.4




[PATCH v2 2/4] roms: opensbi: Add 32-bit firmware image for sifive_u machine

2020-02-24 Thread Bin Meng
Although the real world SiFive HiFive Unleashed board is a 64-bit
hardware configuration, with QEMU it is possible to test 32-bit
configuration with the same hardware features.

This updates the roms Makefile to add the build rules for creating
the 32-bit OpenSBI firmware image for sifive_u machine. A pre-built
OpenSBI v0.6 image has been added as the default bios for 32-bit
sifive_u machine.

Signed-off-by: Bin Meng 

---

Changes in v2:
- Update the 32-bit sifive_u bios image to OpenSBI v0.6

 Makefile |   2 +-
 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin | Bin 0 -> 49472 bytes
 roms/Makefile|   7 +++
 3 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100644 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin

diff --git a/Makefile b/Makefile
index 146a91b..b140855 100644
--- a/Makefile
+++ b/Makefile
@@ -804,7 +804,7 @@ u-boot.e500 u-boot-sam460-20100605.bin \
 qemu_vga.ndrv \
 edk2-licenses.txt \
 hppa-firmware.img \
-opensbi-riscv32-virt-fw_jump.bin \
+opensbi-riscv32-sifive_u-fw_jump.bin opensbi-riscv32-virt-fw_jump.bin \
 opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin
 
 
diff --git a/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin 
b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin
new file mode 100644
index 
..bab13f597ac9da31518f0a2bb22c2a1dbd56380d
GIT binary patch
literal 49472
zcmcG%3tUrIwm-g4PEJmO55TC=j<%Et2yHDIA6FeMuMojU)e#+R?X;YtV`utssN=Q0
zPQm0P21L||DXq>>AE3+NkYIv|(99f+Nu*{2Pr#qgYA{!I}{%wJSXC>uaR0?=x`^{8gO6zQ+>A``?}V
zWtVJ?RR8>=zWR@L)6)G2rKMwKM%-W5bBUDp!6cT=iF^2AUBHMstO}wF;>lytfurg$
ztB8=~M?Upg##?Bw;jzA_>vGKo4_U*h2ZDAUQV#@Toh
zLa!R0)-3(P-i#5nM1A2{na6Il7Zqs3%6;RT79pTcmc_mL6Oc_%w5bHuC46z8I+;
z-t(yh+0|bgbKZ~tBicvt-HVasSK1N4AWS9;grUQ;?U5-3+VJzTKsr2Vb0=h7)10Jz
zX+CPl)n-|ARvX5XP~JVgwKK2{CQ`@toEw51^ygS|%6Vn3n!g+zSo+eVcPXt9WDbQc
z>obfR=G@ie#JDwq=+>}A{Y+m*_m>|?cwYy8+0L#Zj?N!QbzfZpX3HBMk`ZkC%*Z
zxrxJlka4&_!^h3MWfSIS5q6gh{XGcY4rSe`S)JAdiC4C|+#T@ln;+FZH98
zSt0XcuSLy_bwAkJnH51stA>fi3{jIF|FZEbo17!r^!}{S@XE;Q)Edo)7zLFom>rhF
zvC%3{r?SfI7ce5Gq6S_S?ShsDd1)+dFhjAT}3XOWp9EfoyO>L(km
z4Vx{y7EWSq$M+E1)ltM#f1C!7iT`YZzZyi`;4426U*3(+o!b3(6tfKV>
z9+Wxp3-$km`u?$_Va{9O#r)DysX|_B-^zCl4M8KNfjB=ER7`QJ;@JJ>iSVXR9k~
ztLtly)E+<7SbzGHvq#P!yLkMY6F)Rw{rtx1_Affm>Ntj611?TJrF$Vj}J
zD4Vl>PI%g$w1m0G=Vr{iI!`fW+dcSjyi2#?PqVX+dugF^^m;#E>F(;8p%1O#eW(+w7
zW=hT!CM73@NzF-Rrshm#rsYgyrsqs`FZp3HeNYbF`JGJ8eZO7Hlr%$C~IafHzC
z<2bU4UN!iw<~W%$UMk1wrK`UjA#rq^N&1p4CrXajA2T-|Idc3HQ0UOv+U!APCQsbC
zKN@Q{Fl?=fVO`r8qw51^i{jHY34B_?dHz$P>>)eHI!|)!K?`SemU6~JE{?5j
z=2%xbXRK}I!a18}6>&5#BGsHOa{!Z|;HKyX4QI~er>wDQER5Q2W)2t3DzMG{G2YS2
zGfN9j6};ap>NO1%cjsD9SjcZg1M8Bo5Q19z87U^UA28wktb%G_Q7_UqB1OmIR-!qL
zT0v#`p17IQj8Q?P$nA*>c|1oSDSF7v2}|3UP0a!MdUq
zM%Q>nVDF5zCuMA{OUAmIWky%4Ebv*;!Iky}SEP0?2hHm6ehUdpPid3x#l8{W;`=sX
zQb#Hv)zWDKdIsMv7OcRDajM7vwfU6deI{@Fd0yWssEaxTfO@qH)9UT}wU7d)}M
zWAXgFR5msO&(9lONis2S-BD>YXU0)0quIdZ=+zHcn8C>!P(sb=|Db!Jop@r;&6j?QfAGYH&?nKb48XoZ|jfQyp*r
zo!C?%a$AtRP2FoZH$(J{X)6o>8xuG$|a%P^CV*B#;{GAc?^Jki
z(8?jX0Y=F@!jKnpW{4XYo>8mA~llgF~*Ub$S&)#Ya>
zrmqRDmu>X6fR_BNY{9JInQFxuuf%RBfMf(dF5uG)d|H2kk0-8j9%Srdiq|XSQ^m}O
zJIX6eaVE6ugDznK5|GmRN179M}$SXurE
z>mKXATpB5dQA+EF=qf%w=)%*`HiDLFjyQp%%CI5lZ?~98}+L)wBxtg9a|M>ib
zr}jJ*{`C5%WecuOf9^TVWXlS}I|r7gU8-OX4@q11v7d9k($RTMd1)#1Ac?;^48k|1
zB#4v7pjkb+P#eaPo*ZY#jtYB-UUVg{yWNIVKkJn{`BN%wP}0(~Ci)>Vq2Zs*s8t+^
ztWP~eLRdo~c6KLEgdkO4U!U9FOawj8HTU)H
zJANFLC|qjp9a*FeQ(;Zn@Uwd1PAb14&3MS5C`hw$cSy67=${MyYexTCd-N~IMY)7&
z%6c{_meF_P9-d0EmsT5n|4{vvFp9Ibtn`N%Yjl-nKh^qjJ;tb9nRs-zxMHk3k-G(6
z<0$6Zh|=%!4{G+(wVu12GTE)?+G!89rKR5ts7Om#xy<%xvN(Fepx2lwxvR+Aw
zjh=L`UT!{m?_O%;pnx0{kb?s9z_~!jMp~;V_tG(uIB7=h?3%gNBqY;mTQ-K2nQ~mV
zSDjt!Zid(lhQ$2VX>lKeQ^nJs#2e1Wvth(t~rWt0T?e!9whn
ze)aP;#Gq3J?yuW#JzVSw3meU((6LMvB~A=aUGE)FCgpqIx**L^V{#$ZUlHps=8<7<
zkG;nGAK!=CSdnPO#eZoP9q2?DJP`%G6ew8PdOd|Grc6=Mwj^z!59?}kt18(w^bJMm$D
z{lCHI=cQc$KBpjGpz$5mI?AD&+t(MOF^FHgc$ho}nAK!1h?2tGXNSsng
zobsL$=Pu*L=ySmTcVgq$%p$9yTYL9YmLgMP*#>c3nPpYn=RRH9F|Gyr*!rZ83Vpg9
z`X!Yv-MA?cT3X?>cxC*Z)EN}OESyGk1#uqNNG$=m4DY0#Julx*36uqniweeX
zdGPKK6s$9Fg{ix}e}H}}XPqukq8XHE1tq$li7qPTspdIC+yhR5wN#e1+b|keWmd5v
z)-N6IyzkdAyybQqV!h9c4FTFLEM(rj#0adZpME7#!zHdtOm{{WQj5+I+Hc6=pIzF!2sUv?M1msS;73Z(%xMGS)sM
zai4vq#Td;IHd+tsR5T-)_$vN#YAa9~I76ipXrSaRYX-6Wren>l$24
zZFYfriL{dSkN<7FqxmAaaneJ$s*>*5A
zIOSIa*4Ta!81!wE=Ol42xO=Ov>(GPa6#vKF-wx|4>d|^W#kNy#0^c!3b>%}7s{+=8D{edj9yI;eB+0-T!-LjWnvm+b!Qhg?}er`3@
zF{wr~zY=<;sVsMdm_Noe<-88XOYuSdu#i`=XCv03zhu5CfkA7RxuxDmC?7gyd{ax!er_j2zWZ4Etwew}|coURkO#hz9%H;O@LX{9aHr
z$^4M7revfZPfeJ*XX<2;_G!NO*tp~78RoOz9o@4dOGH|K?Q8BNt~1AQsXS7w8`&|h
zj%s8zRFZjD0BNr@p_^`J#z?l#SJ)r{GN>oc465enXvdIc{63xR7Ss`;LW|yYm{Lh@FQq#=*NCx}4T+v}4|VxvxWtKm
zKAc-kIkC)i;46uq{9~IEg;o4O4f=?)rAL>k-!xng=J3b|Z=4O&+7QPKSqR~Urn
zPxdddYm0gEY4XF#C54fNp#IdKYPJ@CVge=u%RgO#2{(c

[PATCH v2 1/4] roms: opensbi: Upgrade from v0.5 to v0.6

2020-02-24 Thread Bin Meng
: ariane-fpga: Fix doc styles
82fd42f doc: qemu_virt: Fix doc styles
f8ce996 doc: sifive_fu540: Fix doc styles
27a5c7f doc: thead-c910: Fix doc styles
0b41453 Revert "lib: Use __builtin_ctzl() in pmp_get()"
c66543d lib: utils: htif: Fix 32-bit build
bc874e3 lib: Don't check MIDELEG and MEDELEG at end of delegate_traps()
24c3082 lib: Print interrupt and exception delegation in boot prints
66fb729 platform: sifive: fu540: Add 32-bit specific fdt/payload addresses
3e7d666 platform: qemu: virt: Correct the typo in config.mk
c3b3b8f lib: Fix typo in atomic exchange functions
3936243 lib: Use available hart mask for correct hbase value
f8b3bb8 lib: Simplify the for-loop in sbi_ipi_send_many()
ac5e821 include: Bump-up version to 0.6

Signed-off-by: Bin Meng 

---

Changes in v2:
- new patch: Upgrade opensbi from v0.5 to v0.6

 pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin 40984 -> 41280 bytes
 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 49160 -> 53760 bytes
 pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin 45064 -> 49664 bytes
 roms/opensbi |   2 +-
 4 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin 
b/pc-bios/opensbi-riscv32-virt-fw_jump.bin
index 
6c5b7b89f676392b687d9835ac9fbdc34f3052cd..c9654e70471764b0ee13e4d10b6f9368c6bcbf57
 100644
GIT binary patch
delta 19518
zcmcJ13s@7!7VvB~yGcML7$m5ukw6esMC0RXEAk2vs)!b}+K0-DueMrCZEIU^z_7uf
zh)n2p;%5ANcD%N``$SYv0Qmd$~Rcb`4wGCD&%}UY@%q}d++~$-ygr@?9QAy
zbLO0xGc)JRvb{`HRxUDV#SALSV31bEqLBewDLgS^RK$ysmX)E7=Qyzs#SLH-N-07L
zsWh6OJYopscu9L(LzVW0yx6FJ@A5%=seG=9I3v*Br1
zCguUa+RDs!08N7YdLDn=c+0w?pqtxc7Q%WBXwRmwMn#zww*}sT(g1u
zzMLUU8L-hdmaBReao<)@FCGy1q#x!a(T)0c}Io(`n=rk1p4ZRNauTnb?
ztQfdLVN~}*YE>!{8WJSpcT*`yDU?WqGbd{Vx*QIq0u5J(IZKBJkyX)}La=_42$TrgpXuu)w2$v1no0N3IgP$M1Yjz
zpKV)mXL|UJ;8b~dD8Ohz7!svR7^y?UZ*w!=br*yp`Vya^{htezrpjl9-U&ZCP}diW?4?mK(M?z8!4PSly|Pn|mRb^VF#o&`4nc@!{;So
zIqORYn|I+6>^N!?SCeAdM4l!u`mrfQ>IRreIHr>$Ekx;lg6+**1Yt$QeA_2-nI
zWO`1yrD^ebVT5g5e_VBvV#y~feYqN)MRHo}Ryd5P>SlLF!oZ#U(
zylh@d3zsev8>{=WbhV77twF5OI-cFlezPGGzbIE5ax2zYUc4>TY<8R8;dqj(X2-S(
zd7*}g7U$E1i5+o3v(A^am~YtcWjtMp=;~{T
zKAnM}C&+keG)14fi|C5a(Qc`qbT?Df*hm!_etHg-v)aY?s7SV4ax$mrx;J$jb
zCHKO8j8xI}%SgNM6#4{y+WIp$K|G;lbCfo3<|b$SgM{!bd62(Hbq{*KIm2XrnHO$nPLa7{r;@S9e6sFQHFt
z0eNLmq-(SlwC$!{`W-5l6gBA$RJu;lFO%vUqlA7c7~RX-rR~TbninO!^Do;&8zSwh
zvN?r3mzd{u{F$N;{)wZAq6p%?)u9
zw_cdZLISO-ckH36Fa;}ayUYtYd*6+*hoXtJz8^!!xG_e3Fk_6FzyL!?yYz&>A*FcV
zL=mRWxGDjevhgRJZ(c$_BU#9f0?FWASyFzhN)B;2on(d+Cx?s~OXC(%Z
zRHFnQm{*{}NHUO7AIJawVh>v!I^X+_fYAst2p`d%?<%OH3JE9`$^#Zd`S6m@QZ;C_
zF=iWO)R`z+pKqXy`XkhC_T+|0Nm9;Lm|dS#7^{^GT@AL?8ps%};~2*rah7r`TEr2a
zewCVXwi-z-dx#y#h~E*O+jJ=0FM4xy7#~5cNh{=ujj@M^uhRE!oXnY?
zgX`}_6tya;l{pu^b8h?$LY-@@_5!;g2D{)7c40JrJ|f7l2`mDPQ`8(8$ET}}R=}tc
zvoNOtYcz|uW+KHlmMUswsBf|r-kH?Y4YbaiHcn<~qfSH9F=J^zMw`+HSgFlUW~XlO
zJR#cVpa7IyRCdGomQdyF4;u)B=W>kI=fPT75p8WUfVpTz-GxsW0-=V3Ih#%xdu@Ci
zpE9_k7=#H@Oq~}odQ>zKKM^jG>n9UQiDfUb4JqT1G$b=!uV9gAa2_w=vaQG~%2U$O
zuCN56V_VlAALUfusOWREh#C!R(q3G#yE4E0L|Odhncpotl_oV+&$u+_!b|nZXBVDX
zT347IVm@R(lBEv0)($e9di<>$IfWUVMbZx|8ET@wm_=P38*;DCSMHX;b2E8fq1;TK
z%gFO8WtIe6Te~`p9Ww{ya2qZn?v-&$ZQt<}w%+Y3GPDL#+!l#<(OrKkJ(gQ9?ydMB
z7zrk$U|7d9VIL?z25ZpcmOnowD34F$Wn7k6j$6G@%lCBcPB13fU`##%V^Tu-$+Sx@
zI;LtMrRbYUX_vGiThsF$bg(v}c2m)Q?6}DBaV$kCQ$O1bpoVm!ItZ=mt
zX$bXGUwb&*f}G<`K-WtN`t+wK}uJ}Kddh_
z2j|*DL|{p1|n+dByVyNAr6QjIRm=yP1TAG9sI!4M7eY3W}X17#?lPq*%vMdpR4
ztnuz|;mOfwq9bDu#WEla(yrzNX*sTDMkSITFc)T=Y!tei*-r15AkIzJ%gJ-w_9zfY
zLsKv3e(Ii26nCSkhb9*`f-*$5ES~#`VFV)~f$1LzMq(U(-XqA6ZY8>*8dK**hf=yn
z9Qef%9t0b$^YYZ)R*{y~g$2I`n}d!k-zVFaEW0rRrswjs4yelir=W}+9Xzj<$x_&1FW4IK~B~y
zL~aTRk_%Hw
z8hoi(qLMhC42zzJV*TPaJM==u{(?vL8s779eZJgl(GxjWdg<{fPt_B-usGntU@si%
z=@qyMAGEMmGkQ%qY6#71ken1~E-kq;4N=Hf5q
z!$bw!@GW^iQPUPI_4Mr_!8@YDwoZYCD}us1JpBpbs)w@^WK{cbQv6UOMktoBJ(_el(;~NJAZp|8FEMz+NV>R{-o4Kc@KqHr1!-a`oJ;;@%b$
zSa=h=Sz!r4V=cZ>M=WbHjX?~egLJ6K&=f>*8Is-|v*=(RaniQl>CyaBuBQwfDY<9{
zU%v{#||ZJmd&Gr^NM_!E17T2S-2eWVm9Mg}W)HF%>
zH+J4GmPaH;6fLSpRe;k&$F2FjN4lO#Irp7bV)z}UqT=3#7TeF~JClkZ@&#

[PATCH v2 3/4] riscv: sifive_u: Update BIOS_FILENAME for 32-bit

2020-02-24 Thread Bin Meng
Update BIOS_FILENAME to consider 32-bit bios image file name.

Tested booting Linux v5.5 32-bit image (built from rv32_defconfig
plus CONFIG_SOC_SIFIVE) with the default 32-bit bios image.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v2: None

 hw/riscv/sifive_u.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ca561d3..371133e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -57,7 +57,11 @@
 
 #include 
 
-#define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin"
+#if defined(TARGET_RISCV32)
+# define BIOS_FILENAME "opensbi-riscv32-sifive_u-fw_jump.bin"
+#else
+# define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin"
+#endif
 
 static const struct MemmapEntry {
 hwaddr base;
-- 
2.7.4




Re: [PATCH v2] riscv: sifive_u: Add a "serial" property for board serial number

2020-03-03 Thread Bin Meng
Hi Alistair,

On Tue, Mar 3, 2020 at 8:07 AM Alistair Francis  wrote:
>
> On Mon, Feb 24, 2020 at 9:02 PM Bin Meng  wrote:
> >
> > Hi Alistair,
> >
> > On Tue, Feb 25, 2020 at 5:14 AM Alistair Francis  
> > wrote:
> > >
> > > On Sun, Feb 16, 2020 at 5:56 AM Bin Meng  wrote:
> > > >
> > > > At present the board serial number is hard-coded to 1, and passed
> > > > to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> > > > the serial number to generate a unique MAC address for the on-chip
> > > > ethernet controller. When multiple QEMU 'sifive_u' instances are
> > > > created and connected to the same subnet, they all have the same
> > > > MAC address hence it creates a unusable network.
> > > >
> > > > A new "serial" property is introduced to specify the board serial
> > > > number. When not given, the default serial number 1 is used.
> > > >
> > > > Signed-off-by: Bin Meng 
> > > >
> > > > ---
> > > >
> > > > Changes in v2:
> > > > - Move setting OTP serial number property from riscv_sifive_u_soc_init()
> > > >   to riscv_sifive_u_soc_realize(), to fix the 'check-qtest-riscv' error.
> > > >   I am not really sure why doing so could fix the 'make check' error.
> > > >   The v1 patch worked fine and nothing seems wrong.
> > > >
> > > >  hw/riscv/sifive_u.c | 21 -
> > > >  include/hw/riscv/sifive_u.h |  1 +
> > > >  2 files changed, 21 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> > > > index 0e12b3c..ca561d3 100644
> > > > --- a/hw/riscv/sifive_u.c
> > > > +++ b/hw/riscv/sifive_u.c
> > > > @@ -34,6 +34,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "qemu/error-report.h"
> > > >  #include "qapi/error.h"
> > > > +#include "qapi/visitor.h"
> > > >  #include "hw/boards.h"
> > > >  #include "hw/loader.h"
> > > >  #include "hw/sysbus.h"
> > > > @@ -434,7 +435,6 @@ static void riscv_sifive_u_soc_init(Object *obj)
> > > >TYPE_SIFIVE_U_PRCI);
> > > >  sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
> > > >TYPE_SIFIVE_U_OTP);
> > > > -qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
> > > >  sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
> > > >TYPE_CADENCE_GEM);
> > > >  }
> > > > @@ -453,6 +453,18 @@ static void sifive_u_set_start_in_flash(Object 
> > > > *obj, bool value, Error **errp)
> > > >  s->start_in_flash = value;
> > > >  }
> > > >
> > > > +static void sifive_u_get_serial(Object *obj, Visitor *v, const char 
> > > > *name,
> > > > +void *opaque, Error **errp)
> > > > +{
> > > > +visit_type_uint32(v, name, (uint32_t *)opaque, errp);
> > > > +}
> > > > +
> > > > +static void sifive_u_set_serial(Object *obj, Visitor *v, const char 
> > > > *name,
> > > > +void *opaque, Error **errp)
> > > > +{
> > > > +visit_type_uint32(v, name, (uint32_t *)opaque, errp);
> > >
> > > This is a little confusing. Maybe it's worth adding a comment that
> > > opaque is s->serial?
> >
> > Yes, I can add a comment.
> >
> > >
> > > Either that or change opaque to be SiFiveUState *s and then access
> > > serial via the struct.
> >
> > Do you mean something like this?
> >
> > Calling object_property_add() with opaque as NULL, not >serial:
> >
> > object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
> > sifive_u_set_serial, NULL, NULL, NULL);
> >
> > Then in the sifive_u_get_serial() or sifive_u_set_serial(), replace
> > opaque with RISCV_U_MACHINE(obj)->serial.
> >
> > Wow, it looks we have designed so flexible APIs :)
> >
> > >
> > > > +}
> > > > +
> > > >  static void riscv_sifive_u_machine_instance_init(Object *obj)
> > > >  {
> > > >  SiFi

Re: [PATCH] riscv: virt: Allow PCI address 0

2020-02-02 Thread Bin Meng
Hi Palmer,

On Sat, Nov 23, 2019 at 6:41 AM Palmer Dabbelt  wrote:
>
> On Fri, 22 Nov 2019 07:27:52 PST (-0800), bmeng...@gmail.com wrote:
> > When testing e1000 with the virt machine, e1000's I/O space cannot
> > be accessed. Debugging shows that the I/O BAR (BAR1) is correctly
> > written with address 0 plus I/O enable bit, but QEMU's "info pci"
> > shows that:
> >
> >   Bus  0, device   1, function 0:
> > Ethernet controller: PCI device 8086:100e
> >   ...
> >   BAR1: I/O at 0x [0x003e].
> >   ...
> >
> > It turns out we should set pci_allow_0_address to true to allow 0
> > PCI address, otherwise pci_bar_address() treats such address as
> > PCI_BAR_UNMAPPED.
> >
> > Signed-off-by: Bin Meng 
> > ---
> >
> >  hw/riscv/virt.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 23f340d..411bef5 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -603,6 +603,7 @@ static void riscv_virt_machine_class_init(ObjectClass 
> > *oc, void *data)
> >  mc->init = riscv_virt_board_init;
> >  mc->max_cpus = 8;
> >  mc->default_cpu_type = VIRT_CPU;
> > +mc->pci_allow_0_address = true;
> >  }
> >
> >  static const TypeInfo riscv_virt_machine_typeinfo = {
>
> Reviewed-by: Palmer Dabbelt 
>
> I've put this on for-next, as I don't think this is 4.2 material.

Looks you missed picking up this one :(

Regards,
Bin



[PATCH 1/2] riscv: roms: Add 32-bit OpenSBI firmware image for sifive_u

2020-02-20 Thread Bin Meng
Although the real world SiFive HiFive Unleashed board is a 64-bit
hardware configuration, with QEMU it is possible to test 32-bit
configuration with the same hardware features.

This updates the roms Makefile to add the build rules for creating
the 32-bit OpenSBI firmware image for sifive_u machine. A pre-built
OpenSBI image (built from commit 3e7d666) has been added as the
default bios for 32-bit sifive_u machine.

Signed-off-by: Bin Meng 
---

 Makefile |   2 +-
 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin | Bin 0 -> 49472 bytes
 roms/Makefile|   7 +++
 3 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100644 pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin

diff --git a/Makefile b/Makefile
index b5a7377..ee7aa6d 100644
--- a/Makefile
+++ b/Makefile
@@ -804,7 +804,7 @@ u-boot.e500 u-boot-sam460-20100605.bin \
 qemu_vga.ndrv \
 edk2-licenses.txt \
 hppa-firmware.img \
-opensbi-riscv32-virt-fw_jump.bin \
+opensbi-riscv32-sifive_u-fw_jump.bin opensbi-riscv32-virt-fw_jump.bin \
 opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin
 
 
diff --git a/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin 
b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin
new file mode 100644
index 
..93e2556baa261bfd796cdc484b345bf958c8afea
GIT binary patch
literal 49472
zcmce<3tUrIwm-g4PEJmO55TBst1S`%p{+7bwmfJ_Q5GSc5WXIb-Yf;
zTQE7qfCw5frPUeg1C*IsYpP7Wf8`k>S|7E7)v4ARk!l~_uc0Z3D#==_x}EW
z{e+X8v-e(Wuf6u#Yp=c5I(j8X9A=K_H7YVHRIkQ2PDvc1lIT?$(*9dPIfxO4a@rs@
zAzHOMUYz>$2;Awf?q^pJVq29O7sTQT>%OfkN+n(QVoh5Vr0aeRt7C~BWo)Lc(Wb2|
z(f9pL^kaV>ZW?~A)@NA`29{jcbae-+xNA}g5kf2@SE4jgq`x8
zwg2wDGwS`WJFP+fDC_Uv*Zbt?F2V3NYQ0Vxiv?#jBYf^=T6eL#SfVScV%90vvF^jE
z9jn#~|El6-oZRCC=WmGcc{Q_emwbo4dndWL>&^`sP9EC*f71%h)qW9y;QxU$S
z>d4X%J?}??%0NBd^>3ypc#eJ2$OT=*Z$<1^4oeO@Wxc+yf{1ZUoLYl`R2_ws+x{<~tiBVTpOVkc$dmIy`1`$EM#1
zI!*i1bli@s&9eBsE|@2Qyn9AVhi@B9n4ax9Hv}c<&#

[PATCH 2/2] riscv: sifive_u: Update BIOS_FILENAME for 32-bit

2020-02-20 Thread Bin Meng
Update BIOS_FILENAME to consider 32-bit bios image file name.

Tested booting Linux v5.5 32-bit image (built from rv32_defconfig
plus CONFIG_SOC_SIFIVE) with the default 32-bit bios image.

Signed-off-by: Bin Meng 
---

 hw/riscv/sifive_u.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ca561d3..371133e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -57,7 +57,11 @@
 
 #include 
 
-#define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin"
+#if defined(TARGET_RISCV32)
+# define BIOS_FILENAME "opensbi-riscv32-sifive_u-fw_jump.bin"
+#else
+# define BIOS_FILENAME "opensbi-riscv64-sifive_u-fw_jump.bin"
+#endif
 
 static const struct MemmapEntry {
 hwaddr base;
-- 
2.7.4




Re: [PATCH 1/2] riscv: roms: Add 32-bit OpenSBI firmware image for sifive_u

2020-02-20 Thread Bin Meng
Hi Philippe,

On Fri, Feb 21, 2020 at 1:31 AM Philippe Mathieu-Daudé
 wrote:
>
> Hi Bin,
>
> On 2/20/20 3:42 PM, Bin Meng wrote:
> > Although the real world SiFive HiFive Unleashed board is a 64-bit
> > hardware configuration, with QEMU it is possible to test 32-bit
> > configuration with the same hardware features.
> >
> > This updates the roms Makefile to add the build rules for creating
> > the 32-bit OpenSBI firmware image for sifive_u machine. A pre-built
> > OpenSBI image (built from commit 3e7d666) has been added as the
> > default bios for 32-bit sifive_u machine.
>
> With QEMU:
>
> fatal: ambiguous argument '3e7d666': unknown revision or path not in the
> working tree.
>
> This looks like an OpenSBI commit but QEMU only include up to v0.5.
>
> Can you build v0.5? Else can you update the submodule?
>

Will do in v2.

> Also, can you add a CI job to build this, so we have reproducible builds
> (see QEMU commit 71920809ceabed as example)?

I cannot find any document for how to test CI job with gitlab CI. Does
QEMU has a public CI runner for testing?

Regards,
Bin



Re: [PATCH] riscv: sifive_u: Add a "serial" property for board serial number

2020-02-11 Thread Bin Meng
Hi Palmer,

On Tue, Feb 11, 2020 at 3:55 AM Palmer Dabbelt  wrote:
>
> On Wed, 29 Jan 2020 07:29:11 PST (-0800), Palmer Dabbelt wrote:
> > On Fri, 10 Jan 2020 07:52:05 GMT (+), bmeng...@gmail.com wrote:
> >> Hi Palmer,
> >>
> >> On Fri, Nov 22, 2019 at 10:38 AM Palmer Dabbelt
> >>  wrote:
> >>>
> >>> On Thu, 21 Nov 2019 17:10:18 PST (-0800), bmeng...@gmail.com wrote:
> >>> > On Sat, Nov 16, 2019 at 11:08 PM Bin Meng  wrote:
> >>> >>
> >>> >> At present the board serial number is hard-coded to 1, and passed
> >>> >> to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> >>> >> the serial number to generate a unique MAC address for the on-chip
> >>> >> ethernet controller. When multiple QEMU 'sifive_u' instances are
> >>> >> created and connected to the same subnet, they all have the same
> >>> >> MAC address hence it creates a unusable network.
> >>> >>
> >>> >> A new "serial" property is introduced to specify the board serial
> >>> >> number. When not given, the default serial number 1 is used.
> >>> >>
> >>> >> Signed-off-by: Bin Meng 
> >>> >> ---
> >>> >>
> >>> >>  hw/riscv/sifive_u.c | 21 -
> >>> >>  include/hw/riscv/sifive_u.h |  1 +
> >>> >>  2 files changed, 21 insertions(+), 1 deletion(-)
> >>> >>
> >>> >
> >>> > ping?
> >>>
> >>> Sorry, it looks like I dropped this one.  I've put it in the queue for 
> >>> 5.0,
> >>> with a
> >>>
> >>> Reviewed-by: Palmer Dabbelt 
> >>
> >> Has this been applied somewhere?
> >
> > Weird, not sure how I managed to screw this up again.  It's actually on 
> > for-master as
> >
> > * a828041ba6 - riscv: sifive_u: Add a "serial" property for board 
> > serial number (50 seconds ago) 
> >
> > with any luck I'll manage to avoid screwing it up a third time.
>
> Ah, OK -- the issue here is that this fails "make check", specifically
>
> $ make check-qtest-riscv64
> make[1]: Entering directory '/home/palmerdabbelt/life/riscv/qemu/slirp'
> make[1]: Nothing to be done for 'all'.
> make[1]: Leaving directory '/home/palmerdabbelt/life/riscv/qemu/slirp'
> CHK version_gen.h
>   TESTcheck-qtest-riscv64: tests/qtest/cdrom-test
>   TESTcheck-qtest-riscv64: tests/qtest/device-introspect-test
> 
> /home/palmerdabbelt/life/riscv/qemu/hw/riscv/sifive_u.c:406:riscv_sifive_u_soc_init:
>  Object 0x55baf3feea00 is not an instance of type sifive_u-machine
> Broken pipe
> tests/qtest/libqtest.c:149: kill_qemu() detected QEMU death from signal 6 
> (Aborted)
> ERROR - too few tests run (expected 6, got 5)
> make: *** 
> [/home/palmerdabbelt/life/riscv/qemu/tests/Makefile.include:630: 
> check-qtest-riscv64] Error 1
>
> which is probably how it kept getting disappeared -- I just forgot to reply on
> the list.  I'm going to hold it back from the PR I'm staging right now, LMK if
> you have a fix.

OK, I will take a look. I remember I did run "make check" but it did
not report any issue before. Is 'make check-qtest-riscv64' not part of
'make check'?

Regards,
Bin



[PATCH v2] riscv: sifive_u: Add a "serial" property for board serial number

2020-02-16 Thread Bin Meng
At present the board serial number is hard-coded to 1, and passed
to OTP model during initialization. Firmware (FSBL, U-Boot) uses
the serial number to generate a unique MAC address for the on-chip
ethernet controller. When multiple QEMU 'sifive_u' instances are
created and connected to the same subnet, they all have the same
MAC address hence it creates a unusable network.

A new "serial" property is introduced to specify the board serial
number. When not given, the default serial number 1 is used.

Signed-off-by: Bin Meng 

---

Changes in v2:
- Move setting OTP serial number property from riscv_sifive_u_soc_init()
  to riscv_sifive_u_soc_realize(), to fix the 'check-qtest-riscv' error.
  I am not really sure why doing so could fix the 'make check' error.
  The v1 patch worked fine and nothing seems wrong.

 hw/riscv/sifive_u.c | 21 -
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 0e12b3c..ca561d3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -34,6 +34,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/visitor.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "hw/sysbus.h"
@@ -434,7 +435,6 @@ static void riscv_sifive_u_soc_init(Object *obj)
   TYPE_SIFIVE_U_PRCI);
 sysbus_init_child_obj(obj, "otp", >otp, sizeof(s->otp),
   TYPE_SIFIVE_U_OTP);
-qdev_prop_set_uint32(DEVICE(>otp), "serial", OTP_SERIAL);
 sysbus_init_child_obj(obj, "gem", >gem, sizeof(s->gem),
   TYPE_CADENCE_GEM);
 }
@@ -453,6 +453,18 @@ static void sifive_u_set_start_in_flash(Object *obj, bool 
value, Error **errp)
 s->start_in_flash = value;
 }
 
+static void sifive_u_get_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
+static void sifive_u_set_serial(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
 static void riscv_sifive_u_machine_instance_init(Object *obj)
 {
 SiFiveUState *s = RISCV_U_MACHINE(obj);
@@ -464,11 +476,17 @@ static void riscv_sifive_u_machine_instance_init(Object 
*obj)
 "Set on to tell QEMU's ROM to jump to " \
 "flash. Otherwise QEMU will jump to DRAM",
 NULL);
+
+s->serial = OTP_SERIAL;
+object_property_add(obj, "serial", "uint32", sifive_u_get_serial,
+sifive_u_set_serial, NULL, >serial, NULL);
+object_property_set_description(obj, "serial", "Board serial number", 
NULL);
 }
 
 static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
+SiFiveUState *us = RISCV_U_MACHINE(ms);
 SiFiveUSoCState *s = RISCV_U_SOC(dev);
 const struct MemmapEntry *memmap = sifive_u_memmap;
 MemoryRegion *system_memory = get_system_memory();
@@ -554,6 +572,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 object_property_set_bool(OBJECT(>prci), true, "realized", );
 sysbus_mmio_map(SYS_BUS_DEVICE(>prci), 0, memmap[SIFIVE_U_PRCI].base);
 
+qdev_prop_set_uint32(DEVICE(>otp), "serial", us->serial);
 object_property_set_bool(OBJECT(>otp), true, "realized", );
 sysbus_mmio_map(SYS_BUS_DEVICE(>otp), 0, memmap[SIFIVE_U_OTP].base);
 
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 82667b5..7cf742e 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -59,6 +59,7 @@ typedef struct SiFiveUState {
 int fdt_size;
 
 bool start_in_flash;
+uint32_t serial;
 } SiFiveUState;
 
 enum {
-- 
2.7.4




Re: [PATCH 2/2] riscv: sifive_u: Update BIOS_FILENAME for 32-bit

2020-02-21 Thread Bin Meng
On Sat, Feb 22, 2020 at 3:51 AM Alistair Francis  wrote:
>
> On Thu, Feb 20, 2020 at 6:43 AM Bin Meng  wrote:
> >
> > Update BIOS_FILENAME to consider 32-bit bios image file name.
> >
> > Tested booting Linux v5.5 32-bit image (built from rv32_defconfig
> > plus CONFIG_SOC_SIFIVE) with the default 32-bit bios image.
>
> Do we really want to support a 32-bit sifive_u machine?
>

QEMU is an emulator, why not? With 32-bit sifive_u machine, we can
have 32-bit test coverage for SiFive specific drivers that cannot be
done with the 'virt' machine.

Regards,
Bin



Re: [PATCH 1/2] riscv: roms: Add 32-bit OpenSBI firmware image for sifive_u

2020-02-22 Thread Bin Meng
Hi Philippe,

On Fri, Feb 21, 2020 at 4:54 PM Philippe Mathieu-Daudé
 wrote:
>
> On 2/21/20 6:54 AM, Anup Patel wrote:
> > On Fri, Feb 21, 2020 at 8:08 AM Bin Meng  wrote:
> >>
> >> Hi Philippe,
> >>
> >> On Fri, Feb 21, 2020 at 1:31 AM Philippe Mathieu-Daudé
> >>  wrote:
> >>>
> >>> Hi Bin,
> >>>
> >>> On 2/20/20 3:42 PM, Bin Meng wrote:
> >>>> Although the real world SiFive HiFive Unleashed board is a 64-bit
> >>>> hardware configuration, with QEMU it is possible to test 32-bit
> >>>> configuration with the same hardware features.
> >>>>
> >>>> This updates the roms Makefile to add the build rules for creating
> >>>> the 32-bit OpenSBI firmware image for sifive_u machine. A pre-built
> >>>> OpenSBI image (built from commit 3e7d666) has been added as the
> >>>> default bios for 32-bit sifive_u machine.
> >>>
> >>> With QEMU:
> >>>
> >>> fatal: ambiguous argument '3e7d666': unknown revision or path not in the
> >>> working tree.
> >>>
> >>> This looks like an OpenSBI commit but QEMU only include up to v0.5.
> >>>
> >>> Can you build v0.5? Else can you update the submodule?
> >>>
> >>
> >> Will do in v2.
> >
> > We plan to release OpenSBI v0.6 on monday (24th Feb 2020) so maybe
> > you can update all RISC-V ROM images based on OpenSBI v0.6 ??
>
> Sounds cleaner.

Yes, will update all RISC-V ROM images to v0.6 in v2.

>
> Suggestions when updating a QEMU git-submodule:
>
>
> - Include output of submodule 'git-log --reverse --oneline'
>
> - Send series/pull-request with 'git-format-patch --no-binary'
>

Sure. I believe with "--no-binary" I will need provide a repo for pull?

> >
> >>
> >>> Also, can you add a CI job to build this, so we have reproducible builds
> >>> (see QEMU commit 71920809ceabed as example)?
> >>
> >> I cannot find any document for how to test CI job with gitlab CI. Does
> >> QEMU has a public CI runner for testing?
>
> There is:
>
> https://wiki.qemu.org/Testing
> https://wiki.qemu.org/Testing/CI
>
> Currently you can use whatever CI best suits you (although long term is
> probably to rely more on GitLab, because it allows adding runners on
> particular hardware/setup).

Thank you very much for the pointers. I will add a CI job in v2.

Regards,
Bin



Re: [PATCH v2] riscv: sifive_u: Add a "serial" property for board serial number

2020-02-22 Thread Bin Meng
On Sun, Feb 16, 2020 at 9:55 PM Bin Meng  wrote:
>
> At present the board serial number is hard-coded to 1, and passed
> to OTP model during initialization. Firmware (FSBL, U-Boot) uses
> the serial number to generate a unique MAC address for the on-chip
> ethernet controller. When multiple QEMU 'sifive_u' instances are
> created and connected to the same subnet, they all have the same
> MAC address hence it creates a unusable network.
>
> A new "serial" property is introduced to specify the board serial
> number. When not given, the default serial number 1 is used.
>
> Signed-off-by: Bin Meng 
>
> ---
>
> Changes in v2:
> - Move setting OTP serial number property from riscv_sifive_u_soc_init()
>   to riscv_sifive_u_soc_realize(), to fix the 'check-qtest-riscv' error.
>   I am not really sure why doing so could fix the 'make check' error.
>   The v1 patch worked fine and nothing seems wrong.
>
>  hw/riscv/sifive_u.c | 21 -
>  include/hw/riscv/sifive_u.h |  1 +
>  2 files changed, 21 insertions(+), 1 deletion(-)
>

Ping?

Regards,
Bin



<    1   2   3   4   5   6   7   8   9   10   >