Re: [PULL 00/17] Block layer patches

2020-12-31 Thread Peter Maydell
On Fri, 18 Dec 2020 at 12:10, Kevin Wolf  wrote:
>
> The following changes since commit 75ee62ac606bfc9eb59310b9446df3434bf6e8c2:
>
>   Merge remote-tracking branch 
> 'remotes/ehabkost-gl/tags/x86-next-pull-request' into staging (2020-12-17 
> 18:53:36 +)
>
> are available in the Git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to be7c5ddd0d80e2d6cf8e3ef12c049851d28d9c26:
>
>   block/vpc: Use sizeof() instead of HEADER_SIZE for footer size (2020-12-18 
> 12:43:30 +0100)
>
> 
> Block layer patches:
>
> - Add qemu-storage-daemon documentation
> - hw/block/nand: Decommission the NAND museum
> - vpc: Clean up some buffer abuse
> - nfs: fix int overflow in nfs_client_open_qdict
> - Several iotests fixes


Applied, thanks.

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

-- PMM



[PATCH 15/18] hw/pci-host/bonito: Map north bridge region in bonito_host_realize()

2020-12-31 Thread Philippe Mathieu-Daudé
The 'north bridge' is not part of the PCI function,
so create and map it in bonito_host_realize().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index c09d54cca82..099bb737c77 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -638,6 +638,13 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("PCI_2",
 (hwaddr)BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE,
 2 * GiB);
+
+/* set the north bridge pci configure mapping */
+/* north bridge PCI configure space. 0x1fe0  - 0x1fe0 00ff */
+memory_region_init_io(&phb->conf_mem, OBJECT(phb), &pci_host_conf_le_ops, 
bs,
+  "north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
+memory_region_add_subregion(get_system_memory(), BONITO_PCICONFIG_BASE,
+&phb->conf_mem);
 }
 
 static void bonito_pci_realize(PCIDevice *dev, Error **errp)
@@ -660,30 +667,24 @@ static void bonito_pci_realize(PCIDevice *dev, Error 
**errp)
 sysbus_init_mmio(sysbus, &s->iomem);
 sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
 
-/* set the north bridge pci configure  mapping */
-memory_region_init_io(&phb->conf_mem, OBJECT(s), &pci_host_conf_le_ops, s,
-  "north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
-sysbus_init_mmio(sysbus, &phb->conf_mem);
-sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE);
-
 /* set the south bridge pci configure  mapping */
 memory_region_init_io(&phb->data_mem, OBJECT(s), &bonito_spciconf_ops, s,
   "south-bridge-pci-config", BONITO_SPCICONFIG_SIZE);
 sysbus_init_mmio(sysbus, &phb->data_mem);
-sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE);
+sysbus_mmio_map(sysbus, 1, BONITO_SPCICONFIG_BASE);
 
 create_unimplemented_device("bonito", BONITO_REG_BASE, BONITO_REG_SIZE);
 
 memory_region_init_io(&s->iomem_ldma, OBJECT(s), &bonito_ldma_ops, s,
   "ldma", 0x100);
 sysbus_init_mmio(sysbus, &s->iomem_ldma);
-sysbus_mmio_map(sysbus, 3, 0x1fe00200);
+sysbus_mmio_map(sysbus, 2, 0x1fe00200);
 
 /* PCI copier */
 memory_region_init_io(&s->iomem_cop, OBJECT(s), &bonito_cop_ops, s,
   "cop", 0x100);
 sysbus_init_mmio(sysbus, &s->iomem_cop);
-sysbus_mmio_map(sysbus, 4, 0x1fe00300);
+sysbus_mmio_map(sysbus, 3, 0x1fe00300);
 
 create_unimplemented_device("ROMCS", BONITO_FLASH_BASE, 60 * MiB);
 
@@ -691,14 +692,14 @@ static void bonito_pci_realize(PCIDevice *dev, Error 
**errp)
 memory_region_init_alias(&s->bonito_pciio, OBJECT(s), "isa_mmio",
  get_system_io(), 0, BONITO_PCIIO_SIZE);
 sysbus_init_mmio(sysbus, &s->bonito_pciio);
-sysbus_mmio_map(sysbus, 5, BONITO_PCIIO_BASE);
+sysbus_mmio_map(sysbus, 4, BONITO_PCIIO_BASE);
 
 /* add pci local io mapping */
 
 memory_region_init_alias(&s->bonito_localio, OBJECT(s), "IOCS[0]",
  get_system_io(), 0, 256 * KiB);
 sysbus_init_mmio(sysbus, &s->bonito_localio);
-sysbus_mmio_map(sysbus, 6, BONITO_DEV_BASE);
+sysbus_mmio_map(sysbus, 5, BONITO_DEV_BASE);
 create_unimplemented_device("IOCS[1]", BONITO_DEV_BASE + 1 * 256 * KiB,
 256 * KiB);
 create_unimplemented_device("IOCS[2]", BONITO_DEV_BASE + 2 * 256 * KiB,
-- 
2.26.2




[PATCH 17/18] hw/pci-host/bonito: Declare TYPE_BONITO_PCI_HOST_BRIDGE in include/

2020-12-31 Thread Philippe Mathieu-Daudé
Declare TYPE_BONITO_PCI_HOST_BRIDGE in the new "hw/pci-host/bonito.h"
header, so we can inline the bonito_init() call in the next commit.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/pci-host/bonito.h | 34 ++
 hw/pci-host/bonito.c | 16 +---
 MAINTAINERS  |  1 +
 3 files changed, 36 insertions(+), 15 deletions(-)
 create mode 100644 include/hw/pci-host/bonito.h

diff --git a/include/hw/pci-host/bonito.h b/include/hw/pci-host/bonito.h
new file mode 100644
index 000..d0264f34783
--- /dev/null
+++ b/include/hw/pci-host/bonito.h
@@ -0,0 +1,34 @@
+/*
+ * Algorithmics Bonito64 'north bridge' controller
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * Copyright (c) 2020 Philippe Mathieu-Daudé 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_PCI_HOST_BONITO_H
+#define HW_PCI_HOST_BONITO_H
+
+#include "exec/memory.h"
+#include "hw/pci/pci_host.h"
+#include "qom/object.h"
+
+typedef struct BonitoPciState BonitoPciState;
+
+#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
+OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE)
+
+typedef struct BonitoState BonitoState;
+
+struct BonitoState {
+/*< private >*/
+PCIHostState parent_obj;
+/*< public >*/
+qemu_irq *pic;
+BonitoPciState *pci_dev;
+MemoryRegion pci_mem;
+MemoryRegion pcimem_lo_alias[3];
+};
+
+#endif
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 5a8a85ae443..b959b353854 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -45,6 +45,7 @@
 #include "hw/pci/pci.h"
 #include "hw/irq.h"
 #include "hw/mips/mips.h"
+#include "hw/pci-host/bonito.h"
 #include "hw/pci/pci_host.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
@@ -198,8 +199,6 @@ FIELD(PCIMAP, 2G,   18, 1)
 busno) << 16) & 0xff) + (((devno) << 11) & 0xf800) + \
 (((funno) << 8) & 0x700) + (regno))
 
-typedef struct BonitoState BonitoState;
-
 struct BonitoPciState {
 PCIDevice dev;
 
@@ -227,20 +226,7 @@ struct BonitoPciState {
 MemoryRegion iomem_cop;
 MemoryRegion bonito_pciio;
 MemoryRegion bonito_localio;
-
 };
-typedef struct BonitoPciState BonitoPciState;
-
-struct BonitoState {
-PCIHostState parent_obj;
-qemu_irq *pic;
-BonitoPciState *pci_dev;
-MemoryRegion pci_mem;
-MemoryRegion pcimem_lo_alias[3];
-};
-
-#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
-OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE)
 
 #define TYPE_PCI_BONITO "Bonito"
 OBJECT_DECLARE_SIMPLE_TYPE(BonitoPciState, PCI_BONITO)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e7c8f04885..2e22830efba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1153,6 +1153,7 @@ F: hw/mips/fuloong2e.c
 F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
+F: include/hw/pci-host/bonito.h
 
 Loongson-3 virtual platforms
 M: Huacai Chen 
-- 
2.26.2




[RFC PATCH 14/18] hw/pci-host/bonito: Simplify using pci_host_conf_le_ops MemoryRegionOps

2020-12-31 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 35 +--
 1 file changed, 1 insertion(+), 34 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 4dcaa2fa8bb..c09d54cca82 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -362,39 +362,6 @@ static const MemoryRegionOps bonito_northbridge_ops = {
 },
 };
 
-static void bonito_pciconf_writel(void *opaque, hwaddr addr,
-  uint64_t val, unsigned size)
-{
-BonitoPciState *s = opaque;
-PCIDevice *d = PCI_DEVICE(s);
-
-DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %lx\n", addr, val);
-d->config_write(d, addr, val, 4);
-}
-
-static uint64_t bonito_pciconf_readl(void *opaque, hwaddr addr,
- unsigned size)
-{
-
-BonitoPciState *s = opaque;
-PCIDevice *d = PCI_DEVICE(s);
-
-DPRINTF("bonito_pciconf_readl "TARGET_FMT_plx"\n", addr);
-return d->config_read(d, addr, 4);
-}
-
-/* north bridge PCI configure space. 0x1fe0  - 0x1fe0 00ff */
-
-static const MemoryRegionOps bonito_pciconf_ops = {
-.read = bonito_pciconf_readl,
-.write = bonito_pciconf_writel,
-.endianness = DEVICE_LITTLE_ENDIAN,
-.valid = {
-.min_access_size = 4,
-.max_access_size = 4,
-},
-};
-
 static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr,
   unsigned size)
 {
@@ -694,7 +661,7 @@ static void bonito_pci_realize(PCIDevice *dev, Error **errp)
 sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
 
 /* set the north bridge pci configure  mapping */
-memory_region_init_io(&phb->conf_mem, OBJECT(s), &bonito_pciconf_ops, s,
+memory_region_init_io(&phb->conf_mem, OBJECT(s), &pci_host_conf_le_ops, s,
   "north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
 sysbus_init_mmio(sysbus, &phb->conf_mem);
 sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE);
-- 
2.26.2




[PATCH 13/18] hw/pci-host/bonito: Create PCI regions in bonito_host_realize()

2020-12-31 Thread Philippe Mathieu-Daudé
The PCI regions belong to the 'host' device, not the PCI function.
Move the PCI regions creation there.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 1c88ccc6af8..4dcaa2fa8bb 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -654,6 +654,7 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
 {
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
+MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1);
 
 memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
@@ -662,6 +663,14 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
  PCI_DEVFN(5, 0), 32, TYPE_PCI_BUS);
 
 create_unimplemented_device("pci.io", BONITO_PCIIO_BASE, 1 * MiB);
+
+memory_region_init_alias(pcimem_alias, NULL, "pci.mem.alias",
+ &bs->pci_mem, 0, BONITO_PCIHI_SIZE);
+memory_region_add_subregion(get_system_memory(),
+BONITO_PCIHI_BASE, pcimem_alias);
+create_unimplemented_device("PCI_2",
+(hwaddr)BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE,
+2 * GiB);
 }
 
 static void bonito_pci_realize(PCIDevice *dev, Error **errp)
@@ -669,8 +678,6 @@ static void bonito_pci_realize(PCIDevice *dev, Error **errp)
 BonitoPciState *s = PCI_BONITO(dev);
 SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
 PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
-BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost);
-MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1);
 
 assert(!target_words_bigendian()); /* FIXME not supported */
 
@@ -732,14 +739,6 @@ static void bonito_pci_realize(PCIDevice *dev, Error 
**errp)
 create_unimplemented_device("IOCS[3]", BONITO_DEV_BASE + 3 * 256 * KiB,
 256 * KiB);
 
-memory_region_init_alias(pcimem_alias, NULL, "pci.mem.alias",
- &bs->pci_mem, 0, BONITO_PCIHI_SIZE);
-memory_region_add_subregion(get_system_memory(),
-BONITO_PCIHI_BASE, pcimem_alias);
-create_unimplemented_device("PCI_2",
-(hwaddr)BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE,
-2 * GiB);
-
 /* set the default value of north bridge pci config */
 pci_set_word(dev->config + PCI_COMMAND, 0x);
 pci_set_word(dev->config + PCI_STATUS, 0x);
-- 
2.26.2




[RFC PATCH 18/18] hw/mips/fuloong2e: Inline bonito_init()

2020-12-31 Thread Philippe Mathieu-Daudé
Remove bonito_init() by inlining it.

Signed-off-by: Philippe Mathieu-Daudé 
---
TBC next year.
---
 include/hw/mips/mips.h |  3 ---
 hw/mips/fuloong2e.c|  7 ++-
 hw/pci-host/bonito.c   | 15 ---
 3 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 6c9c8805f3f..609a33881f6 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -12,9 +12,6 @@
 /* gt64xxx.c */
 PCIBus *gt64120_register(qemu_irq *pic);
 
-/* bonito.c */
-PCIBus *bonito_init(qemu_irq *pic);
-
 /* rc4030.c */
 typedef struct rc4030DMAState *rc4030_dma;
 void rc4030_dma_read(void *dma, uint8_t *buf, int len);
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 45c596f4fe5..19b3788e816 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -25,6 +25,7 @@
 #include "qapi/error.h"
 #include "cpu.h"
 #include "hw/clock.h"
+#include "hw/pci-host/bonito.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
 #include "hw/isa/superio.h"
@@ -303,6 +304,7 @@ static void mips_fuloong2e_init(MachineState *machine)
 MIPSCPU *cpu;
 CPUMIPSState *env;
 DeviceState *dev;
+BonitoState *bonito;
 
 cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
 clock_set_hz(cpuclk, 53308); /* ~533 MHz */
@@ -360,7 +362,10 @@ static void mips_fuloong2e_init(MachineState *machine)
 cpu_mips_clock_init(cpu);
 
 /* North bridge, Bonito --> IP2 */
-pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
+bonito = BONITO_PCI_HOST_BRIDGE(qdev_new(TYPE_BONITO_PCI_HOST_BRIDGE));
+bonito->pic = (qemu_irq *)&(env->irq[2]); /* TODO link/property */
+sysbus_realize_and_unref(SYS_BUS_DEVICE(bonito), &error_fatal);
+pci_bus = PCI_HOST_BRIDGE(bonito)->bus;
 
 /* South bridge -> IP5 */
 vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5],
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index b959b353854..28d385ff363 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -714,21 +714,6 @@ static void bonito_pci_realize(PCIDevice *dev, Error 
**errp)
 qemu_register_reset(bonito_reset, s);
 }
 
-PCIBus *bonito_init(qemu_irq *pic)
-{
-DeviceState *dev;
-BonitoState *pcihost;
-PCIHostState *phb;
-
-dev = qdev_new(TYPE_BONITO_PCI_HOST_BRIDGE);
-phb = PCI_HOST_BRIDGE(dev);
-pcihost = BONITO_PCI_HOST_BRIDGE(dev);
-pcihost->pic = pic;
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-
-return phb->bus;
-}
-
 static void bonito_pci_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
-- 
2.26.2




[PATCH 12/18] hw/pci-host/bonito: Rename PCIBonitoState -> BonitoPciState

2020-12-31 Thread Philippe Mathieu-Daudé
As we use BonitoState for the whole device, rename
the PCI function device as BonitoPciState.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 44 ++--
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 06f5e683c81..1c88ccc6af8 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -200,7 +200,7 @@ FIELD(PCIMAP, 2G,   18, 1)
 
 typedef struct BonitoState BonitoState;
 
-struct PCIBonitoState {
+struct BonitoPciState {
 PCIDevice dev;
 
 BonitoState *pcihost;
@@ -229,12 +229,12 @@ struct PCIBonitoState {
 MemoryRegion bonito_localio;
 
 };
-typedef struct PCIBonitoState PCIBonitoState;
+typedef struct BonitoPciState BonitoPciState;
 
 struct BonitoState {
 PCIHostState parent_obj;
 qemu_irq *pic;
-PCIBonitoState *pci_dev;
+BonitoPciState *pci_dev;
 MemoryRegion pci_mem;
 MemoryRegion pcimem_lo_alias[3];
 };
@@ -243,9 +243,9 @@ struct BonitoState {
 OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE)
 
 #define TYPE_PCI_BONITO "Bonito"
-OBJECT_DECLARE_SIMPLE_TYPE(PCIBonitoState, PCI_BONITO)
+OBJECT_DECLARE_SIMPLE_TYPE(BonitoPciState, PCI_BONITO)
 
-static void bonito_remap(PCIBonitoState *s)
+static void bonito_remap(BonitoPciState *s)
 {
 static const char *const region_name[3] = {
 "pci.lomem0", "pci.lomem1", "pci.lomem2"
@@ -273,7 +273,7 @@ static void bonito_remap(PCIBonitoState *s)
 static void bonito_northbridge_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 uint32_t saddr;
 
 saddr = addr >> 2;
@@ -338,7 +338,7 @@ static void bonito_northbridge_write(void *opaque, hwaddr 
addr,
 static uint64_t bonito_northbridge_read(void *opaque, hwaddr addr,
  unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 uint32_t saddr;
 
 saddr = addr >> 2;
@@ -365,7 +365,7 @@ static const MemoryRegionOps bonito_northbridge_ops = {
 static void bonito_pciconf_writel(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 PCIDevice *d = PCI_DEVICE(s);
 
 DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %lx\n", addr, val);
@@ -376,7 +376,7 @@ static uint64_t bonito_pciconf_readl(void *opaque, hwaddr 
addr,
  unsigned size)
 {
 
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 PCIDevice *d = PCI_DEVICE(s);
 
 DPRINTF("bonito_pciconf_readl "TARGET_FMT_plx"\n", addr);
@@ -399,7 +399,7 @@ static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr,
   unsigned size)
 {
 uint32_t val;
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 
 if (addr >= sizeof(s->bonldma)) {
 return 0;
@@ -413,7 +413,7 @@ static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr,
 static void bonito_ldma_writel(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 
 if (addr >= sizeof(s->bonldma)) {
 return;
@@ -436,7 +436,7 @@ static uint64_t bonito_cop_readl(void *opaque, hwaddr addr,
  unsigned size)
 {
 uint32_t val;
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 
 if (addr >= sizeof(s->boncop)) {
 return 0;
@@ -450,7 +450,7 @@ static uint64_t bonito_cop_readl(void *opaque, hwaddr addr,
 static void bonito_cop_writel(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 
 if (addr >= sizeof(s->boncop)) {
 return;
@@ -471,7 +471,7 @@ static const MemoryRegionOps bonito_cop_ops = {
 
 static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
 uint32_t cfgaddr;
 uint32_t idsel;
@@ -509,7 +509,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr 
addr)
 static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val,
   unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 PCIDevice *d = PCI_DEVICE(s);
 PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
 uint32_t pciaddr;
@@ -536,7 +536,7 @@ static void bonito_spciconf_write(void *opaque, hwaddr 
addr, uint64_t val,
 
 static uint64_t bonito_spciconf_read(void *opaque, hwaddr addr, unsigned size)
 {
-PCIBonitoState *s = opaque;
+BonitoPciState *s = opaque;
 PCIDevice *d = PCI_DEVICE(s);
 PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);

[PATCH 11/18] hw/pci-host/bonito: Rename PCI function helpers

2020-12-31 Thread Philippe Mathieu-Daudé
Rename PCI function related helpers as 'bonito_pci_*'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 45f31512b25..06f5e683c81 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -664,7 +664,7 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
 create_unimplemented_device("pci.io", BONITO_PCIIO_BASE, 1 * MiB);
 }
 
-static void bonito_realize(PCIDevice *dev, Error **errp)
+static void bonito_pci_realize(PCIDevice *dev, Error **errp)
 {
 PCIBonitoState *s = PCI_BONITO(dev);
 SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
@@ -778,12 +778,12 @@ PCIBus *bonito_init(qemu_irq *pic)
 return phb->bus;
 }
 
-static void bonito_class_init(ObjectClass *klass, void *data)
+static void bonito_pci_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-k->realize = bonito_realize;
+k->realize = bonito_pci_realize;
 k->vendor_id = 0xdf53;
 k->device_id = 0x00d5;
 k->revision = 0x01;
@@ -797,11 +797,11 @@ static void bonito_class_init(ObjectClass *klass, void 
*data)
 dc->user_creatable = false;
 }
 
-static const TypeInfo bonito_info = {
+static const TypeInfo bonito_pci_info = {
 .name  = TYPE_PCI_BONITO,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCIBonitoState),
-.class_init= bonito_class_init,
+.class_init= bonito_pci_class_init,
 .interfaces = (InterfaceInfo[]) {
 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
 { },
@@ -825,7 +825,7 @@ static const TypeInfo bonito_host_info = {
 static void bonito_register_types(void)
 {
 type_register_static(&bonito_host_info);
-type_register_static(&bonito_info);
+type_register_static(&bonito_pci_info);
 }
 
 type_init(bonito_register_types)
-- 
2.26.2




[PATCH 09/18] hw/pci-host/bonito: Rename north bridge helpers

2020-12-31 Thread Philippe Mathieu-Daudé
Rename north bridge related helpers as 'bonito_northbridge_*'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index a091ef15d27..d91ed82c99e 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -270,7 +270,7 @@ static void bonito_remap(PCIBonitoState *s)
 }
 }
 
-static void bonito_writel(void *opaque, hwaddr addr,
+static void bonito_northbridge_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
 PCIBonitoState *s = opaque;
@@ -335,7 +335,7 @@ static void bonito_writel(void *opaque, hwaddr addr,
 }
 }
 
-static uint64_t bonito_readl(void *opaque, hwaddr addr,
+static uint64_t bonito_northbridge_read(void *opaque, hwaddr addr,
  unsigned size)
 {
 PCIBonitoState *s = opaque;
@@ -352,9 +352,9 @@ static uint64_t bonito_readl(void *opaque, hwaddr addr,
 }
 }
 
-static const MemoryRegionOps bonito_ops = {
-.read = bonito_readl,
-.write = bonito_writel,
+static const MemoryRegionOps bonito_northbridge_ops = {
+.read = bonito_northbridge_read,
+.write = bonito_northbridge_write,
 .endianness = DEVICE_NATIVE_ENDIAN,
 .valid = {
 .min_access_size = 4,
@@ -681,7 +681,7 @@ static void bonito_realize(PCIDevice *dev, Error **errp)
 pci_config_set_prog_interface(dev->config, 0x00);
 
 /* set the north bridge register mapping */
-memory_region_init_io(&s->iomem, OBJECT(s), &bonito_ops, s,
+memory_region_init_io(&s->iomem, OBJECT(s), &bonito_northbridge_ops, s,
   "north-bridge-register", BONITO_INTERNAL_REG_SIZE);
 sysbus_init_mmio(sysbus, &s->iomem);
 sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
-- 
2.26.2




[PATCH 16/18] hw/pci-host/bonito: Create TYPE_PCI_BONITO in bonito_host_realize()

2020-12-31 Thread Philippe Mathieu-Daudé
As it doesn't make sens to create the TYPE_BONITO_PCI_HOST_BRIDGE
PCI function device without its host side, create it in the host
realize(). This will allow to inline bonito_init() in few commits.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 099bb737c77..5a8a85ae443 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -622,6 +622,7 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
 MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1);
+PCIDevice *pci_dev;
 
 memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
@@ -645,6 +646,11 @@ static void bonito_host_realize(DeviceState *dev, Error 
**errp)
   "north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
 memory_region_add_subregion(get_system_memory(), BONITO_PCICONFIG_BASE,
 &phb->conf_mem);
+
+pci_dev = pci_new(PCI_DEVFN(0, 0), TYPE_PCI_BONITO);
+PCI_BONITO(pci_dev)->pcihost = bs;
+bs->pci_dev = PCI_BONITO(pci_dev);
+pci_realize_and_unref(pci_dev, phb->bus, &error_fatal);
 }
 
 static void bonito_pci_realize(PCIDevice *dev, Error **errp)
@@ -727,8 +733,6 @@ PCIBus *bonito_init(qemu_irq *pic)
 DeviceState *dev;
 BonitoState *pcihost;
 PCIHostState *phb;
-BonitoPciState *s;
-PCIDevice *d;
 
 dev = qdev_new(TYPE_BONITO_PCI_HOST_BRIDGE);
 phb = PCI_HOST_BRIDGE(dev);
@@ -736,12 +740,6 @@ PCIBus *bonito_init(qemu_irq *pic)
 pcihost->pic = pic;
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 
-d = pci_new(PCI_DEVFN(0, 0), TYPE_PCI_BONITO);
-s = PCI_BONITO(d);
-s->pcihost = pcihost;
-pcihost->pci_dev = s;
-pci_realize_and_unref(d, phb->bus, &error_fatal);
-
 return phb->bus;
 }
 
-- 
2.26.2




[RFC PATCH 08/18] hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified

2020-12-31 Thread Philippe Mathieu-Daudé
Per the datasheet (Chapter 5.7.1. "PCI address regions"),
the PCIMAP register:

  Map the 64Mbyte regions marked "PCI_Lo" in the CPU's memory map,
  each of which can be assigned to any 64 Mbyte-aligned region of
  PCI memory. The address appearing on the PCI bus consists of the
  low 26 bits of the CPU physical address, with the high 6 bits
  coming from the appropriate base6 field. Each of the three regions
  is an independent window onto PCI memory, and can be positioned on
  any 64Mbyte boundary in PCI space.

Remap the 3 regions on reset and when PCIMAP is updated.

Signed-off-by: Philippe Mathieu-Daudé 
---
RFC: memory_region_is_mapped() is probably not the best call to check
 if this is the first call.

 hw/pci-host/bonito.c | 49 
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 29c0294d289..a091ef15d27 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -138,6 +138,10 @@ FIELD(BONGENCFG, PCIQUEUE,  12, 1)
 
 /* 4. PCI address map control */
 #define BONITO_PCIMAP   (0x10 >> 2)  /* 0x110 */
+FIELD(PCIMAP, LO0,   0, 6)
+FIELD(PCIMAP, LO1,   6, 6)
+FIELD(PCIMAP, LO2,  12, 6)
+FIELD(PCIMAP, 2G,   18, 1)
 #define BONITO_PCIMEMBASECFG(0x14 >> 2)  /* 0x114 */
 #define BONITO_PCIMAP_CFG   (0x18 >> 2)  /* 0x118 */
 
@@ -232,6 +236,7 @@ struct BonitoState {
 qemu_irq *pic;
 PCIBonitoState *pci_dev;
 MemoryRegion pci_mem;
+MemoryRegion pcimem_lo_alias[3];
 };
 
 #define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
@@ -240,6 +245,31 @@ OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, 
BONITO_PCI_HOST_BRIDGE)
 #define TYPE_PCI_BONITO "Bonito"
 OBJECT_DECLARE_SIMPLE_TYPE(PCIBonitoState, PCI_BONITO)
 
+static void bonito_remap(PCIBonitoState *s)
+{
+static const char *const region_name[3] = {
+"pci.lomem0", "pci.lomem1", "pci.lomem2"
+};
+BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost);
+
+for (size_t i = 0; i < 3; i++) {
+uint32_t offset = extract32(s->regs[BONITO_PCIMAP], 6 * i, 6) << 26;
+
+if (memory_region_is_mapped(&bs->pcimem_lo_alias[i])) {
+memory_region_del_subregion(get_system_memory(),
+&bs->pcimem_lo_alias[i]);
+object_unparent(OBJECT(&bs->pcimem_lo_alias[i]));
+}
+
+memory_region_init_alias(&bs->pcimem_lo_alias[i], OBJECT(s),
+ region_name[i], &bs->pci_mem,
+ offset, 64 * MiB);
+memory_region_add_subregion(get_system_memory(),
+BONITO_PCILO_BASE + i * 64 * MiB,
+&bs->pcimem_lo_alias[i]);
+}
+}
+
 static void bonito_writel(void *opaque, hwaddr addr,
   uint64_t val, unsigned size)
 {
@@ -253,7 +283,6 @@ static void bonito_writel(void *opaque, hwaddr addr,
 switch (saddr) {
 case BONITO_IODEVCFG:
 case BONITO_SDCFG:
-case BONITO_PCIMAP:
 case BONITO_PCIMEMBASECFG:
 case BONITO_PCIMAP_CFG:
 case BONITO_GPIODATA:
@@ -275,6 +304,10 @@ static void bonito_writel(void *opaque, hwaddr addr,
 case BONITO_MEMSIZE:
 s->regs[saddr] = val;
 break;
+case BONITO_PCIMAP:
+s->regs[saddr] = val;
+bonito_remap(s);
+break;
 case BONITO_BONGENCFG:
 if (!FIELD_EX32(s->regs[saddr], BONGENCFG, CPUSELFRESET)
 && FIELD_EX32(val, BONGENCFG, CPUSELFRESET)) {
@@ -603,6 +636,8 @@ static void bonito_reset(void *opaque)
 s->regs[BONITO_DQCFG] = 0x8;
 s->regs[BONITO_MEMSIZE] = 0x1000;
 s->regs[BONITO_PCIMAP] = 0x6140;
+
+bonito_remap(s);
 }
 
 static const VMStateDescription vmstate_bonito = {
@@ -619,7 +654,6 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
 {
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
-MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 3);
 
 memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
@@ -627,17 +661,6 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
  dev, &bs->pci_mem, get_system_io(),
  PCI_DEVFN(5, 0), 32, TYPE_PCI_BUS);
 
-for (size_t i = 0; i < 3; i++) {
-char *name = g_strdup_printf("pci.lomem%zu", i);
-
-memory_region_init_alias(&pcimem_lo_alias[i], NULL, name,
- &bs->pci_mem, i * 64 * MiB, 64 * MiB);
-memory_region_add_subregion(get_system_memory(),
-BONITO_PCILO_BASE + i * 64 * MiB,
-&pcimem_lo_alias[i]);
-g_free(name);
-}
-
 create_unimplemented_device("pci.io", BONITO_PCIIO_

[PATCH 10/18] hw/pci-host/bonito: Rename PCI host helpers

2020-12-31 Thread Philippe Mathieu-Daudé
Rename PCI host side related helpers as 'bonito_host_*'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index d91ed82c99e..45f31512b25 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -574,7 +574,7 @@ static const MemoryRegionOps bonito_spciconf_ops = {
 
 #define BONITO_IRQ_BASE 32
 
-static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
+static void bonito_host_set_irq(void *opaque, int irq_num, int level)
 {
 BonitoState *s = opaque;
 qemu_irq *pic = s->pic;
@@ -593,7 +593,7 @@ static void pci_bonito_set_irq(void *opaque, int irq_num, 
int level)
 }
 
 /* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */
-static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num)
+static int bonito_host_map_irq(PCIDevice *pci_dev, int irq_num)
 {
 int slot;
 
@@ -650,14 +650,14 @@ static const VMStateDescription vmstate_bonito = {
 }
 };
 
-static void bonito_pcihost_realize(DeviceState *dev, Error **errp)
+static void bonito_host_realize(DeviceState *dev, Error **errp)
 {
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
 
 memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
- pci_bonito_set_irq, pci_bonito_map_irq,
+ bonito_host_set_irq, bonito_host_map_irq,
  dev, &bs->pci_mem, get_system_io(),
  PCI_DEVFN(5, 0), 32, TYPE_PCI_BUS);
 
@@ -808,23 +808,23 @@ static const TypeInfo bonito_info = {
 },
 };
 
-static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
+static void bonito_host_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
-dc->realize = bonito_pcihost_realize;
+dc->realize = bonito_host_realize;
 }
 
-static const TypeInfo bonito_pcihost_info = {
+static const TypeInfo bonito_host_info = {
 .name  = TYPE_BONITO_PCI_HOST_BRIDGE,
 .parent= TYPE_PCI_HOST_BRIDGE,
 .instance_size = sizeof(BonitoState),
-.class_init= bonito_pcihost_class_init,
+.class_init= bonito_host_class_init,
 };
 
 static void bonito_register_types(void)
 {
-type_register_static(&bonito_pcihost_info);
+type_register_static(&bonito_host_info);
 type_register_static(&bonito_info);
 }
 
-- 
2.26.2




[PATCH 07/18] hw/pci-host/bonito: Make BONPONCFG register read-only

2020-12-31 Thread Philippe Mathieu-Daudé
Per the datasheet (Chapter 5.2. "Power-on settable configuration
register - bonponcfg"), the bonponcfg can only be modified using
"pull-up on the corresponding IOD0-15 signal". Do not allow
update of this register by the CPU.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 93820f69e49..29c0294d289 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -251,7 +251,6 @@ static void bonito_writel(void *opaque, hwaddr addr,
 DPRINTF("bonito_writel "TARGET_FMT_plx" val %lx saddr %x\n",
 addr, val, saddr);
 switch (saddr) {
-case BONITO_BONPONCFG:
 case BONITO_IODEVCFG:
 case BONITO_SDCFG:
 case BONITO_PCIMAP:
@@ -292,6 +291,7 @@ static void bonito_writel(void *opaque, hwaddr addr,
 s->regs[BONITO_INTENCLR] = val;
 s->regs[BONITO_INTEN] &= ~val;
 break;
+case BONITO_BONPONCFG:
 case BONITO_INTEN:
 case BONITO_INTISR:
 DPRINTF("write to readonly bonito register %x\n", saddr);
-- 
2.26.2




[RFC PATCH 06/18] hw/pci-host/bonito: Do not allow big-endian targets

2020-12-31 Thread Philippe Mathieu-Daudé
This model is not complete for big-endian targets,
do not allow its use.

Signed-off-by: Philippe Mathieu-Daudé 
---
Yes I must improve that, I know =) However enough for now
to post the following patches.
---
 hw/pci-host/bonito.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 104c58331d0..93820f69e49 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -53,6 +53,7 @@
 #include "hw/misc/unimp.h"
 #include "hw/registerfields.h"
 #include "qom/object.h"
+#include "hw/core/cpu.h"
 
 /* #define DEBUG_BONITO */
 
@@ -354,7 +355,7 @@ static uint64_t bonito_pciconf_readl(void *opaque, hwaddr 
addr,
 static const MemoryRegionOps bonito_pciconf_ops = {
 .read = bonito_pciconf_readl,
 .write = bonito_pciconf_writel,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
@@ -648,6 +649,8 @@ static void bonito_realize(PCIDevice *dev, Error **errp)
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost);
 MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1);
 
+assert(!target_words_bigendian()); /* FIXME not supported */
+
 /*
  * Bonito North Bridge, built on FPGA,
  * VENDOR_ID/DEVICE_ID are "undefined"
-- 
2.26.2




[PATCH 04/18] hw/pci-host/bonito: Use pci_config_set_interrupt_pin()

2020-12-31 Thread Philippe Mathieu-Daudé
Replace pci_set_byte(PCI_INTERRUPT_PIN) by
pci_config_set_interrupt_pin().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 4c903d4f682..fe94e6740b5 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -723,7 +723,8 @@ static void bonito_realize(PCIDevice *dev, Error **errp)
 pci_set_word(dev->config + PCI_SUBSYSTEM_ID, 0x);
 
 pci_set_byte(dev->config + PCI_INTERRUPT_LINE, 0x00);
-pci_set_byte(dev->config + PCI_INTERRUPT_PIN, 0x01);
+pci_config_set_interrupt_pin(dev->config, 0x01); /* interrupt pin A */
+
 pci_set_byte(dev->config + PCI_MIN_GNT, 0x3c);
 pci_set_byte(dev->config + PCI_MAX_LAT, 0x00);
 
-- 
2.26.2




[PATCH 05/18] hw/pci-host/bonito: Simplify soft reset using FIELD_EX32()

2020-12-31 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index fe94e6740b5..104c58331d0 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -244,7 +244,6 @@ static void bonito_writel(void *opaque, hwaddr addr,
 {
 PCIBonitoState *s = opaque;
 uint32_t saddr;
-int reset = 0;
 
 saddr = addr >> 2;
 
@@ -277,13 +276,12 @@ static void bonito_writel(void *opaque, hwaddr addr,
 s->regs[saddr] = val;
 break;
 case BONITO_BONGENCFG:
-if (!(s->regs[saddr] & 0x04) && (val & 0x04)) {
-reset = 1; /* bit 2 jump from 0 to 1 cause reset */
-}
-s->regs[saddr] = val;
-if (reset) {
+if (!FIELD_EX32(s->regs[saddr], BONGENCFG, CPUSELFRESET)
+&& FIELD_EX32(val, BONGENCFG, CPUSELFRESET)) {
+/* bit 2 jump from 0 to 1 cause reset */
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 }
+s->regs[saddr] = val;
 break;
 case BONITO_INTENSET:
 s->regs[BONITO_INTENSET] = val;
-- 
2.26.2




[PATCH 03/18] hw/pci-host/bonito: Use PCI_DEVFN() macro

2020-12-31 Thread Philippe Mathieu-Daudé
Use the PCI_DEVFN() macro to replace the '0x28' magic value,
this way it is clearer we access PCI function #0 of slot #5.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index efeba29011f..4c903d4f682 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -626,7 +626,7 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
 phb->bus = pci_register_root_bus(dev, "pci",
  pci_bonito_set_irq, pci_bonito_map_irq,
  dev, &bs->pci_mem, get_system_io(),
- 0x28, 32, TYPE_PCI_BUS);
+ PCI_DEVFN(5, 0), 32, TYPE_PCI_BUS);
 
 for (size_t i = 0; i < 3; i++) {
 char *name = g_strdup_printf("pci.lomem%zu", i);
-- 
2.26.2




[PATCH 02/18] hw/pci-host/bonito: Display hexadecimal value with '0x' prefix

2020-12-31 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 0634f3289c4..efeba29011f 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -463,8 +463,8 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr 
addr)
 regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
 
 if (idsel == 0) {
-error_report("error in bonito pci config address " TARGET_FMT_plx
- ",pcimap_cfg=%x", addr, s->regs[BONITO_PCIMAP_CFG]);
+error_report("error in bonito pci config address 0x" TARGET_FMT_plx
+ ",pcimap_cfg=0x%x", addr, s->regs[BONITO_PCIMAP_CFG]);
 exit(1);
 }
 pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno);
-- 
2.26.2




[PATCH 01/18] hw/pci-host/bonito: Remove unused definitions

2020-12-31 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/pci-host/bonito.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index a99eced0657..0634f3289c4 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -189,12 +189,6 @@ FIELD(BONGENCFG, PCIQUEUE,  12, 1)
 #define BONITO_PCICONF_REG_MASK0xFC
 #define BONITO_PCICONF_REG_OFFSET  0
 
-
-/* idsel BIT = pci slot number +12 */
-#define PCI_SLOT_BASE  12
-#define PCI_IDSEL_VIA686B_BIT  (17)
-#define PCI_IDSEL_VIA686B  (1 << PCI_IDSEL_VIA686B_BIT)
-
 #define PCI_ADDR(busno , devno , funno , regno)  \
 busno) << 16) & 0xff) + (((devno) << 11) & 0xf800) + \
 (((funno) << 8) & 0x700) + (regno))
-- 
2.26.2




[PATCH 00/18] hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified

2020-12-31 Thread Philippe Mathieu-Daudé
Patches I wrote while reviewing/testing Jiaxun's v3 [1] trying
to understand the problem with "Fixup pci.lomem mapping" [2].

The issue should be fixed by patch #8 of this series:
'Remap PCI "lo" regions when PCIMAP reg is modified'.
The rest are cleanups patches.

Happy new year,

Phil.

[1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769286.html
[2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769294.html

Philippe Mathieu-Daudé (18):
  hw/pci-host/bonito: Remove unused definitions
  hw/pci-host/bonito: Display hexadecimal value with '0x' prefix
  hw/pci-host/bonito: Use PCI_DEVFN() macro
  hw/pci-host/bonito: Use pci_config_set_interrupt_pin()
  hw/pci-host/bonito: Simplify soft reset using FIELD_EX32()
  hw/pci-host/bonito: Do not allow big-endian targets
  hw/pci-host/bonito: Make BONPONCFG register read-only
  hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified
  hw/pci-host/bonito: Rename north bridge helpers
  hw/pci-host/bonito: Rename PCI host helpers
  hw/pci-host/bonito: Rename PCI function helpers
  hw/pci-host/bonito: Rename PCIBonitoState -> BonitoPciState
  hw/pci-host/bonito: Create PCI regions in bonito_host_realize()
  hw/pci-host/bonito: Simplify using pci_host_conf_le_ops
MemoryRegionOps
  hw/pci-host/bonito: Map north bridge region in bonito_host_realize()
  hw/pci-host/bonito: Create TYPE_PCI_BONITO in bonito_host_realize()
  hw/pci-host/bonito: Declare TYPE_BONITO_PCI_HOST_BRIDGE in include/
  hw/mips/fuloong2e: Inline bonito_init()

 include/hw/mips/mips.h   |   3 -
 include/hw/pci-host/bonito.h |  34 
 hw/mips/fuloong2e.c  |   7 +-
 hw/pci-host/bonito.c | 357 +++
 MAINTAINERS  |   1 +
 5 files changed, 197 insertions(+), 205 deletions(-)
 create mode 100644 include/hw/pci-host/bonito.h

-- 
2.26.2




Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping

2020-12-31 Thread BALATON Zoltan via

On Thu, 31 Dec 2020, BALATON Zoltan via wrote:

On Thu, 31 Dec 2020, Peter Maydell wrote:
On Thu, 31 Dec 2020 at 15:11, Peter Maydell  
wrote:

On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan  wrote:


Avoid mapping multiple interrupts to the same irq. Instead map them to
the 4 PCI interrupts and use an or-gate in the board to connect them
to the interrupt controller. This does not fix any known problem but
does not seem to cause a new problem either and may be cleaner at least.

Signed-off-by: BALATON Zoltan 
Tested-by: Guenter Roeck 


So, this patch is a behavioural change, but I think it's
probably a change to the right behaviour. The difference
is relatively slight, but you would see it if there are two
different PCI cards and they both assert a different PCI
interrupt, and then one of them lowers the interrupt
before the other:


This turns out to be wrong -- I hadn't looked at the QEMU PCI
code, but it has an internal implementation of logic that
gives the same behaviour as an explicit OR gate. Basically
pci_change_irq_level() tracks how many assert/deasserts of
the (mapped) IRQ lines have happened, so it only calls the
controller's set_irq function when the count of asserted
inputs goes down to 0. So both the current code and this
patch's change are functionally correct.


I've remembered we had this discussion before and arrived to the same 
conclusion that current code was equivalently working but could not recall 
the reason.



I'm not sure which would be nominally closer to the "real hardware":
the 440ex CPU/SoC datasheet lists a single PCI0INT signal, but
it says it is an output, not an input, so I'm pretty sure there's
something I don't understand about PCI here. (Also, unlike the
440EP it provides PCI Express as well as PCI.)


The SoC is called 460EX (despite having a PPC 440 core not 460 one) but I 
think you've looked at the right data sheet and it's just a typo. I also 
don't know how the board is wired so I think in this case I prefer dropping 
this patch and keeping the current code just for simplicity but to avoid 
going through this again maybe we should add a comment saying why it's 
working. Can you please suggest a test for such comment pointing to the


I mean "text" not "test" above.

relevant part of pci_change_irq_level() you refer to above? I don't think I 
understand it enough to document it.


Thank you,
BALATON Zoltan






Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping

2020-12-31 Thread BALATON Zoltan via

On Thu, 31 Dec 2020, Peter Maydell wrote:

On Thu, 31 Dec 2020 at 15:11, Peter Maydell  wrote:

On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan  wrote:


Avoid mapping multiple interrupts to the same irq. Instead map them to
the 4 PCI interrupts and use an or-gate in the board to connect them
to the interrupt controller. This does not fix any known problem but
does not seem to cause a new problem either and may be cleaner at least.

Signed-off-by: BALATON Zoltan 
Tested-by: Guenter Roeck 


So, this patch is a behavioural change, but I think it's
probably a change to the right behaviour. The difference
is relatively slight, but you would see it if there are two
different PCI cards and they both assert a different PCI
interrupt, and then one of them lowers the interrupt
before the other:


This turns out to be wrong -- I hadn't looked at the QEMU PCI
code, but it has an internal implementation of logic that
gives the same behaviour as an explicit OR gate. Basically
pci_change_irq_level() tracks how many assert/deasserts of
the (mapped) IRQ lines have happened, so it only calls the
controller's set_irq function when the count of asserted
inputs goes down to 0. So both the current code and this
patch's change are functionally correct.


I've remembered we had this discussion before and arrived to the same 
conclusion that current code was equivalently working but could not recall 
the reason.



I'm not sure which would be nominally closer to the "real hardware":
the 440ex CPU/SoC datasheet lists a single PCI0INT signal, but
it says it is an output, not an input, so I'm pretty sure there's
something I don't understand about PCI here. (Also, unlike the
440EP it provides PCI Express as well as PCI.)


The SoC is called 460EX (despite having a PPC 440 core not 460 one) but I 
think you've looked at the right data sheet and it's just a typo. I also 
don't know how the board is wired so I think in this case I prefer 
dropping this patch and keeping the current code just for simplicity but 
to avoid going through this again maybe we should add a comment saying why 
it's working. Can you please suggest a test for such comment pointing to 
the relevant part of pci_change_irq_level() you refer to above? I don't 
think I understand it enough to document it.


Thank you,
BALATON Zoltan



Re: [PATCH v2 3/3] trace: recommend "log" backend for getting started with tracing

2020-12-31 Thread BALATON Zoltan via

On Thu, 31 Dec 2020, Peter Maydell wrote:

On Wed, 16 Dec 2020 at 16:09, Stefan Hajnoczi  wrote:


The "simple" backend is actually more complicated to use than the "log"
backend. Update the quickstart documentation to feature the "log"
backend instead of the "simple" backend.

Suggested-by: Peter Maydell 
Signed-off-by: Stefan Hajnoczi 
---
 docs/devel/tracing.rst | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/docs/devel/tracing.rst b/docs/devel/tracing.rst
index 76cc1b24fa..e60058bf55 100644
--- a/docs/devel/tracing.rst
+++ b/docs/devel/tracing.rst
@@ -11,22 +11,22 @@ for debugging, profiling, and observing execution.
 Quickstart
 ==

-1. Build with the 'simple' trace backend::
+Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write``
+events::

-./configure --enable-trace-backends=simple
-make
+$ qemu --trace "memory_region_ops_*" ...
+...
+719585@1608130130.441188:memory_region_ops_read cpu 0 mr 0x562fdfbb3820 
addr 0x3cc value 0x67 size 1
+719585@1608130130.441190:memory_region_ops_write cpu 0 mr 0x562fdfbd2f00 
addr 0x3d4 value 0x70e size 2

-2. Create a file with the events you want to trace::
+This output comes from the "log" trace backend that is enabled by default when
+``./configure --enable-trace-backends=BACKENDS`` was not explicitly specified.

-echo memory_region_ops_read >/tmp/events
+More than one trace event pattern can be specified by providing a file
+instead::


Does --trace really not let you specify more than one pattern
without resorting to putting them into a file? That sounds like a
deficiency compared to -d (which allows -d trace:PATTERN,trace:PATTERN...)
that we could look at fixing...


Ir's possible to give more patterns in multiple options, I'm using that, 
such as:


-trace enable="pci*" -trace enable="ide*"

For a lot of patterns using a file may be clearer though.

This reminds me to the plainlog backend I've submitted. What happened to 
that? See:


https://lists.nongnu.org/archive/html/qemu-devel/2020-06/msg07296.html

I'd like a solution that can be set at compile time and does not need 
another command line option to turn off time stamps. (Timestamps are 
annoyong when comparing logs that's often necessary to check changes.) I'm 
still using my plainlog patch but I have to disable that when bisecting.


Regards,
BALATON Zoltan


Anyway,
Reviewed-by: Peter Maydell 

thanks
-- PMM






[Bug 1909770] Re: qemu-cris segfaults upon loading userspace binary

2020-12-31 Thread ON7WPI
That did indeed fix it, thank you!

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1909770

Title:
  qemu-cris segfaults upon loading userspace binary

Status in QEMU:
  New

Bug description:
  I am on commit 65a3c5984074313602fb5f61cc5f464abfb020c7 (latest as far
  as I know). I compiled qemu with --enable-debug.

  I'm trying to run a userspace CRIS binary (`./qemu-cris -cpu crisv10
  ./basic`), but this segfaults. When opening the coredump in gdb, I get

  gdb-peda$ bt
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  #4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
  filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
  envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
  bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
  #5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
  envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
  #6  0x7f272a1a4152 in __libc_start_main () from /usr/lib/libc.so.6
  #7  0x564a2f786cee in _start ()

  Or as a full backtrace:
  gdb-peda$ bt full
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  No symbol table info available.
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  host_start = 0x92134
  host_map_start = 0x93000
  host_end = 0x94000
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  vaddr = 0x82134
  vaddr_em = 0x82140
  vaddr_len = 0x2000
  vaddr_po = 0x134
  vaddr_ps = 0x82000
  vaddr_ef = 0x82134
  elf_prot = 0x3
  eppnt = 0x7fffe9f54974
  ehdr = 0x7fffe9f54920
  phdr = 0x7fffe9f54954
  load_addr = 0x8
  load_bias = 0x0
  loaddr = 0x8
  hiaddr = 0x1082140
  error = 0x8
  i = 0x1
  retval = 0x273d2e9c
  prot_exec = 0x4
  err = 0x0
  __func__ = "load_elf_image"
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  interp_info = {
load_bias = 0x0,
load_addr = 0x0,
start_code = 0x0,
end_code = 0x0,
start_data = 0x0,
end_data = 0x0,
start_brk = 0x0,
brk = 0x0,
reserve_brk = 0x0,
start_mmap = 0x0,
start_stack = 0x0,
stack_limit = 0x0,
entry = 0x0,
code_offset = 0x0,
data_offset = 0x0,
saved_auxv = 0x0,
auxv_len = 0x0,
arg_start = 0x0,
arg_end = 0x0,
arg_strings = 0x0,
env_strings = 0x0,
file_string = 0x0,
elf_flags = 0x0,
personality = 0x0,
alignment = 0x0,
loadmap_addr = 0x0,
nsegs = 0x0,
loadsegs = 0x0,
pt_dynamic_addr = 0x0,
interpreter_loadmap_addr = 0x0,
interpreter_pt_dynamic_addr = 0x0,
other_info = 0x0,
note_flags = 0x0
  }
  elf_ex = {
e_ident = "|\214\t1\000\000\000\000\262\002\356_\000\000\000",
e_type = 0x8c7c,
e_machine = 0x3109,
e_version = 0x0,
e_entry = 0x5fee02b2,
e_phoff = 0x0,
e_shoff = 0x31098c7c,
e_flags = 0x0,
e_ehsize = 0x0,
e_phentsize = 0x0,
e_phnum = 0x0,
e_shentsize = 0x0,
e_shnum = 0x0,
e_shstrndx = 0x0
  }
  elf_interpreter = 0x0
  scratch = 0x7f272a358021  "H\213D$\bH\203\304(\303\017\037D"
  #4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
  filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
  envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
  bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
  retval = 0x400
  #5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
  envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
  regs1 = {

[Bug 1909770] Re: qemu-cris segfaults upon loading userspace binary

2020-12-31 Thread Peter Maydell
Sounds like it's probably the bug where we don't correctly handle ELF BSS 
segments which have no content in the file at all (ie they're just "zero this 
memory" with no content). If so, this patch (currently in review) will fix it:
https://patchew.org/QEMU/c9106487-dc4d-120a-bd48-665b3c617...@gmail.com/
and you could also work around it by making sure your guest binary has some r/w 
data so it doesn't have a segment that's purely BSS.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1909770

Title:
  qemu-cris segfaults upon loading userspace binary

Status in QEMU:
  New

Bug description:
  I am on commit 65a3c5984074313602fb5f61cc5f464abfb020c7 (latest as far
  as I know). I compiled qemu with --enable-debug.

  I'm trying to run a userspace CRIS binary (`./qemu-cris -cpu crisv10
  ./basic`), but this segfaults. When opening the coredump in gdb, I get

  gdb-peda$ bt
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  #4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
  filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
  envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
  bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
  #5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
  envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
  #6  0x7f272a1a4152 in __libc_start_main () from /usr/lib/libc.so.6
  #7  0x564a2f786cee in _start ()

  Or as a full backtrace:
  gdb-peda$ bt full
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  No symbol table info available.
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  host_start = 0x92134
  host_map_start = 0x93000
  host_end = 0x94000
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  vaddr = 0x82134
  vaddr_em = 0x82140
  vaddr_len = 0x2000
  vaddr_po = 0x134
  vaddr_ps = 0x82000
  vaddr_ef = 0x82134
  elf_prot = 0x3
  eppnt = 0x7fffe9f54974
  ehdr = 0x7fffe9f54920
  phdr = 0x7fffe9f54954
  load_addr = 0x8
  load_bias = 0x0
  loaddr = 0x8
  hiaddr = 0x1082140
  error = 0x8
  i = 0x1
  retval = 0x273d2e9c
  prot_exec = 0x4
  err = 0x0
  __func__ = "load_elf_image"
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  interp_info = {
load_bias = 0x0,
load_addr = 0x0,
start_code = 0x0,
end_code = 0x0,
start_data = 0x0,
end_data = 0x0,
start_brk = 0x0,
brk = 0x0,
reserve_brk = 0x0,
start_mmap = 0x0,
start_stack = 0x0,
stack_limit = 0x0,
entry = 0x0,
code_offset = 0x0,
data_offset = 0x0,
saved_auxv = 0x0,
auxv_len = 0x0,
arg_start = 0x0,
arg_end = 0x0,
arg_strings = 0x0,
env_strings = 0x0,
file_string = 0x0,
elf_flags = 0x0,
personality = 0x0,
alignment = 0x0,
loadmap_addr = 0x0,
nsegs = 0x0,
loadsegs = 0x0,
pt_dynamic_addr = 0x0,
interpreter_loadmap_addr = 0x0,
interpreter_pt_dynamic_addr = 0x0,
other_info = 0x0,
note_flags = 0x0
  }
  elf_ex = {
e_ident = "|\214\t1\000\000\000\000\262\002\356_\000\000\000",
e_type = 0x8c7c,
e_machine = 0x3109,
e_version = 0x0,
e_entry = 0x5fee02b2,
e_phoff = 0x0,
e_shoff = 0x31098c7c,
e_flags = 0x0,
e_ehsize = 0x0,
e_phentsize = 0x0,
e_phnum = 0x0,
e_shentsize = 0x0,
e_shnum = 0x0,
e_shstrndx = 0x0
  }
  elf_interpreter = 0x0
  scratch = 0x7f272a358021  "H\213D$\bH\203\304(\303\017\037D"
  #4  0x564a2f81f

Re: [PULL 00/15] migration queue

2020-12-31 Thread Peter Maydell
On Fri, 18 Dec 2020 at 10:41, Dr. David Alan Gilbert (git)
 wrote:
>
> From: "Dr. David Alan Gilbert" 
>
> The following changes since commit 75ee62ac606bfc9eb59310b9446df3434bf6e8c2:
>
>   Merge remote-tracking branch 
> 'remotes/ehabkost-gl/tags/x86-next-pull-request' into staging (2020-12-17 
> 18:53:36 +)
>
> are available in the Git repository at:
>
>   git://github.com/dagrh/qemu.git tags/pull-migration-20201218a
>
> for you to fetch changes up to 36d0fe65160d83cb065de9b6fe60114ee127d9f0:
>
>   migration: Don't allow migration if vm is in POSTMIGRATE (2020-12-18 
> 10:08:25 +)
>
> 
> Monitor, virtiofsd and migration pull
>
> HMP cleanups
> Migration fixes
>   Note the change in behaviour of not allowing a postmigrate migrtion
>   rather than crashing
>
> Virtiofsd cleanups and fixes
>   --thread-pool-size=0 for no thread pool (faster for some workloads)
>
> Signed-off-by: Dr. David Alan Gilbert 
>


Applied, thanks.

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

-- PMM



[Bug 1909770] Re: qemu-cris segfaults upon loading userspace binary

2020-12-31 Thread ON7WPI
** Tags added: linux-user

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1909770

Title:
  qemu-cris segfaults upon loading userspace binary

Status in QEMU:
  New

Bug description:
  I am on commit 65a3c5984074313602fb5f61cc5f464abfb020c7 (latest as far
  as I know). I compiled qemu with --enable-debug.

  I'm trying to run a userspace CRIS binary (`./qemu-cris -cpu crisv10
  ./basic`), but this segfaults. When opening the coredump in gdb, I get

  gdb-peda$ bt
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  #4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
  filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
  envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
  bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
  #5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
  envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
  #6  0x7f272a1a4152 in __libc_start_main () from /usr/lib/libc.so.6
  #7  0x564a2f786cee in _start ()

  Or as a full backtrace:
  gdb-peda$ bt full
  #0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
  No symbol table info available.
  #1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
  prot=0x3) at ../linux-user/elfload.c:1865
  host_start = 0x92134
  host_map_start = 0x93000
  host_end = 0x94000
  #2  0x564a2f7bff65 in load_elf_image (
  image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
  info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
  bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
  at ../linux-user/elfload.c:2801
  vaddr = 0x82134
  vaddr_em = 0x82140
  vaddr_len = 0x2000
  vaddr_po = 0x134
  vaddr_ps = 0x82000
  vaddr_ef = 0x82134
  elf_prot = 0x3
  eppnt = 0x7fffe9f54974
  ehdr = 0x7fffe9f54920
  phdr = 0x7fffe9f54954
  load_addr = 0x8
  load_bias = 0x0
  loaddr = 0x8
  hiaddr = 0x1082140
  error = 0x8
  i = 0x1
  retval = 0x273d2e9c
  prot_exec = 0x4
  err = 0x0
  __func__ = "load_elf_image"
  #3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
  info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
  interp_info = {
load_bias = 0x0,
load_addr = 0x0,
start_code = 0x0,
end_code = 0x0,
start_data = 0x0,
end_data = 0x0,
start_brk = 0x0,
brk = 0x0,
reserve_brk = 0x0,
start_mmap = 0x0,
start_stack = 0x0,
stack_limit = 0x0,
entry = 0x0,
code_offset = 0x0,
data_offset = 0x0,
saved_auxv = 0x0,
auxv_len = 0x0,
arg_start = 0x0,
arg_end = 0x0,
arg_strings = 0x0,
env_strings = 0x0,
file_string = 0x0,
elf_flags = 0x0,
personality = 0x0,
alignment = 0x0,
loadmap_addr = 0x0,
nsegs = 0x0,
loadsegs = 0x0,
pt_dynamic_addr = 0x0,
interpreter_loadmap_addr = 0x0,
interpreter_pt_dynamic_addr = 0x0,
other_info = 0x0,
note_flags = 0x0
  }
  elf_ex = {
e_ident = "|\214\t1\000\000\000\000\262\002\356_\000\000\000",
e_type = 0x8c7c,
e_machine = 0x3109,
e_version = 0x0,
e_entry = 0x5fee02b2,
e_phoff = 0x0,
e_shoff = 0x31098c7c,
e_flags = 0x0,
e_ehsize = 0x0,
e_phentsize = 0x0,
e_phnum = 0x0,
e_shentsize = 0x0,
e_shnum = 0x0,
e_shstrndx = 0x0
  }
  elf_interpreter = 0x0
  scratch = 0x7f272a358021  "H\213D$\bH\203\304(\303\017\037D"
  #4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
  filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
  envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
  bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
  retval = 0x400
  #5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
  envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
  regs1 = {
orig_r10 

[Bug 1909770] [NEW] qemu-cris segfaults upon loading userspace binary

2020-12-31 Thread ON7WPI
Public bug reported:

I am on commit 65a3c5984074313602fb5f61cc5f464abfb020c7 (latest as far
as I know). I compiled qemu with --enable-debug.

I'm trying to run a userspace CRIS binary (`./qemu-cris -cpu crisv10
./basic`), but this segfaults. When opening the coredump in gdb, I get

gdb-peda$ bt
#0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
#1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
prot=0x3) at ../linux-user/elfload.c:1865
#2  0x564a2f7bff65 in load_elf_image (
image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
at ../linux-user/elfload.c:2801
#3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
#4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
#5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
#6  0x7f272a1a4152 in __libc_start_main () from /usr/lib/libc.so.6
#7  0x564a2f786cee in _start ()

Or as a full backtrace:
gdb-peda$ bt full
#0  0x7f272a2e1ee1 in __memset_avx2_erms () from /usr/lib/libc.so.6
No symbol table info available.
#1  0x564a2f7bcda7 in zero_bss (elf_bss=0x82134, last_bss=0x84000, 
prot=0x3) at ../linux-user/elfload.c:1865
host_start = 0x92134
host_map_start = 0x93000
host_end = 0x94000
#2  0x564a2f7bff65 in load_elf_image (
image_name=0x7fffe9f5703d "./basic", image_fd=0x3, 
info=0x7fffe9f547c0, pinterp_name=0x7fffe9f545b0, 
bprm_buf=0x7fffe9f54920 "\177ELF\001\001\001")
at ../linux-user/elfload.c:2801
vaddr = 0x82134
vaddr_em = 0x82140
vaddr_len = 0x2000
vaddr_po = 0x134
vaddr_ps = 0x82000
vaddr_ef = 0x82134
elf_prot = 0x3
eppnt = 0x7fffe9f54974
ehdr = 0x7fffe9f54920
phdr = 0x7fffe9f54954
load_addr = 0x8
load_bias = 0x0
loaddr = 0x8
hiaddr = 0x1082140
error = 0x8
i = 0x1
retval = 0x273d2e9c
prot_exec = 0x4
err = 0x0
__func__ = "load_elf_image"
#3  0x564a2f7c0a12 in load_elf_binary (bprm=0x7fffe9f54920, 
info=0x7fffe9f547c0) at ../linux-user/elfload.c:3104
interp_info = {
  load_bias = 0x0,
  load_addr = 0x0,
  start_code = 0x0,
  end_code = 0x0,
  start_data = 0x0,
  end_data = 0x0,
  start_brk = 0x0,
  brk = 0x0,
  reserve_brk = 0x0,
  start_mmap = 0x0,
  start_stack = 0x0,
  stack_limit = 0x0,
  entry = 0x0,
  code_offset = 0x0,
  data_offset = 0x0,
  saved_auxv = 0x0,
  auxv_len = 0x0,
  arg_start = 0x0,
  arg_end = 0x0,
  arg_strings = 0x0,
  env_strings = 0x0,
  file_string = 0x0,
  elf_flags = 0x0,
  personality = 0x0,
  alignment = 0x0,
  loadmap_addr = 0x0,
  nsegs = 0x0,
  loadsegs = 0x0,
  pt_dynamic_addr = 0x0,
  interpreter_loadmap_addr = 0x0,
  interpreter_pt_dynamic_addr = 0x0,
  other_info = 0x0,
  note_flags = 0x0
}
elf_ex = {
  e_ident = "|\214\t1\000\000\000\000\262\002\356_\000\000\000",
  e_type = 0x8c7c,
  e_machine = 0x3109,
  e_version = 0x0,
  e_entry = 0x5fee02b2,
  e_phoff = 0x0,
  e_shoff = 0x31098c7c,
  e_flags = 0x0,
  e_ehsize = 0x0,
  e_phentsize = 0x0,
  e_phnum = 0x0,
  e_shentsize = 0x0,
  e_shnum = 0x0,
  e_shstrndx = 0x0
}
elf_interpreter = 0x0
scratch = 0x7f272a358021  "H\213D$\bH\203\304(\303\017\037D"
#4  0x564a2f81f290 in loader_exec (fdexec=0x3, 
filename=0x7fffe9f5703d "./basic", argv=0x564a2f9f3cc0, 
envp=0x564a2fa12600, regs=0x7fffe9f54860, infop=0x7fffe9f547c0, 
bprm=0x7fffe9f54920) at ../linux-user/linuxload.c:147
retval = 0x400
#5  0x564a2f7c4f9f in main (argc=0x4, argv=0x7fffe9f54e78, 
envp=0x7fffe9f54ea0) at ../linux-user/main.c:808
regs1 = {
  orig_r10 = 0x0,
  r0 = 0x0,
  r1 = 0x0,
  r2 = 0x0,
  r3 = 0x0,
  r4 = 0x0,
  r5 = 0x0,
  r6 = 0x0,
  r7 = 0x0,
  r8 = 0x0,
  r9 = 0x0,
  r10 = 0x0,
  r11 = 0x0,
  r12 = 0x0,
  r13 = 0x0,
  acr = 0x0,
  srs = 0x0,
  mof = 0x0,
  spc = 0x0,
  ccs = 0x0,
  srp = 0x0,
  erp = 0x0,
  exs = 0x0,
  eda = 0x0
}
reg

Re: [PATCH 1/3] target/arm: keep translation start level unsigned

2020-12-31 Thread Richard Henderson
On 12/31/20 1:55 AM, Rémi Denis-Courmont wrote:
> Le jeudi 31 décembre 2020, 00:10:09 EET Richard Henderson a écrit :
>> On 12/18/20 6:33 AM, remi.denis.courm...@huawei.com wrote:
>>> From: Rémi Denis-Courmont 
>>>
>>> Signed-off-by: Rémi Denis-Courmont 
>>> ---
>>>
>>>  target/arm/helper.c | 14 ++
>>>  1 file changed, 6 insertions(+), 8 deletions(-)
>>
>> The patch does more than what is described above.
> 
> No? It removes generating negative values, and handling them, for translation 
> levels.

But the removal of generating negative values, i.e. the mask with 3, is clearly
tied to TTST and makes no sense by itself.

Maybe the whole thing is clearer all squashed together...


r~



Re: [PATCH 1/3] target/arm: keep translation start level unsigned

2020-12-31 Thread Richard Henderson
On 12/31/20 1:59 AM, Rémi Denis-Courmont wrote:
> Le jeudi 31 décembre 2020, 00:38:14 EET Richard Henderson a écrit :
>> On 12/30/20 2:10 PM, Richard Henderson wrote:
>>> On 12/18/20 6:33 AM, remi.denis.courm...@huawei.com wrote:
 From: Rémi Denis-Courmont 

 Signed-off-by: Rémi Denis-Courmont 
 ---

  target/arm/helper.c | 14 ++
  1 file changed, 6 insertions(+), 8 deletions(-)
>>>
>>> The patch does more than what is described above.
>>>
 diff --git a/target/arm/helper.c b/target/arm/helper.c
 index df195c314c..b927e53ab0 100644
 --- a/target/arm/helper.c
 +++ b/target/arm/helper.c

 @@ -10821,17 +10821,12 @@ do_fault:
   * Returns true if the suggested S2 translation parameters are OK and
   * false otherwise.
   */

 -static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
 +static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint32_t
 level,

 int inputsize, int stride)
  
  {
  
  const int grainsize = stride + 3;
  int startsizecheck;

 -/* Negative levels are never allowed.  */
 -if (level < 0) {
 -return false;
 -}
 -
>>>
>>> I would expect this to be the only hunk from the patch description. 
>>> Probably changing this negative check to a >= 3 check.
>>
>> Having read the next patch, I think you should drop this type change.
>>
 @@ -11203,7 +11201,7 @@ static bool get_phys_addr_lpae(CPUARMState *env,
 uint64_t address,>> 
  if (!aarch64 || stride == 9) {
  
  /* AArch32 or 4KB pages */

 -startlevel = 2 - sl0;
 +startlevel = (2 - sl0) & 3;
>>
>> This hunk belongs with the next patch, implementing TTST, and should be
>> conditional.  I.e.
>>
>> if (stride == 9) {
>> startlevel = 2 - sl0;
>> if (aarch64 &&
>> cpu_isar_feature(aa64_st, env_archcpu(env)) {
>> startlevel &= 3;
>> }
> 
> You can do that but:
> 1) Nothing in the spec says that SL0 == b11 without ST means start level -1. 
> It's undefined, and I don't see any reasons to treat it differently than with 
> ST.

By that logic there's no reason to treat it differently at all; you could drop
the feature check entirely.  In lieu, -1 makes a decent error indicator.

> 2) Functionally, checking for ST seems to belong naturally within 
> check_s2_mmu_setup() in this particular case.

I guess.  I'll leave it to Peter's preference.


r~



Re: [PATCH v2 2/3] sam460ex: Remove FDT_PPC dependency from KConfig

2020-12-31 Thread Philippe Mathieu-Daudé
On 12/31/20 12:11 PM, BALATON Zoltan via wrote:
> Dependency on FDT_PPC was added in commit b0048f76095
> ("hw/ppc/Kconfig: Only select FDT helper for machines using it") but
> it does not seem to be really necessary so remove it again.
> 
> Signed-off-by: BALATON Zoltan 
> ---
> v2: Do not remove PPC405, reworded commit message
> 
>  hw/ppc/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
> index 8548f42b0d..f1e1be208e 100644
> --- a/hw/ppc/Kconfig
> +++ b/hw/ppc/Kconfig
> @@ -64,7 +64,6 @@ config SAM460EX
>  select SMBUS_EEPROM
>  select USB_EHCI_SYSBUS
>  select USB_OHCI
> -select FDT_PPC
>  
>  config PREP
>  bool
> 

Reviewed-by: Philippe Mathieu-Daudé 




Re: [PULL 00/14] Linux user for 6.0 patches

2020-12-31 Thread Peter Maydell
On Fri, 18 Dec 2020 at 10:26, Laurent Vivier  wrote:
>
> The following changes since commit af3f37319cb1e1ca0c42842ecdbd1bcfc64a4b6f:
>
>   Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' int=
> o staging (2020-12-15 21:24:31 +)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/linux-user-for-6.0-pull-request
>
> for you to fetch changes up to 7a5805a08f942325b373643099f784cdac65c9ea:
>
>   linux-user/sparc: Handle tstate in sparc64_get/set_context() (2020-12-18 11=
> :23:29 +0100)
>
> 
> Add MIPS Loongson 2F/3A
> sparc64 bug fix
> Implement copy_file_range
> Add most IFTUN ioctls
> Fix mremap


Applied, thanks.

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

-- PMM



Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping

2020-12-31 Thread Peter Maydell
On Thu, 31 Dec 2020 at 15:11, Peter Maydell  wrote:
>
> On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan  wrote:
> >
> > Avoid mapping multiple interrupts to the same irq. Instead map them to
> > the 4 PCI interrupts and use an or-gate in the board to connect them
> > to the interrupt controller. This does not fix any known problem but
> > does not seem to cause a new problem either and may be cleaner at least.
> >
> > Signed-off-by: BALATON Zoltan 
> > Tested-by: Guenter Roeck 
>
> So, this patch is a behavioural change, but I think it's
> probably a change to the right behaviour. The difference
> is relatively slight, but you would see it if there are two
> different PCI cards and they both assert a different PCI
> interrupt, and then one of them lowers the interrupt
> before the other:

This turns out to be wrong -- I hadn't looked at the QEMU PCI
code, but it has an internal implementation of logic that
gives the same behaviour as an explicit OR gate. Basically
pci_change_irq_level() tracks how many assert/deasserts of
the (mapped) IRQ lines have happened, so it only calls the
controller's set_irq function when the count of asserted
inputs goes down to 0. So both the current code and this
patch's change are functionally correct.

I'm not sure which would be nominally closer to the "real hardware":
the 440ex CPU/SoC datasheet lists a single PCI0INT signal, but
it says it is an output, not an input, so I'm pretty sure there's
something I don't understand about PCI here. (Also, unlike the
440EP it provides PCI Express as well as PCI.)

thanks
-- PMM



Re: Problems with irq mapping in qemu v5.2

2020-12-31 Thread Peter Maydell
On Fri, 25 Dec 2020 at 23:45, BALATON Zoltan via  wrote:
> For the Bamboo board we have 4 interrupts connected to the PCI bus in the
> board but also have a comment in ppc4xx_pci.c near the above function
> saying:
>
> /* On Bamboo, all pins from each slot are tied to a single board IRQ. This
>   * may need further refactoring for other boards. */
> static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> {
>  int slot = pci_dev->devfn >> 3;
>
>  trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot);
>
>  return slot - 1;
> }
>
> Now I'm not sure what that comment means:

It definitely doesn't match the code, anyway...

> 1. All PCI INTA from all slots go to one irq, PCI INTB to another and so on
>
> or
>
> 2. All PCI interrupts (INTA-D) from first slot are connected to one irq on
> the board, then those from next slot are to another irq and so on

I looked at the datasheet for the PPC440EP SoC itself, and it
has only a single PCIINT pin, so all boards using this CPU
must end up only asserting one interrupt line into the interrupt
controller (presumably via an on-board OR gate?)

> The slot - 1 mapping seems to correspond more to 2. but that also means we
> can only have 4 slots.

You can have more than 4 slots -- one common approach is to
stripe the 4 interrupts across slots, so that if you have
4 interrupts 0, 1, 2, 3 then in slot 0 they are wired
INTA=0, INTB=1, INTC=2, INTD=3, and in slot 1 they are
INTA=1, INTB=2, INTC=3, INTD=0, and in slot 2 they are
INTA=2, INTB=3, INTC=4, INTD=1, and so on.
This just helps to spread the interrupt usage out and
minimise sharing of interrupts between devices, because most
PCI cards only ever use INTA (though they are permitted to use
all 4 if they have a need for it, I think.) This kind of striping
is just implemented by how you connect the pins on the PCI slots.
(This striping is what function pci_swizzle_map_irq_fn() implements.)

In QEMU's PCI implementation, it's OK for the mapping function
to reuse IRQ numbers -- PCI IRQ line changes go via pci_change_irq_level(),
which first calls the controller-specific map_irq function, and then
in pci_bus_change_irq_level() keeps a count of how many different
devices have asserted the (mapped) IRQ, so it calls the
controller's set_irq method with effectively the logical-OR of
all the input levels. (I was wrong about this in another email I
just wrote -- I'll go back and correct that in a moment.)

> I did not find a picture of the real board so don't
> know how many slots that has or how they are connected. I think we need
> more info on the real hardware to tell what's the correct mapping here.

Yeah, I couldn't find any documentation for the board itself either :-(

Incidentally, if guest software like Linux has been written and
tested on QEMU and not on the real hardware, then bugs in the
mapping of IRQs can be painful to try to fix, because if the
kernel was written with the equal-but-opposite bug it will then
not run on a bugfixed QEMU. We had a bit of a mess with the
QEMU versatilepb PCI controller that way.

thanks
-- PMM



Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping

2020-12-31 Thread Peter Maydell
On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan  wrote:
>
> Avoid mapping multiple interrupts to the same irq. Instead map them to
> the 4 PCI interrupts and use an or-gate in the board to connect them
> to the interrupt controller. This does not fix any known problem but
> does not seem to cause a new problem either and may be cleaner at least.
>
> Signed-off-by: BALATON Zoltan 
> Tested-by: Guenter Roeck 

So, this patch is a behavioural change, but I think it's
probably a change to the right behaviour. The difference
is relatively slight, but you would see it if there are two
different PCI cards and they both assert a different PCI
interrupt, and then one of them lowers the interrupt
before the other:

device A:   _|-|
device B:   |--|

With the old code, the signal values as seen by the UIC
look like this:
UIC input:  _|-|
(this is because when device A says "interrupt line value 0 now"
we just pass "interrupt line value 0" through to the output).

and with an OR gate they look like:
UIC input:  _|-|
(which is probably the actual behaviour -- UIC line stays
signalled until all PCI interrupts are quelled).

For this to matter to a guest it would have to be doing something
a bit odd in its interrupt handling code, though, I suspect
(like saying "stop looking for device drivers which need to
service their device once the UIC interrupt is no longer asserted").

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v2] meson: fix ncurses detection on macOS

2020-12-31 Thread Yonggang Luo
On Wed, Dec 30, 2020 at 2:17 PM Chris Hofstaedtler 
wrote:
>
> Without this, meson fails with "curses package not usable" when using
ncurses
> 6.2. Apparently the wide functions (addwstr, etc) are hidden behind the
extra
> define, and meson does not define it at that detection stage.
>
> Regression from b01a4fd3bd7d6f2 ("configure: Define NCURSES_WIDECHAR if
we're
> using curses"). The meson conversion has seen many iterations of the
curses
> check, so pinpointing the exact commit breaking this is not so easy.
>
> Signed-off-by: Chris Hofstaedtler 
> Cc: Peter Maydell 
> Cc: Philippe Mathieu-Daudé 
> Cc: Samuel Thibault 
> Cc: Yonggang Luo 
> ---
>  meson.build | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/meson.build b/meson.build
> index 372576f82c..fd74728674 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -500,16 +500,16 @@ if have_system and not
get_option('curses').disabled()
>  endif
>endforeach
>msg = get_option('curses').enabled() ? 'curses library not found' : ''
> +  curses_compile_args = ['-DNCURSES_WIDECHAR']
>if curses.found()
> -if cc.links(curses_test, dependencies: [curses])
> -  curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR',
dependencies: [curses])
> +if cc.links(curses_test, args: curses_compile_args, dependencies:
[curses])
> +  curses = declare_dependency(compile_args: curses_compile_args,
dependencies: [curses])
>  else
>msg = 'curses package not usable'
>curses = not_found
>  endif
>endif
>if not curses.found()
> -curses_compile_args = ['-DNCURSES_WIDECHAR']
>  has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
>  if targetos != 'windows' and not has_curses_h
>message('Trying with /usr/include/ncursesw')
> --
> 2.29.2
>

Reviewed-by: Yonggang Luo 

--
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


Re: [PATCH v2 3/3] trace: recommend "log" backend for getting started with tracing

2020-12-31 Thread Peter Maydell
On Wed, 16 Dec 2020 at 16:09, Stefan Hajnoczi  wrote:
>
> The "simple" backend is actually more complicated to use than the "log"
> backend. Update the quickstart documentation to feature the "log"
> backend instead of the "simple" backend.
>
> Suggested-by: Peter Maydell 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  docs/devel/tracing.rst | 35 ++-
>  1 file changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/docs/devel/tracing.rst b/docs/devel/tracing.rst
> index 76cc1b24fa..e60058bf55 100644
> --- a/docs/devel/tracing.rst
> +++ b/docs/devel/tracing.rst
> @@ -11,22 +11,22 @@ for debugging, profiling, and observing execution.
>  Quickstart
>  ==
>
> -1. Build with the 'simple' trace backend::
> +Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write``
> +events::
>
> -./configure --enable-trace-backends=simple
> -make
> +$ qemu --trace "memory_region_ops_*" ...
> +...
> +719585@1608130130.441188:memory_region_ops_read cpu 0 mr 0x562fdfbb3820 
> addr 0x3cc value 0x67 size 1
> +719585@1608130130.441190:memory_region_ops_write cpu 0 mr 0x562fdfbd2f00 
> addr 0x3d4 value 0x70e size 2
>
> -2. Create a file with the events you want to trace::
> +This output comes from the "log" trace backend that is enabled by default 
> when
> +``./configure --enable-trace-backends=BACKENDS`` was not explicitly 
> specified.
>
> -echo memory_region_ops_read >/tmp/events
> +More than one trace event pattern can be specified by providing a file
> +instead::

Does --trace really not let you specify more than one pattern
without resorting to putting them into a file? That sounds like a
deficiency compared to -d (which allows -d trace:PATTERN,trace:PATTERN...)
that we could look at fixing...

Anyway,
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PULL v2 00/14] Compile QEMU with -Wimplicit-fallthrough

2020-12-31 Thread Peter Maydell
On Fri, 18 Dec 2020 at 08:27, Thomas Huth  wrote:
>
>  Hi!
>
> The following changes since commit 75ee62ac606bfc9eb59310b9446df3434bf6e8c2:
>
>   Merge remote-tracking branch 
> 'remotes/ehabkost-gl/tags/x86-next-pull-request'
>   into staging (2020-12-17 18:53:36 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/huth/qemu.git tags/pull-request-2020-12-18
>
> for you to fetch changes up to 0a2ebce92a3f10a89843e4a7a8e2f2eba4f7b109:
>
>   configure: Compile with -Wimplicit-fallthrough=2 (2020-12-18 09:15:47 +0100)
>
> 
> * Compile QEMU with -Wimplicit-fallthrough=2 to avoid bugs in
>   switch-case statements
> 


Applied, thanks.

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

-- PMM



[PATCH] cpu-throttle: Remove timer_mod() from cpu_throttle_set()

2020-12-31 Thread Utkarsh Tripathi
During migrations, after each iteration, cpu_throttle_set() is called,
which irrespective of input, re-arms the timer according to value of
new_throttle_pct. This causes cpu_throttle_thread() to be delayed in
getting scheduled and consqeuntly lets guest run for more time than what
the throttle value should allow. This leads to spikes in guest throughput
at high cpu-throttle percentage whenever cpu_throttle_set() is called.

A solution would be not to modify the timer immediately in
cpu_throttle_set(), instead, only modify throttle_percentage so that the
throttle would automatically adjust to the required percentage when
cpu_throttle_timer_tick() is invoked.

Manually tested the patch using following configuration:

Guest:
Centos7 (3.10.0-123.el7.x86_64)
Total Memory - 64GB , CPUs - 16
Tool used - stress (1.0.4)
Workload - stress --vm 32 --vm-bytes 1G --vm-keep

Migration Parameters:
Network Bandwidth - 500MBPS
cpu-throttle-initial - 99

Results:
With timer_mod(): fails to converge, continues indefinitely
Without timer_mod(): converges in 249 sec

Signed-off-by: Utkarsh Tripathi 
---
 softmmu/cpu-throttle.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/softmmu/cpu-throttle.c b/softmmu/cpu-throttle.c
index 2ec4b8e..8c2144a 100644
--- a/softmmu/cpu-throttle.c
+++ b/softmmu/cpu-throttle.c
@@ -90,14 +90,21 @@ static void cpu_throttle_timer_tick(void *opaque)
 
 void cpu_throttle_set(int new_throttle_pct)
 {
+/*
+ * boolean to store whether throttle is already active or not,
+ * before modifying throttle_percentage
+ */
+bool throttle_active = cpu_throttle_active();
+
 /* Ensure throttle percentage is within valid range */
 new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
 new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
 
 qatomic_set(&throttle_percentage, new_throttle_pct);
 
-timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
-   CPU_THROTTLE_TIMESLICE_NS);
+if (!throttle_active) {
+cpu_throttle_timer_tick(NULL);
+}
 }
 
 void cpu_throttle_stop(void)
-- 
1.8.3.1




[PATCH 21/22] docs/system: Add RISC-V documentation

2020-12-31 Thread Bin Meng
From: Bin Meng 

Add RISC-V system emulator documentation for generic information.
`Board-specific documentation` and `RISC-V CPU features` are only
a placeholder and will be added in the future.

Signed-off-by: Bin Meng 
---

 docs/system/target-riscv.rst | 62 
 docs/system/targets.rst  |  1 +
 2 files changed, 63 insertions(+)
 create mode 100644 docs/system/target-riscv.rst

diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
new file mode 100644
index 00..978b96cbdb
--- /dev/null
+++ b/docs/system/target-riscv.rst
@@ -0,0 +1,62 @@
+.. _RISC-V-System-emulator:
+
+RISC-V System emulator
+==
+
+QEMU can emulate both 32-bit and 64-bit RISC-V CPUs. Use the
+``qemu-system-riscv64`` executable to simulate a 64-bit RISC-V machine,
+``qemu-system-riscv32`` executable to simulate a 32-bit RISC-V machine.
+
+QEMU has generally good support for RISC-V guests. It has support for
+several different machines. The reason we support so many is that
+RISC-V hardware is much more widely varying than x86 hardware. RISC-V
+CPUs are generally built into "system-on-chip" (SoC) designs created by
+many different companies with different devices, and these SoCs are
+then built into machines which can vary still further even if they use
+the same SoC.
+
+For most boards the CPU type is fixed (matching what the hardware has),
+so typically you don't need to specify the CPU type by hand, except for
+special cases like the ``virt`` board.
+
+Choosing a board model
+--
+
+For QEMU's RISC-V system emulation, you must specify which board
+model you want to use with the ``-M`` or ``--machine`` option;
+there is no default.
+
+Because RISC-V systems differ so much and in fundamental ways, typically
+operating system or firmware images intended to run on one machine
+will not run at all on any other. This is often surprising for new
+users who are used to the x86 world where every system looks like a
+standard PC. (Once the kernel has booted, most userspace software
+cares much less about the detail of the hardware.)
+
+If you already have a system image or a kernel that works on hardware
+and you want to boot with QEMU, check whether QEMU lists that machine
+in its ``-machine help`` output. If it is listed, then you can probably
+use that board model. If it is not listed, then unfortunately your image
+will almost certainly not boot on QEMU. (You might be able to
+extract the filesystem and use that with a different kernel which
+boots on a system that QEMU does emulate.)
+
+If you don't care about reproducing the idiosyncrasies of a particular
+bit of hardware, such as small amount of RAM, no PCI or other hard
+disk, etc., and just want to run Linux, the best option is to use the
+``virt`` board. This is a platform which doesn't correspond to any
+real hardware and is designed for use in virtual machines. You'll
+need to compile Linux with a suitable configuration for running on
+the ``virt`` board. ``virt`` supports PCI, virtio, recent CPUs and
+large amounts of RAM. It also supports 64-bit CPUs.
+
+Board-specific documentation
+
+
+Unfortunately many of the RISC-V boards QEMU supports are currently
+undocumented; you can get a complete list by running
+``qemu-system-riscv64 --machine help``, or
+``qemu-system-riscv32 --machine help``.
+
+RISC-V CPU features
+---
diff --git a/docs/system/targets.rst b/docs/system/targets.rst
index 564cea9a9b..75ed1087fd 100644
--- a/docs/system/targets.rst
+++ b/docs/system/targets.rst
@@ -19,6 +19,7 @@ Contents:
target-m68k
target-mips
target-ppc
+   target-riscv
target-rx
target-s390x
target-sparc
-- 
2.25.1




[PATCH 17/22] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds the QSPI0 controller to the SoC, and connnects an ISSI
25WP256 flash to it. The generation of corresponding device tree
source fragment is also added.

With this commit, upstream U-Boot for the SiFive HiFive Unleashed
board can boot on QEMU 'sifive_u' out of the box. This allows users
to develop and test the recommended RISC-V boot flow with a real
world use case: ZSBL (in QEMU) loads U-Boot SPL from SPI flash to
L2LIM, then U-Boot SPL loads the payload from SPI flash that is
combined with OpenSBI fw_dynamic firmware and U-Boot proper.

Specify machine property `msel` to 6 to allow booting from the SPI
flash. U-Boot spl is directly loaded via `-bios`, and subsequent
payload is stored in the SPI flash image. Example command line:

$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -smp 5 -m 8G \
-bios u-boot-spl.bin -drive file=spi-nor.img,if=mtd

Signed-off-by: Bin Meng 
---

 include/hw/riscv/sifive_u.h |  4 +++
 hw/riscv/sifive_u.c | 52 +
 hw/riscv/Kconfig|  2 ++
 3 files changed, 58 insertions(+)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index a9f7b4a084..8824b7c031 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -26,6 +26,7 @@
 #include "hw/gpio/sifive_gpio.h"
 #include "hw/misc/sifive_u_otp.h"
 #include "hw/misc/sifive_u_prci.h"
+#include "hw/ssi/sifive_spi.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -45,6 +46,7 @@ typedef struct SiFiveUSoCState {
 SIFIVEGPIOState gpio;
 SiFiveUOTPState otp;
 SiFivePDMAState dma;
+SiFiveSPIState spi0;
 CadenceGEMState gem;
 
 uint32_t serial;
@@ -82,6 +84,7 @@ enum {
 SIFIVE_U_DEV_UART0,
 SIFIVE_U_DEV_UART1,
 SIFIVE_U_DEV_GPIO,
+SIFIVE_U_DEV_QSPI0,
 SIFIVE_U_DEV_OTP,
 SIFIVE_U_DEV_DMC,
 SIFIVE_U_DEV_FLASH0,
@@ -120,6 +123,7 @@ enum {
 SIFIVE_U_PDMA_IRQ5 = 28,
 SIFIVE_U_PDMA_IRQ6 = 29,
 SIFIVE_U_PDMA_IRQ7 = 30,
+SIFIVE_U_QSPI0_IRQ = 51,
 SIFIVE_U_GEM_IRQ = 0x35
 };
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index f5c400dd44..acac4feef1 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -15,6 +15,7 @@
  * 5) OTP (One-Time Programmable) memory with stored serial number
  * 6) GEM (Gigabit Ethernet Controller) and management block
  * 7) DMA (Direct Memory Access Controller)
+ * 8) SPI0 connected to an SPI flash
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -44,6 +45,7 @@
 #include "hw/char/serial.h"
 #include "hw/cpu/cluster.h"
 #include "hw/misc/unimp.h"
+#include "hw/ssi/ssi.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_u.h"
@@ -74,6 +76,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_DEV_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
+[SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
 [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
 [SIFIVE_U_DEV_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DEV_GEM] =  { 0x1009, 0x2000 },
@@ -342,6 +345,32 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 "sifive,fu540-c000-ccache");
 g_free(nodename);
 
+nodename = g_strdup_printf("/soc/spi@%lx",
+(long)memmap[SIFIVE_U_DEV_QSPI0].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+prci_phandle, PRCI_CLK_TLCLK);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI0_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_DEV_QSPI0].base,
+0x0, memmap[SIFIVE_U_DEV_QSPI0].size);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
+g_free(nodename);
+
+nodename = g_strdup_printf("/soc/spi@%lx/flash@0",
+(long)memmap[SIFIVE_U_DEV_QSPI0].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "spi-rx-bus-width", 4);
+qemu_fdt_setprop_cell(fdt, nodename, "spi-tx-bus-width", 4);
+qemu_fdt_setprop(fdt, nodename, "m25p,fast-read", NULL, 0);
+qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 5000);
+qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "jedec,spi-nor");
+g_free(nodename);
+
 phy_phandle = phandle++;
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_DEV_GEM].base);
@@ -439,6 +468,9 @@ static void sifive_u_machine_init(MachineState *machine)
   

[PATCH 20/22] docs/system: Sort targets in alphabetical order

2020-12-31 Thread Bin Meng
From: Bin Meng 

Signed-off-by: Bin Meng 
---

 docs/system/targets.rst | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/docs/system/targets.rst b/docs/system/targets.rst
index 560783644d..564cea9a9b 100644
--- a/docs/system/targets.rst
+++ b/docs/system/targets.rst
@@ -7,16 +7,21 @@ various targets are mentioned in the following sections.
 
 Contents:
 
+..
+   This table of contents should be kept sorted alphabetically
+   by the title text of each file, which isn't the same ordering
+   as an alphabetical sort by filename.
+
 .. toctree::
 
-   target-i386
+   target-arm
+   target-avr
+   target-m68k
+   target-mips
target-ppc
+   target-rx
+   target-s390x
target-sparc
target-sparc64
-   target-mips
-   target-arm
-   target-m68k
+   target-i386
target-xtensa
-   target-s390x
-   target-rx
-   target-avr
-- 
2.25.1




David Gibson, please read

2020-12-31 Thread BALATON Zoltan via

Hello,

I've just sent this but my messages to you are bouncing with:

: Host or domain name not found. Name service
error for name=gibson.dropbear.id.au type=MX: Host not found, try again

after trying for a week so you may have missed it even though I've cc'd 
you.


I've also noticed that my patches don't show up in patchwork and my From 
address gets modified by the list that don't seem to be the case for other 
messages so I wonder if it may be something with my email.


I've sent this to the list too so you have a chance to see it, please 
reply off list.


Regards,
BALATON Zoltan

On Thu, 31 Dec 2020, BALATON Zoltan via wrote:

v2 of https://patchew.org/QEMU/cover.1608937677.git.bala...@eik.bme.hu/
with added Tested-by from Guenter and revised patch 2 as suggested by
Philippe.

Regards,
BALATON Zoltan

BALATON Zoltan (3):
 ppc4xx: Move common dependency on serial to common option
 sam460ex: Remove FDT_PPC dependency from KConfig
 sam460ex: Clean up irq mapping

hw/ppc/Kconfig   |  7 ++-
hw/ppc/ppc440_pcix.c | 28 ++--
hw/ppc/sam460ex.c| 16 +---
3 files changed, 29 insertions(+), 22 deletions(-)






[PATCH 15/22] hw/sd: ssi-sd: Support multiple block write

2020-12-31 Thread Bin Meng
From: Bin Meng 

For a multiple block write operation, each block begins with a multi
write start token. Unlike the SD mode that the multiple block write
ends when receiving a STOP_TRAN command (CMD12), a special stop tran
tocken is used to signal the card.

Emulating this by manually sending a CMD12 to the SD card core, to
bring it out of the receiving data state.

Signed-off-by: Bin Meng 
---

 hw/sd/ssi-sd.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 21a96e91f0..6cf5d749c7 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -99,6 +99,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
 static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
 {
 ssi_sd_state *s = SSI_SD(dev);
+SDRequest request;
+uint8_t longresp[16];
 
 /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data.  */
 if (s->mode == SSI_SD_DATA_READ && val == 0x4c) {
@@ -115,9 +117,31 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 return SSI_DUMMY;
 break;
 case SSI_TOKEN_SINGLE:
+case SSI_TOKEN_MULTI_WRITE:
 DPRINTF("Start write block\n");
 s->mode = SSI_SD_DATA_WRITE;
 return SSI_DUMMY;
+case SSI_TOKEN_STOP_TRAN:
+DPRINTF("Stop multiple write\n");
+
+/* manually issue cmd12 to stop the transfer */
+request.cmd = 12;
+request.arg = 0;
+s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
+if (s->arglen <= 0) {
+s->arglen = 1;
+/* a zero value indicates the card is busy */
+s->response[0] = 0;
+DPRINTF("SD card busy\n");
+} else {
+s->arglen = 1;
+/* a non-zero value indicates the card is ready */
+s->response[0] = SSI_DUMMY;
+}
+
+s->mode = SSI_SD_RESPONSE;
+s->response_pos = 0;
+return SSI_DUMMY;
 }
 
 s->cmd = val & 0x3f;
@@ -126,8 +150,6 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 return SSI_DUMMY;
 case SSI_SD_CMDARG:
 if (s->arglen == 4) {
-SDRequest request;
-uint8_t longresp[16];
 /* FIXME: Check CRC.  */
 request.cmd = s->cmd;
 request.arg = ldl_be_p(s->cmdarg);
-- 
2.25.1




[PATCH 12/22] hw/sd: sd.h: Cosmetic change of using spaces

2020-12-31 Thread Bin Meng
From: Bin Meng 

QEMU conding convention prefers spaces over tabs.

Signed-off-by: Bin Meng 
---

 include/hw/sd/sd.h | 42 +-
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 59d108d453..05ef9b73e5 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -33,27 +33,27 @@
 #include "hw/qdev-core.h"
 #include "qom/object.h"
 
-#define OUT_OF_RANGE   (1 << 31)
-#define ADDRESS_ERROR  (1 << 30)
-#define BLOCK_LEN_ERROR(1 << 29)
-#define ERASE_SEQ_ERROR(1 << 28)
-#define ERASE_PARAM(1 << 27)
-#define WP_VIOLATION   (1 << 26)
-#define CARD_IS_LOCKED (1 << 25)
-#define LOCK_UNLOCK_FAILED (1 << 24)
-#define COM_CRC_ERROR  (1 << 23)
-#define ILLEGAL_COMMAND(1 << 22)
-#define CARD_ECC_FAILED(1 << 21)
-#define CC_ERROR   (1 << 20)
-#define SD_ERROR   (1 << 19)
-#define CID_CSD_OVERWRITE  (1 << 16)
-#define WP_ERASE_SKIP  (1 << 15)
-#define CARD_ECC_DISABLED  (1 << 14)
-#define ERASE_RESET(1 << 13)
-#define CURRENT_STATE  (7 << 9)
-#define READY_FOR_DATA (1 << 8)
-#define APP_CMD(1 << 5)
-#define AKE_SEQ_ERROR  (1 << 3)
+#define OUT_OF_RANGE(1 << 31)
+#define ADDRESS_ERROR   (1 << 30)
+#define BLOCK_LEN_ERROR (1 << 29)
+#define ERASE_SEQ_ERROR (1 << 28)
+#define ERASE_PARAM (1 << 27)
+#define WP_VIOLATION(1 << 26)
+#define CARD_IS_LOCKED  (1 << 25)
+#define LOCK_UNLOCK_FAILED  (1 << 24)
+#define COM_CRC_ERROR   (1 << 23)
+#define ILLEGAL_COMMAND (1 << 22)
+#define CARD_ECC_FAILED (1 << 21)
+#define CC_ERROR(1 << 20)
+#define SD_ERROR(1 << 19)
+#define CID_CSD_OVERWRITE   (1 << 16)
+#define WP_ERASE_SKIP   (1 << 15)
+#define CARD_ECC_DISABLED   (1 << 14)
+#define ERASE_RESET (1 << 13)
+#define CURRENT_STATE   (7 << 9)
+#define READY_FOR_DATA  (1 << 8)
+#define APP_CMD (1 << 5)
+#define AKE_SEQ_ERROR   (1 << 3)
 
 enum SDPhySpecificationVersion {
 SD_PHY_SPECv1_10_VERS = 1,
-- 
2.25.1




[PATCH 18/22] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds the QSPI2 controller to the SoC, and connnects an SD
card to it. The generation of corresponding device tree source
fragment is also added.

Specify machine property `msel` to 11 to boot the same upstream
U-Boot SPL and payload image for the SiFive HiFive Unleashed board.
Note subsequent payload is stored in the SD card image.

$ qemu-system-riscv64 -nographic -M sifive_u,msel=11 -smp 5 -m 8G \
-bios u-boot-spl.bin -drive file=sdcard.img,if=sd

Signed-off-by: Bin Meng 
---

 include/hw/riscv/sifive_u.h |  3 +++
 hw/riscv/sifive_u.c | 43 +++--
 hw/riscv/Kconfig|  1 +
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 8824b7c031..de1464a2ce 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -47,6 +47,7 @@ typedef struct SiFiveUSoCState {
 SiFiveUOTPState otp;
 SiFivePDMAState dma;
 SiFiveSPIState spi0;
+SiFiveSPIState spi2;
 CadenceGEMState gem;
 
 uint32_t serial;
@@ -85,6 +86,7 @@ enum {
 SIFIVE_U_DEV_UART1,
 SIFIVE_U_DEV_GPIO,
 SIFIVE_U_DEV_QSPI0,
+SIFIVE_U_DEV_QSPI2,
 SIFIVE_U_DEV_OTP,
 SIFIVE_U_DEV_DMC,
 SIFIVE_U_DEV_FLASH0,
@@ -99,6 +101,7 @@ enum {
 SIFIVE_U_L2CC_IRQ2 = 3,
 SIFIVE_U_UART0_IRQ = 4,
 SIFIVE_U_UART1_IRQ = 5,
+SIFIVE_U_QSPI2_IRQ = 6,
 SIFIVE_U_GPIO_IRQ0 = 7,
 SIFIVE_U_GPIO_IRQ1 = 8,
 SIFIVE_U_GPIO_IRQ2 = 9,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index acac4feef1..d59333d18d 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -16,6 +16,7 @@
  * 6) GEM (Gigabit Ethernet Controller) and management block
  * 7) DMA (Direct Memory Access Controller)
  * 8) SPI0 connected to an SPI flash
+ * 9) SPI2 connected to an SD card
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -77,6 +78,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
+[SIFIVE_U_DEV_QSPI2] ={ 0x1005, 0x1000 },
 [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
 [SIFIVE_U_DEV_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DEV_GEM] =  { 0x1009, 0x2000 },
@@ -345,6 +347,31 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 "sifive,fu540-c000-ccache");
 g_free(nodename);
 
+nodename = g_strdup_printf("/soc/spi@%lx",
+(long)memmap[SIFIVE_U_DEV_QSPI2].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+prci_phandle, PRCI_CLK_TLCLK);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI2_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_DEV_QSPI2].base,
+0x0, memmap[SIFIVE_U_DEV_QSPI2].size);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
+g_free(nodename);
+
+nodename = g_strdup_printf("/soc/spi@%lx/mmc@0",
+(long)memmap[SIFIVE_U_DEV_QSPI2].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop(fdt, nodename, "disable-wp", NULL, 0);
+qemu_fdt_setprop_cells(fdt, nodename, "voltage-ranges", 3300, 3300);
+qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 2000);
+qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "mmc-spi-slot");
+g_free(nodename);
+
 nodename = g_strdup_printf("/soc/spi@%lx",
 (long)memmap[SIFIVE_U_DEV_QSPI0].base);
 qemu_fdt_add_subnode(fdt, nodename);
@@ -469,8 +496,8 @@ static void sifive_u_machine_init(MachineState *machine)
 uint32_t fdt_load_addr;
 uint64_t kernel_entry;
 DriveInfo *dinfo;
-DeviceState *flash_dev;
-qemu_irq flash_cs;
+DeviceState *flash_dev, *sd_dev;
+qemu_irq flash_cs, sd_cs;
 
 /* Initialize SoC */
 object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
@@ -616,6 +643,12 @@ static void sifive_u_machine_init(MachineState *machine)
 
 flash_cs = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi0), 1, flash_cs);
+
+/* Connect an SD card to SPI2 */
+sd_dev = ssi_create_peripheral(s->soc.spi2.spi, "ssi-sd");
+
+sd_cs = qdev_get_gpio_in_named(sd_dev, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi2), 1, sd_cs);
 }
 
 static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
@@ -730,6 +763,7 @@ static void sifive_u_soc_instance_init(O

[PATCH 13/22] hw/sd: Introduce receive_ready() callback

2020-12-31 Thread Bin Meng
From: Bin Meng 

At present there is a data_ready() callback for the SD data read
path. Let's add a receive_ready() for the SD data write path.

Signed-off-by: Bin Meng 
---

 include/hw/sd/sd.h |  2 ++
 hw/sd/core.c   | 13 +
 hw/sd/sd.c |  6 ++
 3 files changed, 21 insertions(+)

diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 05ef9b73e5..47360ba4ee 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -116,6 +116,7 @@ struct SDCardClass {
  * Return: byte value read
  */
 uint8_t (*read_byte)(SDState *sd);
+bool (*receive_ready)(SDState *sd);
 bool (*data_ready)(SDState *sd);
 void (*set_voltage)(SDState *sd, uint16_t millivolts);
 uint8_t (*get_dat_lines)(SDState *sd);
@@ -187,6 +188,7 @@ void sdbus_write_data(SDBus *sdbus, const void *buf, size_t 
length);
  * Read multiple bytes of data on the data lines of a SD bus.
  */
 void sdbus_read_data(SDBus *sdbus, void *buf, size_t length);
+bool sdbus_receive_ready(SDBus *sd);
 bool sdbus_data_ready(SDBus *sd);
 bool sdbus_get_inserted(SDBus *sd);
 bool sdbus_get_readonly(SDBus *sd);
diff --git a/hw/sd/core.c b/hw/sd/core.c
index 08c93b5903..30ee62c510 100644
--- a/hw/sd/core.c
+++ b/hw/sd/core.c
@@ -160,6 +160,19 @@ void sdbus_read_data(SDBus *sdbus, void *buf, size_t 
length)
 }
 }
 
+bool sdbus_receive_ready(SDBus *sdbus)
+{
+SDState *card = get_card(sdbus);
+
+if (card) {
+SDCardClass *sc = SD_CARD_GET_CLASS(card);
+
+return sc->receive_ready(card);
+}
+
+return false;
+}
+
 bool sdbus_data_ready(SDBus *sdbus)
 {
 SDState *card = get_card(sdbus);
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 67e5f7c05d..f19e38625a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2036,6 +2036,11 @@ uint8_t sd_read_byte(SDState *sd)
 return ret;
 }
 
+static bool sd_receive_ready(SDState *sd)
+{
+return sd->state == sd_receivingdata_state;
+}
+
 static bool sd_data_ready(SDState *sd)
 {
 return sd->state == sd_sendingdata_state;
@@ -2147,6 +2152,7 @@ static void sd_class_init(ObjectClass *klass, void *data)
 sc->do_command = sd_do_command;
 sc->write_byte = sd_write_byte;
 sc->read_byte = sd_read_byte;
+sc->receive_ready = sd_receive_ready;
 sc->data_ready = sd_data_ready;
 sc->enable = sd_enable;
 sc->get_inserted = sd_get_inserted;
-- 
2.25.1




[PATCH 14/22] hw/sd: ssi-sd: Support single block write

2020-12-31 Thread Bin Meng
From: Bin Meng 

Add 2 more states for the block write operation. The SPI host needs
to send a data start tocken to start the transfer, and the data block
written to the card will be acknowledged by a data response tocken.

Signed-off-by: Bin Meng 
---

 hw/sd/ssi-sd.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 8eb48550cf..21a96e91f0 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -42,6 +42,8 @@ typedef enum {
 SSI_SD_DATA_START,
 SSI_SD_DATA_READ,
 SSI_SD_DATA_CRC16,
+SSI_SD_DATA_WRITE,
+SSI_SD_SKIP_CRC16,
 } ssi_sd_mode;
 
 struct ssi_sd_state {
@@ -52,6 +54,7 @@ struct ssi_sd_state {
 uint8_t response[5];
 uint16_t crc16;
 int32_t read_bytes;
+int32_t write_bytes;
 int32_t arglen;
 int32_t response_pos;
 int32_t stopping;
@@ -90,6 +93,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
 /* dummy value - don't care */
 #define SSI_DUMMY   0xff
 
+/* data accepted */
+#define DATA_RESPONSE_ACCEPTED  0x05
+
 static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
 {
 ssi_sd_state *s = SSI_SD(dev);
@@ -103,10 +109,17 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 
 switch (s->mode) {
 case SSI_SD_CMD:
-if (val == SSI_DUMMY) {
+switch (val) {
+case SSI_DUMMY:
 DPRINTF("NULL command\n");
 return SSI_DUMMY;
+break;
+case SSI_TOKEN_SINGLE:
+DPRINTF("Start write block\n");
+s->mode = SSI_SD_DATA_WRITE;
+return SSI_DUMMY;
 }
+
 s->cmd = val & 0x3f;
 s->mode = SSI_SD_CMDARG;
 s->arglen = 0;
@@ -235,6 +248,27 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 s->response_pos = 0;
 }
 return val;
+case SSI_SD_DATA_WRITE:
+sdbus_write_byte(&s->sdbus, val);
+s->write_bytes++;
+if (!sdbus_receive_ready(&s->sdbus) || s->write_bytes == 512) {
+DPRINTF("Data write end\n");
+s->mode = SSI_SD_SKIP_CRC16;
+s->response_pos = 0;
+}
+return val;
+case SSI_SD_SKIP_CRC16:
+/* we don't verify the crc16 */
+s->response_pos++;
+if (s->response_pos == 2) {
+DPRINTF("CRC16 receive end\n");
+s->mode = SSI_SD_RESPONSE;
+s->write_bytes = 0;
+s->arglen = 1;
+s->response[0] = DATA_RESPONSE_ACCEPTED;
+s->response_pos = 0;
+}
+return SSI_DUMMY;
 }
 /* Should never happen.  */
 return SSI_DUMMY;
@@ -325,6 +359,7 @@ static void ssi_sd_reset(DeviceState *dev)
 memset(s->response, 0, sizeof(s->response));
 s->crc16 = 0;
 s->read_bytes = 0;
+s->write_bytes = 0;
 s->arglen = 0;
 s->response_pos = 0;
 s->stopping = 0;
-- 
2.25.1




[PATCH 10/22] hw/sd: sd: Remove duplicated codes in single/multiple block read/write

2020-12-31 Thread Bin Meng
From: Bin Meng 

The single block read (CMD17) codes are the same as the multiple
block read (CMD18). Merge them into one. The same applies to single
block write (CMD24) and multiple block write (CMD25).

Signed-off-by: Bin Meng 
---

 hw/sd/sd.c | 47 ---
 1 file changed, 47 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 52c7217fe1..1ada616e1e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1180,24 +1180,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 17:   /* CMD17:  READ_SINGLE_BLOCK */
-switch (sd->state) {
-case sd_transfer_state:
-
-if (addr + sd->blk_len > sd->size) {
-sd->card_status |= ADDRESS_ERROR;
-return sd_r1;
-}
-
-sd->state = sd_sendingdata_state;
-sd->data_start = addr;
-sd->data_offset = 0;
-return sd_r1;
-
-default:
-break;
-}
-break;
-
 case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
 switch (sd->state) {
 case sd_transfer_state:
@@ -1244,35 +1226,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 /* Block write commands (Class 4) */
 case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
-switch (sd->state) {
-case sd_transfer_state:
-/* Writing in SPI mode not implemented.  */
-if (sd->spi)
-break;
-
-if (addr + sd->blk_len > sd->size) {
-sd->card_status |= ADDRESS_ERROR;
-return sd_r1;
-}
-
-sd->state = sd_receivingdata_state;
-sd->data_start = addr;
-sd->data_offset = 0;
-sd->blk_written = 0;
-
-if (sd_wp_addr(sd, sd->data_start)) {
-sd->card_status |= WP_VIOLATION;
-}
-if (sd->csd[14] & 0x30) {
-sd->card_status |= WP_VIOLATION;
-}
-return sd_r1;
-
-default:
-break;
-}
-break;
-
 case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
 switch (sd->state) {
 case sd_transfer_state:
-- 
2.25.1




[PATCH 22/22] docs/system: riscv: Add documentation for sifive_u machine

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds detailed documentation for RISC-V `sifive_u` machine,
including the following information:

- Supported devices
- Hardware configuration information
- Boot options
- Machine-specific options
- Running Linux kernel
- Running VxWorks kernel
- Running U-Boot, and with an alternate configuration

Signed-off-by: Bin Meng 

---

 docs/system/riscv/sifive_u.rst | 336 +
 docs/system/target-riscv.rst   |  10 +
 2 files changed, 346 insertions(+)
 create mode 100644 docs/system/riscv/sifive_u.rst

diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
new file mode 100644
index 00..7e133d8ff3
--- /dev/null
+++ b/docs/system/riscv/sifive_u.rst
@@ -0,0 +1,336 @@
+SiFive HiFive Unleashed (``sifive_u``)
+==
+
+SiFive HiFive Unleashed Development Board is the ultimate RISC‑V development
+board featuring the Freedom U540 multi-core RISC‑V processor.
+
+Supported devices
+-
+
+The ``sifive_u`` machine supports the following devices:
+
+ * 1 E51 / E31 core
+ * Up to 4 U54 / U34 cores
+ * Core Level Interruptor (CLINT)
+ * Platform-Level Interrupt Controller (PLIC)
+ * Power, Reset, Clock, Interrupt (PRCI)
+ * L2 Loosely Integrated Memory (L2-LIM)
+ * DDR memory controller
+ * 2 UARTs
+ * 1 GEM ethernet controller
+ * 1 GPIO controller
+ * 1 One-Time Programmable (OTP) memory with stored serial number
+ * 1 DMA controller
+ * 2 QSPI controllers
+ * 1 ISSI 25WP256 flash
+ * 1 SD card in SPI mode
+
+Please note the real world HiFive Unleashed board has a fixed configuration of
+1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit mode.
+With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
+is also possible to create a 32-bit variant with the same peripherals execpt
+that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
+testing of 32-bit guest software.
+
+Hardware configuration information
+--
+
+The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
+which it passes to the guest. This provides information about the addresses,
+interrupt lines and other configuration of the various devices in the system.
+Guest software should discover the devices that are present in the generated
+DTB instead of using a DTB for the real hardware, as some of the devices are
+not modeled by QEMU and trying to access these devices may cause unexpected
+behavior.
+
+Boot options
+
+
+The ``sifive_u`` machine can start using the standard -kernel functionality
+for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
+(S-mode) or ELF executable with the default OpenSBI firmware image as the
+-bios. It also supports booting the unmodified U-Boot bootloader using the
+standard -bios functionality.
+
+Machine-specific options
+
+
+The following machine-specific options are supported:
+
+- serial=nnn
+
+  The board serial number. When not given, the default serial number 1 is used.
+
+  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
+  The current usage is only used to store the serial number of the board at
+  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
+  it to generate a unique MAC address to be programmed to the on-chip GEM
+  ethernet controller. When multiple QEMU ``sifive_u`` machines are created
+  and connected to the same subnet, they all have the same MAC address hence
+  it creates a unusable network. In such scenario, user should give different
+  values to serial= when creating different ``sifive_u`` machines.
+
+- start-in-flash
+
+  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
+  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
+  When not given, it defaults to direct DRAM booting.
+
+- msel=[6|11]
+
+  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
+
+  The FU540 SoC supports booting from several sources, which are controlled
+  using the Mode Select pins on the chip. Typically, the boot process runs
+  through several stages before it begins execution of user-provided programs.
+  These stages typically include the following:
+
+  1. Zeroth Stage Boot Loader (ZSBL), which is contained in an on-chip mask
+ ROM and provided by QEMU. Note QEMU implemented ROM codes are not the
+ same as what is programmed in the hardware. The QEMU one is a simplified
+ version, but it provides the same functionality as the hardware.
+  2. First Stage Boot Loader (FSBL), which brings up PLLs and DDR memory.
+ This is U-Boot SPL.
+  3. Second Stage Boot Loader (SSBL), which further initializes additional
+ peripherals as needed. This is U-Boot proper combined with an OpenSBI
+ fw_dynamic firmware image.
+
+  msel=6 means FSBL and SSBL are both on the QSPI flash. msel=11 means FSBL
+  and SS

[PATCH 11/22] hw/sd: sd: Allow single/multiple block write for SPI mode

2020-12-31 Thread Bin Meng
From: Bin Meng 

At present the single/multiple block write in SPI mode is blocked
by sd_normal_command(). Remove the limitation.

Signed-off-by: Bin Meng 
---

 hw/sd/sd.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 1ada616e1e..67e5f7c05d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1229,9 +1229,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
 switch (sd->state) {
 case sd_transfer_state:
-/* Writing in SPI mode not implemented.  */
-if (sd->spi)
-break;
 
 if (addr + sd->blk_len > sd->size) {
 sd->card_status |= ADDRESS_ERROR;
-- 
2.25.1




[PATCH 08/22] hw/sd: ssi-sd: Support multiple block read (CMD18)

2020-12-31 Thread Bin Meng
From: Bin Meng 

In the case of a multiple block read operation every transfered
block has its suffix of CRC16. Update the state machine logic to
handle multiple block read.

This also fixed the wrong command index for STOP_TRANSMISSION,
the required command to interupt the multiple block read command,
in the old codes. It should be CMD12 (0x4c), not CMD13 (0x4d).

Signed-off-by: Bin Meng 
---

 hw/sd/ssi-sd.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 10b0ac2eaf..889260bd8f 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -51,6 +51,7 @@ struct ssi_sd_state {
 uint8_t cmdarg[4];
 uint8_t response[5];
 uint16_t crc16;
+int32_t read_bytes;
 int32_t arglen;
 int32_t response_pos;
 int32_t stopping;
@@ -82,7 +83,7 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t 
val)
 ssi_sd_state *s = SSI_SD(dev);
 
 /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data.  */
-if (s->mode == SSI_SD_DATA_READ && val == 0x4d) {
+if (s->mode == SSI_SD_DATA_READ && val == 0x4c) {
 s->mode = SSI_SD_CMD;
 /* There must be at least one byte delay before the card responds.  */
 s->stopping = 1;
@@ -200,8 +201,9 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 return 0xfe;
 case SSI_SD_DATA_READ:
 val = sdbus_read_byte(&s->sdbus);
+s->read_bytes++;
 s->crc16 = crc_ccitt_false(s->crc16, (uint8_t *)&val, 1);
-if (!sdbus_data_ready(&s->sdbus)) {
+if (!sdbus_data_ready(&s->sdbus) || s->read_bytes == 512) {
 DPRINTF("Data read end\n");
 s->mode = SSI_SD_DATA_CRC16;
 }
@@ -212,7 +214,12 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 s->response_pos++;
 if (s->response_pos == 2) {
 DPRINTF("CRC16 read end\n");
-s->mode = SSI_SD_CMD;
+if (s->read_bytes == 512 && s->cmd != 17) {
+s->mode = SSI_SD_DATA_START;
+} else {
+s->mode = SSI_SD_CMD;
+}
+s->read_bytes = 0;
 s->response_pos = 0;
 }
 return val;
@@ -252,6 +259,7 @@ static const VMStateDescription vmstate_ssi_sd = {
 VMSTATE_UINT8_ARRAY(cmdarg, ssi_sd_state, 4),
 VMSTATE_UINT8_ARRAY(response, ssi_sd_state, 5),
 VMSTATE_UINT16(crc16, ssi_sd_state),
+VMSTATE_INT32(read_bytes, ssi_sd_state),
 VMSTATE_INT32(arglen, ssi_sd_state),
 VMSTATE_INT32(response_pos, ssi_sd_state),
 VMSTATE_INT32(stopping, ssi_sd_state),
@@ -304,6 +312,7 @@ static void ssi_sd_reset(DeviceState *dev)
 memset(s->cmdarg, 0, sizeof(s->cmdarg));
 memset(s->response, 0, sizeof(s->response));
 s->crc16 = 0;
+s->read_bytes = 0;
 s->arglen = 0;
 s->response_pos = 0;
 s->stopping = 0;
-- 
2.25.1




[PATCH 19/22] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value

2020-12-31 Thread Bin Meng
From: Bin Meng 

All other peripherals' IRQs are in the format of decimal value.
Change SIFIVE_U_GEM_IRQ to be consistent.

Signed-off-by: Bin Meng 
---

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

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index de1464a2ce..2656b39808 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -127,7 +127,7 @@ enum {
 SIFIVE_U_PDMA_IRQ6 = 29,
 SIFIVE_U_PDMA_IRQ7 = 30,
 SIFIVE_U_QSPI0_IRQ = 51,
-SIFIVE_U_GEM_IRQ = 0x35
+SIFIVE_U_GEM_IRQ = 53
 };
 
 enum {
-- 
2.25.1




[PATCH 07/22] hw/sd: ssi-sd: Suffix a data block with CRC16

2020-12-31 Thread Bin Meng
From: Bin Meng 

Per the SD spec, a valid data block is suffixed with a 16-bit CRC
generated by the standard CCITT polynomial x16+x12+x5+1. This part
is currently missing in the ssi-sd state machine. Without it, all
data block transfer fails in guest software because the expected
CRC16 is missing on the data out line.

Fixes: 775616c3ae8c ("Partial SD card SPI mode support")
Signed-off-by: Bin Meng 
---

 hw/sd/ssi-sd.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 228ce4ddc7..10b0ac2eaf 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -17,6 +17,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/sd/sd.h"
 #include "qapi/error.h"
+#include "qemu/crc-ccitt.h"
 #include "qemu/module.h"
 #include "qom/object.h"
 
@@ -40,6 +41,7 @@ typedef enum {
 SSI_SD_RESPONSE,
 SSI_SD_DATA_START,
 SSI_SD_DATA_READ,
+SSI_SD_DATA_CRC16,
 } ssi_sd_mode;
 
 struct ssi_sd_state {
@@ -48,6 +50,7 @@ struct ssi_sd_state {
 int cmd;
 uint8_t cmdarg[4];
 uint8_t response[5];
+uint16_t crc16;
 int32_t arglen;
 int32_t response_pos;
 int32_t stopping;
@@ -193,12 +196,24 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 case SSI_SD_DATA_START:
 DPRINTF("Start read block\n");
 s->mode = SSI_SD_DATA_READ;
+s->response_pos = 0;
 return 0xfe;
 case SSI_SD_DATA_READ:
 val = sdbus_read_byte(&s->sdbus);
+s->crc16 = crc_ccitt_false(s->crc16, (uint8_t *)&val, 1);
 if (!sdbus_data_ready(&s->sdbus)) {
 DPRINTF("Data read end\n");
+s->mode = SSI_SD_DATA_CRC16;
+}
+return val;
+case SSI_SD_DATA_CRC16:
+val = (s->crc16 & 0xff00) >> 8;
+s->crc16 <<= 8;
+s->response_pos++;
+if (s->response_pos == 2) {
+DPRINTF("CRC16 read end\n");
 s->mode = SSI_SD_CMD;
+s->response_pos = 0;
 }
 return val;
 }
@@ -236,6 +251,7 @@ static const VMStateDescription vmstate_ssi_sd = {
 VMSTATE_INT32(cmd, ssi_sd_state),
 VMSTATE_UINT8_ARRAY(cmdarg, ssi_sd_state, 4),
 VMSTATE_UINT8_ARRAY(response, ssi_sd_state, 5),
+VMSTATE_UINT16(crc16, ssi_sd_state),
 VMSTATE_INT32(arglen, ssi_sd_state),
 VMSTATE_INT32(response_pos, ssi_sd_state),
 VMSTATE_INT32(stopping, ssi_sd_state),
@@ -287,6 +303,7 @@ static void ssi_sd_reset(DeviceState *dev)
 s->cmd = 0;
 memset(s->cmdarg, 0, sizeof(s->cmdarg));
 memset(s->response, 0, sizeof(s->response));
+s->crc16 = 0;
 s->arglen = 0;
 s->response_pos = 0;
 s->stopping = 0;
-- 
2.25.1




[PATCH 09/22] hw/sd: ssi-sd: Use macros for the dummy value and tokens in the transfer

2020-12-31 Thread Bin Meng
From: Bin Meng 

At present the codes use hardcoded numbers (0xff/0xfe) for the dummy
value and block start token. Replace them with macros, and add more
tokens for multiple block write.

Signed-off-by: Bin Meng 
---

 hw/sd/ssi-sd.c | 30 +-
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 889260bd8f..8eb48550cf 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -78,6 +78,18 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
 #define SSI_SDR_ADDRESS_ERROR   0x2000
 #define SSI_SDR_PARAMETER_ERROR 0x4000
 
+/* reading and writing blocks start with these tokens and end with crc16 */
+
+/* multiple block write */
+#define SSI_TOKEN_MULTI_WRITE   0xfc
+/* terminate multiple block write */
+#define SSI_TOKEN_STOP_TRAN 0xfd
+/* single block read/write, multiple block read */
+#define SSI_TOKEN_SINGLE0xfe
+
+/* dummy value - don't care */
+#define SSI_DUMMY   0xff
+
 static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
 {
 ssi_sd_state *s = SSI_SD(dev);
@@ -91,14 +103,14 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 
 switch (s->mode) {
 case SSI_SD_CMD:
-if (val == 0xff) {
+if (val == SSI_DUMMY) {
 DPRINTF("NULL command\n");
-return 0xff;
+return SSI_DUMMY;
 }
 s->cmd = val & 0x3f;
 s->mode = SSI_SD_CMDARG;
 s->arglen = 0;
-return 0xff;
+return SSI_DUMMY;
 case SSI_SD_CMDARG:
 if (s->arglen == 4) {
 SDRequest request;
@@ -173,14 +185,14 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 } else {
 s->cmdarg[s->arglen++] = val;
 }
-return 0xff;
+return SSI_DUMMY;
 case SSI_SD_PREP_RESP:
 s->mode = SSI_SD_RESPONSE;
-return 0xff;
+return SSI_DUMMY;
 case SSI_SD_RESPONSE:
 if (s->stopping) {
 s->stopping = 0;
-return 0xff;
+return SSI_DUMMY;
 }
 if (s->response_pos < s->arglen) {
 DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
@@ -193,12 +205,12 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 DPRINTF("End of command\n");
 s->mode = SSI_SD_CMD;
 }
-return 0xff;
+return SSI_DUMMY;
 case SSI_SD_DATA_START:
 DPRINTF("Start read block\n");
 s->mode = SSI_SD_DATA_READ;
 s->response_pos = 0;
-return 0xfe;
+return SSI_TOKEN_SINGLE;
 case SSI_SD_DATA_READ:
 val = sdbus_read_byte(&s->sdbus);
 s->read_bytes++;
@@ -225,7 +237,7 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 return val;
 }
 /* Should never happen.  */
-return 0xff;
+return SSI_DUMMY;
 }
 
 static int ssi_sd_post_load(void *opaque, int version_id)
-- 
2.25.1




[PATCH 05/22] hw/sd: sd: Drop sd_crc16()

2020-12-31 Thread Bin Meng
From: Bin Meng 

commit f6fb1f9b319f ("sdcard: Correct CRC16 offset in sd_function_switch()")
changed the 16-bit CRC to be stored at offset 64. In fact, this CRC
calculation is completely wrong. From the original codes, it wants
to calculate the CRC16 of the first 64 bytes of sd->data[], however
passing 64 as the `width` to sd_crc16() actually counts 256 bytes
starting from the `message` for the CRC16 calculation, which is not
what we want.

Besides that, it seems exisitng sd_crc16() algorithm does not match
the SD spec, which says CRC16 is the CCITT one but the calculation
does not produce expected result. It turns out the CRC16 was never
transfered outside the sd core, as in sd_read_byte() we see:

if (sd->data_offset >= 64)
sd->state = sd_transfer_state;

Given above reaons, let's drop it.

Signed-off-by: Bin Meng 
---

 hw/sd/sd.c | 18 --
 1 file changed, 18 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2036734da1..52c7217fe1 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -270,23 +270,6 @@ static uint8_t sd_crc7(const void *message, size_t width)
 return shift_reg;
 }
 
-static uint16_t sd_crc16(const void *message, size_t width)
-{
-int i, bit;
-uint16_t shift_reg = 0x;
-const uint16_t *msg = (const uint16_t *)message;
-width <<= 1;
-
-for (i = 0; i < width; i ++, msg ++)
-for (bit = 15; bit >= 0; bit --) {
-shift_reg <<= 1;
-if ((shift_reg >> 15) ^ ((*msg >> bit) & 1))
-shift_reg ^= 0x1011;
-}
-
-return shift_reg;
-}
-
 #define OCR_POWER_DELAY_NS  50 /* 0.5ms */
 
 FIELD(OCR, VDD_VOLTAGE_WINDOW,  0, 24)
@@ -842,7 +825,6 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
 sd->data[16 - (i >> 1)] |= new_func << ((i % 2) * 4);
 }
 memset(&sd->data[17], 0, 47);
-stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
 }
 
 static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
-- 
2.25.1




[PATCH 16/22] hw/ssi: Add SiFive SPI controller support

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds the SiFive SPI controller model for the FU540 SoC.
The direct memory-mapped SPI flash mode is unsupported.

Signed-off-by: Bin Meng 
---

 include/hw/ssi/sifive_spi.h |  47 ++
 hw/ssi/sifive_spi.c | 290 
 hw/ssi/Kconfig  |   4 +
 hw/ssi/meson.build  |   1 +
 4 files changed, 342 insertions(+)
 create mode 100644 include/hw/ssi/sifive_spi.h
 create mode 100644 hw/ssi/sifive_spi.c

diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h
new file mode 100644
index 00..dc29d9e3a9
--- /dev/null
+++ b/include/hw/ssi/sifive_spi.h
@@ -0,0 +1,47 @@
+/*
+ * QEMU model of the SiFive SPI Controller
+ *
+ * Copyright (c) 2020 Wind River Systems, Inc.
+ *
+ * Author:
+ *   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 .
+ */
+
+#ifndef HW_SIFIVE_SPI_H
+#define HW_SIFIVE_SPI_H
+
+#define SIFIVE_SPI_REG_NUM  (0x78 / 4)
+
+#define TYPE_SIFIVE_SPI "sifive.spi"
+#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)
+
+typedef struct SiFiveSPIState {
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+qemu_irq irq;
+
+uint32_t num_cs;
+qemu_irq *cs_lines;
+
+SSIBus *spi;
+
+Fifo8 tx_fifo;
+Fifo8 rx_fifo;
+
+uint32_t regs[SIFIVE_SPI_REG_NUM];
+} SiFiveSPIState;
+
+#endif /* HW_SIFIVE_SPI_H */
diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
new file mode 100644
index 00..e1caaf8ade
--- /dev/null
+++ b/hw/ssi/sifive_spi.c
@@ -0,0 +1,290 @@
+/*
+ * QEMU model of the SiFive SPI Controller
+ *
+ * Copyright (c) 2020 Wind River Systems, Inc.
+ *
+ * Author:
+ *   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 .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "hw/ssi/ssi.h"
+#include "sysemu/sysemu.h"
+#include "qemu/fifo8.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/ssi/sifive_spi.h"
+
+#define R_SCKDIV(0x00 / 4)
+#define R_SCKMODE   (0x04 / 4)
+#define R_CSID  (0x10 / 4)
+#define R_CSDEF (0x14 / 4)
+#define R_CSMODE(0x18 / 4)
+#define R_DELAY0(0x28 / 4)
+#define R_DELAY1(0x2C / 4)
+#define R_FMT   (0x40 / 4)
+#define R_TXDATA(0x48 / 4)
+#define R_RXDATA(0x4C / 4)
+#define R_TXMARK(0x50 / 4)
+#define R_RXMARK(0x54 / 4)
+#define R_FCTRL (0x60 / 4)
+#define R_FFMT  (0x64 / 4)
+#define R_IE(0x70 / 4)
+#define R_IP(0x74 / 4)
+
+#define TXDATA_FULL (1 << 31)
+#define RXDATA_EMPTY(1 << 31)
+
+#define IE_TXWM (1 << 0)
+#define IE_RXWM (1 << 1)
+
+#define IP_TXWM (1 << 0)
+#define IP_RXWM (1 << 1)
+
+#define FIFO_CAPACITY   8
+
+static void sifive_spi_txfifo_reset(SiFiveSPIState *s)
+{
+fifo8_reset(&s->tx_fifo);
+
+s->regs[R_TXDATA] &= ~TXDATA_FULL;
+s->regs[R_IP] &= ~IP_TXWM;
+}
+
+static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)
+{
+fifo8_reset(&s->rx_fifo);
+
+s->regs[R_RXDATA] |= RXDATA_EMPTY;
+s->regs[R_IP] &= ~IP_RXWM;
+}
+
+static void sifive_spi_update_cs(SiFiveSPIState *s)
+{
+int i;
+
+for (i = 0; i < s->num_cs; i++) {
+if (s->regs[R_CSDEF] & (1 << i)) {
+qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));
+}
+}
+}
+
+static void sifive_spi_update_irq(SiFiveSPIState *s)
+{
+int level;
+
+if (fifo8_num_used(&s->tx_fifo) < s->regs[R_TXMARK]) {
+s->regs[R_IP] |= IP_TXWM;
+} else {
+s->regs[R_IP] &= ~IP_TXWM;
+}
+
+if (fifo8_num_used(&s->rx_fifo) > s->regs[R_RXMARK]) {
+s->regs[R_IP] |= IP_RXWM;
+} else {
+s->regs[R_IP] &= ~IP_RXWM;
+}
+
+level = s->regs[R_IP] & s->regs[R_IE] ? 1 : 0;
+qemu_set_irq(s->irq, level);
+}
+

[PATCH 03/22] hw/sd: ssi-sd: Fix incorrect card response sequence

2020-12-31 Thread Bin Meng
From: Bin Meng 

Per the "Physical Layer Specification Version 8.00" chapter 7.5.1,
"Command/Response", there is a minimum 8 clock cycles (Ncr) before
the card response shows up on the data out line. However current
implementation jumps directly to the sending response state after
all 6 bytes command is received, which is a spec violation.

Add a new state PREP_RESP in the ssi-sd state machine to handle it.

Fixes: 775616c3ae8c ("Partial SD card SPI mode support")
Signed-off-by: Bin Meng 
---

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

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 9a75e0095c..228ce4ddc7 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -36,6 +36,7 @@ do { fprintf(stderr, "ssi_sd: error: " fmt , ## 
__VA_ARGS__);} while (0)
 typedef enum {
 SSI_SD_CMD = 0,
 SSI_SD_CMDARG,
+SSI_SD_PREP_RESP,
 SSI_SD_RESPONSE,
 SSI_SD_DATA_START,
 SSI_SD_DATA_READ,
@@ -163,12 +164,15 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
uint32_t val)
 s->response[1] = status;
 DPRINTF("Card status 0x%02x\n", status);
 }
-s->mode = SSI_SD_RESPONSE;
+s->mode = SSI_SD_PREP_RESP;
 s->response_pos = 0;
 } else {
 s->cmdarg[s->arglen++] = val;
 }
 return 0xff;
+case SSI_SD_PREP_RESP:
+s->mode = SSI_SD_RESPONSE;
+return 0xff;
 case SSI_SD_RESPONSE:
 if (s->stopping) {
 s->stopping = 0;
-- 
2.25.1




[PATCH 06/22] util: Add CRC16 (CCITT) calculation routines

2020-12-31 Thread Bin Meng
From: Bin Meng 

Import CRC16 calculation routines from Linux kernel v5.10:

  include/linux/crc-ccitt.h
  lib/crc-ccitt.c

to QEMU:

  include/qemu/crc-ccitt.h
  util/crc-ccitt.c

Signed-off-by: Bin Meng 
---

 include/qemu/crc-ccitt.h |  33 ++
 util/crc-ccitt.c | 127 +++
 util/meson.build |   1 +
 3 files changed, 161 insertions(+)
 create mode 100644 include/qemu/crc-ccitt.h
 create mode 100644 util/crc-ccitt.c

diff --git a/include/qemu/crc-ccitt.h b/include/qemu/crc-ccitt.h
new file mode 100644
index 00..c017a8157e
--- /dev/null
+++ b/include/qemu/crc-ccitt.h
@@ -0,0 +1,33 @@
+/*
+ * CRC16 (CCITT) Checksum Algorithm
+ *
+ * Copyright (c) 2020 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng 
+ *
+ * From Linux kernel v5.10 include/linux/crc-ccitt.h
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _CRC_CCITT_H
+#define _CRC_CCITT_H
+
+extern uint16_t const crc_ccitt_table[256];
+extern uint16_t const crc_ccitt_false_table[256];
+
+extern uint16_t crc_ccitt(uint16_t crc, const uint8_t *buffer, size_t len);
+extern uint16_t crc_ccitt_false(uint16_t crc, const uint8_t *buffer, size_t 
len);
+
+static inline uint16_t crc_ccitt_byte(uint16_t crc, const uint8_t c)
+{
+return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
+}
+
+static inline uint16_t crc_ccitt_false_byte(uint16_t crc, const uint8_t c)
+{
+return (crc << 8) ^ crc_ccitt_false_table[(crc >> 8) ^ c];
+}
+
+#endif /* _CRC_CCITT_H */
diff --git a/util/crc-ccitt.c b/util/crc-ccitt.c
new file mode 100644
index 00..481e45c380
--- /dev/null
+++ b/util/crc-ccitt.c
@@ -0,0 +1,127 @@
+/*
+ * CRC16 (CCITT) Checksum Algorithm
+ *
+ * Copyright (c) 2020 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng 
+ *
+ * From Linux kernel v5.10 lib/crc-ccitt.c
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/crc-ccitt.h"
+
+/*
+ * This mysterious table is just the CRC of each possible byte. It can be
+ * computed using the standard bit-at-a-time methods. The polynomial can
+ * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12.
+ * Add the implicit x^16, and you have the standard CRC-CCITT.
+ */
+uint16_t const crc_ccitt_table[256] = {
+0x, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/*
+ * Similar table to calculate CRC16 variant known as CRC-CCITT-FALSE
+ * Reflected bits order, does not augment final value.
+ */
+uint16_t const crc_ccitt_false_table[256] = {
+0x, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C

[PATCH 01/22] hw/block: m25p80: Add ISSI SPI flash support

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds the ISSI SPI flash support. The number of dummy cycles in
fast read, fast read dual output and fast read quad output commands
is currently using the default 8. Per the datasheet [1], the number
of dummy cycles configurable, but this is not modeled.

For flash whose size is larger than 16 MiB, the sequence of 3-byte
address along with EXTADD bit in the bank address register (BAR) is
not supported. Currently we assume that guest software will alawys
use op codes with 4-byte address sequence. Fortunately this is the
case for both U-Boot and Linux.

[1] http://www.issi.com/WW/pdf/25LP-WP256.pdf

Signed-off-by: Bin Meng 
---

 hw/block/m25p80.c | 38 +-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 844cabea21..8a62bc4bc4 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -411,6 +411,7 @@ typedef enum {
 MAN_NUMONYX,
 MAN_WINBOND,
 MAN_SST,
+MAN_ISSI,
 MAN_GENERIC,
 } Manufacturer;
 
@@ -486,6 +487,8 @@ static inline Manufacturer get_man(Flash *s)
 return MAN_MACRONIX;
 case 0xBF:
 return MAN_SST;
+case 0x9D:
+return MAN_ISSI;
 default:
 return MAN_GENERIC;
 }
@@ -705,6 +708,9 @@ static void complete_collecting_data(Flash *s)
 case MAN_SPANSION:
 s->quad_enable = !!(s->data[1] & 0x02);
 break;
+case MAN_ISSI:
+s->quad_enable = extract32(s->data[0], 6, 1);
+break;
 case MAN_MACRONIX:
 s->quad_enable = extract32(s->data[0], 6, 1);
 if (s->len > 1) {
@@ -897,6 +903,16 @@ static void decode_fast_read_cmd(Flash *s)
 SPANSION_DUMMY_CLK_LEN
 );
 break;
+case MAN_ISSI:
+/*
+ * The fast read instruction code is followed by address bytes and
+ * dummy cycles, transmitted via the SI line.
+ *
+ * The number of dummy cycles are configurable but this is currently
+ * unmodeled, hence the default value 8 is used.
+ */
+s->needed_bytes += ((8 * 1) / 8);
+break;
 default:
 break;
 }
@@ -936,6 +952,16 @@ static void decode_dio_read_cmd(Flash *s)
 break;
 }
 break;
+case MAN_ISSI:
+/*
+ * The fast read dual I/O instruction code is followed by address bytes
+ * and dummy cycles, transmitted via the IO1 and IO0 line.
+ *
+ * The number of dummy cycles are configurable but this is currently
+ * unmodeled, hence the default value 4 is used.
+ */
+s->needed_bytes += ((4 * 2) / 8);
+break;
 default:
 break;
 }
@@ -976,6 +1002,16 @@ static void decode_qio_read_cmd(Flash *s)
 break;
 }
 break;
+case MAN_ISSI:
+/*
+ * The fast read quad I/O instruction code is followed by address bytes
+ * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
+ *
+ * The number of dummy cycles are configurable but this is currently
+ * unmodeled, hence the default value 6 is used.
+ */
+s->needed_bytes += ((6 * 4) / 8);
+break;
 default:
 break;
 }
@@ -1134,7 +1170,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
 
 case RDSR:
 s->data[0] = (!!s->write_enable) << 1;
-if (get_man(s) == MAN_MACRONIX) {
+if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
 s->data[0] |= (!!s->quad_enable) << 6;
 }
 if (get_man(s) == MAN_SST) {
-- 
2.25.1




[PATCH 04/22] hw/sd: sd: Support CMD59 for SPI mode

2020-12-31 Thread Bin Meng
From: Bin Meng 

After the card is put into SPI mode, CRC check for all commands
including CMD0 will be done according to CMD59 setting. But this
command is currently unimplemented. Simply allow the decoding of
CMD59, but the CRC check is still ignored.

Signed-off-by: Bin Meng 
---

 hw/sd/sd.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 1842c03797..2036734da1 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1516,18 +1516,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 if (!sd->spi) {
 goto bad_cmd;
 }
-goto unimplemented_spi_cmd;
+return sd_r1;
 
 default:
 bad_cmd:
 qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd);
 return sd_illegal;
-
-unimplemented_spi_cmd:
-/* Commands that are recognised but not yet implemented in SPI mode.  
*/
-qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n",
-  req.cmd);
-return sd_illegal;
 }
 
 qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state\n", req.cmd);
-- 
2.25.1




[PATCH 00/22] hw/riscv: sifive_u: Add missing SPI support

2020-12-31 Thread Bin Meng
From: Bin Meng 

This adds the missing SPI support to the `sifive_u` machine in the QEMU
mainline. With this series, upstream U-Boot for the SiFive HiFive Unleashed
board can boot on QEMU `sifive_u` out of the box. This allows users to
develop and test the recommended RISC-V boot flow with a real world use
case: ZSBL (in QEMU) loads U-Boot SPL from SD card or SPI flash to L2LIM,
then U-Boot SPL loads the payload from SD card or SPI flash that is a
combination of OpenSBI fw_dynamic firmware and U-Boot proper.

The m25p80 model is updated to support ISSI flash series. A bunch of
ssi-sd issues are fixed, and writing to SD card in SPI mode is supported.

reST documentation for RISC-V is added. Currently only `sifive_u`
machine is documented, but more to come.


Bin Meng (22):
  hw/block: m25p80: Add ISSI SPI flash support
  hw/block: m25p80: Add various ISSI flash information
  hw/sd: ssi-sd: Fix incorrect card response sequence
  hw/sd: sd: Support CMD59 for SPI mode
  hw/sd: sd: Drop sd_crc16()
  util: Add CRC16 (CCITT) calculation routines
  hw/sd: ssi-sd: Suffix a data block with CRC16
  hw/sd: ssi-sd: Support multiple block read (CMD18)
  hw/sd: ssi-sd: Use macros for the dummy value and tokens in the
transfer
  hw/sd: sd: Remove duplicated codes in single/multiple block read/write
  hw/sd: sd: Allow single/multiple block write for SPI mode
  hw/sd: sd.h: Cosmetic change of using spaces
  hw/sd: Introduce receive_ready() callback
  hw/sd: ssi-sd: Support single block write
  hw/sd: ssi-sd: Support multiple block write
  hw/ssi: Add SiFive SPI controller support
  hw/riscv: sifive_u: Add QSPI0 controller and connect a flash
  hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card
  hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value
  docs/system: Sort targets in alphabetical order
  docs/system: Add RISC-V documentation
  docs/system: riscv: Add documentation for sifive_u machine

 docs/system/riscv/sifive_u.rst | 336 +
 docs/system/target-riscv.rst   |  72 +++
 docs/system/targets.rst|  20 +-
 include/hw/riscv/sifive_u.h|   9 +-
 include/hw/sd/sd.h |  44 ++---
 include/hw/ssi/sifive_spi.h|  47 +
 include/qemu/crc-ccitt.h   |  33 
 hw/block/m25p80.c  |  51 -
 hw/riscv/sifive_u.c|  91 +
 hw/sd/core.c   |  13 ++
 hw/sd/sd.c |  82 +---
 hw/sd/ssi-sd.c | 127 +++--
 hw/ssi/sifive_spi.c| 290 
 util/crc-ccitt.c   | 127 +
 hw/riscv/Kconfig   |   3 +
 hw/ssi/Kconfig |   4 +
 hw/ssi/meson.build |   1 +
 util/meson.build   |   1 +
 18 files changed, 1232 insertions(+), 119 deletions(-)
 create mode 100644 docs/system/riscv/sifive_u.rst
 create mode 100644 docs/system/target-riscv.rst
 create mode 100644 include/hw/ssi/sifive_spi.h
 create mode 100644 include/qemu/crc-ccitt.h
 create mode 100644 hw/ssi/sifive_spi.c
 create mode 100644 util/crc-ccitt.c

-- 
2.25.1




[PATCH 02/22] hw/block: m25p80: Add various ISSI flash information

2020-12-31 Thread Bin Meng
From: Bin Meng 

This updates the flash information table to include various ISSI
flashes that are supported by upstream U-Boot and Linux kernel.

Signed-off-by: Bin Meng 
---

 hw/block/m25p80.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 8a62bc4bc4..e82deb41c6 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -209,6 +209,19 @@ static const FlashPartInfo known_devices[] = {
 { INFO("640s33b", 0x898913,  0,  64 << 10, 128, 0) },
 { INFO("n25q064", 0x20ba17,  0,  64 << 10, 128, 0) },
 
+/* ISSI */
+{ INFO("is25lq040b",  0x9d4013,  0,  64 << 10,   8, ER_4K) },
+{ INFO("is25lp080d",  0x9d6014,  0,  64 << 10,  16, ER_4K) },
+{ INFO("is25lp016d",  0x9d6015,  0,  64 << 10,  32, ER_4K) },
+{ INFO("is25lp032",   0x9d6016,  0,  64 << 10,  64, ER_4K) },
+{ INFO("is25lp064",   0x9d6017,  0,  64 << 10, 128, ER_4K) },
+{ INFO("is25lp128",   0x9d6018,  0,  64 << 10, 256, ER_4K) },
+{ INFO("is25lp256",   0x9d6019,  0,  64 << 10, 512, ER_4K) },
+{ INFO("is25wp032",   0x9d7016,  0,  64 << 10,  64, ER_4K) },
+{ INFO("is25wp064",   0x9d7017,  0,  64 << 10, 128, ER_4K) },
+{ INFO("is25wp128",   0x9d7018,  0,  64 << 10, 256, ER_4K) },
+{ INFO("is25wp256",   0x9d7019,  0,  64 << 10, 512, ER_4K) },
+
 /* Macronix */
 { INFO("mx25l2005a",  0xc22012,  0,  64 << 10,   4, ER_4K) },
 { INFO("mx25l4005a",  0xc22013,  0,  64 << 10,   8, ER_4K) },
-- 
2.25.1




[PATCH v2 2/3] sam460ex: Remove FDT_PPC dependency from KConfig

2020-12-31 Thread BALATON Zoltan via
Dependency on FDT_PPC was added in commit b0048f76095
("hw/ppc/Kconfig: Only select FDT helper for machines using it") but
it does not seem to be really necessary so remove it again.

Signed-off-by: BALATON Zoltan 
---
v2: Do not remove PPC405, reworded commit message

 hw/ppc/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 8548f42b0d..f1e1be208e 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -64,7 +64,6 @@ config SAM460EX
 select SMBUS_EEPROM
 select USB_EHCI_SYSBUS
 select USB_OHCI
-select FDT_PPC
 
 config PREP
 bool
-- 
2.21.3




[PATCH v2 3/3] sam460ex: Clean up irq mapping

2020-12-31 Thread BALATON Zoltan via
Avoid mapping multiple interrupts to the same irq. Instead map them to
the 4 PCI interrupts and use an or-gate in the board to connect them
to the interrupt controller. This does not fix any known problem but
does not seem to cause a new problem either and may be cleaner at least.

Signed-off-by: BALATON Zoltan 
Tested-by: Guenter Roeck 
---
 hw/ppc/Kconfig   |  1 +
 hw/ppc/ppc440_pcix.c | 28 ++--
 hw/ppc/sam460ex.c| 16 +---
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index f1e1be208e..ebb70803c4 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -59,6 +59,7 @@ config SAM460EX
 select PFLASH_CFI01
 select IDE_SII3112
 select M41T80
+select OR_IRQ
 select PPC440
 select SM501
 select SMBUS_EEPROM
diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index ee952314c8..504decbbc2 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -57,8 +57,8 @@ struct PPC440PCIXState {
 PCIDevice *dev;
 struct PLBOutMap pom[PPC440_PCIX_NR_POMS];
 struct PLBInMap pim[PPC440_PCIX_NR_PIMS];
+qemu_irq irq[PCI_NUM_PINS];
 uint32_t sts;
-qemu_irq irq;
 AddressSpace bm_as;
 MemoryRegion bm;
 
@@ -415,24 +415,20 @@ static void ppc440_pcix_reset(DeviceState *dev)
 s->sts = 0;
 }
 
-/* All pins from each slot are tied to a single board IRQ.
- * This may need further refactoring for other boards. */
 static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num)
 {
-trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0);
-return 0;
+int n = (irq_num + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
+
+trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, n);
+return n;
 }
 
 static void ppc440_pcix_set_irq(void *opaque, int irq_num, int level)
 {
-qemu_irq *pci_irq = opaque;
+qemu_irq *pci_irqs = opaque;
 
 trace_ppc440_pcix_set_irq(irq_num);
-if (irq_num < 0) {
-error_report("%s: PCI irq %d", __func__, irq_num);
-return;
-}
-qemu_set_irq(*pci_irq, level);
+qemu_set_irq(pci_irqs[irq_num], level);
 }
 
 static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn)
@@ -472,15 +468,19 @@ static void ppc440_pcix_realize(DeviceState *dev, Error 
**errp)
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 PPC440PCIXState *s;
 PCIHostState *h;
+int i;
 
 h = PCI_HOST_BRIDGE(dev);
 s = PPC440_PCIX_HOST_BRIDGE(dev);
 
-sysbus_init_irq(sbd, &s->irq);
+for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
+sysbus_init_irq(sbd, &s->irq[i]);
+}
 memory_region_init(&s->busmem, OBJECT(dev), "pci bus memory", UINT64_MAX);
 h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq,
- ppc440_pcix_map_irq, &s->irq, &s->busmem,
- get_system_io(), PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS);
+ ppc440_pcix_map_irq, s->irq, &s->busmem,
+ get_system_io(), PCI_DEVFN(0, 0), ARRAY_SIZE(s->irq),
+ TYPE_PCI_BUS);
 
 s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge");
 
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 14e6583eb0..59b19fbca1 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -33,6 +33,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/reset.h"
 #include "hw/sysbus.h"
+#include "hw/or-irq.h"
 #include "hw/char/serial.h"
 #include "hw/i2c/ppc4xx_i2c.h"
 #include "hw/i2c/smbus_eeprom.h"
@@ -292,7 +293,7 @@ static void sam460ex_init(MachineState *machine)
 SysBusDevice *sbdev;
 struct boot_info *boot_info;
 uint8_t *spd_data;
-int success;
+int i, success;
 
 cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
 env = &cpu->env;
@@ -382,13 +383,22 @@ static void sam460ex_init(MachineState *machine)
 
 /* PCI bus */
 ppc460ex_pcie_init(env);
-/* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */
-dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, uic[1][0]);
+dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, NULL);
 pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
 if (!pci_bus) {
 error_report("couldn't create PCI controller!");
 exit(1);
 }
+/* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */
+sbdev = SYS_BUS_DEVICE(dev);
+dev = qdev_new(TYPE_OR_IRQ);
+object_property_set_int(OBJECT(dev), "num-lines", PCI_NUM_PINS,
+&error_fatal);
+qdev_realize_and_unref(dev, NULL, &error_fatal);
+for (i = 0; i < PCI_NUM_PINS; i++) {
+sysbus_connect_irq(sbdev, i, qdev_get_gpio_in(dev, i));
+}
+qdev_connect_gpio_out(dev, 0, uic[1][0]);
 memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(),
  0, 0x1);
 memory_region_add_subregion(get_system_memory(), 0xc0800, isa);
-- 
2.21.3




[PATCH v2 1/3] ppc4xx: Move common dependency on serial to common option

2020-12-31 Thread BALATON Zoltan via
All machines that select SERIAL also select PPC4XX so we can just add
this common dependency there once.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/Kconfig | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index dd86e664d2..8548f42b0d 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -37,7 +37,6 @@ config PPC405
 select M48T59
 select PFLASH_CFI02
 select PPC4XX
-select SERIAL
 
 config PPC440
 bool
@@ -46,13 +45,13 @@ config PPC440
 imply E1000_PCI
 select PCI_EXPRESS
 select PPC4XX
-select SERIAL
 select FDT_PPC
 
 config PPC4XX
 bool
 select BITBANG_I2C
 select PCI
+select SERIAL
 
 config SAM460EX
 bool
@@ -61,7 +60,6 @@ config SAM460EX
 select IDE_SII3112
 select M41T80
 select PPC440
-select SERIAL
 select SM501
 select SMBUS_EEPROM
 select USB_EHCI_SYSBUS
@@ -123,7 +121,6 @@ config VIRTEX
 bool
 select PPC4XX
 select PFLASH_CFI01
-select SERIAL
 select XILINX
 select XILINX_ETHLITE
 select FDT_PPC
-- 
2.21.3




[PATCH v2 0/3] Clean up sam460ex irq mapping

2020-12-31 Thread BALATON Zoltan via
v2 of https://patchew.org/QEMU/cover.1608937677.git.bala...@eik.bme.hu/
with added Tested-by from Guenter and revised patch 2 as suggested by
Philippe.

Regards,
BALATON Zoltan

BALATON Zoltan (3):
  ppc4xx: Move common dependency on serial to common option
  sam460ex: Remove FDT_PPC dependency from KConfig
  sam460ex: Clean up irq mapping

 hw/ppc/Kconfig   |  7 ++-
 hw/ppc/ppc440_pcix.c | 28 ++--
 hw/ppc/sam460ex.c| 16 +---
 3 files changed, 29 insertions(+), 22 deletions(-)

-- 
2.21.3




Re: [PATCH 1/2] hw/ssi: imx_spi: Correct the burst length > 32 bit transfer logic

2020-12-31 Thread Philippe Mathieu-Daudé
On 12/17/20 6:28 AM, Bin Meng wrote:
> From: Bin Meng 
> 
> For the ECSPIx_CONREG register BURST_LENGTH field, the manual says:
> 
> 0x020 A SPI burst contains the 1 LSB in first word and all 32 bits in second 
> word.
> 0x021 A SPI burst contains the 2 LSB in first word and all 32 bits in second 
> word.
> 
> Current logic uses either s->burst_length or 32, whichever smaller,
> to determine how many bits it should read from the tx fifo each time.
> For example, for a 48 bit burst length, current logic transfers the
> first 32 bit from the first word in the tx fifo, followed by a 16
> bit from the second word in the tx fifo, which is wrong. The correct
> logic should be: transfer the first 16 bit from the first word in
> the tx fifo, followed by a 32 bit from the second word in the tx fifo.
> 
> With this change, SPI flash can be successfully probed by U-Boot on
> imx6 sabrelite board.
> 
>   => sf probe
>   SF: Detected sst25vf016b with page size 256 Bytes, erase size 4 KiB, total 
> 2 MiB
> 
> Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
> Signed-off-by: Bin Meng 
> ---
> 
>  hw/ssi/imx_spi.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
> index 85c172e..509fb9f 100644
> --- a/hw/ssi/imx_spi.c
> +++ b/hw/ssi/imx_spi.c
> @@ -178,7 +178,10 @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
>  
>  DPRINTF("data tx:0x%08x\n", tx);
>  
> -tx_burst = MIN(s->burst_length, 32);
> +tx_burst = s->burst_length % 32;
> +if (tx_burst == 0) {
> +tx_burst = 32;
> +}

Or alternatively using ternary operator:

   tx_burst = (s->burst_length % 32) ?: 32;

Reviewed-by: Philippe Mathieu-Daudé 

>  
>  rx = 0;
>  
> 




Re: [PATCH v2] meson: fix Cocoa option in summary

2020-12-31 Thread Philippe Mathieu-Daudé
On 12/30/20 11:16 PM, Chris Hofstaedtler wrote:
> Cocoa support was always shown as "no", even it if was enabled.
> 
> Fixes: b4e312e953b ("configure: move cocoa option to Meson")
> Cc: Paolo Bonzini 
> Cc: Peter Maydell 
> Cc: Philippe Mathieu-Daudé 
> Signed-off-by: Chris Hofstaedtler 
> ---
>  meson.build | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/meson.build b/meson.build
> index 372576f82c..1112ca8fc2 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2082,7 +2082,7 @@ summary_info += {'strip binaries':
> get_option('strip')}
>  summary_info += {'profiler':  config_host.has_key('CONFIG_PROFILER')}
>  summary_info += {'static build':  config_host.has_key('CONFIG_STATIC')}
>  if targetos == 'darwin'
> -  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
> +  summary_info += {'Cocoa support': config_host_data.get('CONFIG_COCOA', 
> false)}
>  endif
>  # TODO: add back version
>  summary_info += {'SDL support':   sdl.found()}
> 

Reviewed-by: Philippe Mathieu-Daudé 




Re: [RFC PATCH v2] x86/cpu: initialize the CPU concurrently

2020-12-31 Thread Zhenyu Ye
Hi Eduardo,

On 2020/12/25 2:06, Eduardo Habkost wrote:
>>
>> The most time-consuming operation in haxm is ioctl(HAX_VM_IOCTL_VCPU_CREATE).
>> Saddly this can not be split.
>>
>> Even if we fix the problem in haxm, other accelerators may also have
>> this problem.  So I think if we can make the x86_cpu_new() concurrently,
>> we should try to do it.
> 
> Changing the code to run all VCPU initialization actions for all
> accelerators concurrently would require carefully reviewing the
> VCPU thread code for all accelerators, looking for races.  Sounds
> like a challenging task.  We could avoid that if we do something
> that will parallelize only what we really need (and know to be
> safe).
> 

Yes, we must make sure that all accelerators could work parallelly,
even including the corresponding VCPU_CREATE_IOCTL, which is not
under qemu's control.

Fortunately, we have found out why ioctl(HAX_VM_IOCTL_VCPU_CREATE)
in haxm took such a long time.  It alloced vtlb when doing vcpu_create(),
which has been discarded and is useless.  After removing corresponding
operation, the vcpu initialization time is reduced to within 10ms.

Thanks for your attention and discussion.

Thanks,
Zhenyu






Re: [PATCH v3 3/8] acpi/gpex: Inform os to keep firmware resource map

2020-12-31 Thread Jiahui Cen



On 2020/12/31 5:22, Michael S. Tsirkin wrote:
> On Tue, Dec 29, 2020 at 02:41:42PM +0100, Igor Mammedov wrote:
>> On Wed, 23 Dec 2020 17:08:31 +0800
>> Jiahui Cen  wrote:
>>
>>> There may be some differences in pci resource assignment between guest os
>>> and firmware.
>>>
>>> Eg. A Bridge with Bus [d2]
>>> -+-[:d2]---01.0-[d3]01.0
>>>
>>> where [d2:01.00] is a pcie-pci-bridge with BAR0 (mem, 64-bit, non-pref) 
>>> [size=256]
>>>   [d3:01.00] is a PCI Device with BAR0 (mem, 64-bit, pref) 
>>> [size=128K]
>>>   BAR4 (mem, 64-bit, pref) 
>>> [size=64M]
>>>
>>> In EDK2, the Resource Map would be:
>>> PciBus: Resource Map for Bridge [D2|01|00]
>>> Type = PMem64; Base = 0x800400; Length = 0x410; 
>>> Alignment = 0x3FF
>>>Base = 0x800400; Length = 0x400; Alignment = 
>>> 0x3FF;  Owner = PCI [D3|01|00:20]
>>>Base = 0x800800; Length = 0x2;   Alignment = 
>>> 0x1;Owner = PCI [D3|01|00:10]
>>> Type =  Mem64; Base = 0x800810; Length = 0x100; Alignment = 
>>> 0xFFF
>>> It would use 0x410 to calculate the root bus's PMem64 resource 
>>> window.
>>>
>>> While in Linux, kernel will use 0x1FF as the alignment to calculate
>>> the PMem64 size, which would be 0x600. So kernel would try to
>>> allocate 0x600 from the PMem64 resource window, but since the window
>>> size is 0x410 as assigned by EDK2, the allocation would fail.
>>>
>>> The diffences could result in resource assignment failure.
>>>
>>> Using _DSM #5 method to inform guest os not to ignore the PCI configuration
>>> that firmware has done at boot time could handle the differences.
>>
>> I'm not sure about this one, 
>> OS should able to reconfigure PCI resources according to what and where is 
>> plugged
>> (and it even more true is hotplug is taken into account)
> 
> spec says this:
> 
> 0: No (The operating system must not ignore the PCI configuration that 
> firmware has done
> at boot time. However, the operating system is free to configure the devices 
> in this hierarchy
> that have not been configured by the firmware. There may be a reduced level 
> of hot plug
> capability support in this hierarchy due to resource constraints. This 
> situation is the same as
> the legacy situation where this _DSM is not provided.)
> 1: Yes (The operating system may ignore the PCI configuration that the 
> firmware has done
> at boot time, and reconfigure/rebalance the resources in the hierarchy.)
> 
> and
> 
> IMPLEMENTATION NOTE
> This _DSM function provides backwards compatibility on platforms that can run 
> legacy operating
> systems.
> Operating systems for two different architectures (e.g., x86 and x64) can be 
> installed on a platform.
> The firmware cannot distinguish the operating system in time to change the 
> boot configuration of
> devices. Say for instance, an x86 operating system in non-PAE mode is 
> installed on a system. The
> x86 operating system cannot access device resource space above 4 GiB. So the 
> firmware is required
> to configure devices at boot time using addresses below 4 GiB. On the other 
> hand, if an x64
> operating system is installed on this system, it can access device resources 
> above the 4 GiB so it does
> not want the firmware to constrain the resource assignment below 4 GiB that 
> the firmware
> configures at boot time. It is not possible for the firmware to change this 
> by the time it boots the
> operating system. Ignoring the configurations done by firmware at boot time 
> will allow the
> operating system to push resource assignment using addresses above 4 GiB for 
> an x64 operating
> system while constrain it to addresses below 4 GiB for an x86 operating 
> system.
> 
> so fundamentally, saying "1" here just means "you can ignore what
> firmware configured if you like".
> 
> 
> I have a different question though: our CRS etc is based on what
> firmware configured. Is that ok? Or is ACPI expected to somehow
> reconfigure itself when OS reconfigures devices?
> Think it's ok but could not find documentation either way.

In my humble opinion, it is ok.

I'm not sure whether it is useful, but PCI Firmware Specification Revision 3.0 
Chapter 3.5 said:

Firmware must configure all Host Bridges in the systems, even if they are not 
connected to a
console or boot device. Firmware must configure Host Bridges in order to allow 
operating systems
to use the devices below the Host Bridges. This is because the Host Bridges 
programming model is
not defined by the PCI Specifications. “Configured” in this context means that:
- Memory and I/O resources are assigned and configured.
‰- Includes both the resources consumed by the Host Bridge and the resources 
passed through to
the secondary bus.
‰- The bridge is enabled to receive and forward transactions.
‰- The bridge is operating in “safe” mode. Safe mode includes: