All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/6] OpenRISC Device Tree Generation
@ 2022-02-19  6:42 Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne

Changes since v2:
 - Fix description to say devicetree "generation" not "support"
 - Fix up various indentation issues.
 - Use HWADDR_PRIx string formatting.
 - Split device tree population out to device init.
 - Do not load device tree or initrd if we have no kernel.
 - Added patches to split uart initialization out to it's own function fix 2 CPU
   limit.

Changes since v1:
 - Fixed typos pointed out by Philippe
 - Moved usage of machine state to patch 3/4
 - added config dependency on FDT

This series adds device tree generation for the OpenRISC SIM hardware.

The simulator will generate an FDT and pass it to the kernel.

For example:
  qemu-system-or1k -cpu or1200 -M or1k-sim \
    -kernel /home/shorne/work/linux/vmlinux \
    -initrd /home/shorne/work/linux/initramfs.cpio.gz \
    -serial mon:stdio -nographic -gdb tcp::10001 -m 32

Using the linux kernel or1ksim_defconfig we can remove the built-in
dts and the kernel will boot as expected.  The real benefit here is
being able to specify an external initrd which qemu will load into
memory and the device tree will tell the kernel where to find it.

Tested this by booting single core and SMP kernels with 4x CPUs.

Stafford Horne (6):
  hw/openrisc/openrisc_sim: Create machine state for or1ksim
  hw/openrisc/openrisc_sim: Parameterize initialization
  hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  hw/openrisc/openrisc_sim: Increase max_cpus to 4
  hw/openrisc/openrisc_sim: Add automatic device tree generation
  hw/openrisc/openrisc_sim: Add support for initrd loading

 configs/targets/or1k-softmmu.mak |   1 +
 hw/openrisc/openrisc_sim.c       | 308 ++++++++++++++++++++++++++++---
 2 files changed, 285 insertions(+), 24 deletions(-)

-- 
2.31.1



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

* [PATCH v3 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development
  Cc: Peter Maydell, Stafford Horne, Philippe Mathieu-Daudé, Jia Liu

This will allow us to attach machine state attributes like
the device tree fdt.

Signed-off-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/openrisc/openrisc_sim.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 73fe383c2d..26d2370e60 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -37,6 +37,18 @@
 
 #define KERNEL_LOAD_ADDR 0x100
 
+#define TYPE_OR1KSIM_MACHINE MACHINE_TYPE_NAME("or1k-sim")
+#define OR1KSIM_MACHINE(obj) \
+    OBJECT_CHECK(Or1ksimState, (obj), TYPE_OR1KSIM_MACHINE)
+
+typedef struct Or1ksimState {
+    /*< private >*/
+    MachineState parent_obj;
+
+    /*< public >*/
+
+} Or1ksimState;
+
 static struct openrisc_boot_info {
     uint32_t bootstrap_pc;
 } boot_info;
@@ -183,8 +195,10 @@ static void openrisc_sim_init(MachineState *machine)
     openrisc_load_kernel(ram_size, kernel_filename);
 }
 
-static void openrisc_sim_machine_init(MachineClass *mc)
+static void openrisc_sim_machine_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "or1k simulation";
     mc->init = openrisc_sim_init;
     mc->max_cpus = 2;
@@ -192,4 +206,16 @@ static void openrisc_sim_machine_init(MachineClass *mc)
     mc->default_cpu_type = OPENRISC_CPU_TYPE_NAME("or1200");
 }
 
-DEFINE_MACHINE("or1k-sim", openrisc_sim_machine_init)
+static const TypeInfo or1ksim_machine_typeinfo = {
+    .name       = TYPE_OR1KSIM_MACHINE,
+    .parent     = TYPE_MACHINE,
+    .class_init = openrisc_sim_machine_init,
+    .instance_size = sizeof(Or1ksimState),
+};
+
+static void or1ksim_machine_init_register_types(void)
+{
+    type_register_static(&or1ksim_machine_typeinfo);
+}
+
+type_init(or1ksim_machine_init_register_types)
-- 
2.31.1



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

* [PATCH v3 2/6] hw/openrisc/openrisc_sim: Parameterize initialization
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development
  Cc: Peter Maydell, Stafford Horne, Philippe Mathieu-Daudé, Jia Liu

Move magic numbers to variables and enums. These will be reused for
upcoming fdt initialization.

Signed-off-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/openrisc/openrisc_sim.c | 42 ++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 26d2370e60..d12b3e0c5e 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -49,6 +49,29 @@ typedef struct Or1ksimState {
 
 } Or1ksimState;
 
+enum {
+    OR1KSIM_DRAM,
+    OR1KSIM_UART,
+    OR1KSIM_ETHOC,
+    OR1KSIM_OMPIC,
+};
+
+enum {
+    OR1KSIM_OMPIC_IRQ = 1,
+    OR1KSIM_UART_IRQ = 2,
+    OR1KSIM_ETHOC_IRQ = 4,
+};
+
+static const struct MemmapEntry {
+    hwaddr base;
+    hwaddr size;
+} or1ksim_memmap[] = {
+    [OR1KSIM_DRAM] =      { 0x00000000,          0 },
+    [OR1KSIM_UART] =      { 0x90000000,      0x100 },
+    [OR1KSIM_ETHOC] =     { 0x92000000,      0x800 },
+    [OR1KSIM_OMPIC] =     { 0x98000000,         16 },
+};
+
 static struct openrisc_boot_info {
     uint32_t bootstrap_pc;
 } boot_info;
@@ -176,21 +199,24 @@ static void openrisc_sim_init(MachineState *machine)
     memory_region_add_subregion(get_system_memory(), 0, ram);
 
     if (nd_table[0].used) {
-        openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
-                              cpus, 4, nd_table);
+        openrisc_sim_net_init(or1ksim_memmap[OR1KSIM_ETHOC].base,
+                              or1ksim_memmap[OR1KSIM_ETHOC].base + 0x400,
+                              smp_cpus, cpus,
+                              OR1KSIM_ETHOC_IRQ, nd_table);
     }
 
     if (smp_cpus > 1) {
-        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
+        openrisc_sim_ompic_init(or1ksim_memmap[OR1KSIM_OMPIC].base, smp_cpus,
+                                cpus, OR1KSIM_OMPIC_IRQ);
 
-        serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
-                                    get_cpu_irq(cpus, 1, 2));
+        serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, OR1KSIM_UART_IRQ),
+                                    get_cpu_irq(cpus, 1, OR1KSIM_UART_IRQ));
     } else {
-        serial_irq = get_cpu_irq(cpus, 0, 2);
+        serial_irq = get_cpu_irq(cpus, 0, OR1KSIM_UART_IRQ);
     }
 
-    serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
-                   115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
+    serial_mm_init(get_system_memory(), or1ksim_memmap[OR1KSIM_UART].base, 0,
+                   serial_irq, 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
 
     openrisc_load_kernel(ram_size, kernel_filename);
 }
-- 
2.31.1



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

* [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  2022-02-19 13:01   ` Peter Maydell
  2022-02-20 20:06   ` Philippe Mathieu-Daudé
  2022-02-19  6:42 ` [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne, Jia Liu

Currently the OpenRISC SMP configuration only supports 2 cores due to
the UART IRQ routing being limited to 2 cores.  As was done in commit
1eeffbeb11 ("hw/openrisc/openrisc_sim: Use IRQ splitter when connecting
IRQ to multiple CPUs") we can use a splitter to wire more than 2 CPUs.

This patch moves serial initialization out to it's own function and
uses a splitter to connect multiple CPU irq lines to the UART.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index d12b3e0c5e..5bfbac00f8 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -137,6 +137,28 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
     sysbus_mmio_map(s, 0, base);
 }
 
+static void openrisc_sim_serial_init(hwaddr base, int num_cpus,
+                                     OpenRISCCPU *cpus[], int irq_pin)
+{
+    qemu_irq serial_irq;
+    int i;
+
+    if (num_cpus > 1) {
+        DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
+        qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
+        qdev_realize_and_unref(splitter, NULL, &error_fatal);
+        for (i = 0; i < num_cpus; i++) {
+            qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
+        }
+        serial_irq = qdev_get_gpio_in(splitter, 0);
+    } else {
+        serial_irq = get_cpu_irq(cpus, 0, irq_pin);
+    }
+    serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
+                   serial_hd(0), DEVICE_NATIVE_ENDIAN);
+}
+
+
 static void openrisc_load_kernel(ram_addr_t ram_size,
                                  const char *kernel_filename)
 {
@@ -177,7 +199,6 @@ static void openrisc_sim_init(MachineState *machine)
     const char *kernel_filename = machine->kernel_filename;
     OpenRISCCPU *cpus[2] = {};
     MemoryRegion *ram;
-    qemu_irq serial_irq;
     int n;
     unsigned int smp_cpus = machine->smp.cpus;
 
@@ -208,15 +229,10 @@ static void openrisc_sim_init(MachineState *machine)
     if (smp_cpus > 1) {
         openrisc_sim_ompic_init(or1ksim_memmap[OR1KSIM_OMPIC].base, smp_cpus,
                                 cpus, OR1KSIM_OMPIC_IRQ);
-
-        serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, OR1KSIM_UART_IRQ),
-                                    get_cpu_irq(cpus, 1, OR1KSIM_UART_IRQ));
-    } else {
-        serial_irq = get_cpu_irq(cpus, 0, OR1KSIM_UART_IRQ);
     }
 
-    serial_mm_init(get_system_memory(), or1ksim_memmap[OR1KSIM_UART].base, 0,
-                   serial_irq, 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
+    openrisc_sim_serial_init(or1ksim_memmap[OR1KSIM_UART].base, smp_cpus, cpus,
+                             OR1KSIM_UART_IRQ);
 
     openrisc_load_kernel(ram_size, kernel_filename);
 }
-- 
2.31.1



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

* [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
                   ` (2 preceding siblings ...)
  2022-02-19  6:42 ` [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  2022-02-19 13:02   ` Peter Maydell
  2022-02-20 20:07   ` Philippe Mathieu-Daudé
  2022-02-19  6:42 ` [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
  2022-02-19  6:42 ` [PATCH v3 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne
  5 siblings, 2 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne, Jia Liu

Now that we no longer have a limit of 2 CPUs due to fixing the
IRQ routing issues we can increase the max.  Here we increase
the limit to 4, we could go higher, but currently OMPIC has a
limit of 4, so we align with that.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 5bfbac00f8..8cfb92bec6 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -37,6 +37,8 @@
 
 #define KERNEL_LOAD_ADDR 0x100
 
+#define OR1KSIM_CPUS_MAX 4
+
 #define TYPE_OR1KSIM_MACHINE MACHINE_TYPE_NAME("or1k-sim")
 #define OR1KSIM_MACHINE(obj) \
     OBJECT_CHECK(Or1ksimState, (obj), TYPE_OR1KSIM_MACHINE)
@@ -197,12 +199,12 @@ static void openrisc_sim_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
     const char *kernel_filename = machine->kernel_filename;
-    OpenRISCCPU *cpus[2] = {};
+    OpenRISCCPU *cpus[OR1KSIM_CPUS_MAX] = {};
     MemoryRegion *ram;
     int n;
     unsigned int smp_cpus = machine->smp.cpus;
 
-    assert(smp_cpus >= 1 && smp_cpus <= 2);
+    assert(smp_cpus >= 1 && smp_cpus <= OR1KSIM_CPUS_MAX);
     for (n = 0; n < smp_cpus; n++) {
         cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
         if (cpus[n] == NULL) {
@@ -243,7 +245,7 @@ static void openrisc_sim_machine_init(ObjectClass *oc, void *data)
 
     mc->desc = "or1k simulation";
     mc->init = openrisc_sim_init;
-    mc->max_cpus = 2;
+    mc->max_cpus = OR1KSIM_CPUS_MAX;
     mc->is_default = true;
     mc->default_cpu_type = OPENRISC_CPU_TYPE_NAME("or1200");
 }
-- 
2.31.1



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

* [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
                   ` (3 preceding siblings ...)
  2022-02-19  6:42 ` [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  2022-02-19 13:06   ` Peter Maydell
  2022-02-19  6:42 ` [PATCH v3 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne
  5 siblings, 1 reply; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne, Jia Liu

Using the device tree means that qemu can now directly tell
the kernel what hardware is configured rather than use having
to maintain and update a separate device tree file.

This patch adds automatic device tree generation support for the
OpenRISC simulator.  A device tree is built up based on the state of the
configure openrisc simulator.

This is then dumped to memory and the load address is passed to the
kernel in register r3.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 configs/targets/or1k-softmmu.mak |   1 +
 hw/openrisc/openrisc_sim.c       | 189 ++++++++++++++++++++++++++++---
 2 files changed, 175 insertions(+), 15 deletions(-)

diff --git a/configs/targets/or1k-softmmu.mak b/configs/targets/or1k-softmmu.mak
index 1dfb93e46d..9e1d4a1fb1 100644
--- a/configs/targets/or1k-softmmu.mak
+++ b/configs/targets/or1k-softmmu.mak
@@ -1,2 +1,3 @@
 TARGET_ARCH=openrisc
 TARGET_WORDS_BIGENDIAN=y
+TARGET_NEED_FDT=y
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 8cfb92bec6..e0e71c0faa 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -29,15 +29,20 @@
 #include "net/net.h"
 #include "hw/loader.h"
 #include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
 #include "hw/sysbus.h"
 #include "sysemu/qtest.h"
 #include "sysemu/reset.h"
 #include "hw/core/split-irq.h"
 
+#include <libfdt.h>
+
 #define KERNEL_LOAD_ADDR 0x100
 
 #define OR1KSIM_CPUS_MAX 4
+#define OR1KSIM_CLK_MHZ 20000000
 
 #define TYPE_OR1KSIM_MACHINE MACHINE_TYPE_NAME("or1k-sim")
 #define OR1KSIM_MACHINE(obj) \
@@ -48,6 +53,8 @@ typedef struct Or1ksimState {
     MachineState parent_obj;
 
     /*< public >*/
+    void *fdt;
+    int fdt_size;
 
 } Or1ksimState;
 
@@ -76,6 +83,7 @@ static const struct MemmapEntry {
 
 static struct openrisc_boot_info {
     uint32_t bootstrap_pc;
+    uint32_t fdt_addr;
 } boot_info;
 
 static void main_cpu_reset(void *opaque)
@@ -86,6 +94,7 @@ static void main_cpu_reset(void *opaque)
     cpu_reset(CPU(cpu));
 
     cpu_set_pc(cs, boot_info.bootstrap_pc);
+    cpu_set_gpr(&cpu->env, 3, boot_info.fdt_addr);
 }
 
 static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
@@ -93,12 +102,77 @@ static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
     return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
 }
 
-static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
+static void openrisc_create_fdt(Or1ksimState *state,
+                                const struct MemmapEntry *memmap,
+                                int num_cpus, uint64_t mem_size,
+                                const char *cmdline)
+{
+    void *fdt;
+    int cpu;
+    char *nodename;
+    int pic_ph;
+
+    fdt = state->fdt = create_device_tree(&state->fdt_size);
+    if (!fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    qemu_fdt_setprop_string(fdt, "/", "compatible", "opencores,or1ksim");
+    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x1);
+    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
+
+    nodename = g_strdup_printf("/memory@%" HWADDR_PRIx,
+                               memmap[OR1KSIM_DRAM].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg",
+                           memmap[OR1KSIM_DRAM].base, mem_size);
+    qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
+    g_free(nodename);
+
+    qemu_fdt_add_subnode(fdt, "/cpus");
+    qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
+    qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
+
+    for (cpu = 0; cpu < num_cpus; cpu++) {
+        nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+        qemu_fdt_add_subnode(fdt, nodename);
+        qemu_fdt_setprop_string(fdt, nodename, "compatible",
+                                "opencores,or1200-rtlsvn481");
+        qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
+        qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+                              OR1KSIM_CLK_MHZ);
+        g_free(nodename);
+    }
+
+    nodename = (char *)"/pic";
+    qemu_fdt_add_subnode(fdt, nodename);
+    pic_ph = qemu_fdt_alloc_phandle(fdt);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible",
+                            "opencores,or1k-pic-level");
+    qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 1);
+    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "phandle", pic_ph);
+
+    qemu_fdt_setprop_cell(fdt, "/", "interrupt-parent", pic_ph);
+
+    qemu_fdt_add_subnode(fdt, "/chosen");
+    if (cmdline) {
+        qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+    }
+
+    /* Create aliases node for use by devices. */
+    qemu_fdt_add_subnode(fdt, "/aliases");
+}
+
+static void openrisc_sim_net_init(Or1ksimState *state, hwaddr base, hwaddr size,
                                   int num_cpus, OpenRISCCPU *cpus[],
                                   int irq_pin, NICInfo *nd)
 {
+    void *fdt = state->fdt;
     DeviceState *dev;
     SysBusDevice *s;
+    char *nodename;
     int i;
 
     dev = qdev_new("open_eth");
@@ -118,14 +192,28 @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
         sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
     }
     sysbus_mmio_map(s, 0, base);
-    sysbus_mmio_map(s, 1, descriptors);
+    sysbus_mmio_map(s, 1, base + 0x400);
+
+    /* Init device tree node for ethoc. */
+    nodename = g_strdup_printf("/ethoc@%" HWADDR_PRIx, base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "opencores,ethoc");
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+    qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
+
+    qemu_fdt_setprop_string(fdt, "/aliases", "enet0", nodename);
+    g_free(nodename);
 }
 
-static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
+static void openrisc_sim_ompic_init(Or1ksimState *state, hwaddr base,
+                                    hwaddr size, int num_cpus,
                                     OpenRISCCPU *cpus[], int irq_pin)
 {
+    void *fdt = state->fdt;
     DeviceState *dev;
     SysBusDevice *s;
+    char *nodename;
     int i;
 
     dev = qdev_new("or1k-ompic");
@@ -137,11 +225,24 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
         sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
     }
     sysbus_mmio_map(s, 0, base);
+
+    /* Add device tree node for ompic. */
+    nodename = g_strdup_printf("/ompic@%" HWADDR_PRIx, base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "openrisc,ompic");
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+    g_free(nodename);
 }
 
-static void openrisc_sim_serial_init(hwaddr base, int num_cpus,
+static void openrisc_sim_serial_init(Or1ksimState *state, hwaddr base,
+                                     hwaddr size, int num_cpus,
                                      OpenRISCCPU *cpus[], int irq_pin)
 {
+    void *fdt = state->fdt;
+    char *nodename;
     qemu_irq serial_irq;
     int i;
 
@@ -158,29 +259,45 @@ static void openrisc_sim_serial_init(hwaddr base, int num_cpus,
     }
     serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
                    serial_hd(0), DEVICE_NATIVE_ENDIAN);
-}
 
+    /* Add device tree node for serial. */
+    nodename = g_strdup_printf("/serial@%" HWADDR_PRIx, base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "ns16550a");
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", base, size);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", irq_pin);
+    qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", OR1KSIM_CLK_MHZ);
+    qemu_fdt_setprop(fdt, nodename, "big-endian", NULL, 0);
+
+    /* The /chosen node is created during fdt creation. */
+    qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
+    qemu_fdt_setprop_string(fdt, "/aliases", "uart0", nodename);
+    g_free(nodename);
+}
 
-static void openrisc_load_kernel(ram_addr_t ram_size,
-                                 const char *kernel_filename)
+static hwaddr openrisc_load_kernel(ram_addr_t ram_size,
+                                   const char *kernel_filename)
 {
     long kernel_size;
     uint64_t elf_entry;
+    uint64_t high_addr;
     hwaddr entry;
 
     if (kernel_filename && !qtest_enabled()) {
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &elf_entry, NULL, NULL, NULL, 1, EM_OPENRISC,
-                               1, 0);
+                               &elf_entry, NULL, &high_addr, NULL, 1,
+                               EM_OPENRISC, 1, 0);
         entry = elf_entry;
         if (kernel_size < 0) {
             kernel_size = load_uimage(kernel_filename,
                                       &entry, NULL, NULL, NULL, NULL);
+            high_addr = entry + kernel_size;
         }
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
                                               ram_size - KERNEL_LOAD_ADDR);
+            high_addr = KERNEL_LOAD_ADDR + kernel_size;
         }
 
         if (entry <= 0) {
@@ -192,7 +309,38 @@ static void openrisc_load_kernel(ram_addr_t ram_size,
             exit(1);
         }
         boot_info.bootstrap_pc = entry;
+
+        return high_addr;
     }
+    return 0;
+}
+
+static uint32_t openrisc_load_fdt(Or1ksimState *state, hwaddr load_start,
+                                  uint64_t mem_size)
+{
+    void *fdt = state->fdt;
+    uint32_t fdt_addr;
+    int ret;
+    int fdtsize = fdt_totalsize(fdt);
+
+    if (fdtsize <= 0) {
+        error_report("invalid device-tree");
+        exit(1);
+    }
+
+    /* We put fdt right after the kernel and/or initrd. */
+    fdt_addr = ROUND_UP(load_start, 4);
+
+    ret = fdt_pack(fdt);
+    /* Should only fail if we've built a corrupted tree */
+    g_assert(ret == 0);
+    /* copy in the device tree */
+    qemu_fdt_dumpdtb(fdt, fdtsize);
+
+    rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
+                          &address_space_memory);
+
+    return fdt_addr;
 }
 
 static void openrisc_sim_init(MachineState *machine)
@@ -200,7 +348,9 @@ static void openrisc_sim_init(MachineState *machine)
     ram_addr_t ram_size = machine->ram_size;
     const char *kernel_filename = machine->kernel_filename;
     OpenRISCCPU *cpus[OR1KSIM_CPUS_MAX] = {};
+    Or1ksimState *state = OR1KSIM_MACHINE(machine);
     MemoryRegion *ram;
+    hwaddr load_addr;
     int n;
     unsigned int smp_cpus = machine->smp.cpus;
 
@@ -221,22 +371,31 @@ static void openrisc_sim_init(MachineState *machine)
     memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
     memory_region_add_subregion(get_system_memory(), 0, ram);
 
+    openrisc_create_fdt(state, or1ksim_memmap, smp_cpus, machine->ram_size,
+                        machine->kernel_cmdline);
+
     if (nd_table[0].used) {
-        openrisc_sim_net_init(or1ksim_memmap[OR1KSIM_ETHOC].base,
-                              or1ksim_memmap[OR1KSIM_ETHOC].base + 0x400,
+        openrisc_sim_net_init(state, or1ksim_memmap[OR1KSIM_ETHOC].base,
+                              or1ksim_memmap[OR1KSIM_ETHOC].size,
                               smp_cpus, cpus,
                               OR1KSIM_ETHOC_IRQ, nd_table);
     }
 
     if (smp_cpus > 1) {
-        openrisc_sim_ompic_init(or1ksim_memmap[OR1KSIM_OMPIC].base, smp_cpus,
-                                cpus, OR1KSIM_OMPIC_IRQ);
+        openrisc_sim_ompic_init(state, or1ksim_memmap[OR1KSIM_OMPIC].base,
+                                or1ksim_memmap[OR1KSIM_UART].size,
+                                smp_cpus, cpus, OR1KSIM_OMPIC_IRQ);
     }
 
-    openrisc_sim_serial_init(or1ksim_memmap[OR1KSIM_UART].base, smp_cpus, cpus,
+    openrisc_sim_serial_init(state, or1ksim_memmap[OR1KSIM_UART].base,
+                             or1ksim_memmap[OR1KSIM_UART].size, smp_cpus, cpus,
                              OR1KSIM_UART_IRQ);
 
-    openrisc_load_kernel(ram_size, kernel_filename);
+    load_addr = openrisc_load_kernel(ram_size, kernel_filename);
+    if (load_addr > 0) {
+        boot_info.fdt_addr = openrisc_load_fdt(state, load_addr,
+                                               machine->ram_size);
+    }
 }
 
 static void openrisc_sim_machine_init(ObjectClass *oc, void *data)
-- 
2.31.1



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

* [PATCH v3 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading
  2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
                   ` (4 preceding siblings ...)
  2022-02-19  6:42 ` [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
@ 2022-02-19  6:42 ` Stafford Horne
  5 siblings, 0 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-19  6:42 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne, Jia Liu

The initrd passed via the command line is loaded into memory.  It's
location and size is then added to the device tree so the kernel knows
where to find it.

Signed-off-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/openrisc/openrisc_sim.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index e0e71c0faa..8184caa60b 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -315,6 +315,33 @@ static hwaddr openrisc_load_kernel(ram_addr_t ram_size,
     return 0;
 }
 
+static hwaddr openrisc_load_initrd(Or1ksimState *state, const char *filename,
+                                   hwaddr load_start, uint64_t mem_size)
+{
+    void *fdt = state->fdt;
+    int size;
+    hwaddr start;
+
+    /* We put the initrd right after the kernel; page aligned. */
+    start = TARGET_PAGE_ALIGN(load_start);
+
+    size = load_ramdisk(filename, start, mem_size - start);
+    if (size < 0) {
+        size = load_image_targphys(filename, start, mem_size - start);
+        if (size < 0) {
+            error_report("could not load ramdisk '%s'", filename);
+            exit(1);
+        }
+    }
+
+    qemu_fdt_setprop_cell(fdt, "/chosen",
+                          "linux,initrd-start", start);
+    qemu_fdt_setprop_cell(fdt, "/chosen",
+                          "linux,initrd-end", start + size);
+
+    return start + size;
+}
+
 static uint32_t openrisc_load_fdt(Or1ksimState *state, hwaddr load_start,
                                   uint64_t mem_size)
 {
@@ -393,6 +420,10 @@ static void openrisc_sim_init(MachineState *machine)
 
     load_addr = openrisc_load_kernel(ram_size, kernel_filename);
     if (load_addr > 0) {
+        if (machine->initrd_filename) {
+            load_addr = openrisc_load_initrd(state, machine->initrd_filename,
+                                             load_addr, machine->ram_size);
+        }
         boot_info.fdt_addr = openrisc_load_fdt(state, load_addr,
                                                machine->ram_size);
     }
-- 
2.31.1



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

* Re: [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  2022-02-19  6:42 ` [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
@ 2022-02-19 13:01   ` Peter Maydell
  2022-02-20 20:06   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2022-02-19 13:01 UTC (permalink / raw)
  To: Stafford Horne; +Cc: QEMU Development, Jia Liu

On Sat, 19 Feb 2022 at 06:42, Stafford Horne <shorne@gmail.com> wrote:
>
> Currently the OpenRISC SMP configuration only supports 2 cores due to
> the UART IRQ routing being limited to 2 cores.  As was done in commit
> 1eeffbeb11 ("hw/openrisc/openrisc_sim: Use IRQ splitter when connecting
> IRQ to multiple CPUs") we can use a splitter to wire more than 2 CPUs.
>
> This patch moves serial initialization out to it's own function and
> uses a splitter to connect multiple CPU irq lines to the UART.
>
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4
  2022-02-19  6:42 ` [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
@ 2022-02-19 13:02   ` Peter Maydell
  2022-02-20 20:07   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2022-02-19 13:02 UTC (permalink / raw)
  To: Stafford Horne; +Cc: QEMU Development, Jia Liu

On Sat, 19 Feb 2022 at 06:42, Stafford Horne <shorne@gmail.com> wrote:
>
> Now that we no longer have a limit of 2 CPUs due to fixing the
> IRQ routing issues we can increase the max.  Here we increase
> the limit to 4, we could go higher, but currently OMPIC has a
> limit of 4, so we align with that.
>
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/openrisc_sim.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation
  2022-02-19  6:42 ` [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
@ 2022-02-19 13:06   ` Peter Maydell
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2022-02-19 13:06 UTC (permalink / raw)
  To: Stafford Horne; +Cc: QEMU Development, Jia Liu

On Sat, 19 Feb 2022 at 06:42, Stafford Horne <shorne@gmail.com> wrote:
>
> Using the device tree means that qemu can now directly tell
> the kernel what hardware is configured rather than use having
> to maintain and update a separate device tree file.
>
> This patch adds automatic device tree generation support for the
> OpenRISC simulator.  A device tree is built up based on the state of the
> configure openrisc simulator.
>
> This is then dumped to memory and the load address is passed to the
> kernel in register r3.
>
> Signed-off-by: Stafford Horne <shorne@gmail.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


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

* Re: [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  2022-02-19  6:42 ` [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
  2022-02-19 13:01   ` Peter Maydell
@ 2022-02-20 20:06   ` Philippe Mathieu-Daudé
  2022-02-21  0:08     ` Stafford Horne
  1 sibling, 1 reply; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-02-20 20:06 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Peter Maydell, Jia Liu

On 19/2/22 07:42, Stafford Horne wrote:
> Currently the OpenRISC SMP configuration only supports 2 cores due to
> the UART IRQ routing being limited to 2 cores.  As was done in commit
> 1eeffbeb11 ("hw/openrisc/openrisc_sim: Use IRQ splitter when connecting
> IRQ to multiple CPUs") we can use a splitter to wire more than 2 CPUs.
> 
> This patch moves serial initialization out to it's own function and
> uses a splitter to connect multiple CPU irq lines to the UART.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>   hw/openrisc/openrisc_sim.c | 32 ++++++++++++++++++++++++--------
>   1 file changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index d12b3e0c5e..5bfbac00f8 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -137,6 +137,28 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
>       sysbus_mmio_map(s, 0, base);
>   }
>   
> +static void openrisc_sim_serial_init(hwaddr base, int num_cpus,
> +                                     OpenRISCCPU *cpus[], int irq_pin)
> +{
> +    qemu_irq serial_irq;
> +    int i;
> +
> +    if (num_cpus > 1) {
> +        DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
> +        qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
> +        qdev_realize_and_unref(splitter, NULL, &error_fatal);
> +        for (i = 0; i < num_cpus; i++) {
> +            qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
> +        }
> +        serial_irq = qdev_get_gpio_in(splitter, 0);
> +    } else {
> +        serial_irq = get_cpu_irq(cpus, 0, irq_pin);
> +    }

Up to here the code seems a generic helper:

   or1k_cpus_connect_device(OpenRISCCPU *cpus[],
                            unsigned num_cpus,
                            unsigned irq_pin);

> +    serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
> +                   serial_hd(0), DEVICE_NATIVE_ENDIAN);

This part specific to UART.

> +}

Anyhow,
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4
  2022-02-19  6:42 ` [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
  2022-02-19 13:02   ` Peter Maydell
@ 2022-02-20 20:07   ` Philippe Mathieu-Daudé
  2022-02-20 23:59     ` Stafford Horne
  1 sibling, 1 reply; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-02-20 20:07 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Peter Maydell, Jia Liu

On 19/2/22 07:42, Stafford Horne wrote:
> Now that we no longer have a limit of 2 CPUs due to fixing the
> IRQ routing issues we can increase the max.  Here we increase
> the limit to 4, we could go higher, but currently OMPIC has a
> limit of 4, so we align with that.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>   hw/openrisc/openrisc_sim.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4
  2022-02-20 20:07   ` Philippe Mathieu-Daudé
@ 2022-02-20 23:59     ` Stafford Horne
  0 siblings, 0 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-20 23:59 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: Peter Maydell, QEMU Development, Jia Liu

On Sun, Feb 20, 2022 at 09:07:17PM +0100, Philippe Mathieu-Daudé wrote:
> On 19/2/22 07:42, Stafford Horne wrote:
> > Now that we no longer have a limit of 2 CPUs due to fixing the
> > IRQ routing issues we can increase the max.  Here we increase
> > the limit to 4, we could go higher, but currently OMPIC has a
> > limit of 4, so we align with that.
> > 
> > Signed-off-by: Stafford Horne <shorne@gmail.com>
> > ---
> >   hw/openrisc/openrisc_sim.c | 8 +++++---
> >   1 file changed, 5 insertions(+), 3 deletions(-)
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Thank you.

-Stafford


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

* Re: [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  2022-02-20 20:06   ` Philippe Mathieu-Daudé
@ 2022-02-21  0:08     ` Stafford Horne
  0 siblings, 0 replies; 14+ messages in thread
From: Stafford Horne @ 2022-02-21  0:08 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: Peter Maydell, QEMU Development, Jia Liu

On Sun, Feb 20, 2022 at 09:06:41PM +0100, Philippe Mathieu-Daudé wrote:
> On 19/2/22 07:42, Stafford Horne wrote:
> > Currently the OpenRISC SMP configuration only supports 2 cores due to
> > the UART IRQ routing being limited to 2 cores.  As was done in commit
> > 1eeffbeb11 ("hw/openrisc/openrisc_sim: Use IRQ splitter when connecting
> > IRQ to multiple CPUs") we can use a splitter to wire more than 2 CPUs.
> > 
> > This patch moves serial initialization out to it's own function and
> > uses a splitter to connect multiple CPU irq lines to the UART.
> > 
> > Signed-off-by: Stafford Horne <shorne@gmail.com>
> > ---
> >   hw/openrisc/openrisc_sim.c | 32 ++++++++++++++++++++++++--------
> >   1 file changed, 24 insertions(+), 8 deletions(-)
> > 
> > diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> > index d12b3e0c5e..5bfbac00f8 100644
> > --- a/hw/openrisc/openrisc_sim.c
> > +++ b/hw/openrisc/openrisc_sim.c
> > @@ -137,6 +137,28 @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
> >       sysbus_mmio_map(s, 0, base);
> >   }
> > +static void openrisc_sim_serial_init(hwaddr base, int num_cpus,
> > +                                     OpenRISCCPU *cpus[], int irq_pin)
> > +{
> > +    qemu_irq serial_irq;
> > +    int i;
> > +
> > +    if (num_cpus > 1) {
> > +        DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
> > +        qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
> > +        qdev_realize_and_unref(splitter, NULL, &error_fatal);
> > +        for (i = 0; i < num_cpus; i++) {
> > +            qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
> > +        }
> > +        serial_irq = qdev_get_gpio_in(splitter, 0);
> > +    } else {
> > +        serial_irq = get_cpu_irq(cpus, 0, irq_pin);
> > +    }
> 
> Up to here the code seems a generic helper:
> 
>   or1k_cpus_connect_device(OpenRISCCPU *cpus[],
>                            unsigned num_cpus,
>                            unsigned irq_pin);

Right, this is similar to that used in openrisc_sim_net_init.  I thought about
sharing the code but I didn't think it worth adding helper.

The main reason for me is that openrisc_sim_net_init doesn't expose the qemu_irq
and just does sysbus_connect_irq.  While openrisc_sim_serial_init exposes the
qemu_irq.

I think a generic function would have to look like:

    qemu_irq openrisc_cpus_irq_pin_init(OpenRISCCPU *cpus[],
                                        unsigned num_cpus,
                                        unsigned irq_pin);

I would like to leave this as is for now as.

> > +    serial_mm_init(get_system_memory(), base, 0, serial_irq, 115200,
> > +                   serial_hd(0), DEVICE_NATIVE_ENDIAN);
> 
> This part specific to UART.

Right.

> > +}
> 
> Anyhow,
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Thank you,

Adding this to the patch as is.

-Stafford


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

end of thread, other threads:[~2022-02-21  0:10 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-19  6:42 [PATCH v3 0/6] OpenRISC Device Tree Generation Stafford Horne
2022-02-19  6:42 ` [PATCH v3 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
2022-02-19  6:42 ` [PATCH v3 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
2022-02-19  6:42 ` [PATCH v3 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
2022-02-19 13:01   ` Peter Maydell
2022-02-20 20:06   ` Philippe Mathieu-Daudé
2022-02-21  0:08     ` Stafford Horne
2022-02-19  6:42 ` [PATCH v3 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
2022-02-19 13:02   ` Peter Maydell
2022-02-20 20:07   ` Philippe Mathieu-Daudé
2022-02-20 23:59     ` Stafford Horne
2022-02-19  6:42 ` [PATCH v3 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
2022-02-19 13:06   ` Peter Maydell
2022-02-19  6:42 ` [PATCH v3 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne

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