All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0
@ 2022-02-26  1:59 Stafford Horne
  2022-02-26  1:59 ` [PULL v2 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development; +Cc: Stafford Horne

The following changes since commit 4aa2e497a98bafe962e72997f67a369e4b52d9c1:

  Merge remote-tracking branch 'remotes/berrange-gitlab/tags/misc-next-pull-request' into staging (2022-02-23 09:25:05 +0000)

are available in the Git repository at:

  git://github.com/stffrdhrn/qemu.git tags/or1k-pull-request

for you to fetch changes up to 9576abf28280499a4497f39c2fae55bf97285e94:

  hw/openrisc/openrisc_sim: Add support for initrd loading (2022-02-26 10:39:36 +0900)

----------------------------------------------------------------
OpenRISC patches

 - Add automatic DTS generation to openrisc_sim

----------------------------------------------------------------

Since v1:
 - Added fdt file include into meson.build
 - I couldn't figure out how to run CI easily, so but I think this is the right
   fix.

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/meson.build          |   2 +-
 hw/openrisc/openrisc_sim.c       | 308 ++++++++++++++++++++++++++++++++++++---
 3 files changed, 286 insertions(+), 25 deletions(-)


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

* [PULL v2 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-26  1:59 ` [PULL v2 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development; +Cc: Stafford Horne, Philippe Mathieu-Daudé

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] 8+ messages in thread

* [PULL v2 2/6] hw/openrisc/openrisc_sim: Parameterize initialization
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
  2022-02-26  1:59 ` [PULL v2 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-26  1:59 ` [PULL v2 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development; +Cc: Stafford Horne, Philippe Mathieu-Daudé

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] 8+ messages in thread

* [PULL v2 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
  2022-02-26  1:59 ` [PULL v2 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
  2022-02-26  1:59 ` [PULL v2 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-26  1:59 ` [PULL v2 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development
  Cc: Peter Maydell, Stafford Horne, Philippe Mathieu-Daudé

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>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 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] 8+ messages in thread

* [PULL v2 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
                   ` (2 preceding siblings ...)
  2022-02-26  1:59 ` [PULL v2 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-26  1:59 ` [PULL v2 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development
  Cc: Peter Maydell, Stafford Horne, Philippe Mathieu-Daudé

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>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 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] 8+ messages in thread

* [PULL v2 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
                   ` (3 preceding siblings ...)
  2022-02-26  1:59 ` [PULL v2 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-26  1:59 ` [PULL v2 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne
  2022-02-28 16:46 ` [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne

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>
---
Since v1:
 - Added fdt to CONFIG_OR1K_SIM source set

 configs/targets/or1k-softmmu.mak |   1 +
 hw/openrisc/meson.build          |   2 +-
 hw/openrisc/openrisc_sim.c       | 189 ++++++++++++++++++++++++++++---
 3 files changed, 176 insertions(+), 16 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/meson.build b/hw/openrisc/meson.build
index 947f63ee08..ec48172c9d 100644
--- a/hw/openrisc/meson.build
+++ b/hw/openrisc/meson.build
@@ -1,5 +1,5 @@
 openrisc_ss = ss.source_set()
 openrisc_ss.add(files('cputimer.c'))
-openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
+openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: [files('openrisc_sim.c'), fdt])
 
 hw_arch += {'openrisc': openrisc_ss}
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] 8+ messages in thread

* [PULL v2 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
                   ` (4 preceding siblings ...)
  2022-02-26  1:59 ` [PULL v2 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
@ 2022-02-26  1:59 ` Stafford Horne
  2022-02-28 16:46 ` [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Stafford Horne @ 2022-02-26  1:59 UTC (permalink / raw)
  To: QEMU Development; +Cc: Peter Maydell, Stafford Horne

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] 8+ messages in thread

* Re: [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0
  2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
                   ` (5 preceding siblings ...)
  2022-02-26  1:59 ` [PULL v2 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne
@ 2022-02-28 16:46 ` Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2022-02-28 16:46 UTC (permalink / raw)
  To: Stafford Horne; +Cc: QEMU Development

On Sat, 26 Feb 2022 at 02:03, Stafford Horne <shorne@gmail.com> wrote:
>
> The following changes since commit 4aa2e497a98bafe962e72997f67a369e4b52d9c1:
>
>   Merge remote-tracking branch 'remotes/berrange-gitlab/tags/misc-next-pull-request' into staging (2022-02-23 09:25:05 +0000)
>
> are available in the Git repository at:
>
>   git://github.com/stffrdhrn/qemu.git tags/or1k-pull-request
>
> for you to fetch changes up to 9576abf28280499a4497f39c2fae55bf97285e94:
>
>   hw/openrisc/openrisc_sim: Add support for initrd loading (2022-02-26 10:39:36 +0900)
>
> ----------------------------------------------------------------
> OpenRISC patches
>
>  - Add automatic DTS generation to openrisc_sim
>
> ----------------------------------------------------------------
>
> Since v1:
>  - Added fdt file include into meson.build
>  - I couldn't figure out how to run CI easily, so but I think this is the right
>    fix.


Applied, thanks.

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

-- PMM


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

end of thread, other threads:[~2022-02-28 16:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-26  1:59 [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Stafford Horne
2022-02-26  1:59 ` [PULL v2 1/6] hw/openrisc/openrisc_sim: Create machine state for or1ksim Stafford Horne
2022-02-26  1:59 ` [PULL v2 2/6] hw/openrisc/openrisc_sim: Parameterize initialization Stafford Horne
2022-02-26  1:59 ` [PULL v2 3/6] hw/openrisc/openrisc_sim: Use IRQ splitter when connecting UART Stafford Horne
2022-02-26  1:59 ` [PULL v2 4/6] hw/openrisc/openrisc_sim: Increase max_cpus to 4 Stafford Horne
2022-02-26  1:59 ` [PULL v2 5/6] hw/openrisc/openrisc_sim: Add automatic device tree generation Stafford Horne
2022-02-26  1:59 ` [PULL v2 6/6] hw/openrisc/openrisc_sim: Add support for initrd loading Stafford Horne
2022-02-28 16:46 ` [PULL v2 0/6] OpenRISC DTS Generation patches for 7.0 Peter Maydell

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