All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/20] ppc: QOM'ify 405 board
@ 2022-08-03 13:28 Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 01/20] ppc/ppc405: Remove taihu machine Cédric Le Goater
                   ` (20 more replies)
  0 siblings, 21 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Hello,

Here is large series QOM'ifying the PPC405 board. It introduces a new
generic machine and SoC models, converts the current device models to
QOM and populates the SoC. The process is quite mechanical without too
much issues to handle. The noisy part is the initial patch introducing
the SoC realize routine.

What's left ?

* The DCR read/writre handlers are attached in table to the CPU
  instance. We could probably rework the whole with a specific address
  space and memory regions handling the implemented registers. I don't
  think this is necessary.

* the SDRAM mappings are very baroque and certainly could be simplified.
  I think we should QOMify the ppc440 machines before addressing this
  part.

Thanks,

C.

Changes in v2 :

 - docs/about/removed-features.rst update
 - Fix compile breakage (uic)
 - Fix CPU reset, which breaking u-boot boot
 - Changed prefix of memory regions to "ppc405"
 - Reduced the number of RAM banks to 1. Second was a dummy one to
   please ppc405ep_init()

Cédric Le Goater (20):
  ppc/ppc405: Remove taihu machine
  ppc/ppc405: Introduce a PPC405 generic machine
  ppc/ppc405: Move devices under the ref405ep machine
  ppc/ppc405: Introduce a PPC405 SoC
  ppc/ppc405: Start QOMification of the SoC
  ppc/ppc405: QOM'ify CPU
  ppc/ppc405: QOM'ify CPC
  ppc/ppc405: QOM'ify GPT
  ppc/ppc405: QOM'ify OCM
  ppc/ppc405: QOM'ify GPIO
  ppc/ppc405: QOM'ify DMA
  ppc/ppc405: QOM'ify EBC
  ppc/ppc405: QOM'ify OPBA
  ppc/ppc405: QOM'ify POB
  ppc/ppc405: QOM'ify PLB
  ppc/ppc405: QOM'ify MAL
  ppc/ppc405: QOM'ify FPGA
  ppc/ppc405: QOM'ify UIC
  ppc/ppc405: QOM'ify I2C
  ppc/ppc4xx: Fix sdram trace events

 docs/about/deprecated.rst       |   9 -
 docs/about/removed-features.rst |   6 +
 docs/system/ppc/embedded.rst    |   1 -
 hw/ppc/ppc405.h                 | 210 ++++++++-
 include/hw/ppc/ppc4xx.h         |  29 ++
 hw/ppc/ppc405_boards.c          | 366 ++++-----------
 hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------
 hw/ppc/ppc4xx_devs.c            | 124 +++--
 MAINTAINERS                     |   2 +-
 9 files changed, 894 insertions(+), 652 deletions(-)

-- 
2.37.1



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

* [PATCH v2 01/20] ppc/ppc405: Remove taihu machine
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 17:16   ` Daniel Henrique Barboza
  2022-08-03 13:28 ` [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine Cédric Le Goater
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

It has been deprecated since 7.0.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 docs/about/deprecated.rst       |   9 --
 docs/about/removed-features.rst |   6 +
 docs/system/ppc/embedded.rst    |   1 -
 hw/ppc/ppc405_boards.c          | 232 --------------------------------
 MAINTAINERS                     |   2 +-
 5 files changed, 7 insertions(+), 243 deletions(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 7ee26626d5cf..2f9b41aaea48 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -233,15 +233,6 @@ deprecated; use the new name ``dtb-randomness`` instead. The new name
 better reflects the way this property affects all random data within
 the device tree blob, not just the ``kaslr-seed`` node.
 
-PPC 405 ``taihu`` machine (since 7.0)
-'''''''''''''''''''''''''''''''''''''
-
-The PPC 405 CPU is a system-on-a-chip, so all 405 machines are very similar,
-except for some external periphery. However, the periphery of the ``taihu``
-machine is hardly emulated at all (e.g. neither the LCD nor the USB part had
-been implemented), so there is not much value added by this board. Use the
-``ref405ep`` machine instead.
-
 ``pc-i440fx-1.4`` up to ``pc-i440fx-1.7`` (since 7.0)
 '''''''''''''''''''''''''''''''''''''''''''''''''''''
 
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index c7b9dadd5d63..8fad2f4d5e9b 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -661,6 +661,12 @@ Aspeed ``swift-bmc`` machine (removed in 7.0)
 This machine was removed because it was unused. Alternative AST2500 based
 OpenPOWER machines are ``witherspoon-bmc`` and ``romulus-bmc``.
 
+ppc ``taihu`` machine (removed in 7.2)
+'''''''''''''''''''''''''''''''''''''''''''''
+
+This machine was removed because it was partially emulated and 405
+machines are very similar. Use the ``ref405ep`` machine instead.
+
 linux-user mode CPUs
 --------------------
 
diff --git a/docs/system/ppc/embedded.rst b/docs/system/ppc/embedded.rst
index cfffbda24da9..af3b3d9fa460 100644
--- a/docs/system/ppc/embedded.rst
+++ b/docs/system/ppc/embedded.rst
@@ -6,5 +6,4 @@ Embedded family boards
 - ``ppce500``              generic paravirt e500 platform
 - ``ref405ep``             ref405ep
 - ``sam460ex``             aCube Sam460ex
-- ``taihu``                taihu
 - ``virtex-ml507``         Xilinx Virtex ML507 reference design
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index a66ad05e3ac3..1a4e7588c584 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -342,241 +342,9 @@ static const TypeInfo ref405ep_type = {
     .class_init = ref405ep_class_init,
 };
 
-/*****************************************************************************/
-/* AMCC Taihu evaluation board */
-/* - PowerPC 405EP processor
- * - SDRAM               128 MB at 0x00000000
- * - Boot flash          2 MB   at 0xFFE00000
- * - Application flash   32 MB  at 0xFC000000
- * - 2 serial ports
- * - 2 ethernet PHY
- * - 1 USB 1.1 device    0x50000000
- * - 1 LCD display       0x50100000
- * - 1 CPLD              0x50100000
- * - 1 I2C EEPROM
- * - 1 I2C thermal sensor
- * - a set of LEDs
- * - bit-bang SPI port using GPIOs
- * - 1 EBC interface connector 0 0x50200000
- * - 1 cardbus controller + expansion slot.
- * - 1 PCI expansion slot.
- */
-typedef struct taihu_cpld_t taihu_cpld_t;
-struct taihu_cpld_t {
-    uint8_t reg0;
-    uint8_t reg1;
-};
-
-static uint64_t taihu_cpld_read(void *opaque, hwaddr addr, unsigned size)
-{
-    taihu_cpld_t *cpld;
-    uint32_t ret;
-
-    cpld = opaque;
-    switch (addr) {
-    case 0x0:
-        ret = cpld->reg0;
-        break;
-    case 0x1:
-        ret = cpld->reg1;
-        break;
-    default:
-        ret = 0;
-        break;
-    }
-
-    return ret;
-}
-
-static void taihu_cpld_write(void *opaque, hwaddr addr,
-                             uint64_t value, unsigned size)
-{
-    taihu_cpld_t *cpld;
-
-    cpld = opaque;
-    switch (addr) {
-    case 0x0:
-        /* Read only */
-        break;
-    case 0x1:
-        cpld->reg1 = value;
-        break;
-    default:
-        break;
-    }
-}
-
-static const MemoryRegionOps taihu_cpld_ops = {
-    .read = taihu_cpld_read,
-    .write = taihu_cpld_write,
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void taihu_cpld_reset (void *opaque)
-{
-    taihu_cpld_t *cpld;
-
-    cpld = opaque;
-    cpld->reg0 = 0x01;
-    cpld->reg1 = 0x80;
-}
-
-static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
-{
-    taihu_cpld_t *cpld;
-    MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
-
-    cpld = g_new0(taihu_cpld_t, 1);
-    memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 0x100);
-    memory_region_add_subregion(sysmem, base, cpld_memory);
-    qemu_register_reset(&taihu_cpld_reset, cpld);
-}
-
-static void taihu_405ep_init(MachineState *machine)
-{
-    MachineClass *mc = MACHINE_GET_CLASS(machine);
-    const char *bios_name = machine->firmware ?: BIOS_FILENAME;
-    const char *kernel_filename = machine->kernel_filename;
-    const char *initrd_filename = machine->initrd_filename;
-    char *filename;
-    MemoryRegion *sysmem = get_system_memory();
-    MemoryRegion *bios;
-    MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
-    hwaddr ram_bases[2], ram_sizes[2];
-    long bios_size;
-    target_ulong kernel_base, initrd_base;
-    long kernel_size, initrd_size;
-    int linux_boot;
-    int fl_idx;
-    DriveInfo *dinfo;
-    DeviceState *uicdev;
-
-    if (machine->ram_size != mc->default_ram_size) {
-        char *sz = size_to_str(mc->default_ram_size);
-        error_report("Invalid RAM size, should be %s", sz);
-        g_free(sz);
-        exit(EXIT_FAILURE);
-    }
-
-    ram_bases[0] = 0;
-    ram_sizes[0] = 0x04000000;
-    memory_region_init_alias(&ram_memories[0], NULL,
-                             "taihu_405ep.ram-0", machine->ram, ram_bases[0],
-                             ram_sizes[0]);
-    ram_bases[1] = 0x04000000;
-    ram_sizes[1] = 0x04000000;
-    memory_region_init_alias(&ram_memories[1], NULL,
-                             "taihu_405ep.ram-1", machine->ram, ram_bases[1],
-                             ram_sizes[1]);
-    ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
-                  33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
-    /* allocate and load BIOS */
-    fl_idx = 0;
-#if defined(USE_FLASH_BIOS)
-    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-    if (dinfo) {
-        bios_size = 2 * MiB;
-        pflash_cfi02_register(0xFFE00000,
-                              "taihu_405ep.bios", bios_size,
-                              blk_by_legacy_dinfo(dinfo),
-                              64 * KiB, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
-        fl_idx++;
-    } else
-#endif
-    {
-        bios = g_new(MemoryRegion, 1);
-        memory_region_init_rom(bios, NULL, "taihu_405ep.bios", BIOS_SIZE,
-                               &error_fatal);
-        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-        if (filename) {
-            bios_size = load_image_size(filename,
-                                        memory_region_get_ram_ptr(bios),
-                                        BIOS_SIZE);
-            g_free(filename);
-            if (bios_size < 0) {
-                error_report("Could not load PowerPC BIOS '%s'", bios_name);
-                exit(1);
-            }
-            bios_size = (bios_size + 0xfff) & ~0xfff;
-            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
-        } else if (!qtest_enabled()) {
-            error_report("Could not load PowerPC BIOS '%s'", bios_name);
-            exit(1);
-        }
-    }
-    /* Register Linux flash */
-    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-    if (dinfo) {
-        bios_size = 32 * MiB;
-        pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size,
-                              blk_by_legacy_dinfo(dinfo),
-                              64 * KiB, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
-        fl_idx++;
-    }
-    /* Register CLPD & LCD display */
-    taihu_cpld_init(sysmem, 0x50100000);
-    /* Load kernel */
-    linux_boot = (kernel_filename != NULL);
-    if (linux_boot) {
-        kernel_base = KERNEL_LOAD_ADDR;
-        /* now we can load the kernel */
-        kernel_size = load_image_targphys(kernel_filename, kernel_base,
-                                          machine->ram_size - kernel_base);
-        if (kernel_size < 0) {
-            error_report("could not load kernel '%s'", kernel_filename);
-            exit(1);
-        }
-        /* load initrd */
-        if (initrd_filename) {
-            initrd_base = INITRD_LOAD_ADDR;
-            initrd_size = load_image_targphys(initrd_filename, initrd_base,
-                                              machine->ram_size - initrd_base);
-            if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
-            }
-        } else {
-            initrd_base = 0;
-            initrd_size = 0;
-        }
-    } else {
-        kernel_base = 0;
-        kernel_size = 0;
-        initrd_base = 0;
-        initrd_size = 0;
-    }
-}
-
-static void taihu_class_init(ObjectClass *oc, void *data)
-{
-    MachineClass *mc = MACHINE_CLASS(oc);
-
-    mc->desc = "taihu";
-    mc->init = taihu_405ep_init;
-    mc->default_ram_size = 0x08000000;
-    mc->default_ram_id = "taihu_405ep.ram";
-    mc->deprecation_reason = "incomplete, use 'ref405ep' instead";
-}
-
-static const TypeInfo taihu_type = {
-    .name = MACHINE_TYPE_NAME("taihu"),
-    .parent = TYPE_MACHINE,
-    .class_init = taihu_class_init,
-};
-
 static void ppc405_machine_init(void)
 {
     type_register_static(&ref405ep_type);
-    type_register_static(&taihu_type);
 }
 
 type_init(ppc405_machine_init)
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ce4227ff650..1729c0901cea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1282,7 +1282,7 @@ F: hw/openrisc/openrisc_sim.c
 
 PowerPC Machines
 ----------------
-405 (ref405ep and taihu)
+405 (ref405ep)
 L: qemu-ppc@nongnu.org
 S: Orphan
 F: hw/ppc/ppc405_boards.c
-- 
2.37.1



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

* [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 01/20] ppc/ppc405: Remove taihu machine Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 17:03   ` BALATON Zoltan
  2022-08-03 22:07   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 03/20] ppc/ppc405: Move devices under the ref405ep machine Cédric Le Goater
                   ` (18 subsequent siblings)
  20 siblings, 2 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

We will use this machine as a base to define the ref405ep and possibly
the PPC405 hotfoot board as found in the Linux kernel.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405_boards.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 1a4e7588c584..4c269b6526a5 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -50,6 +50,15 @@
 
 #define USE_FLASH_BIOS
 
+struct Ppc405MachineState {
+    /* Private */
+    MachineState parent_obj;
+    /* Public */
+};
+
+#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
+
 /*****************************************************************************/
 /* PPC405EP reference board (IBM) */
 /* Standalone board with:
@@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void *data)
 
     mc->desc = "ref405ep";
     mc->init = ref405ep_init;
-    mc->default_ram_size = 0x08000000;
-    mc->default_ram_id = "ef405ep.ram";
 }
 
 static const TypeInfo ref405ep_type = {
     .name = MACHINE_TYPE_NAME("ref405ep"),
-    .parent = TYPE_MACHINE,
+    .parent = TYPE_PPC405_MACHINE,
     .class_init = ref405ep_class_init,
 };
 
+static void ppc405_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "PPC405 generic machine";
+    mc->default_ram_size = 0x08000000;
+    mc->default_ram_id = "ppc405.ram";
+}
+
+static const TypeInfo ppc405_machine_type = {
+    .name = TYPE_PPC405_MACHINE,
+    .parent = TYPE_MACHINE,
+    .instance_size = sizeof(Ppc405MachineState),
+    .class_init = ppc405_machine_class_init,
+    .abstract = true,
+};
+
 static void ppc405_machine_init(void)
 {
+    type_register_static(&ppc405_machine_type);
     type_register_static(&ref405ep_type);
 }
 
-- 
2.37.1



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

* [PATCH v2 03/20] ppc/ppc405: Move devices under the ref405ep machine
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 01/20] ppc/ppc405: Remove taihu machine Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC Cédric Le Goater
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405_boards.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4c269b6526a5..24ec948d22a4 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -230,13 +230,11 @@ static void boot_from_kernel(MachineState *machine, PowerPCCPU *cpu)
     env->load_info = &boot_info;
 }
 
-static void ref405ep_init(MachineState *machine)
+static void ppc405_init(MachineState *machine)
 {
     MachineClass *mc = MACHINE_GET_CLASS(machine);
     const char *kernel_filename = machine->kernel_filename;
     PowerPCCPU *cpu;
-    DeviceState *dev;
-    SysBusDevice *s;
     MemoryRegion *sram = g_new(MemoryRegion, 1);
     MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
     hwaddr ram_bases[2], ram_sizes[2];
@@ -294,15 +292,6 @@ static void ref405ep_init(MachineState *machine)
         memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
     }
 
-    /* Register FPGA */
-    ref405ep_fpga_init(sysmem, PPC405EP_FPGA_BASE);
-    /* Register NVRAM */
-    dev = qdev_new("sysbus-m48t08");
-    qdev_prop_set_int32(dev, "base-year", 1968);
-    s = SYS_BUS_DEVICE(dev);
-    sysbus_realize_and_unref(s, &error_fatal);
-    sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE);
-
     /* Load kernel and initrd using U-Boot images */
     if (kernel_filename && machine->firmware) {
         target_ulong kernel_base, initrd_base;
@@ -335,6 +324,23 @@ static void ref405ep_init(MachineState *machine)
     }
 }
 
+static void ref405ep_init(MachineState *machine)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    ppc405_init(machine);
+
+    /* Register FPGA */
+    ref405ep_fpga_init(get_system_memory(), PPC405EP_FPGA_BASE);
+    /* Register NVRAM */
+    dev = qdev_new("sysbus-m48t08");
+    qdev_prop_set_int32(dev, "base-year", 1968);
+    s = SYS_BUS_DEVICE(dev);
+    sysbus_realize_and_unref(s, &error_fatal);
+    sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE);
+}
+
 static void ref405ep_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -354,6 +360,7 @@ static void ppc405_machine_class_init(ObjectClass *oc, void *data)
     MachineClass *mc = MACHINE_CLASS(oc);
 
     mc->desc = "PPC405 generic machine";
+    mc->init = ppc405_init;
     mc->default_ram_size = 0x08000000;
     mc->default_ram_id = "ppc405.ram";
 }
-- 
2.37.1



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

* [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (2 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 03/20] ppc/ppc405: Move devices under the ref405ep machine Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 22:13   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC Cédric Le Goater
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

It is an initial model to start QOMification of the PPC405 board.
QOM'ified devices will be reintroduced one by one. Start with the
memory regions, which name prefix is changed to "ppc405".

Also, initialize only one RAM bank. The second bank is a dummy one
(zero size) which is here to match the hard coded number of banks in
ppc405ep_init(). We will adjust this number when ppc4xx_sdram_init()
can be called directly, after we have replaced ppc405ep_init().

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h        | 17 +++++++++++++++
 hw/ppc/ppc405_boards.c | 29 +++++++++++--------------
 hw/ppc/ppc405_uc.c     | 49 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 83f156f585c8..c8cddb71733a 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -25,6 +25,7 @@
 #ifndef PPC405_H
 #define PPC405_H
 
+#include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
 
 #define PPC405EP_SDRAM_BASE 0x00000000
@@ -62,6 +63,22 @@ struct ppc4xx_bd_info_t {
     uint32_t bi_iic_fast[2];
 };
 
+#define TYPE_PPC405_SOC "ppc405-soc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
+
+struct Ppc405SoCState {
+    /* Private */
+    DeviceState parent_obj;
+
+    /* Public */
+    MemoryRegion sram;
+    MemoryRegion ram_memories[2];
+    hwaddr ram_bases[2], ram_sizes[2];
+
+    MemoryRegion *dram_mr;
+    hwaddr ram_size;
+};
+
 /* PowerPC 405 core */
 ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
 
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 24ec948d22a4..96db52c5a309 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -54,6 +54,8 @@ struct Ppc405MachineState {
     /* Private */
     MachineState parent_obj;
     /* Public */
+
+    Ppc405SoCState soc;
 };
 
 #define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
@@ -232,12 +234,10 @@ static void boot_from_kernel(MachineState *machine, PowerPCCPU *cpu)
 
 static void ppc405_init(MachineState *machine)
 {
+    Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
     MachineClass *mc = MACHINE_GET_CLASS(machine);
     const char *kernel_filename = machine->kernel_filename;
     PowerPCCPU *cpu;
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
-    hwaddr ram_bases[2], ram_sizes[2];
     MemoryRegion *sysmem = get_system_memory();
     DeviceState *uicdev;
 
@@ -248,23 +248,18 @@ static void ppc405_init(MachineState *machine)
         exit(EXIT_FAILURE);
     }
 
-    /* XXX: fix this */
-    memory_region_init_alias(&ram_memories[0], NULL, "ef405ep.ram.alias",
-                             machine->ram, 0, machine->ram_size);
-    ram_bases[0] = 0;
-    ram_sizes[0] = machine->ram_size;
-    memory_region_init(&ram_memories[1], NULL, "ef405ep.ram1", 0);
-    ram_bases[1] = 0x00000000;
-    ram_sizes[1] = 0x00000000;
+    object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
+                            TYPE_PPC405_SOC);
+    object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
+                             machine->ram_size, &error_fatal);
+    object_property_set_link(OBJECT(&ppc405->soc), "dram",
+                             OBJECT(machine->ram), &error_abort);
+    qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
 
-    cpu = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
+    cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, ppc405->soc.ram_bases,
+                        ppc405->soc.ram_sizes,
                         33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
 
-    /* allocate SRAM */
-    memory_region_init_ram(sram, NULL, "ef405ep.sram", PPC405EP_SRAM_SIZE,
-                           &error_fatal);
-    memory_region_add_subregion(sysmem, PPC405EP_SRAM_BASE, sram);
-
     /* allocate and load BIOS */
     if (machine->firmware) {
         MemoryRegion *bios = g_new(MemoryRegion, 1);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index d6420c88d3a6..7033bac6bf3f 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -30,6 +30,7 @@
 #include "hw/ppc/ppc.h"
 #include "hw/i2c/ppc4xx_i2c.h"
 #include "hw/irq.h"
+#include "hw/qdev-properties.h"
 #include "ppc405.h"
 #include "hw/char/serial.h"
 #include "qemu/timer.h"
@@ -1530,3 +1531,51 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
 
     return cpu;
 }
+
+static void ppc405_soc_realize(DeviceState *dev, Error **errp)
+{
+    Ppc405SoCState *s = PPC405_SOC(dev);
+    Error *err = NULL;
+
+    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
+                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
+    s->ram_bases[0] = 0;
+    s->ram_sizes[0] = s->ram_size;
+
+    /* allocate SRAM */
+    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
+                           PPC405EP_SRAM_SIZE,  &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
+                                &s->sram);
+}
+
+static Property ppc405_soc_properties[] = {
+    DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
+                     MemoryRegion *),
+    DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_soc_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_soc_realize;
+    dc->user_creatable = false;
+    device_class_set_props(dc, ppc405_soc_properties);
+}
+
+static const TypeInfo ppc405_types[] = {
+    {
+        .name           = TYPE_PPC405_SOC,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(Ppc405SoCState),
+        .class_init     = ppc405_soc_class_init,
+    }
+};
+
+DEFINE_TYPES(ppc405_types)
-- 
2.37.1



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

* [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (3 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 22:23   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 06/20] ppc/ppc405: QOM'ify CPU Cédric Le Goater
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

This moves all the code previously done in the ppc405ep_init() routine
under ppc405_soc_realize(). We can also adjust the number of banks now
that we have control on ppc4xx_sdram_init().

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h        |  16 ++---
 hw/ppc/ppc405_boards.c |  12 ++--
 hw/ppc/ppc405_uc.c     | 144 ++++++++++++++++++++---------------------
 3 files changed, 83 insertions(+), 89 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index c8cddb71733a..2c912b328eaf 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -72,11 +72,16 @@ struct Ppc405SoCState {
 
     /* Public */
     MemoryRegion sram;
-    MemoryRegion ram_memories[2];
-    hwaddr ram_bases[2], ram_sizes[2];
+    MemoryRegion ram_memories[1];
+    hwaddr ram_bases[1], ram_sizes[1];
+    bool do_dram_init;
 
     MemoryRegion *dram_mr;
     hwaddr ram_size;
+
+    uint32_t sysclk;
+    PowerPCCPU *cpu;
+    DeviceState *uic;
 };
 
 /* PowerPC 405 core */
@@ -85,11 +90,4 @@ ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
 void ppc4xx_plb_init(CPUPPCState *env);
 void ppc405_ebc_init(CPUPPCState *env);
 
-PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
-                        MemoryRegion ram_memories[2],
-                        hwaddr ram_bases[2],
-                        hwaddr ram_sizes[2],
-                        uint32_t sysclk, DeviceState **uicdev,
-                        int do_init);
-
 #endif /* PPC405_H */
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 96db52c5a309..363cb0770506 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -237,9 +237,7 @@ static void ppc405_init(MachineState *machine)
     Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
     MachineClass *mc = MACHINE_GET_CLASS(machine);
     const char *kernel_filename = machine->kernel_filename;
-    PowerPCCPU *cpu;
     MemoryRegion *sysmem = get_system_memory();
-    DeviceState *uicdev;
 
     if (machine->ram_size != mc->default_ram_size) {
         char *sz = size_to_str(mc->default_ram_size);
@@ -254,12 +252,12 @@ static void ppc405_init(MachineState *machine)
                              machine->ram_size, &error_fatal);
     object_property_set_link(OBJECT(&ppc405->soc), "dram",
                              OBJECT(machine->ram), &error_abort);
+    object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
+                             !(kernel_filename == NULL), &error_abort);
+    object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", 33333333,
+                             &error_abort);
     qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
 
-    cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, ppc405->soc.ram_bases,
-                        ppc405->soc.ram_sizes,
-                        33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
-
     /* allocate and load BIOS */
     if (machine->firmware) {
         MemoryRegion *bios = g_new(MemoryRegion, 1);
@@ -315,7 +313,7 @@ static void ppc405_init(MachineState *machine)
 
     /* Load ELF kernel and rootfs.cpio */
     } else if (kernel_filename && !machine->firmware) {
-        boot_from_kernel(machine, cpu);
+        boot_from_kernel(machine, ppc405->soc.cpu);
     }
 }
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 7033bac6bf3f..ed1099e08bbd 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1432,130 +1432,128 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
 #endif
 }
 
-PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
-                        MemoryRegion ram_memories[2],
-                        hwaddr ram_bases[2],
-                        hwaddr ram_sizes[2],
-                        uint32_t sysclk, DeviceState **uicdevp,
-                        int do_init)
+static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
+    Ppc405SoCState *s = PPC405_SOC(dev);
     clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
-    PowerPCCPU *cpu;
     CPUPPCState *env;
-    DeviceState *uicdev;
-    SysBusDevice *uicsbd;
+    Error *err = NULL;
+
+    /* allocate SRAM */
+    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
+                           PPC405EP_SRAM_SIZE,  &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
+                                &s->sram);
 
     memset(clk_setup, 0, sizeof(clk_setup));
+
     /* init CPUs */
-    cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
+    s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
                       &clk_setup[PPC405EP_CPU_CLK],
-                      &tlb_clk_setup, sysclk);
-    env = &cpu->env;
+                      &tlb_clk_setup, s->sysclk);
+    env = &s->cpu->env;
     clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
     clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
-    /* Internal devices init */
-    /* Memory mapped devices registers */
+
+    /* CPU control */
+    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
+
     /* PLB arbitrer */
     ppc4xx_plb_init(env);
+
     /* PLB to OPB bridge */
     ppc4xx_pob_init(env);
+
     /* OBP arbitrer */
     ppc4xx_opba_init(0xef600600);
+
     /* Universal interrupt controller */
-    uicdev = qdev_new(TYPE_PPC_UIC);
-    uicsbd = SYS_BUS_DEVICE(uicdev);
+    s->uic = qdev_new(TYPE_PPC_UIC);
 
-    object_property_set_link(OBJECT(uicdev), "cpu", OBJECT(cpu),
+    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(s->cpu),
                              &error_fatal);
-    sysbus_realize_and_unref(uicsbd, &error_fatal);
-
-    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT,
-                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT));
-    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT,
-                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
+    if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
+        return;
+    }
 
-    *uicdevp = uicdev;
+    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
+                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_INT));
+    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
+                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_CINT));
 
     /* SDRAM controller */
-        /* XXX 405EP has no ECC interrupt */
-    ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 17), 2, ram_memories,
-                      ram_bases, ram_sizes, do_init);
+    /* XXX 405EP has no ECC interrupt */
+    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
+                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
+    s->ram_bases[0] = 0;
+    s->ram_sizes[0] = s->ram_size;
+
+    ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17),
+                      ARRAY_SIZE(s->ram_memories), s->ram_memories,
+                      s->ram_bases, s->ram_sizes, s->do_dram_init);
+
     /* External bus controller */
     ppc405_ebc_init(env);
+
     /* DMA controller */
-    dma_irqs[0] = qdev_get_gpio_in(uicdev, 5);
-    dma_irqs[1] = qdev_get_gpio_in(uicdev, 6);
-    dma_irqs[2] = qdev_get_gpio_in(uicdev, 7);
-    dma_irqs[3] = qdev_get_gpio_in(uicdev, 8);
+    dma_irqs[0] = qdev_get_gpio_in(s->uic, 5);
+    dma_irqs[1] = qdev_get_gpio_in(s->uic, 6);
+    dma_irqs[2] = qdev_get_gpio_in(s->uic, 7);
+    dma_irqs[3] = qdev_get_gpio_in(s->uic, 8);
     ppc405_dma_init(env, dma_irqs);
-    /* IIC controller */
+
+    /* I2C controller */
     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
-                         qdev_get_gpio_in(uicdev, 2));
+                         qdev_get_gpio_in(s->uic, 2));
     /* GPIO */
     ppc405_gpio_init(0xef600700);
+
     /* Serial ports */
     if (serial_hd(0) != NULL) {
-        serial_mm_init(address_space_mem, 0xef600300, 0,
-                       qdev_get_gpio_in(uicdev, 0),
+        serial_mm_init(get_system_memory(), 0xef600300, 0,
+                       qdev_get_gpio_in(s->uic, 0),
                        PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
                        DEVICE_BIG_ENDIAN);
     }
     if (serial_hd(1) != NULL) {
-        serial_mm_init(address_space_mem, 0xef600400, 0,
-                       qdev_get_gpio_in(uicdev, 1),
+        serial_mm_init(get_system_memory(), 0xef600400, 0,
+                       qdev_get_gpio_in(s->uic, 1),
                        PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
                        DEVICE_BIG_ENDIAN);
     }
+
     /* OCM */
     ppc405_ocm_init(env);
+
     /* GPT */
-    gpt_irqs[0] = qdev_get_gpio_in(uicdev, 19);
-    gpt_irqs[1] = qdev_get_gpio_in(uicdev, 20);
-    gpt_irqs[2] = qdev_get_gpio_in(uicdev, 21);
-    gpt_irqs[3] = qdev_get_gpio_in(uicdev, 22);
-    gpt_irqs[4] = qdev_get_gpio_in(uicdev, 23);
+    gpt_irqs[0] = qdev_get_gpio_in(s->uic, 19);
+    gpt_irqs[1] = qdev_get_gpio_in(s->uic, 20);
+    gpt_irqs[2] = qdev_get_gpio_in(s->uic, 21);
+    gpt_irqs[3] = qdev_get_gpio_in(s->uic, 22);
+    gpt_irqs[4] = qdev_get_gpio_in(s->uic, 23);
     ppc4xx_gpt_init(0xef600000, gpt_irqs);
-    /* PCI */
-    /* Uses UIC IRQs 3, 16, 18 */
+
     /* MAL */
-    mal_irqs[0] = qdev_get_gpio_in(uicdev, 11);
-    mal_irqs[1] = qdev_get_gpio_in(uicdev, 12);
-    mal_irqs[2] = qdev_get_gpio_in(uicdev, 13);
-    mal_irqs[3] = qdev_get_gpio_in(uicdev, 14);
+    mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
+    mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
+    mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
+    mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
     ppc4xx_mal_init(env, 4, 2, mal_irqs);
+
     /* Ethernet */
     /* Uses UIC IRQs 9, 15, 17 */
-    /* CPU control */
-    ppc405ep_cpc_init(env, clk_setup, sysclk);
-
-    return cpu;
-}
-
-static void ppc405_soc_realize(DeviceState *dev, Error **errp)
-{
-    Ppc405SoCState *s = PPC405_SOC(dev);
-    Error *err = NULL;
-
-    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
-                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
-    s->ram_bases[0] = 0;
-    s->ram_sizes[0] = s->ram_size;
-
-    /* allocate SRAM */
-    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
-                           PPC405EP_SRAM_SIZE,  &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
-                                &s->sram);
 }
 
 static Property ppc405_soc_properties[] = {
     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
                      MemoryRegion *),
+    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
+    DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.37.1



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

* [PATCH v2 06/20] ppc/ppc405: QOM'ify CPU
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (4 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC Cédric Le Goater
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Drop the use of ppc4xx_init() and duplicate a bit of code related to
clocks in the SoC realize routine. We will clean that up in the
following patches.

ppc_dcr_init() simply allocates default DCR handlers for the CPU. Maybe
this could be done in model initializer of the CPU families needing it.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h         |  2 +-
 include/hw/ppc/ppc4xx.h |  1 +
 hw/ppc/ppc405_boards.c  |  2 +-
 hw/ppc/ppc405_uc.c      | 35 +++++++++++++++++++++++++----------
 hw/ppc/ppc4xx_devs.c    |  2 +-
 5 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 2c912b328eaf..ae64549537c6 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -80,7 +80,7 @@ struct Ppc405SoCState {
     hwaddr ram_size;
 
     uint32_t sysclk;
-    PowerPCCPU *cpu;
+    PowerPCCPU cpu;
     DeviceState *uic;
 };
 
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index 980f964b5a91..021376c2d260 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -29,6 +29,7 @@
 #include "exec/memory.h"
 
 /* PowerPC 4xx core initialization */
+void ppc4xx_reset(void *opaque);
 PowerPCCPU *ppc4xx_init(const char *cpu_model,
                         clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
                         uint32_t sysclk);
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 363cb0770506..82b51cc457fa 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -313,7 +313,7 @@ static void ppc405_init(MachineState *machine)
 
     /* Load ELF kernel and rootfs.cpio */
     } else if (kernel_filename && !machine->firmware) {
-        boot_from_kernel(machine, ppc405->soc.cpu);
+        boot_from_kernel(machine, &ppc405->soc.cpu);
     }
 }
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index ed1099e08bbd..013dccee898b 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1432,10 +1432,18 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
 #endif
 }
 
+static void ppc405_soc_instance_init(Object *obj)
+{
+    Ppc405SoCState *s = PPC405_SOC(obj);
+
+    object_initialize_child(obj, "cpu", &s->cpu,
+                            POWERPC_CPU_TYPE_NAME("405ep"));
+}
+
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
     Ppc405SoCState *s = PPC405_SOC(dev);
-    clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
+    clk_setup_t clk_setup[PPC405EP_CLK_NB];
     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
     CPUPPCState *env;
     Error *err = NULL;
@@ -1453,12 +1461,18 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     memset(clk_setup, 0, sizeof(clk_setup));
 
     /* init CPUs */
-    s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
-                      &clk_setup[PPC405EP_CPU_CLK],
-                      &tlb_clk_setup, s->sysclk);
-    env = &s->cpu->env;
-    clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
-    clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
+    if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
+        return;
+    }
+    qemu_register_reset(ppc4xx_reset, &s->cpu);
+
+    env = &s->cpu.env;
+
+    clk_setup[PPC405EP_CPU_CLK].cb =
+        ppc_40x_timers_init(env, s->sysclk, PPC_INTERRUPT_PIT);
+    clk_setup[PPC405EP_CPU_CLK].opaque = env;
+
+    ppc_dcr_init(env, NULL, NULL);
 
     /* CPU control */
     ppc405ep_cpc_init(env, clk_setup, s->sysclk);
@@ -1475,16 +1489,16 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     /* Universal interrupt controller */
     s->uic = qdev_new(TYPE_PPC_UIC);
 
-    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(s->cpu),
+    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
                              &error_fatal);
     if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
         return;
     }
 
     sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
-                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_INT));
+                       qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
     sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
-                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_CINT));
+                       qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
     /* SDRAM controller */
     /* XXX 405EP has no ECC interrupt */
@@ -1572,6 +1586,7 @@ static const TypeInfo ppc405_types[] = {
         .name           = TYPE_PPC405_SOC,
         .parent         = TYPE_DEVICE,
         .instance_size  = sizeof(Ppc405SoCState),
+        .instance_init  = ppc405_soc_instance_init,
         .class_init     = ppc405_soc_class_init,
     }
 };
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 737c0896b4f8..f20098cf417c 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -37,7 +37,7 @@
 #include "qapi/error.h"
 #include "trace.h"
 
-static void ppc4xx_reset(void *opaque)
+void ppc4xx_reset(void *opaque)
 {
     PowerPCCPU *cpu = opaque;
 
-- 
2.37.1



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

* [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (5 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 06/20] ppc/ppc405: QOM'ify CPU Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 17:16   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 08/20] ppc/ppc405: QOM'ify GPT Cédric Le Goater
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Introduce a QOM property "cpu" to initialize the DCR handlers. This is
a pattern that we will reuse for the all other 405 devices needing it.

Now that all clock settings are handled at the CPC level, change the
SoC "sys-clk" property to be an alias on the same property in the CPC
model.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    |  39 +++++++++++++++-
 hw/ppc/ppc405_uc.c | 109 +++++++++++++++++++--------------------------
 2 files changed, 85 insertions(+), 63 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ae64549537c6..88c63774d9ba 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -63,6 +63,43 @@ struct ppc4xx_bd_info_t {
     uint32_t bi_iic_fast[2];
 };
 
+typedef struct Ppc405SoCState Ppc405SoCState;
+
+#define TYPE_PPC405_CPC "ppc405-cpc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
+
+enum {
+    PPC405EP_CPU_CLK   = 0,
+    PPC405EP_PLB_CLK   = 1,
+    PPC405EP_OPB_CLK   = 2,
+    PPC405EP_EBC_CLK   = 3,
+    PPC405EP_MAL_CLK   = 4,
+    PPC405EP_PCI_CLK   = 5,
+    PPC405EP_UART0_CLK = 6,
+    PPC405EP_UART1_CLK = 7,
+    PPC405EP_CLK_NB    = 8,
+};
+
+struct Ppc405CpcState {
+    DeviceState parent_obj;
+
+    PowerPCCPU *cpu;
+
+    uint32_t sysclk;
+    clk_setup_t clk_setup[PPC405EP_CLK_NB];
+    uint32_t boot;
+    uint32_t epctl;
+    uint32_t pllmr[2];
+    uint32_t ucr;
+    uint32_t srr;
+    uint32_t jtagid;
+    uint32_t pci;
+    /* Clock and power management */
+    uint32_t er;
+    uint32_t fr;
+    uint32_t sr;
+};
+
 #define TYPE_PPC405_SOC "ppc405-soc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
 
@@ -79,9 +116,9 @@ struct Ppc405SoCState {
     MemoryRegion *dram_mr;
     hwaddr ram_size;
 
-    uint32_t sysclk;
     PowerPCCPU cpu;
     DeviceState *uic;
+    Ppc405CpcState cpc;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 013dccee898b..32bfc9480bc6 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1178,36 +1178,7 @@ enum {
 #endif
 };
 
-enum {
-    PPC405EP_CPU_CLK   = 0,
-    PPC405EP_PLB_CLK   = 1,
-    PPC405EP_OPB_CLK   = 2,
-    PPC405EP_EBC_CLK   = 3,
-    PPC405EP_MAL_CLK   = 4,
-    PPC405EP_PCI_CLK   = 5,
-    PPC405EP_UART0_CLK = 6,
-    PPC405EP_UART1_CLK = 7,
-    PPC405EP_CLK_NB    = 8,
-};
-
-typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
-struct ppc405ep_cpc_t {
-    uint32_t sysclk;
-    clk_setup_t clk_setup[PPC405EP_CLK_NB];
-    uint32_t boot;
-    uint32_t epctl;
-    uint32_t pllmr[2];
-    uint32_t ucr;
-    uint32_t srr;
-    uint32_t jtagid;
-    uint32_t pci;
-    /* Clock and power management */
-    uint32_t er;
-    uint32_t fr;
-    uint32_t sr;
-};
-
-static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
+static void ppc405ep_compute_clocks(Ppc405CpcState *cpc)
 {
     uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
     uint32_t UART0_clk, UART1_clk;
@@ -1302,10 +1273,9 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
 
 static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
 {
-    ppc405ep_cpc_t *cpc;
+    Ppc405CpcState *cpc = PPC405_CPC(opaque);
     uint32_t ret;
 
-    cpc = opaque;
     switch (dcrn) {
     case PPC405EP_CPC0_BOOT:
         ret = cpc->boot;
@@ -1342,9 +1312,8 @@ static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
 
 static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
 {
-    ppc405ep_cpc_t *cpc;
+    Ppc405CpcState *cpc = PPC405_CPC(opaque);
 
-    cpc = opaque;
     switch (dcrn) {
     case PPC405EP_CPC0_BOOT:
         /* Read-only register */
@@ -1377,9 +1346,9 @@ static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
     }
 }
 
-static void ppc405ep_cpc_reset (void *opaque)
+static void ppc405_cpc_reset(DeviceState *dev)
 {
-    ppc405ep_cpc_t *cpc = opaque;
+    Ppc405CpcState *cpc = PPC405_CPC(dev);
 
     cpc->boot = 0x00000010;     /* Boot from PCI - IIC EEPROM disabled */
     cpc->epctl = 0x00000000;
@@ -1391,21 +1360,24 @@ static void ppc405ep_cpc_reset (void *opaque)
     cpc->er = 0x00000000;
     cpc->fr = 0x00000000;
     cpc->sr = 0x00000000;
+    cpc->jtagid = 0x20267049;
     ppc405ep_compute_clocks(cpc);
 }
 
 /* XXX: sysclk should be between 25 and 100 MHz */
-static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
-                               uint32_t sysclk)
+static void ppc405_cpc_realize(DeviceState *dev, Error **errp)
 {
-    ppc405ep_cpc_t *cpc;
+    Ppc405CpcState *cpc = PPC405_CPC(dev);
+    CPUPPCState *env;
+
+    assert(cpc->cpu);
+
+    env = &cpc->cpu->env;
+
+    cpc->clk_setup[PPC405EP_CPU_CLK].cb =
+        ppc_40x_timers_init(env, cpc->sysclk, PPC_INTERRUPT_PIT);
+    cpc->clk_setup[PPC405EP_CPU_CLK].opaque = env;
 
-    cpc = g_new0(ppc405ep_cpc_t, 1);
-    memcpy(cpc->clk_setup, clk_setup,
-           PPC405EP_CLK_NB * sizeof(clk_setup_t));
-    cpc->jtagid = 0x20267049;
-    cpc->sysclk = sysclk;
-    qemu_register_reset(&ppc405ep_cpc_reset, cpc);
     ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
                      &dcr_read_epcpc, &dcr_write_epcpc);
     ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
@@ -1422,14 +1394,23 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
                      &dcr_read_epcpc, &dcr_write_epcpc);
     ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
                      &dcr_read_epcpc, &dcr_write_epcpc);
-#if 0
-    ppc_dcr_register(env, PPC405EP_CPC0_ER, cpc,
-                     &dcr_read_epcpc, &dcr_write_epcpc);
-    ppc_dcr_register(env, PPC405EP_CPC0_FR, cpc,
-                     &dcr_read_epcpc, &dcr_write_epcpc);
-    ppc_dcr_register(env, PPC405EP_CPC0_SR, cpc,
-                     &dcr_read_epcpc, &dcr_write_epcpc);
-#endif
+}
+
+static Property ppc405_cpc_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405CpcState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_UINT32("sys-clk", Ppc405CpcState, sysclk, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_cpc_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_cpc_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_cpc_reset;
+    device_class_set_props(dc, ppc405_cpc_properties);
 }
 
 static void ppc405_soc_instance_init(Object *obj)
@@ -1438,12 +1419,14 @@ static void ppc405_soc_instance_init(Object *obj)
 
     object_initialize_child(obj, "cpu", &s->cpu,
                             POWERPC_CPU_TYPE_NAME("405ep"));
+
+    object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
+    object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
     Ppc405SoCState *s = PPC405_SOC(dev);
-    clk_setup_t clk_setup[PPC405EP_CLK_NB];
     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
     CPUPPCState *env;
     Error *err = NULL;
@@ -1458,8 +1441,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
                                 &s->sram);
 
-    memset(clk_setup, 0, sizeof(clk_setup));
-
     /* init CPUs */
     if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
         return;
@@ -1468,14 +1449,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 
     env = &s->cpu.env;
 
-    clk_setup[PPC405EP_CPU_CLK].cb =
-        ppc_40x_timers_init(env, s->sysclk, PPC_INTERRUPT_PIT);
-    clk_setup[PPC405EP_CPU_CLK].opaque = env;
-
     ppc_dcr_init(env, NULL, NULL);
 
     /* CPU control */
-    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
+    object_property_set_link(OBJECT(&s->cpc), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!qdev_realize(DEVICE(&s->cpc), NULL, errp)) {
+        return;
+    }
 
     /* PLB arbitrer */
     ppc4xx_plb_init(env);
@@ -1566,7 +1547,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 static Property ppc405_soc_properties[] = {
     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
                      MemoryRegion *),
-    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
     DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
     DEFINE_PROP_END_OF_LIST(),
@@ -1583,6 +1563,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_CPC,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(Ppc405CpcState),
+        .class_init     = ppc405_cpc_class_init,
+    }, {
         .name           = TYPE_PPC405_SOC,
         .parent         = TYPE_DEVICE,
         .instance_size  = sizeof(Ppc405SoCState),
-- 
2.37.1



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

* [PATCH v2 08/20] ppc/ppc405: QOM'ify GPT
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (6 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 09/20] ppc/ppc405: QOM'ify OCM Cédric Le Goater
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 22 ++++++++++++
 hw/ppc/ppc405_uc.c | 90 +++++++++++++++++++++++-----------------------
 2 files changed, 67 insertions(+), 45 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 88c63774d9ba..b8b662c0f7d1 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,27 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* General purpose timers */
+#define TYPE_PPC405_GPT "ppc405-gpt"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT);
+struct Ppc405GptState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+
+    int64_t tb_offset;
+    uint32_t tb_freq;
+    QEMUTimer *timer;
+    qemu_irq irqs[5];
+    uint32_t oe;
+    uint32_t ol;
+    uint32_t im;
+    uint32_t is;
+    uint32_t ie;
+    uint32_t comp[5];
+    uint32_t mask[5];
+};
+
 #define TYPE_PPC405_CPC "ppc405-cpc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
 
@@ -119,6 +140,7 @@ struct Ppc405SoCState {
     PowerPCCPU cpu;
     DeviceState *uic;
     Ppc405CpcState cpc;
+    Ppc405GptState gpt;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 32bfc9480bc6..71efcf087c9a 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -926,34 +926,18 @@ static void ppc405_ocm_init(CPUPPCState *env)
 
 /*****************************************************************************/
 /* General purpose timers */
-typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
-struct ppc4xx_gpt_t {
-    MemoryRegion iomem;
-    int64_t tb_offset;
-    uint32_t tb_freq;
-    QEMUTimer *timer;
-    qemu_irq irqs[5];
-    uint32_t oe;
-    uint32_t ol;
-    uint32_t im;
-    uint32_t is;
-    uint32_t ie;
-    uint32_t comp[5];
-    uint32_t mask[5];
-};
-
-static int ppc4xx_gpt_compare (ppc4xx_gpt_t *gpt, int n)
+static int ppc4xx_gpt_compare(Ppc405GptState *gpt, int n)
 {
     /* XXX: TODO */
     return 0;
 }
 
-static void ppc4xx_gpt_set_output (ppc4xx_gpt_t *gpt, int n, int level)
+static void ppc4xx_gpt_set_output(Ppc405GptState *gpt, int n, int level)
 {
     /* XXX: TODO */
 }
 
-static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_set_outputs(Ppc405GptState *gpt)
 {
     uint32_t mask;
     int i;
@@ -974,7 +958,7 @@ static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
     }
 }
 
-static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_set_irqs(Ppc405GptState *gpt)
 {
     uint32_t mask;
     int i;
@@ -989,14 +973,14 @@ static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
     }
 }
 
-static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_compute_timer(Ppc405GptState *gpt)
 {
     /* XXX: TODO */
 }
 
 static uint64_t ppc4xx_gpt_read(void *opaque, hwaddr addr, unsigned size)
 {
-    ppc4xx_gpt_t *gpt = opaque;
+    Ppc405GptState *gpt = PPC405_GPT(opaque);
     uint32_t ret;
     int idx;
 
@@ -1050,7 +1034,7 @@ static uint64_t ppc4xx_gpt_read(void *opaque, hwaddr addr, unsigned size)
 static void ppc4xx_gpt_write(void *opaque, hwaddr addr, uint64_t value,
                              unsigned size)
 {
-    ppc4xx_gpt_t *gpt = opaque;
+    Ppc405GptState *gpt = PPC405_GPT(opaque);
     int idx;
 
     trace_ppc4xx_gpt_write(addr, size, value);
@@ -1116,20 +1100,18 @@ static const MemoryRegionOps gpt_ops = {
 
 static void ppc4xx_gpt_cb (void *opaque)
 {
-    ppc4xx_gpt_t *gpt;
+    Ppc405GptState *gpt = PPC405_GPT(opaque);
 
-    gpt = opaque;
     ppc4xx_gpt_set_irqs(gpt);
     ppc4xx_gpt_set_outputs(gpt);
     ppc4xx_gpt_compute_timer(gpt);
 }
 
-static void ppc4xx_gpt_reset (void *opaque)
+static void ppc405_gpt_reset(DeviceState *dev)
 {
-    ppc4xx_gpt_t *gpt;
+    Ppc405GptState *gpt = PPC405_GPT(dev);
     int i;
 
-    gpt = opaque;
     timer_del(gpt->timer);
     gpt->oe = 0x00000000;
     gpt->ol = 0x00000000;
@@ -1142,21 +1124,28 @@ static void ppc4xx_gpt_reset (void *opaque)
     }
 }
 
-static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
+static void ppc405_gpt_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_gpt_t *gpt;
+    Ppc405GptState *s = PPC405_GPT(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     int i;
 
-    trace_ppc4xx_gpt_init(base);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, s);
+    memory_region_init_io(&s->iomem, OBJECT(s), &gpt_ops, s, "gpt", 0x0d4);
+    sysbus_init_mmio(sbd, &s->iomem);
 
-    gpt = g_new0(ppc4xx_gpt_t, 1);
-    for (i = 0; i < 5; i++) {
-        gpt->irqs[i] = irqs[i];
+    for (i = 0; i < ARRAY_SIZE(s->irqs); i++) {
+        sysbus_init_irq(sbd, &s->irqs[i]);
     }
-    gpt->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, gpt);
-    memory_region_init_io(&gpt->iomem, NULL, &gpt_ops, gpt, "gpt", 0x0d4);
-    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
-    qemu_register_reset(ppc4xx_gpt_reset, gpt);
+}
+
+static void ppc405_gpt_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_gpt_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_gpt_reset;
 }
 
 /*****************************************************************************/
@@ -1422,14 +1411,17 @@ static void ppc405_soc_instance_init(Object *obj)
 
     object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
     object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
+
+    object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
     Ppc405SoCState *s = PPC405_SOC(dev);
-    qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
+    qemu_irq dma_irqs[4], mal_irqs[4];
     CPUPPCState *env;
     Error *err = NULL;
+    int i;
 
     /* allocate SRAM */
     memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
@@ -1526,12 +1518,15 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     ppc405_ocm_init(env);
 
     /* GPT */
-    gpt_irqs[0] = qdev_get_gpio_in(s->uic, 19);
-    gpt_irqs[1] = qdev_get_gpio_in(s->uic, 20);
-    gpt_irqs[2] = qdev_get_gpio_in(s->uic, 21);
-    gpt_irqs[3] = qdev_get_gpio_in(s->uic, 22);
-    gpt_irqs[4] = qdev_get_gpio_in(s->uic, 23);
-    ppc4xx_gpt_init(0xef600000, gpt_irqs);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, 0xef600000);
+
+    for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), i,
+                           qdev_get_gpio_in(s->uic, 19 + i));
+    }
 
     /* MAL */
     mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
@@ -1563,6 +1558,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_GPT,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc405GptState),
+        .class_init     = ppc405_gpt_class_init,
+    }, {
         .name           = TYPE_PPC405_CPC,
         .parent         = TYPE_DEVICE,
         .instance_size  = sizeof(Ppc405CpcState),
-- 
2.37.1



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

* [PATCH v2 09/20] ppc/ppc405: QOM'ify OCM
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (7 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 08/20] ppc/ppc405: QOM'ify GPT Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 10/20] ppc/ppc405: QOM'ify GPIO Cédric Le Goater
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 18 ++++++++++++
 hw/ppc/ppc405_uc.c | 73 ++++++++++++++++++++++++++++------------------
 2 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index b8b662c0f7d1..3bb59624bb1c 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,23 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* On Chip Memory */
+#define TYPE_PPC405_OCM "ppc405-ocm"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM);
+struct Ppc405OcmState {
+    SysBusDevice parent_obj;
+
+    PowerPCCPU *cpu;
+
+    MemoryRegion ram;
+    MemoryRegion isarc_ram;
+    MemoryRegion dsarc_ram;
+    uint32_t isarc;
+    uint32_t isacntl;
+    uint32_t dsarc;
+    uint32_t dsacntl;
+};
+
 /* General purpose timers */
 #define TYPE_PPC405_GPT "ppc405-gpt"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT);
@@ -141,6 +158,7 @@ struct Ppc405SoCState {
     DeviceState *uic;
     Ppc405CpcState cpc;
     Ppc405GptState gpt;
+    Ppc405OcmState ocm;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 71efcf087c9a..efd81fd77255 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -773,20 +773,9 @@ enum {
     OCM0_DSACNTL = 0x01B,
 };
 
-typedef struct ppc405_ocm_t ppc405_ocm_t;
-struct ppc405_ocm_t {
-    MemoryRegion ram;
-    MemoryRegion isarc_ram;
-    MemoryRegion dsarc_ram;
-    uint32_t isarc;
-    uint32_t isacntl;
-    uint32_t dsarc;
-    uint32_t dsacntl;
-};
-
-static void ocm_update_mappings (ppc405_ocm_t *ocm,
-                                 uint32_t isarc, uint32_t isacntl,
-                                 uint32_t dsarc, uint32_t dsacntl)
+static void ocm_update_mappings(Ppc405OcmState *ocm,
+                                uint32_t isarc, uint32_t isacntl,
+                                uint32_t dsarc, uint32_t dsacntl)
 {
     trace_ocm_update_mappings(isarc, isacntl, dsarc, dsacntl, ocm->isarc,
                               ocm->isacntl, ocm->dsarc, ocm->dsacntl);
@@ -830,10 +819,9 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 
 static uint32_t dcr_read_ocm (void *opaque, int dcrn)
 {
-    ppc405_ocm_t *ocm;
+    Ppc405OcmState *ocm = PPC405_OCM(opaque);
     uint32_t ret;
 
-    ocm = opaque;
     switch (dcrn) {
     case OCM0_ISARC:
         ret = ocm->isarc;
@@ -857,10 +845,9 @@ static uint32_t dcr_read_ocm (void *opaque, int dcrn)
 
 static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
 {
-    ppc405_ocm_t *ocm;
+    Ppc405OcmState *ocm = PPC405_OCM(opaque);
     uint32_t isarc, dsarc, isacntl, dsacntl;
 
-    ocm = opaque;
     isarc = ocm->isarc;
     dsarc = ocm->dsarc;
     isacntl = ocm->isacntl;
@@ -886,12 +873,11 @@ static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
     ocm->dsacntl = dsacntl;
 }
 
-static void ocm_reset (void *opaque)
+static void ppc405_ocm_reset(DeviceState *dev)
 {
-    ppc405_ocm_t *ocm;
+    Ppc405OcmState *ocm = PPC405_OCM(dev);
     uint32_t isarc, dsarc, isacntl, dsacntl;
 
-    ocm = opaque;
     isarc = 0x00000000;
     isacntl = 0x00000000;
     dsarc = 0x00000000;
@@ -903,17 +889,21 @@ static void ocm_reset (void *opaque)
     ocm->dsacntl = dsacntl;
 }
 
-static void ppc405_ocm_init(CPUPPCState *env)
+static void ppc405_ocm_realize(DeviceState *dev, Error **errp)
 {
-    ppc405_ocm_t *ocm;
+    Ppc405OcmState *ocm = PPC405_OCM(dev);
+    CPUPPCState *env;
+
+    assert(ocm->cpu);
+
+    env = &ocm->cpu->env;
 
-    ocm = g_new0(ppc405_ocm_t, 1);
     /* XXX: Size is 4096 or 0x04000000 */
-    memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4 * KiB,
+    memory_region_init_ram(&ocm->isarc_ram, OBJECT(ocm), "ppc405.ocm", 4 * KiB,
                            &error_fatal);
-    memory_region_init_alias(&ocm->dsarc_ram, NULL, "ppc405.dsarc",
+    memory_region_init_alias(&ocm->dsarc_ram, OBJECT(ocm), "ppc405.dsarc",
                              &ocm->isarc_ram, 0, 4 * KiB);
-    qemu_register_reset(&ocm_reset, ocm);
+
     ppc_dcr_register(env, OCM0_ISARC,
                      ocm, &dcr_read_ocm, &dcr_write_ocm);
     ppc_dcr_register(env, OCM0_ISACNTL,
@@ -924,6 +914,22 @@ static void ppc405_ocm_init(CPUPPCState *env)
                      ocm, &dcr_read_ocm, &dcr_write_ocm);
 }
 
+static Property ppc405_ocm_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405OcmState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_ocm_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_ocm_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_ocm_reset;
+    device_class_set_props(dc, ppc405_ocm_properties);
+}
+
 /*****************************************************************************/
 /* General purpose timers */
 static int ppc4xx_gpt_compare(Ppc405GptState *gpt, int n)
@@ -1413,6 +1419,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
 
     object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT);
+
+    object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1515,7 +1523,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     }
 
     /* OCM */
-    ppc405_ocm_init(env);
+    object_property_set_link(OBJECT(&s->ocm), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ocm), errp)) {
+        return;
+    }
 
     /* GPT */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt), errp)) {
@@ -1558,6 +1570,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_OCM,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc405OcmState),
+        .class_init     = ppc405_ocm_class_init,
+    }, {
         .name           = TYPE_PPC405_GPT,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc405GptState),
-- 
2.37.1



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

* [PATCH v2 10/20] ppc/ppc405: QOM'ify GPIO
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (8 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 09/20] ppc/ppc405: QOM'ify OCM Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 11/20] ppc/ppc405: QOM'ify DMA Cédric Le Goater
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 21 +++++++++++++++++++
 hw/ppc/ppc405_uc.c | 50 +++++++++++++++++++++-------------------------
 2 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 3bb59624bb1c..36f6fd45217e 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,26 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* GPIO */
+#define TYPE_PPC405_GPIO "ppc405-gpio"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GpioState, PPC405_GPIO);
+struct Ppc405GpioState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion io;
+    uint32_t or;
+    uint32_t tcr;
+    uint32_t osrh;
+    uint32_t osrl;
+    uint32_t tsrh;
+    uint32_t tsrl;
+    uint32_t odr;
+    uint32_t ir;
+    uint32_t rr1;
+    uint32_t isr1h;
+    uint32_t isr1l;
+};
+
 /* On Chip Memory */
 #define TYPE_PPC405_OCM "ppc405-ocm"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM);
@@ -159,6 +179,7 @@ struct Ppc405SoCState {
     Ppc405CpcState cpc;
     Ppc405GptState gpt;
     Ppc405OcmState ocm;
+    Ppc405GpioState gpio;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index efd81fd77255..bd018804594a 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -713,23 +713,6 @@ static void ppc405_dma_init(CPUPPCState *env, qemu_irq irqs[4])
 }
 
 /*****************************************************************************/
-/* GPIO */
-typedef struct ppc405_gpio_t ppc405_gpio_t;
-struct ppc405_gpio_t {
-    MemoryRegion io;
-    uint32_t or;
-    uint32_t tcr;
-    uint32_t osrh;
-    uint32_t osrl;
-    uint32_t tsrh;
-    uint32_t tsrl;
-    uint32_t odr;
-    uint32_t ir;
-    uint32_t rr1;
-    uint32_t isr1h;
-    uint32_t isr1l;
-};
-
 static uint64_t ppc405_gpio_read(void *opaque, hwaddr addr, unsigned size)
 {
     trace_ppc405_gpio_read(addr, size);
@@ -748,20 +731,22 @@ static const MemoryRegionOps ppc405_gpio_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void ppc405_gpio_reset (void *opaque)
+static void ppc405_gpio_realize(DeviceState *dev, Error **errp)
 {
+    Ppc405GpioState *s = PPC405_GPIO(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    memory_region_init_io(&s->io, OBJECT(s), &ppc405_gpio_ops, s, "gpio",
+                          0x038);
+    sysbus_init_mmio(sbd, &s->io);
 }
 
-static void ppc405_gpio_init(hwaddr base)
+static void ppc405_gpio_class_init(ObjectClass *oc, void *data)
 {
-    ppc405_gpio_t *gpio;
-
-    trace_ppc405_gpio_init(base);
+    DeviceClass *dc = DEVICE_CLASS(oc);
 
-    gpio = g_new0(ppc405_gpio_t, 1);
-    memory_region_init_io(&gpio->io, NULL, &ppc405_gpio_ops, gpio, "pgio", 0x038);
-    memory_region_add_subregion(get_system_memory(), base, &gpio->io);
-    qemu_register_reset(&ppc405_gpio_reset, gpio);
+    dc->realize = ppc405_gpio_realize;
+    dc->user_creatable = false;
 }
 
 /*****************************************************************************/
@@ -1421,6 +1406,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT);
 
     object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
+
+    object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1505,8 +1492,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     /* I2C controller */
     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
                          qdev_get_gpio_in(s->uic, 2));
+
     /* GPIO */
-    ppc405_gpio_init(0xef600700);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, 0xef600700);
 
     /* Serial ports */
     if (serial_hd(0) != NULL) {
@@ -1570,6 +1561,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_GPIO,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc405GpioState),
+        .class_init     = ppc405_gpio_class_init,
+    }, {
         .name           = TYPE_PPC405_OCM,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc405OcmState),
-- 
2.37.1



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

* [PATCH v2 11/20] ppc/ppc405: QOM'ify DMA
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (9 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 10/20] ppc/ppc405: QOM'ify GPIO Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC Cédric Le Goater
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 23 +++++++++++++
 hw/ppc/ppc405_uc.c | 80 +++++++++++++++++++++++++++++-----------------
 2 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 36f6fd45217e..1da34a7f10f3 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,28 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+
+
+/* DMA controller */
+#define TYPE_PPC405_DMA "ppc405-dma"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405DmaState, PPC405_DMA);
+struct Ppc405DmaState {
+    SysBusDevice parent_obj;
+
+    PowerPCCPU *cpu;
+
+    qemu_irq irqs[4];
+    uint32_t cr[4];
+    uint32_t ct[4];
+    uint32_t da[4];
+    uint32_t sa[4];
+    uint32_t sg[4];
+    uint32_t sr;
+    uint32_t sgc;
+    uint32_t slp;
+    uint32_t pol;
+};
+
 /* GPIO */
 #define TYPE_PPC405_GPIO "ppc405-gpio"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GpioState, PPC405_GPIO);
@@ -180,6 +202,7 @@ struct Ppc405SoCState {
     Ppc405GptState gpt;
     Ppc405OcmState ocm;
     Ppc405GpioState gpio;
+    Ppc405DmaState dma;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index bd018804594a..6bd93c1cb90c 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -613,35 +613,20 @@ enum {
     DMA0_POL = 0x126,
 };
 
-typedef struct ppc405_dma_t ppc405_dma_t;
-struct ppc405_dma_t {
-    qemu_irq irqs[4];
-    uint32_t cr[4];
-    uint32_t ct[4];
-    uint32_t da[4];
-    uint32_t sa[4];
-    uint32_t sg[4];
-    uint32_t sr;
-    uint32_t sgc;
-    uint32_t slp;
-    uint32_t pol;
-};
-
-static uint32_t dcr_read_dma (void *opaque, int dcrn)
+static uint32_t dcr_read_dma(void *opaque, int dcrn)
 {
     return 0;
 }
 
-static void dcr_write_dma (void *opaque, int dcrn, uint32_t val)
+static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
 {
 }
 
-static void ppc405_dma_reset (void *opaque)
+static void ppc405_dma_reset(DeviceState *dev)
 {
-    ppc405_dma_t *dma;
+    Ppc405DmaState *dma = PPC405_DMA(dev);
     int i;
 
-    dma = opaque;
     for (i = 0; i < 4; i++) {
         dma->cr[i] = 0x00000000;
         dma->ct[i] = 0x00000000;
@@ -655,13 +640,20 @@ static void ppc405_dma_reset (void *opaque)
     dma->pol = 0x00000000;
 }
 
-static void ppc405_dma_init(CPUPPCState *env, qemu_irq irqs[4])
+static void ppc405_dma_realize(DeviceState *dev, Error **errp)
 {
-    ppc405_dma_t *dma;
+    Ppc405DmaState *dma = PPC405_DMA(dev);
+    CPUPPCState *env;
+    int i;
+
+    assert(dma->cpu);
+
+    env = &dma->cpu->env;
+
+    for (i = 0; i < ARRAY_SIZE(dma->irqs); i++) {
+        sysbus_init_irq(SYS_BUS_DEVICE(dma), &dma->irqs[i]);
+    }
 
-    dma = g_new0(ppc405_dma_t, 1);
-    memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
-    qemu_register_reset(&ppc405_dma_reset, dma);
     ppc_dcr_register(env, DMA0_CR0,
                      dma, &dcr_read_dma, &dcr_write_dma);
     ppc_dcr_register(env, DMA0_CT0,
@@ -712,6 +704,22 @@ static void ppc405_dma_init(CPUPPCState *env, qemu_irq irqs[4])
                      dma, &dcr_read_dma, &dcr_write_dma);
 }
 
+static Property ppc405_dma_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405DmaState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_dma_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_dma_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_dma_reset;
+    device_class_set_props(dc, ppc405_dma_properties);
+}
+
 /*****************************************************************************/
 static uint64_t ppc405_gpio_read(void *opaque, hwaddr addr, unsigned size)
 {
@@ -1408,12 +1416,14 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
 
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
+
+    object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
     Ppc405SoCState *s = PPC405_SOC(dev);
-    qemu_irq dma_irqs[4], mal_irqs[4];
+    qemu_irq mal_irqs[4];
     CPUPPCState *env;
     Error *err = NULL;
     int i;
@@ -1483,11 +1493,16 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     ppc405_ebc_init(env);
 
     /* DMA controller */
-    dma_irqs[0] = qdev_get_gpio_in(s->uic, 5);
-    dma_irqs[1] = qdev_get_gpio_in(s->uic, 6);
-    dma_irqs[2] = qdev_get_gpio_in(s->uic, 7);
-    dma_irqs[3] = qdev_get_gpio_in(s->uic, 8);
-    ppc405_dma_init(env, dma_irqs);
+    object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->dma), errp)) {
+        return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
+                           qdev_get_gpio_in(s->uic, 5 + i));
+    }
 
     /* I2C controller */
     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
@@ -1561,6 +1576,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_DMA,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc405DmaState),
+        .class_init     = ppc405_dma_class_init,
+    }, {
         .name           = TYPE_PPC405_GPIO,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc405GpioState),
-- 
2.37.1



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

* [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (10 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 11/20] ppc/ppc405: QOM'ify DMA Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 23:04   ` BALATON Zoltan
  2022-08-03 23:36   ` Daniel Henrique Barboza
  2022-08-03 13:28 ` [PATCH v2 13/20] ppc/ppc405: QOM'ify OPBA Cédric Le Goater
                   ` (8 subsequent siblings)
  20 siblings, 2 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 16 +++++++++++
 hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 1da34a7f10f3..1c7fe07b8084 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* Peripheral controller */
+#define TYPE_PPC405_EBC "ppc405-ebc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
+struct Ppc405EbcState {
+    DeviceState parent_obj;
+
+    PowerPCCPU *cpu;
 
+    uint32_t addr;
+    uint32_t bcr[8];
+    uint32_t bap[8];
+    uint32_t bear;
+    uint32_t besr0;
+    uint32_t besr1;
+    uint32_t cfg;
+};
 
 /* DMA controller */
 #define TYPE_PPC405_DMA "ppc405-dma"
@@ -203,6 +218,7 @@ struct Ppc405SoCState {
     Ppc405OcmState ocm;
     Ppc405GpioState gpio;
     Ppc405DmaState dma;
+    Ppc405EbcState ebc;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 6bd93c1cb90c..0166f3fc36da 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
 
 /*****************************************************************************/
 /* Peripheral controller */
-typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
-struct ppc4xx_ebc_t {
-    uint32_t addr;
-    uint32_t bcr[8];
-    uint32_t bap[8];
-    uint32_t bear;
-    uint32_t besr0;
-    uint32_t besr1;
-    uint32_t cfg;
-};
-
 enum {
     EBC0_CFGADDR = 0x012,
     EBC0_CFGDATA = 0x013,
@@ -411,10 +400,9 @@ enum {
 
 static uint32_t dcr_read_ebc (void *opaque, int dcrn)
 {
-    ppc4xx_ebc_t *ebc;
+    Ppc405EbcState *ebc = PPC405_EBC(opaque);
     uint32_t ret;
 
-    ebc = opaque;
     switch (dcrn) {
     case EBC0_CFGADDR:
         ret = ebc->addr;
@@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
 
 static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
 {
-    ppc4xx_ebc_t *ebc;
+    Ppc405EbcState *ebc = PPC405_EBC(opaque);
 
-    ebc = opaque;
     switch (dcrn) {
     case EBC0_CFGADDR:
         ebc->addr = val;
@@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
     }
 }
 
-static void ebc_reset (void *opaque)
+static void ppc405_ebc_reset(DeviceState *dev)
 {
-    ppc4xx_ebc_t *ebc;
+    Ppc405EbcState *ebc = PPC405_EBC(dev);
     int i;
 
-    ebc = opaque;
     ebc->addr = 0x00000000;
     ebc->bap[0] = 0x7F8FFE80;
     ebc->bcr[0] = 0xFFE28000;
@@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
     ebc->cfg = 0x80400000;
 }
 
-void ppc405_ebc_init(CPUPPCState *env)
+static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_ebc_t *ebc;
+    Ppc405EbcState *ebc = PPC405_EBC(dev);
+    CPUPPCState *env;
+
+    assert(ebc->cpu);
+
+    env = &ebc->cpu->env;
 
-    ebc = g_new0(ppc4xx_ebc_t, 1);
-    qemu_register_reset(&ebc_reset, ebc);
     ppc_dcr_register(env, EBC0_CFGADDR,
                      ebc, &dcr_read_ebc, &dcr_write_ebc);
     ppc_dcr_register(env, EBC0_CFGDATA,
                      ebc, &dcr_read_ebc, &dcr_write_ebc);
 }
 
+static Property ppc405_ebc_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_ebc_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_ebc_reset;
+    device_class_set_props(dc, ppc405_ebc_properties);
+}
+
+void ppc405_ebc_init(CPUPPCState *env)
+{
+    PowerPCCPU *cpu = env_archcpu(env);
+    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
+
+    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+    qdev_realize_and_unref(dev, NULL, &error_fatal);
+}
+
 /*****************************************************************************/
 /* DMA controller */
 enum {
@@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
 
     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
+
+    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
                       s->ram_bases, s->ram_sizes, s->do_dram_init);
 
     /* External bus controller */
-    ppc405_ebc_init(env);
+    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
+        return;
+    }
 
     /* DMA controller */
     object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
@@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_EBC,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(Ppc405EbcState),
+        .class_init     = ppc405_ebc_class_init,
+    }, {
         .name           = TYPE_PPC405_DMA,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc405DmaState),
-- 
2.37.1



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

* [PATCH v2 13/20] ppc/ppc405: QOM'ify OPBA
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (11 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 14/20] ppc/ppc405: QOM'ify POB Cédric Le Goater
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 12 ++++++++++++
 hw/ppc/ppc405_uc.c | 47 +++++++++++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 1c7fe07b8084..808662d81599 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,17 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* OPB arbitrer */
+#define TYPE_PPC405_OPBA "ppc405-opba"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA);
+struct Ppc405OpbaState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion io;
+    uint8_t cr;
+    uint8_t pr;
+};
+
 /* Peripheral controller */
 #define TYPE_PPC405_EBC "ppc405-ebc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
@@ -219,6 +230,7 @@ struct Ppc405SoCState {
     Ppc405GpioState gpio;
     Ppc405DmaState dma;
     Ppc405EbcState ebc;
+    Ppc405OpbaState opba;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0166f3fc36da..04f7af0f8f09 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -310,16 +310,10 @@ static void ppc4xx_pob_init(CPUPPCState *env)
 
 /*****************************************************************************/
 /* OPB arbitrer */
-typedef struct ppc4xx_opba_t ppc4xx_opba_t;
-struct ppc4xx_opba_t {
-    MemoryRegion io;
-    uint8_t cr;
-    uint8_t pr;
-};
 
 static uint64_t opba_readb(void *opaque, hwaddr addr, unsigned size)
 {
-    ppc4xx_opba_t *opba = opaque;
+    Ppc405OpbaState *opba = PPC405_OPBA(opaque);
     uint32_t ret;
 
     switch (addr) {
@@ -341,7 +335,7 @@ static uint64_t opba_readb(void *opaque, hwaddr addr, unsigned size)
 static void opba_writeb(void *opaque, hwaddr addr, uint64_t value,
                         unsigned size)
 {
-    ppc4xx_opba_t *opba = opaque;
+    Ppc405OpbaState *opba = PPC405_OPBA(opaque);
 
     trace_opba_writeb(addr, value);
 
@@ -366,25 +360,30 @@ static const MemoryRegionOps opba_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void ppc4xx_opba_reset (void *opaque)
+static void ppc405_opba_reset(DeviceState *dev)
 {
-    ppc4xx_opba_t *opba;
+    Ppc405OpbaState *opba = PPC405_OPBA(dev);
 
-    opba = opaque;
     opba->cr = 0x00; /* No dynamic priorities - park disabled */
     opba->pr = 0x11;
 }
 
-static void ppc4xx_opba_init(hwaddr base)
+static void ppc405_opba_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_opba_t *opba;
+    Ppc405OpbaState *s = PPC405_OPBA(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-    trace_opba_init(base);
+    memory_region_init_io(&s->io, OBJECT(s), &opba_ops, s, "opba", 0x002);
+    sysbus_init_mmio(sbd, &s->io);
+}
+
+static void ppc405_opba_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
 
-    opba = g_new0(ppc4xx_opba_t, 1);
-    memory_region_init_io(&opba->io, NULL, &opba_ops, opba, "opba", 0x002);
-    memory_region_add_subregion(get_system_memory(), base, &opba->io);
-    qemu_register_reset(ppc4xx_opba_reset, opba);
+    dc->realize = ppc405_opba_realize;
+    dc->reset = ppc405_opba_reset;
+    dc->user_creatable = false;
 }
 
 /*****************************************************************************/
@@ -1434,6 +1433,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 
     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
+
+    object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1478,7 +1479,10 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     ppc4xx_pob_init(env);
 
     /* OBP arbitrer */
-    ppc4xx_opba_init(0xef600600);
+   if (!sysbus_realize(SYS_BUS_DEVICE(&s->opba), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
 
     /* Universal interrupt controller */
     s->uic = qdev_new(TYPE_PPC_UIC);
@@ -1596,6 +1600,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_OPBA,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc405OpbaState),
+        .class_init     = ppc405_opba_class_init,
+    }, {
         .name           = TYPE_PPC405_EBC,
         .parent         = TYPE_DEVICE,
         .instance_size  = sizeof(Ppc405EbcState),
-- 
2.37.1



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

* [PATCH v2 14/20] ppc/ppc405: QOM'ify POB
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (12 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 13/20] ppc/ppc405: QOM'ify OPBA Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB Cédric Le Goater
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 14 +++++++++++
 hw/ppc/ppc405_uc.c | 58 +++++++++++++++++++++++++++++++---------------
 2 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 808662d81599..8acb90427596 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,19 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* PLB to OPB bridge */
+#define TYPE_PPC405_POB "ppc405-pob"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
+struct Ppc405PobState {
+    DeviceState parent_obj;
+
+    PowerPCCPU *cpu;
+
+    uint32_t bear;
+    uint32_t besr0;
+    uint32_t besr1;
+};
+
 /* OPB arbitrer */
 #define TYPE_PPC405_OPBA "ppc405-opba"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA);
@@ -231,6 +244,7 @@ struct Ppc405SoCState {
     Ppc405DmaState dma;
     Ppc405EbcState ebc;
     Ppc405OpbaState opba;
+    Ppc405PobState pob;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 04f7af0f8f09..ca214ee4d741 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -234,19 +234,11 @@ enum {
     POB0_BEAR  = 0x0A4,
 };
 
-typedef struct ppc4xx_pob_t ppc4xx_pob_t;
-struct ppc4xx_pob_t {
-    uint32_t bear;
-    uint32_t besr0;
-    uint32_t besr1;
-};
-
 static uint32_t dcr_read_pob (void *opaque, int dcrn)
 {
-    ppc4xx_pob_t *pob;
+    Ppc405PobState *pob = PPC405_POB(opaque);
     uint32_t ret;
 
-    pob = opaque;
     switch (dcrn) {
     case POB0_BEAR:
         ret = pob->bear;
@@ -268,9 +260,8 @@ static uint32_t dcr_read_pob (void *opaque, int dcrn)
 
 static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)
 {
-    ppc4xx_pob_t *pob;
+    Ppc405PobState *pob = PPC405_POB(opaque);
 
-    pob = opaque;
     switch (dcrn) {
     case POB0_BEAR:
         /* Read only */
@@ -286,26 +277,44 @@ static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)
     }
 }
 
-static void ppc4xx_pob_reset (void *opaque)
+static void ppc405_pob_reset(DeviceState *dev)
 {
-    ppc4xx_pob_t *pob;
+    Ppc405PobState *pob = PPC405_POB(dev);
 
-    pob = opaque;
     /* No error */
     pob->bear = 0x00000000;
     pob->besr0 = 0x0000000;
     pob->besr1 = 0x0000000;
 }
 
-static void ppc4xx_pob_init(CPUPPCState *env)
+static void ppc405_pob_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_pob_t *pob;
+    Ppc405PobState *pob = PPC405_POB(dev);
+    CPUPPCState *env;
+
+    assert(pob->cpu);
+
+    env = &pob->cpu->env;
 
-    pob = g_new0(ppc4xx_pob_t, 1);
     ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
     ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
     ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
-    qemu_register_reset(ppc4xx_pob_reset, pob);
+}
+
+static Property ppc405_pob_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405PobState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_pob_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_pob_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_pob_reset;
+    device_class_set_props(dc, ppc405_pob_properties);
 }
 
 /*****************************************************************************/
@@ -1435,6 +1444,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 
     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
+
+    object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1476,7 +1487,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     ppc4xx_plb_init(env);
 
     /* PLB to OPB bridge */
-    ppc4xx_pob_init(env);
+    object_property_set_link(OBJECT(&s->pob), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!qdev_realize(DEVICE(&s->pob), NULL, errp)) {
+        return;
+    }
 
     /* OBP arbitrer */
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->opba), errp)) {
@@ -1600,6 +1615,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_POB,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(Ppc405PobState),
+        .class_init     = ppc405_pob_class_init,
+    }, {
         .name           = TYPE_PPC405_OPBA,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc405OpbaState),
-- 
2.37.1



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

* [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (13 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 14/20] ppc/ppc405: QOM'ify POB Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 23:38   ` Daniel Henrique Barboza
  2022-08-03 13:28 ` [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL Cédric Le Goater
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    | 14 ++++++++++
 hw/ppc/ppc405_uc.c | 67 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 8acb90427596..8ca32f35ce67 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,19 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* Peripheral local bus arbitrer */
+#define TYPE_PPC405_PLB "ppc405-plb"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PlbState, PPC405_PLB);
+struct Ppc405PlbState {
+    DeviceState parent_obj;
+
+    PowerPCCPU *cpu;
+
+    uint32_t acr;
+    uint32_t bear;
+    uint32_t besr;
+};
+
 /* PLB to OPB bridge */
 #define TYPE_PPC405_POB "ppc405-pob"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
@@ -245,6 +258,7 @@ struct Ppc405SoCState {
     Ppc405EbcState ebc;
     Ppc405OpbaState opba;
     Ppc405PobState pob;
+    Ppc405PlbState plb;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index ca214ee4d741..9bbd524ad5ea 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -148,19 +148,11 @@ enum {
     PLB4A1_ACR = 0x089,
 };
 
-typedef struct ppc4xx_plb_t ppc4xx_plb_t;
-struct ppc4xx_plb_t {
-    uint32_t acr;
-    uint32_t bear;
-    uint32_t besr;
-};
-
 static uint32_t dcr_read_plb (void *opaque, int dcrn)
 {
-    ppc4xx_plb_t *plb;
+    Ppc405PlbState *plb = PPC405_PLB(opaque);
     uint32_t ret;
 
-    plb = opaque;
     switch (dcrn) {
     case PLB0_ACR:
         ret = plb->acr;
@@ -182,9 +174,8 @@ static uint32_t dcr_read_plb (void *opaque, int dcrn)
 
 static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
 {
-    ppc4xx_plb_t *plb;
+    Ppc405PlbState *plb = PPC405_PLB(opaque);
 
-    plb = opaque;
     switch (dcrn) {
     case PLB0_ACR:
         /* We don't care about the actual parameters written as
@@ -202,28 +193,55 @@ static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
     }
 }
 
-static void ppc4xx_plb_reset (void *opaque)
+static void ppc405_plb_reset(DeviceState *dev)
 {
-    ppc4xx_plb_t *plb;
+    Ppc405PlbState *plb = PPC405_PLB(dev);
 
-    plb = opaque;
     plb->acr = 0x00000000;
     plb->bear = 0x00000000;
     plb->besr = 0x00000000;
 }
 
-void ppc4xx_plb_init(CPUPPCState *env)
+static void ppc405_plb_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_plb_t *plb;
+    Ppc405PlbState *plb = PPC405_PLB(dev);
+    CPUPPCState *env;
+
+    assert(plb->cpu);
+
+    env = &plb->cpu->env;
 
-    plb = g_new0(ppc4xx_plb_t, 1);
     ppc_dcr_register(env, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
-    qemu_register_reset(ppc4xx_plb_reset, plb);
+}
+
+static Property ppc405_plb_properties[] = {
+    DEFINE_PROP_LINK("cpu", Ppc405PlbState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_plb_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc405_plb_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc405_plb_reset;
+    device_class_set_props(dc, ppc405_plb_properties);
+}
+
+void ppc4xx_plb_init(CPUPPCState *env)
+{
+    PowerPCCPU *cpu = env_archcpu(env);
+    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
+
+    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+    qdev_realize_and_unref(dev, NULL, &error_fatal);
 }
 
 /*****************************************************************************/
@@ -1446,6 +1464,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
 
     object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
+
+    object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1484,7 +1504,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     }
 
     /* PLB arbitrer */
-    ppc4xx_plb_init(env);
+    object_property_set_link(OBJECT(&s->plb), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!qdev_realize(DEVICE(&s->plb), NULL, errp)) {
+        return;
+    }
 
     /* PLB to OPB bridge */
     object_property_set_link(OBJECT(&s->pob), "cpu", OBJECT(&s->cpu),
@@ -1615,6 +1639,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc405_types[] = {
     {
+        .name           = TYPE_PPC405_PLB,
+        .parent         = TYPE_DEVICE,
+        .instance_size  = sizeof(Ppc405PlbState),
+        .class_init     = ppc405_plb_class_init,
+    }, {
         .name           = TYPE_PPC405_POB,
         .parent         = TYPE_DEVICE,
         .instance_size  = sizeof(Ppc405PobState),
-- 
2.37.1



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

* [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (14 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 23:45   ` Daniel Henrique Barboza
  2022-08-03 13:28 ` [PATCH v2 17/20] ppc/ppc405: QOM'ify FPGA Cédric Le Goater
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h         |   1 +
 include/hw/ppc/ppc4xx.h |  28 ++++++++++
 hw/ppc/ppc405_uc.c      |  20 +++++--
 hw/ppc/ppc4xx_devs.c    | 120 +++++++++++++++++++++++++---------------
 4 files changed, 118 insertions(+), 51 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 8ca32f35ce67..7d585a244d18 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -259,6 +259,7 @@ struct Ppc405SoCState {
     Ppc405OpbaState opba;
     Ppc405PobState pob;
     Ppc405PlbState plb;
+    Ppc4xxMalState mal;
 };
 
 /* PowerPC 405 core */
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index 021376c2d260..c31219265273 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -26,6 +26,7 @@
 #define PPC4XX_H
 
 #include "hw/ppc/ppc.h"
+#include "hw/sysbus.h"
 #include "exec/memory.h"
 
 /* PowerPC 4xx core initialization */
@@ -45,6 +46,33 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
                         hwaddr *ram_sizes,
                         int do_init);
 
+/* Memory Access Layer (MAL) */
+#define TYPE_PPC4xx_MAL "ppc4xx-mal"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxMalState, PPC4xx_MAL);
+struct Ppc4xxMalState {
+    SysBusDevice parent_obj;
+
+    PowerPCCPU *cpu;
+
+    qemu_irq irqs[4];
+    uint32_t cfg;
+    uint32_t esr;
+    uint32_t ier;
+    uint32_t txcasr;
+    uint32_t txcarr;
+    uint32_t txeobisr;
+    uint32_t txdeir;
+    uint32_t rxcasr;
+    uint32_t rxcarr;
+    uint32_t rxeobisr;
+    uint32_t rxdeir;
+    uint32_t *txctpr;
+    uint32_t *rxctpr;
+    uint32_t *rcbs;
+    uint8_t  txcnum;
+    uint8_t  rxcnum;
+};
+
 void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
                      qemu_irq irqs[4]);
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 9bbd524ad5ea..f39e0b44f9cc 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1466,12 +1466,13 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
 
     object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
+
+    object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
     Ppc405SoCState *s = PPC405_SOC(dev);
-    qemu_irq mal_irqs[4];
     CPUPPCState *env;
     Error *err = NULL;
     int i;
@@ -1610,11 +1611,18 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     }
 
     /* MAL */
-    mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
-    mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
-    mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
-    mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
-    ppc4xx_mal_init(env, 4, 2, mal_irqs);
+    object_property_set_int(OBJECT(&s->mal), "txc-num", 4, &error_abort);
+    object_property_set_int(OBJECT(&s->mal), "rxc-num", 2, &error_abort);
+    object_property_set_link(OBJECT(&s->mal), "cpu", OBJECT(&s->cpu),
+                             &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->mal), errp)) {
+        return;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
+                           qdev_get_gpio_in(s->uic, 11 + i));
+    }
 
     /* Ethernet */
     /* Uses UIC IRQs 9, 15, 17 */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index f20098cf417c..0e97347e2839 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -491,32 +491,10 @@ enum {
     MAL0_RCBS1    = 0x1E1,
 };
 
-typedef struct ppc4xx_mal_t ppc4xx_mal_t;
-struct ppc4xx_mal_t {
-    qemu_irq irqs[4];
-    uint32_t cfg;
-    uint32_t esr;
-    uint32_t ier;
-    uint32_t txcasr;
-    uint32_t txcarr;
-    uint32_t txeobisr;
-    uint32_t txdeir;
-    uint32_t rxcasr;
-    uint32_t rxcarr;
-    uint32_t rxeobisr;
-    uint32_t rxdeir;
-    uint32_t *txctpr;
-    uint32_t *rxctpr;
-    uint32_t *rcbs;
-    uint8_t  txcnum;
-    uint8_t  rxcnum;
-};
-
-static void ppc4xx_mal_reset(void *opaque)
+static void ppc4xx_mal_reset(DeviceState *dev)
 {
-    ppc4xx_mal_t *mal;
+    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
 
-    mal = opaque;
     mal->cfg = 0x0007C000;
     mal->esr = 0x00000000;
     mal->ier = 0x00000000;
@@ -530,10 +508,9 @@ static void ppc4xx_mal_reset(void *opaque)
 
 static uint32_t dcr_read_mal(void *opaque, int dcrn)
 {
-    ppc4xx_mal_t *mal;
+    Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
     uint32_t ret;
 
-    mal = opaque;
     switch (dcrn) {
     case MAL0_CFG:
         ret = mal->cfg;
@@ -587,13 +564,12 @@ static uint32_t dcr_read_mal(void *opaque, int dcrn)
 
 static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
 {
-    ppc4xx_mal_t *mal;
+    Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
 
-    mal = opaque;
     switch (dcrn) {
     case MAL0_CFG:
         if (val & 0x80000000) {
-            ppc4xx_mal_reset(mal);
+            ppc4xx_mal_reset(DEVICE(mal));
         }
         mal->cfg = val & 0x00FFC087;
         break;
@@ -644,23 +620,30 @@ static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
     }
 }
 
-void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
-                     qemu_irq irqs[4])
+static void ppc4xx_mal_realize(DeviceState *dev, Error **errp)
 {
-    ppc4xx_mal_t *mal;
+    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    CPUPPCState *env;
     int i;
 
-    assert(txcnum <= 32 && rxcnum <= 32);
-    mal = g_malloc0(sizeof(*mal));
-    mal->txcnum = txcnum;
-    mal->rxcnum = rxcnum;
-    mal->txctpr = g_new0(uint32_t, txcnum);
-    mal->rxctpr = g_new0(uint32_t, rxcnum);
-    mal->rcbs = g_new0(uint32_t, rxcnum);
-    for (i = 0; i < 4; i++) {
-        mal->irqs[i] = irqs[i];
+    assert(mal->cpu);
+
+    env = &mal->cpu->env;
+
+    if (mal->txcnum > 32 || mal->rxcnum > 32) {
+        error_setg(errp, "invalid TXC/RXC number");
+        return;
     }
-    qemu_register_reset(&ppc4xx_mal_reset, mal);
+
+    mal->txctpr = g_new0(uint32_t, mal->txcnum);
+    mal->rxctpr = g_new0(uint32_t, mal->rxcnum);
+    mal->rcbs = g_new0(uint32_t, mal->rxcnum);
+
+    for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
+        sysbus_init_irq(sbd, &mal->irqs[i]);
+    }
+
     ppc_dcr_register(env, MAL0_CFG,
                      mal, &dcr_read_mal, &dcr_write_mal);
     ppc_dcr_register(env, MAL0_ESR,
@@ -683,16 +666,63 @@ void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
                      mal, &dcr_read_mal, &dcr_write_mal);
     ppc_dcr_register(env, MAL0_RXDEIR,
                      mal, &dcr_read_mal, &dcr_write_mal);
-    for (i = 0; i < txcnum; i++) {
+    for (i = 0; i < mal->txcnum; i++) {
         ppc_dcr_register(env, MAL0_TXCTP0R + i,
                          mal, &dcr_read_mal, &dcr_write_mal);
     }
-    for (i = 0; i < rxcnum; i++) {
+    for (i = 0; i < mal->rxcnum; i++) {
         ppc_dcr_register(env, MAL0_RXCTP0R + i,
                          mal, &dcr_read_mal, &dcr_write_mal);
     }
-    for (i = 0; i < rxcnum; i++) {
+    for (i = 0; i < mal->rxcnum; i++) {
         ppc_dcr_register(env, MAL0_RCBS0 + i,
                          mal, &dcr_read_mal, &dcr_write_mal);
     }
 }
+
+static Property ppc4xx_mal_properties[] = {
+    DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState, txcnum, 0),
+    DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0),
+    DEFINE_PROP_LINK("cpu", Ppc4xxMalState, cpu, TYPE_POWERPC_CPU,
+                     PowerPCCPU *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc4xx_mal_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc4xx_mal_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc4xx_mal_reset;
+    device_class_set_props(dc, ppc4xx_mal_properties);
+}
+
+void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
+                     qemu_irq irqs[4])
+{
+    PowerPCCPU *cpu = env_archcpu(env);
+    DeviceState *dev = qdev_new(TYPE_PPC4xx_MAL);
+    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
+    int i;
+
+    qdev_prop_set_uint32(dev, "txc-num", txcnum);
+    qdev_prop_set_uint32(dev, "rxc-num", rxcnum);
+    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+    qdev_realize_and_unref(dev, NULL, &error_fatal);
+
+    for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irqs[i]);
+    }
+}
+
+static const TypeInfo ppc4xx_types[] = {
+    {
+        .name           = TYPE_PPC4xx_MAL,
+        .parent         = TYPE_SYS_BUS_DEVICE,
+        .instance_size  = sizeof(Ppc4xxMalState),
+        .class_init     = ppc4xx_mal_class_init,
+    }
+};
+
+DEFINE_TYPES(ppc4xx_types)
-- 
2.37.1



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

* [PATCH v2 17/20] ppc/ppc405: QOM'ify FPGA
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (15 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 13:28 ` [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC Cédric Le Goater
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405_boards.c | 55 +++++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 82b51cc457fa..2900c267b7ac 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -71,18 +71,23 @@ OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
  * - NVRAM (0xF0000000)
  * - FPGA  (0xF0300000)
  */
-typedef struct ref405ep_fpga_t ref405ep_fpga_t;
-struct ref405ep_fpga_t {
+
+#define TYPE_PPC405_FPGA "ppc405-fpga"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405FpgaState, PPC405_FPGA);
+struct Ppc405FpgaState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+
     uint8_t reg0;
     uint8_t reg1;
 };
 
 static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
 {
-    ref405ep_fpga_t *fpga;
+    Ppc405FpgaState *fpga = PPC405_FPGA(opaque);
     uint32_t ret;
 
-    fpga = opaque;
     switch (addr) {
     case 0x0:
         ret = fpga->reg0;
@@ -101,9 +106,8 @@ static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
 static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
                                  unsigned size)
 {
-    ref405ep_fpga_t *fpga;
+    Ppc405FpgaState *fpga = PPC405_FPGA(opaque);
 
-    fpga = opaque;
     switch (addr) {
     case 0x0:
         /* Read only */
@@ -126,27 +130,39 @@ static const MemoryRegionOps ref405ep_fpga_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void ref405ep_fpga_reset (void *opaque)
+static void ref405ep_fpga_reset(DeviceState *dev)
 {
-    ref405ep_fpga_t *fpga;
+    Ppc405FpgaState *fpga = PPC405_FPGA(dev);
 
-    fpga = opaque;
     fpga->reg0 = 0x00;
     fpga->reg1 = 0x0F;
 }
 
-static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
+static void ref405ep_fpga_realize(DeviceState *dev, Error **errp)
 {
-    ref405ep_fpga_t *fpga;
-    MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
+    Ppc405FpgaState *s = PPC405_FPGA(dev);
 
-    fpga = g_new0(ref405ep_fpga_t, 1);
-    memory_region_init_io(fpga_memory, NULL, &ref405ep_fpga_ops, fpga,
+    memory_region_init_io(&s->iomem, OBJECT(s), &ref405ep_fpga_ops, s,
                           "fpga", 0x00000100);
-    memory_region_add_subregion(sysmem, base, fpga_memory);
-    qemu_register_reset(&ref405ep_fpga_reset, fpga);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static void ref405ep_fpga_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ref405ep_fpga_realize;
+    dc->user_creatable = false;
+    dc->reset = ref405ep_fpga_reset;
 }
 
+static const TypeInfo ref405ep_fpga_type = {
+    .name = TYPE_PPC405_FPGA,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Ppc405FpgaState),
+    .class_init = ref405ep_fpga_class_init,
+};
+
 /*
  * CPU reset handler when booting directly from a loaded kernel
  */
@@ -325,7 +341,11 @@ static void ref405ep_init(MachineState *machine)
     ppc405_init(machine);
 
     /* Register FPGA */
-    ref405ep_fpga_init(get_system_memory(), PPC405EP_FPGA_BASE);
+    dev = qdev_new(TYPE_PPC405_FPGA);
+    object_property_add_child(OBJECT(machine), "fpga", OBJECT(dev));
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, PPC405EP_FPGA_BASE);
+
     /* Register NVRAM */
     dev = qdev_new("sysbus-m48t08");
     qdev_prop_set_int32(dev, "base-year", 1968);
@@ -370,6 +390,7 @@ static void ppc405_machine_init(void)
 {
     type_register_static(&ppc405_machine_type);
     type_register_static(&ref405ep_type);
+    type_register_static(&ref405ep_fpga_type);
 }
 
 type_init(ppc405_machine_init)
-- 
2.37.1



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

* [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (16 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 17/20] ppc/ppc405: QOM'ify FPGA Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 23:26   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C Cédric Le Goater
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    |  3 ++-
 hw/ppc/ppc405_uc.c | 26 +++++++++++++-------------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 7d585a244d18..d29f738cd2d0 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -27,6 +27,7 @@
 
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
+#include "hw/intc/ppc-uic.h"
 
 #define PPC405EP_SDRAM_BASE 0x00000000
 #define PPC405EP_NVRAM_BASE 0xF0000000
@@ -249,7 +250,7 @@ struct Ppc405SoCState {
     hwaddr ram_size;
 
     PowerPCCPU cpu;
-    DeviceState *uic;
+    PPCUIC uic;
     Ppc405CpcState cpc;
     Ppc405GptState gpt;
     Ppc405OcmState ocm;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index f39e0b44f9cc..5cd32e22b7ea 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1448,6 +1448,8 @@ static void ppc405_soc_instance_init(Object *obj)
     object_initialize_child(obj, "cpu", &s->cpu,
                             POWERPC_CPU_TYPE_NAME("405ep"));
 
+    object_initialize_child(obj, "uic", &s->uic, TYPE_PPC_UIC);
+
     object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
     object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
 
@@ -1525,17 +1527,15 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
 
     /* Universal interrupt controller */
-    s->uic = qdev_new(TYPE_PPC_UIC);
-
-    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
+    object_property_set_link(OBJECT(&s->uic), "cpu", OBJECT(&s->cpu),
                              &error_fatal);
-    if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->uic), errp)) {
         return;
     }
 
-    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_INT,
                        qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
-    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_CINT,
                        qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
     /* SDRAM controller */
@@ -1545,7 +1545,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     s->ram_bases[0] = 0;
     s->ram_sizes[0] = s->ram_size;
 
-    ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17),
+    ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17),
                       ARRAY_SIZE(s->ram_memories), s->ram_memories,
                       s->ram_bases, s->ram_sizes, s->do_dram_init);
 
@@ -1565,12 +1565,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 
     for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
-                           qdev_get_gpio_in(s->uic, 5 + i));
+                           qdev_get_gpio_in(DEVICE(&s->uic), 5 + i));
     }
 
     /* I2C controller */
     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
-                         qdev_get_gpio_in(s->uic, 2));
+                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
 
     /* GPIO */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
@@ -1581,13 +1581,13 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     /* Serial ports */
     if (serial_hd(0) != NULL) {
         serial_mm_init(get_system_memory(), 0xef600300, 0,
-                       qdev_get_gpio_in(s->uic, 0),
+                       qdev_get_gpio_in(DEVICE(&s->uic), 0),
                        PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
                        DEVICE_BIG_ENDIAN);
     }
     if (serial_hd(1) != NULL) {
         serial_mm_init(get_system_memory(), 0xef600400, 0,
-                       qdev_get_gpio_in(s->uic, 1),
+                       qdev_get_gpio_in(DEVICE(&s->uic), 1),
                        PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
                        DEVICE_BIG_ENDIAN);
     }
@@ -1607,7 +1607,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 
     for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), i,
-                           qdev_get_gpio_in(s->uic, 19 + i));
+                           qdev_get_gpio_in(DEVICE(&s->uic), 19 + i));
     }
 
     /* MAL */
@@ -1621,7 +1621,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 
     for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
         sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
-                           qdev_get_gpio_in(s->uic, 11 + i));
+                           qdev_get_gpio_in(DEVICE(&s->uic), 11 + i));
     }
 
     /* Ethernet */
-- 
2.37.1



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

* [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (17 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-03 23:31   ` BALATON Zoltan
  2022-08-03 13:28 ` [PATCH v2 20/20] ppc/ppc4xx: Fix sdram trace events Cédric Le Goater
  2022-08-04  6:07 ` [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Having an explicit I2C model object will help if one day we want to
add I2C devices on the bus.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc405.h    |  2 ++
 hw/ppc/ppc405_uc.c | 10 ++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index d29f738cd2d0..d13624ae309c 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -28,6 +28,7 @@
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
 #include "hw/intc/ppc-uic.h"
+#include "hw/i2c/ppc4xx_i2c.h"
 
 #define PPC405EP_SDRAM_BASE 0x00000000
 #define PPC405EP_NVRAM_BASE 0xF0000000
@@ -256,6 +257,7 @@ struct Ppc405SoCState {
     Ppc405OcmState ocm;
     Ppc405GpioState gpio;
     Ppc405DmaState dma;
+    PPC4xxI2CState i2c;
     Ppc405EbcState ebc;
     Ppc405OpbaState opba;
     Ppc405PobState pob;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 5cd32e22b7ea..8f0caa45f5f7 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
 
     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 
+    object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
+
     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 
     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
@@ -1569,8 +1571,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
     }
 
     /* I2C controller */
-    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
-                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
+                       qdev_get_gpio_in(DEVICE(&s->uic), 2));
 
     /* GPIO */
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
-- 
2.37.1



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

* [PATCH v2 20/20] ppc/ppc4xx: Fix sdram trace events
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (18 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C Cédric Le Goater
@ 2022-08-03 13:28 ` Cédric Le Goater
  2022-08-04  6:07 ` [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
  20 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-03 13:28 UTC (permalink / raw)
  To: qemu-ppc
  Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan,
	Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/ppc4xx_devs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 0e97347e2839..c168b4c6484a 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -175,7 +175,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
     }
     sdram->bcr[i] = bcr & 0xFFDEE001;
     if (enabled && (bcr & 0x00000001)) {
-        trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr));
+        trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
         memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
                            sdram_size(bcr));
         memory_region_add_subregion(&sdram->containers[i], 0,
-- 
2.37.1



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

* Re: [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine
  2022-08-03 13:28 ` [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine Cédric Le Goater
@ 2022-08-03 17:03   ` BALATON Zoltan
  2022-08-03 17:35     ` Daniel Henrique Barboza
  2022-08-03 22:07   ` BALATON Zoltan
  1 sibling, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 17:03 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2528 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> We will use this machine as a base to define the ref405ep and possibly
> the PPC405 hotfoot board as found in the Linux kernel.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405_boards.c | 31 ++++++++++++++++++++++++++++---
> 1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 1a4e7588c584..4c269b6526a5 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -50,6 +50,15 @@
>
> #define USE_FLASH_BIOS
>
> +struct Ppc405MachineState {
> +    /* Private */
> +    MachineState parent_obj;
> +    /* Public */
> +};
> +
> +#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);

In other patches the declaration of the state struct comes after the 
OBJECT_DECLARE macro so here instead of above. It would be better to write 
it like that here too for consistency and also because then the DECLARE 
macro starts the object declaration and everything belonging to the object 
are together below it. Declaring the structure before is kind of outside 
the object, although this is only cosmetic and may be a matter of style.

Regards,
BALATON Zoltan

> +
> /*****************************************************************************/
> /* PPC405EP reference board (IBM) */
> /* Standalone board with:
> @@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void *data)
>
>     mc->desc = "ref405ep";
>     mc->init = ref405ep_init;
> -    mc->default_ram_size = 0x08000000;
> -    mc->default_ram_id = "ef405ep.ram";
> }
>
> static const TypeInfo ref405ep_type = {
>     .name = MACHINE_TYPE_NAME("ref405ep"),
> -    .parent = TYPE_MACHINE,
> +    .parent = TYPE_PPC405_MACHINE,
>     .class_init = ref405ep_class_init,
> };
>
> +static void ppc405_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
> +    mc->desc = "PPC405 generic machine";
> +    mc->default_ram_size = 0x08000000;
> +    mc->default_ram_id = "ppc405.ram";
> +}
> +
> +static const TypeInfo ppc405_machine_type = {
> +    .name = TYPE_PPC405_MACHINE,
> +    .parent = TYPE_MACHINE,
> +    .instance_size = sizeof(Ppc405MachineState),
> +    .class_init = ppc405_machine_class_init,
> +    .abstract = true,
> +};
> +
> static void ppc405_machine_init(void)
> {
> +    type_register_static(&ppc405_machine_type);
>     type_register_static(&ref405ep_type);
> }
>
>

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

* Re: [PATCH v2 01/20] ppc/ppc405: Remove taihu machine
  2022-08-03 13:28 ` [PATCH v2 01/20] ppc/ppc405: Remove taihu machine Cédric Le Goater
@ 2022-08-03 17:16   ` Daniel Henrique Barboza
  0 siblings, 0 replies; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-03 17:16 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan



On 8/3/22 10:28, Cédric Le Goater wrote:
> It has been deprecated since 7.0.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---


Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>

>   docs/about/deprecated.rst       |   9 --
>   docs/about/removed-features.rst |   6 +
>   docs/system/ppc/embedded.rst    |   1 -
>   hw/ppc/ppc405_boards.c          | 232 --------------------------------
>   MAINTAINERS                     |   2 +-
>   5 files changed, 7 insertions(+), 243 deletions(-)
> 
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 7ee26626d5cf..2f9b41aaea48 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -233,15 +233,6 @@ deprecated; use the new name ``dtb-randomness`` instead. The new name
>   better reflects the way this property affects all random data within
>   the device tree blob, not just the ``kaslr-seed`` node.
>   
> -PPC 405 ``taihu`` machine (since 7.0)
> -'''''''''''''''''''''''''''''''''''''
> -
> -The PPC 405 CPU is a system-on-a-chip, so all 405 machines are very similar,
> -except for some external periphery. However, the periphery of the ``taihu``
> -machine is hardly emulated at all (e.g. neither the LCD nor the USB part had
> -been implemented), so there is not much value added by this board. Use the
> -``ref405ep`` machine instead.
> -
>   ``pc-i440fx-1.4`` up to ``pc-i440fx-1.7`` (since 7.0)
>   '''''''''''''''''''''''''''''''''''''''''''''''''''''
>   
> diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
> index c7b9dadd5d63..8fad2f4d5e9b 100644
> --- a/docs/about/removed-features.rst
> +++ b/docs/about/removed-features.rst
> @@ -661,6 +661,12 @@ Aspeed ``swift-bmc`` machine (removed in 7.0)
>   This machine was removed because it was unused. Alternative AST2500 based
>   OpenPOWER machines are ``witherspoon-bmc`` and ``romulus-bmc``.
>   
> +ppc ``taihu`` machine (removed in 7.2)
> +'''''''''''''''''''''''''''''''''''''''''''''
> +
> +This machine was removed because it was partially emulated and 405
> +machines are very similar. Use the ``ref405ep`` machine instead.
> +
>   linux-user mode CPUs
>   --------------------
>   
> diff --git a/docs/system/ppc/embedded.rst b/docs/system/ppc/embedded.rst
> index cfffbda24da9..af3b3d9fa460 100644
> --- a/docs/system/ppc/embedded.rst
> +++ b/docs/system/ppc/embedded.rst
> @@ -6,5 +6,4 @@ Embedded family boards
>   - ``ppce500``              generic paravirt e500 platform
>   - ``ref405ep``             ref405ep
>   - ``sam460ex``             aCube Sam460ex
> -- ``taihu``                taihu
>   - ``virtex-ml507``         Xilinx Virtex ML507 reference design
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index a66ad05e3ac3..1a4e7588c584 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -342,241 +342,9 @@ static const TypeInfo ref405ep_type = {
>       .class_init = ref405ep_class_init,
>   };
>   
> -/*****************************************************************************/
> -/* AMCC Taihu evaluation board */
> -/* - PowerPC 405EP processor
> - * - SDRAM               128 MB at 0x00000000
> - * - Boot flash          2 MB   at 0xFFE00000
> - * - Application flash   32 MB  at 0xFC000000
> - * - 2 serial ports
> - * - 2 ethernet PHY
> - * - 1 USB 1.1 device    0x50000000
> - * - 1 LCD display       0x50100000
> - * - 1 CPLD              0x50100000
> - * - 1 I2C EEPROM
> - * - 1 I2C thermal sensor
> - * - a set of LEDs
> - * - bit-bang SPI port using GPIOs
> - * - 1 EBC interface connector 0 0x50200000
> - * - 1 cardbus controller + expansion slot.
> - * - 1 PCI expansion slot.
> - */
> -typedef struct taihu_cpld_t taihu_cpld_t;
> -struct taihu_cpld_t {
> -    uint8_t reg0;
> -    uint8_t reg1;
> -};
> -
> -static uint64_t taihu_cpld_read(void *opaque, hwaddr addr, unsigned size)
> -{
> -    taihu_cpld_t *cpld;
> -    uint32_t ret;
> -
> -    cpld = opaque;
> -    switch (addr) {
> -    case 0x0:
> -        ret = cpld->reg0;
> -        break;
> -    case 0x1:
> -        ret = cpld->reg1;
> -        break;
> -    default:
> -        ret = 0;
> -        break;
> -    }
> -
> -    return ret;
> -}
> -
> -static void taihu_cpld_write(void *opaque, hwaddr addr,
> -                             uint64_t value, unsigned size)
> -{
> -    taihu_cpld_t *cpld;
> -
> -    cpld = opaque;
> -    switch (addr) {
> -    case 0x0:
> -        /* Read only */
> -        break;
> -    case 0x1:
> -        cpld->reg1 = value;
> -        break;
> -    default:
> -        break;
> -    }
> -}
> -
> -static const MemoryRegionOps taihu_cpld_ops = {
> -    .read = taihu_cpld_read,
> -    .write = taihu_cpld_write,
> -    .impl = {
> -        .min_access_size = 1,
> -        .max_access_size = 1,
> -    },
> -    .endianness = DEVICE_NATIVE_ENDIAN,
> -};
> -
> -static void taihu_cpld_reset (void *opaque)
> -{
> -    taihu_cpld_t *cpld;
> -
> -    cpld = opaque;
> -    cpld->reg0 = 0x01;
> -    cpld->reg1 = 0x80;
> -}
> -
> -static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
> -{
> -    taihu_cpld_t *cpld;
> -    MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
> -
> -    cpld = g_new0(taihu_cpld_t, 1);
> -    memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 0x100);
> -    memory_region_add_subregion(sysmem, base, cpld_memory);
> -    qemu_register_reset(&taihu_cpld_reset, cpld);
> -}
> -
> -static void taihu_405ep_init(MachineState *machine)
> -{
> -    MachineClass *mc = MACHINE_GET_CLASS(machine);
> -    const char *bios_name = machine->firmware ?: BIOS_FILENAME;
> -    const char *kernel_filename = machine->kernel_filename;
> -    const char *initrd_filename = machine->initrd_filename;
> -    char *filename;
> -    MemoryRegion *sysmem = get_system_memory();
> -    MemoryRegion *bios;
> -    MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
> -    hwaddr ram_bases[2], ram_sizes[2];
> -    long bios_size;
> -    target_ulong kernel_base, initrd_base;
> -    long kernel_size, initrd_size;
> -    int linux_boot;
> -    int fl_idx;
> -    DriveInfo *dinfo;
> -    DeviceState *uicdev;
> -
> -    if (machine->ram_size != mc->default_ram_size) {
> -        char *sz = size_to_str(mc->default_ram_size);
> -        error_report("Invalid RAM size, should be %s", sz);
> -        g_free(sz);
> -        exit(EXIT_FAILURE);
> -    }
> -
> -    ram_bases[0] = 0;
> -    ram_sizes[0] = 0x04000000;
> -    memory_region_init_alias(&ram_memories[0], NULL,
> -                             "taihu_405ep.ram-0", machine->ram, ram_bases[0],
> -                             ram_sizes[0]);
> -    ram_bases[1] = 0x04000000;
> -    ram_sizes[1] = 0x04000000;
> -    memory_region_init_alias(&ram_memories[1], NULL,
> -                             "taihu_405ep.ram-1", machine->ram, ram_bases[1],
> -                             ram_sizes[1]);
> -    ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
> -                  33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
> -    /* allocate and load BIOS */
> -    fl_idx = 0;
> -#if defined(USE_FLASH_BIOS)
> -    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
> -    if (dinfo) {
> -        bios_size = 2 * MiB;
> -        pflash_cfi02_register(0xFFE00000,
> -                              "taihu_405ep.bios", bios_size,
> -                              blk_by_legacy_dinfo(dinfo),
> -                              64 * KiB, 1,
> -                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
> -                              1);
> -        fl_idx++;
> -    } else
> -#endif
> -    {
> -        bios = g_new(MemoryRegion, 1);
> -        memory_region_init_rom(bios, NULL, "taihu_405ep.bios", BIOS_SIZE,
> -                               &error_fatal);
> -        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> -        if (filename) {
> -            bios_size = load_image_size(filename,
> -                                        memory_region_get_ram_ptr(bios),
> -                                        BIOS_SIZE);
> -            g_free(filename);
> -            if (bios_size < 0) {
> -                error_report("Could not load PowerPC BIOS '%s'", bios_name);
> -                exit(1);
> -            }
> -            bios_size = (bios_size + 0xfff) & ~0xfff;
> -            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
> -        } else if (!qtest_enabled()) {
> -            error_report("Could not load PowerPC BIOS '%s'", bios_name);
> -            exit(1);
> -        }
> -    }
> -    /* Register Linux flash */
> -    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
> -    if (dinfo) {
> -        bios_size = 32 * MiB;
> -        pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size,
> -                              blk_by_legacy_dinfo(dinfo),
> -                              64 * KiB, 1,
> -                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
> -                              1);
> -        fl_idx++;
> -    }
> -    /* Register CLPD & LCD display */
> -    taihu_cpld_init(sysmem, 0x50100000);
> -    /* Load kernel */
> -    linux_boot = (kernel_filename != NULL);
> -    if (linux_boot) {
> -        kernel_base = KERNEL_LOAD_ADDR;
> -        /* now we can load the kernel */
> -        kernel_size = load_image_targphys(kernel_filename, kernel_base,
> -                                          machine->ram_size - kernel_base);
> -        if (kernel_size < 0) {
> -            error_report("could not load kernel '%s'", kernel_filename);
> -            exit(1);
> -        }
> -        /* load initrd */
> -        if (initrd_filename) {
> -            initrd_base = INITRD_LOAD_ADDR;
> -            initrd_size = load_image_targphys(initrd_filename, initrd_base,
> -                                              machine->ram_size - initrd_base);
> -            if (initrd_size < 0) {
> -                error_report("could not load initial ram disk '%s'",
> -                             initrd_filename);
> -                exit(1);
> -            }
> -        } else {
> -            initrd_base = 0;
> -            initrd_size = 0;
> -        }
> -    } else {
> -        kernel_base = 0;
> -        kernel_size = 0;
> -        initrd_base = 0;
> -        initrd_size = 0;
> -    }
> -}
> -
> -static void taihu_class_init(ObjectClass *oc, void *data)
> -{
> -    MachineClass *mc = MACHINE_CLASS(oc);
> -
> -    mc->desc = "taihu";
> -    mc->init = taihu_405ep_init;
> -    mc->default_ram_size = 0x08000000;
> -    mc->default_ram_id = "taihu_405ep.ram";
> -    mc->deprecation_reason = "incomplete, use 'ref405ep' instead";
> -}
> -
> -static const TypeInfo taihu_type = {
> -    .name = MACHINE_TYPE_NAME("taihu"),
> -    .parent = TYPE_MACHINE,
> -    .class_init = taihu_class_init,
> -};
> -
>   static void ppc405_machine_init(void)
>   {
>       type_register_static(&ref405ep_type);
> -    type_register_static(&taihu_type);
>   }
>   
>   type_init(ppc405_machine_init)
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5ce4227ff650..1729c0901cea 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1282,7 +1282,7 @@ F: hw/openrisc/openrisc_sim.c
>   
>   PowerPC Machines
>   ----------------
> -405 (ref405ep and taihu)
> +405 (ref405ep)
>   L: qemu-ppc@nongnu.org
>   S: Orphan
>   F: hw/ppc/ppc405_boards.c


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

* Re: [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC
  2022-08-03 13:28 ` [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC Cédric Le Goater
@ 2022-08-03 17:16   ` BALATON Zoltan
  2022-08-04  5:09     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 17:16 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 10126 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> Introduce a QOM property "cpu" to initialize the DCR handlers. This is
> a pattern that we will reuse for the all other 405 devices needing it.
>
> Now that all clock settings are handled at the CPC level, change the
> SoC "sys-clk" property to be an alias on the same property in the CPC
> model.
>
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h    |  39 +++++++++++++++-
> hw/ppc/ppc405_uc.c | 109 +++++++++++++++++++--------------------------
> 2 files changed, 85 insertions(+), 63 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index ae64549537c6..88c63774d9ba 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -63,6 +63,43 @@ struct ppc4xx_bd_info_t {
>     uint32_t bi_iic_fast[2];
> };
>
> +typedef struct Ppc405SoCState Ppc405SoCState;

This typedef is already done by the OBJECT_DECLARE_SIMPLE_TYPE macro 
below. Could some compilers complain about double typedef? There may be 
some circular dependencies here so to avoid a separate typedef you may 
need to bring the OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC); 
line up here to the front while keeping the actual declaration of the 
state struct and rest of the object later which separates them but adding 
a comment may explain that. I'm not sure if it's better to do that or 
repeating the typedef in advance as done here is better but declaring the 
object in advance is probably a bit cleaner than repeating part of its 
internals just in case this implementation detail ever changes.

Regards,
BALATON Zoltan

> +
> +#define TYPE_PPC405_CPC "ppc405-cpc"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
> +
> +enum {
> +    PPC405EP_CPU_CLK   = 0,
> +    PPC405EP_PLB_CLK   = 1,
> +    PPC405EP_OPB_CLK   = 2,
> +    PPC405EP_EBC_CLK   = 3,
> +    PPC405EP_MAL_CLK   = 4,
> +    PPC405EP_PCI_CLK   = 5,
> +    PPC405EP_UART0_CLK = 6,
> +    PPC405EP_UART1_CLK = 7,
> +    PPC405EP_CLK_NB    = 8,
> +};
> +
> +struct Ppc405CpcState {
> +    DeviceState parent_obj;
> +
> +    PowerPCCPU *cpu;
> +
> +    uint32_t sysclk;
> +    clk_setup_t clk_setup[PPC405EP_CLK_NB];
> +    uint32_t boot;
> +    uint32_t epctl;
> +    uint32_t pllmr[2];
> +    uint32_t ucr;
> +    uint32_t srr;
> +    uint32_t jtagid;
> +    uint32_t pci;
> +    /* Clock and power management */
> +    uint32_t er;
> +    uint32_t fr;
> +    uint32_t sr;
> +};
> +
> #define TYPE_PPC405_SOC "ppc405-soc"
> OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
>
> @@ -79,9 +116,9 @@ struct Ppc405SoCState {
>     MemoryRegion *dram_mr;
>     hwaddr ram_size;
>
> -    uint32_t sysclk;
>     PowerPCCPU cpu;
>     DeviceState *uic;
> +    Ppc405CpcState cpc;
> };
>
> /* PowerPC 405 core */
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 013dccee898b..32bfc9480bc6 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1178,36 +1178,7 @@ enum {
> #endif
> };
>
> -enum {
> -    PPC405EP_CPU_CLK   = 0,
> -    PPC405EP_PLB_CLK   = 1,
> -    PPC405EP_OPB_CLK   = 2,
> -    PPC405EP_EBC_CLK   = 3,
> -    PPC405EP_MAL_CLK   = 4,
> -    PPC405EP_PCI_CLK   = 5,
> -    PPC405EP_UART0_CLK = 6,
> -    PPC405EP_UART1_CLK = 7,
> -    PPC405EP_CLK_NB    = 8,
> -};
> -
> -typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
> -struct ppc405ep_cpc_t {
> -    uint32_t sysclk;
> -    clk_setup_t clk_setup[PPC405EP_CLK_NB];
> -    uint32_t boot;
> -    uint32_t epctl;
> -    uint32_t pllmr[2];
> -    uint32_t ucr;
> -    uint32_t srr;
> -    uint32_t jtagid;
> -    uint32_t pci;
> -    /* Clock and power management */
> -    uint32_t er;
> -    uint32_t fr;
> -    uint32_t sr;
> -};
> -
> -static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
> +static void ppc405ep_compute_clocks(Ppc405CpcState *cpc)
> {
>     uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
>     uint32_t UART0_clk, UART1_clk;
> @@ -1302,10 +1273,9 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
>
> static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
> {
> -    ppc405ep_cpc_t *cpc;
> +    Ppc405CpcState *cpc = PPC405_CPC(opaque);
>     uint32_t ret;
>
> -    cpc = opaque;
>     switch (dcrn) {
>     case PPC405EP_CPC0_BOOT:
>         ret = cpc->boot;
> @@ -1342,9 +1312,8 @@ static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
>
> static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
> {
> -    ppc405ep_cpc_t *cpc;
> +    Ppc405CpcState *cpc = PPC405_CPC(opaque);
>
> -    cpc = opaque;
>     switch (dcrn) {
>     case PPC405EP_CPC0_BOOT:
>         /* Read-only register */
> @@ -1377,9 +1346,9 @@ static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
>     }
> }
>
> -static void ppc405ep_cpc_reset (void *opaque)
> +static void ppc405_cpc_reset(DeviceState *dev)
> {
> -    ppc405ep_cpc_t *cpc = opaque;
> +    Ppc405CpcState *cpc = PPC405_CPC(dev);
>
>     cpc->boot = 0x00000010;     /* Boot from PCI - IIC EEPROM disabled */
>     cpc->epctl = 0x00000000;
> @@ -1391,21 +1360,24 @@ static void ppc405ep_cpc_reset (void *opaque)
>     cpc->er = 0x00000000;
>     cpc->fr = 0x00000000;
>     cpc->sr = 0x00000000;
> +    cpc->jtagid = 0x20267049;
>     ppc405ep_compute_clocks(cpc);
> }
>
> /* XXX: sysclk should be between 25 and 100 MHz */
> -static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
> -                               uint32_t sysclk)
> +static void ppc405_cpc_realize(DeviceState *dev, Error **errp)
> {
> -    ppc405ep_cpc_t *cpc;
> +    Ppc405CpcState *cpc = PPC405_CPC(dev);
> +    CPUPPCState *env;
> +
> +    assert(cpc->cpu);
> +
> +    env = &cpc->cpu->env;
> +
> +    cpc->clk_setup[PPC405EP_CPU_CLK].cb =
> +        ppc_40x_timers_init(env, cpc->sysclk, PPC_INTERRUPT_PIT);
> +    cpc->clk_setup[PPC405EP_CPU_CLK].opaque = env;
>
> -    cpc = g_new0(ppc405ep_cpc_t, 1);
> -    memcpy(cpc->clk_setup, clk_setup,
> -           PPC405EP_CLK_NB * sizeof(clk_setup_t));
> -    cpc->jtagid = 0x20267049;
> -    cpc->sysclk = sysclk;
> -    qemu_register_reset(&ppc405ep_cpc_reset, cpc);
>     ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
>                      &dcr_read_epcpc, &dcr_write_epcpc);
>     ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
> @@ -1422,14 +1394,23 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
>                      &dcr_read_epcpc, &dcr_write_epcpc);
>     ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
>                      &dcr_read_epcpc, &dcr_write_epcpc);
> -#if 0
> -    ppc_dcr_register(env, PPC405EP_CPC0_ER, cpc,
> -                     &dcr_read_epcpc, &dcr_write_epcpc);
> -    ppc_dcr_register(env, PPC405EP_CPC0_FR, cpc,
> -                     &dcr_read_epcpc, &dcr_write_epcpc);
> -    ppc_dcr_register(env, PPC405EP_CPC0_SR, cpc,
> -                     &dcr_read_epcpc, &dcr_write_epcpc);
> -#endif
> +}
> +
> +static Property ppc405_cpc_properties[] = {
> +    DEFINE_PROP_LINK("cpu", Ppc405CpcState, cpu, TYPE_POWERPC_CPU,
> +                     PowerPCCPU *),
> +    DEFINE_PROP_UINT32("sys-clk", Ppc405CpcState, sysclk, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc405_cpc_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc405_cpc_realize;
> +    dc->user_creatable = false;
> +    dc->reset = ppc405_cpc_reset;
> +    device_class_set_props(dc, ppc405_cpc_properties);
> }
>
> static void ppc405_soc_instance_init(Object *obj)
> @@ -1438,12 +1419,14 @@ static void ppc405_soc_instance_init(Object *obj)
>
>     object_initialize_child(obj, "cpu", &s->cpu,
>                             POWERPC_CPU_TYPE_NAME("405ep"));
> +
> +    object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
> +    object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
> }
>
> static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> {
>     Ppc405SoCState *s = PPC405_SOC(dev);
> -    clk_setup_t clk_setup[PPC405EP_CLK_NB];
>     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
>     CPUPPCState *env;
>     Error *err = NULL;
> @@ -1458,8 +1441,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>     memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
>                                 &s->sram);
>
> -    memset(clk_setup, 0, sizeof(clk_setup));
> -
>     /* init CPUs */
>     if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
>         return;
> @@ -1468,14 +1449,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>
>     env = &s->cpu.env;
>
> -    clk_setup[PPC405EP_CPU_CLK].cb =
> -        ppc_40x_timers_init(env, s->sysclk, PPC_INTERRUPT_PIT);
> -    clk_setup[PPC405EP_CPU_CLK].opaque = env;
> -
>     ppc_dcr_init(env, NULL, NULL);
>
>     /* CPU control */
> -    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
> +    object_property_set_link(OBJECT(&s->cpc), "cpu", OBJECT(&s->cpu),
> +                             &error_abort);
> +    if (!qdev_realize(DEVICE(&s->cpc), NULL, errp)) {
> +        return;
> +    }
>
>     /* PLB arbitrer */
>     ppc4xx_plb_init(env);
> @@ -1566,7 +1547,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> static Property ppc405_soc_properties[] = {
>     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
>                      MemoryRegion *),
> -    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
>     DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
>     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
>     DEFINE_PROP_END_OF_LIST(),
> @@ -1583,6 +1563,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>
> static const TypeInfo ppc405_types[] = {
>     {
> +        .name           = TYPE_PPC405_CPC,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(Ppc405CpcState),
> +        .class_init     = ppc405_cpc_class_init,
> +    }, {
>         .name           = TYPE_PPC405_SOC,
>         .parent         = TYPE_DEVICE,
>         .instance_size  = sizeof(Ppc405SoCState),
>

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

* Re: [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine
  2022-08-03 17:03   ` BALATON Zoltan
@ 2022-08-03 17:35     ` Daniel Henrique Barboza
  0 siblings, 0 replies; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-03 17:35 UTC (permalink / raw)
  To: BALATON Zoltan, Cédric Le Goater; +Cc: qemu-ppc, qemu-devel



On 8/3/22 14:03, BALATON Zoltan wrote:
> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> We will use this machine as a base to define the ref405ep and possibly
>> the PPC405 hotfoot board as found in the Linux kernel.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405_boards.c | 31 ++++++++++++++++++++++++++++---
>> 1 file changed, 28 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
>> index 1a4e7588c584..4c269b6526a5 100644
>> --- a/hw/ppc/ppc405_boards.c
>> +++ b/hw/ppc/ppc405_boards.c
>> @@ -50,6 +50,15 @@
>>
>> #define USE_FLASH_BIOS
>>
>> +struct Ppc405MachineState {
>> +    /* Private */
>> +    MachineState parent_obj;
>> +    /* Public */
>> +};
>> +
>> +#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
> 
> In other patches the declaration of the state struct comes after the OBJECT_DECLARE macro so here instead of above. It would be better to write it like that here too for consistency and also because then the DECLARE macro starts the object declaration and everything belonging to the object are together below it. Declaring the structure before is kind of outside the object, although this is only cosmetic and may be a matter of style.

Good point. I moved the struct declaration to after the OBJECT_DECLARE macro.


Thanks,

Daniel

> 
> Regards,
> BALATON Zoltan
> 
>> +
>> /*****************************************************************************/
>> /* PPC405EP reference board (IBM) */
>> /* Standalone board with:
>> @@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void *data)
>>
>>     mc->desc = "ref405ep";
>>     mc->init = ref405ep_init;
>> -    mc->default_ram_size = 0x08000000;
>> -    mc->default_ram_id = "ef405ep.ram";
>> }
>>
>> static const TypeInfo ref405ep_type = {
>>     .name = MACHINE_TYPE_NAME("ref405ep"),
>> -    .parent = TYPE_MACHINE,
>> +    .parent = TYPE_PPC405_MACHINE,
>>     .class_init = ref405ep_class_init,
>> };
>>
>> +static void ppc405_machine_class_init(ObjectClass *oc, void *data)
>> +{
>> +    MachineClass *mc = MACHINE_CLASS(oc);
>> +
>> +    mc->desc = "PPC405 generic machine";
>> +    mc->default_ram_size = 0x08000000;
>> +    mc->default_ram_id = "ppc405.ram";
>> +}
>> +
>> +static const TypeInfo ppc405_machine_type = {
>> +    .name = TYPE_PPC405_MACHINE,
>> +    .parent = TYPE_MACHINE,
>> +    .instance_size = sizeof(Ppc405MachineState),
>> +    .class_init = ppc405_machine_class_init,
>> +    .abstract = true,
>> +};
>> +
>> static void ppc405_machine_init(void)
>> {
>> +    type_register_static(&ppc405_machine_type);
>>     type_register_static(&ref405ep_type);
>> }
>>
>>


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

* Re: [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine
  2022-08-03 13:28 ` [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine Cédric Le Goater
  2022-08-03 17:03   ` BALATON Zoltan
@ 2022-08-03 22:07   ` BALATON Zoltan
  2022-08-04  5:40     ` Cédric Le Goater
  1 sibling, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 22:07 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2559 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> We will use this machine as a base to define the ref405ep and possibly
> the PPC405 hotfoot board as found in the Linux kernel.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405_boards.c | 31 ++++++++++++++++++++++++++++---
> 1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 1a4e7588c584..4c269b6526a5 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -50,6 +50,15 @@
>
> #define USE_FLASH_BIOS
>
> +struct Ppc405MachineState {
> +    /* Private */
> +    MachineState parent_obj;
> +    /* Public */
> +};
> +
> +#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
> +
> /*****************************************************************************/
> /* PPC405EP reference board (IBM) */
> /* Standalone board with:
> @@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void *data)
>
>     mc->desc = "ref405ep";
>     mc->init = ref405ep_init;
> -    mc->default_ram_size = 0x08000000;
> -    mc->default_ram_id = "ef405ep.ram";
> }
>
> static const TypeInfo ref405ep_type = {
>     .name = MACHINE_TYPE_NAME("ref405ep"),
> -    .parent = TYPE_MACHINE,
> +    .parent = TYPE_PPC405_MACHINE,
>     .class_init = ref405ep_class_init,
> };
>
> +static void ppc405_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
> +    mc->desc = "PPC405 generic machine";
> +    mc->default_ram_size = 0x08000000;
> +    mc->default_ram_id = "ppc405.ram";

Is the default RAM size a property of specific boards or the PPC405? I 
think it could be different for different boards so don't see why it's 
moved to the generic machine but maybe it has something to do with how 
other parts of QEMU handles this or I'm not getting what the generic 
PPC405 machine is for.

Would it be clearer to just write 128 * MiB instead of a long hex number 
with extra zeros that's hard to read? It would be a good opportunity to 
change it here.

Regards,
BALATON Zoltan

> +}
> +
> +static const TypeInfo ppc405_machine_type = {
> +    .name = TYPE_PPC405_MACHINE,
> +    .parent = TYPE_MACHINE,
> +    .instance_size = sizeof(Ppc405MachineState),
> +    .class_init = ppc405_machine_class_init,
> +    .abstract = true,
> +};
> +
> static void ppc405_machine_init(void)
> {
> +    type_register_static(&ppc405_machine_type);
>     type_register_static(&ref405ep_type);
> }
>
>

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

* Re: [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC
  2022-08-03 13:28 ` [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC Cédric Le Goater
@ 2022-08-03 22:13   ` BALATON Zoltan
  0 siblings, 0 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 22:13 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 6799 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> It is an initial model to start QOMification of the PPC405 board.
> QOM'ified devices will be reintroduced one by one. Start with the
> memory regions, which name prefix is changed to "ppc405".

I'm not a native speaker but "which name prefix" sounds weird to me here. 
Maybe something like the name prefix of which, with their name prefix or 
maybe whose name prefix is probably better but some English speaker would 
better review this.

>
> Also, initialize only one RAM bank. The second bank is a dummy one
> (zero size) which is here to match the hard coded number of banks in
> ppc405ep_init(). We will adjust this number when ppc4xx_sdram_init()
> can be called directly, after we have replaced ppc405ep_init().
>
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h        | 17 +++++++++++++++
> hw/ppc/ppc405_boards.c | 29 +++++++++++--------------
> hw/ppc/ppc405_uc.c     | 49 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 78 insertions(+), 17 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 83f156f585c8..c8cddb71733a 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -25,6 +25,7 @@
> #ifndef PPC405_H
> #define PPC405_H
>
> +#include "qom/object.h"
> #include "hw/ppc/ppc4xx.h"
>
> #define PPC405EP_SDRAM_BASE 0x00000000
> @@ -62,6 +63,22 @@ struct ppc4xx_bd_info_t {
>     uint32_t bi_iic_fast[2];
> };
>
> +#define TYPE_PPC405_SOC "ppc405-soc"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
> +
> +struct Ppc405SoCState {
> +    /* Private */
> +    DeviceState parent_obj;
> +
> +    /* Public */
> +    MemoryRegion sram;
> +    MemoryRegion ram_memories[2];
> +    hwaddr ram_bases[2], ram_sizes[2];
> +
> +    MemoryRegion *dram_mr;
> +    hwaddr ram_size;
> +};
> +
> /* PowerPC 405 core */
> ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
>
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 24ec948d22a4..96db52c5a309 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -54,6 +54,8 @@ struct Ppc405MachineState {
>     /* Private */
>     MachineState parent_obj;
>     /* Public */
> +
> +    Ppc405SoCState soc;
> };
>
> #define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
> @@ -232,12 +234,10 @@ static void boot_from_kernel(MachineState *machine, PowerPCCPU *cpu)
>
> static void ppc405_init(MachineState *machine)
> {
> +    Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
>     MachineClass *mc = MACHINE_GET_CLASS(machine);
>     const char *kernel_filename = machine->kernel_filename;
>     PowerPCCPU *cpu;
> -    MemoryRegion *sram = g_new(MemoryRegion, 1);
> -    MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
> -    hwaddr ram_bases[2], ram_sizes[2];
>     MemoryRegion *sysmem = get_system_memory();
>     DeviceState *uicdev;
>
> @@ -248,23 +248,18 @@ static void ppc405_init(MachineState *machine)
>         exit(EXIT_FAILURE);
>     }
>
> -    /* XXX: fix this */
> -    memory_region_init_alias(&ram_memories[0], NULL, "ef405ep.ram.alias",
> -                             machine->ram, 0, machine->ram_size);
> -    ram_bases[0] = 0;
> -    ram_sizes[0] = machine->ram_size;
> -    memory_region_init(&ram_memories[1], NULL, "ef405ep.ram1", 0);
> -    ram_bases[1] = 0x00000000;
> -    ram_sizes[1] = 0x00000000;
> +    object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
> +                            TYPE_PPC405_SOC);
> +    object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
> +                             machine->ram_size, &error_fatal);
> +    object_property_set_link(OBJECT(&ppc405->soc), "dram",
> +                             OBJECT(machine->ram), &error_abort);
> +    qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
>
> -    cpu = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
> +    cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, ppc405->soc.ram_bases,
> +                        ppc405->soc.ram_sizes,
>                         33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
>
> -    /* allocate SRAM */
> -    memory_region_init_ram(sram, NULL, "ef405ep.sram", PPC405EP_SRAM_SIZE,
> -                           &error_fatal);
> -    memory_region_add_subregion(sysmem, PPC405EP_SRAM_BASE, sram);
> -
>     /* allocate and load BIOS */
>     if (machine->firmware) {
>         MemoryRegion *bios = g_new(MemoryRegion, 1);
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index d6420c88d3a6..7033bac6bf3f 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -30,6 +30,7 @@
> #include "hw/ppc/ppc.h"
> #include "hw/i2c/ppc4xx_i2c.h"
> #include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> #include "ppc405.h"
> #include "hw/char/serial.h"
> #include "qemu/timer.h"
> @@ -1530,3 +1531,51 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
>
>     return cpu;
> }
> +
> +static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> +{
> +    Ppc405SoCState *s = PPC405_SOC(dev);
> +    Error *err = NULL;
> +
> +    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
> +                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
> +    s->ram_bases[0] = 0;
> +    s->ram_sizes[0] = s->ram_size;
> +
> +    /* allocate SRAM */
> +    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
> +                           PPC405EP_SRAM_SIZE,  &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
> +                                &s->sram);
> +}
> +
> +static Property ppc405_soc_properties[] = {
> +    DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
> +                     MemoryRegion *),
> +    DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc405_soc_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc405_soc_realize;
> +    dc->user_creatable = false;

There's a comment in qemu/include/hw/qdev-core.h saying that if you set 
user_creatable to false then you should add a comment explaining why. Not 
sure it's still a requirement but other places do that and may be useful 
later.

Regards,
BALATON Zoltan

> +    device_class_set_props(dc, ppc405_soc_properties);
> +}
> +
> +static const TypeInfo ppc405_types[] = {
> +    {
> +        .name           = TYPE_PPC405_SOC,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(Ppc405SoCState),
> +        .class_init     = ppc405_soc_class_init,
> +    }
> +};
> +
> +DEFINE_TYPES(ppc405_types)
>

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

* Re: [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC
  2022-08-03 13:28 ` [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC Cédric Le Goater
@ 2022-08-03 22:23   ` BALATON Zoltan
  2022-08-04  6:00     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 22:23 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 12064 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> This moves all the code previously done in the ppc405ep_init() routine
> under ppc405_soc_realize(). We can also adjust the number of banks now
> that we have control on ppc4xx_sdram_init().
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h        |  16 ++---
> hw/ppc/ppc405_boards.c |  12 ++--
> hw/ppc/ppc405_uc.c     | 144 ++++++++++++++++++++---------------------
> 3 files changed, 83 insertions(+), 89 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index c8cddb71733a..2c912b328eaf 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -72,11 +72,16 @@ struct Ppc405SoCState {
>
>     /* Public */
>     MemoryRegion sram;
> -    MemoryRegion ram_memories[2];
> -    hwaddr ram_bases[2], ram_sizes[2];
> +    MemoryRegion ram_memories[1];
> +    hwaddr ram_bases[1], ram_sizes[1];
> +    bool do_dram_init;

I'm not sure about this. First of all what's the point having a 1 element 
array instead of just a normal field if you don't need more than one of 
these? (But then the names in plural become a misnomer too.) On the other 
hand the SoC likely has two banks, it's just that the board only has one 
socket and thus only uses one of it but other boards could have two 
sockets and use both. If the SoC model already has this I'd keep it for 
that cases or to emulate the SoC more precisely. But I may be wrong, I 
haven't checked the chip docs and only dimly remember how this was on 
460EX.

Regards,
BALATON Zoltan

>
>     MemoryRegion *dram_mr;
>     hwaddr ram_size;
> +
> +    uint32_t sysclk;
> +    PowerPCCPU *cpu;
> +    DeviceState *uic;
> };
>
> /* PowerPC 405 core */
> @@ -85,11 +90,4 @@ ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
> void ppc4xx_plb_init(CPUPPCState *env);
> void ppc405_ebc_init(CPUPPCState *env);
>
> -PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
> -                        MemoryRegion ram_memories[2],
> -                        hwaddr ram_bases[2],
> -                        hwaddr ram_sizes[2],
> -                        uint32_t sysclk, DeviceState **uicdev,
> -                        int do_init);
> -
> #endif /* PPC405_H */
> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> index 96db52c5a309..363cb0770506 100644
> --- a/hw/ppc/ppc405_boards.c
> +++ b/hw/ppc/ppc405_boards.c
> @@ -237,9 +237,7 @@ static void ppc405_init(MachineState *machine)
>     Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
>     MachineClass *mc = MACHINE_GET_CLASS(machine);
>     const char *kernel_filename = machine->kernel_filename;
> -    PowerPCCPU *cpu;
>     MemoryRegion *sysmem = get_system_memory();
> -    DeviceState *uicdev;
>
>     if (machine->ram_size != mc->default_ram_size) {
>         char *sz = size_to_str(mc->default_ram_size);
> @@ -254,12 +252,12 @@ static void ppc405_init(MachineState *machine)
>                              machine->ram_size, &error_fatal);
>     object_property_set_link(OBJECT(&ppc405->soc), "dram",
>                              OBJECT(machine->ram), &error_abort);
> +    object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
> +                             !(kernel_filename == NULL), &error_abort);
> +    object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", 33333333,
> +                             &error_abort);
>     qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
>
> -    cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, ppc405->soc.ram_bases,
> -                        ppc405->soc.ram_sizes,
> -                        33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
> -
>     /* allocate and load BIOS */
>     if (machine->firmware) {
>         MemoryRegion *bios = g_new(MemoryRegion, 1);
> @@ -315,7 +313,7 @@ static void ppc405_init(MachineState *machine)
>
>     /* Load ELF kernel and rootfs.cpio */
>     } else if (kernel_filename && !machine->firmware) {
> -        boot_from_kernel(machine, cpu);
> +        boot_from_kernel(machine, ppc405->soc.cpu);
>     }
> }
>
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 7033bac6bf3f..ed1099e08bbd 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1432,130 +1432,128 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
> #endif
> }
>
> -PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
> -                        MemoryRegion ram_memories[2],
> -                        hwaddr ram_bases[2],
> -                        hwaddr ram_sizes[2],
> -                        uint32_t sysclk, DeviceState **uicdevp,
> -                        int do_init)
> +static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> {
> +    Ppc405SoCState *s = PPC405_SOC(dev);
>     clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
>     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
> -    PowerPCCPU *cpu;
>     CPUPPCState *env;
> -    DeviceState *uicdev;
> -    SysBusDevice *uicsbd;
> +    Error *err = NULL;
> +
> +    /* allocate SRAM */
> +    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
> +                           PPC405EP_SRAM_SIZE,  &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
> +                                &s->sram);
>
>     memset(clk_setup, 0, sizeof(clk_setup));
> +
>     /* init CPUs */
> -    cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
> +    s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
>                       &clk_setup[PPC405EP_CPU_CLK],
> -                      &tlb_clk_setup, sysclk);
> -    env = &cpu->env;
> +                      &tlb_clk_setup, s->sysclk);
> +    env = &s->cpu->env;
>     clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
>     clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
> -    /* Internal devices init */
> -    /* Memory mapped devices registers */
> +
> +    /* CPU control */
> +    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
> +
>     /* PLB arbitrer */
>     ppc4xx_plb_init(env);
> +
>     /* PLB to OPB bridge */
>     ppc4xx_pob_init(env);
> +
>     /* OBP arbitrer */
>     ppc4xx_opba_init(0xef600600);
> +
>     /* Universal interrupt controller */
> -    uicdev = qdev_new(TYPE_PPC_UIC);
> -    uicsbd = SYS_BUS_DEVICE(uicdev);
> +    s->uic = qdev_new(TYPE_PPC_UIC);
>
> -    object_property_set_link(OBJECT(uicdev), "cpu", OBJECT(cpu),
> +    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(s->cpu),
>                              &error_fatal);
> -    sysbus_realize_and_unref(uicsbd, &error_fatal);
> -
> -    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT,
> -                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT));
> -    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT,
> -                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
> +    if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
> +        return;
> +    }
>
> -    *uicdevp = uicdev;
> +    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
> +                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_INT));
> +    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
> +                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_CINT));
>
>     /* SDRAM controller */
> -        /* XXX 405EP has no ECC interrupt */
> -    ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 17), 2, ram_memories,
> -                      ram_bases, ram_sizes, do_init);
> +    /* XXX 405EP has no ECC interrupt */
> +    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
> +                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
> +    s->ram_bases[0] = 0;
> +    s->ram_sizes[0] = s->ram_size;
> +
> +    ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17),
> +                      ARRAY_SIZE(s->ram_memories), s->ram_memories,
> +                      s->ram_bases, s->ram_sizes, s->do_dram_init);
> +
>     /* External bus controller */
>     ppc405_ebc_init(env);
> +
>     /* DMA controller */
> -    dma_irqs[0] = qdev_get_gpio_in(uicdev, 5);
> -    dma_irqs[1] = qdev_get_gpio_in(uicdev, 6);
> -    dma_irqs[2] = qdev_get_gpio_in(uicdev, 7);
> -    dma_irqs[3] = qdev_get_gpio_in(uicdev, 8);
> +    dma_irqs[0] = qdev_get_gpio_in(s->uic, 5);
> +    dma_irqs[1] = qdev_get_gpio_in(s->uic, 6);
> +    dma_irqs[2] = qdev_get_gpio_in(s->uic, 7);
> +    dma_irqs[3] = qdev_get_gpio_in(s->uic, 8);
>     ppc405_dma_init(env, dma_irqs);
> -    /* IIC controller */
> +
> +    /* I2C controller */
>     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
> -                         qdev_get_gpio_in(uicdev, 2));
> +                         qdev_get_gpio_in(s->uic, 2));
>     /* GPIO */
>     ppc405_gpio_init(0xef600700);
> +
>     /* Serial ports */
>     if (serial_hd(0) != NULL) {
> -        serial_mm_init(address_space_mem, 0xef600300, 0,
> -                       qdev_get_gpio_in(uicdev, 0),
> +        serial_mm_init(get_system_memory(), 0xef600300, 0,
> +                       qdev_get_gpio_in(s->uic, 0),
>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
>                        DEVICE_BIG_ENDIAN);
>     }
>     if (serial_hd(1) != NULL) {
> -        serial_mm_init(address_space_mem, 0xef600400, 0,
> -                       qdev_get_gpio_in(uicdev, 1),
> +        serial_mm_init(get_system_memory(), 0xef600400, 0,
> +                       qdev_get_gpio_in(s->uic, 1),
>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
>                        DEVICE_BIG_ENDIAN);
>     }
> +
>     /* OCM */
>     ppc405_ocm_init(env);
> +
>     /* GPT */
> -    gpt_irqs[0] = qdev_get_gpio_in(uicdev, 19);
> -    gpt_irqs[1] = qdev_get_gpio_in(uicdev, 20);
> -    gpt_irqs[2] = qdev_get_gpio_in(uicdev, 21);
> -    gpt_irqs[3] = qdev_get_gpio_in(uicdev, 22);
> -    gpt_irqs[4] = qdev_get_gpio_in(uicdev, 23);
> +    gpt_irqs[0] = qdev_get_gpio_in(s->uic, 19);
> +    gpt_irqs[1] = qdev_get_gpio_in(s->uic, 20);
> +    gpt_irqs[2] = qdev_get_gpio_in(s->uic, 21);
> +    gpt_irqs[3] = qdev_get_gpio_in(s->uic, 22);
> +    gpt_irqs[4] = qdev_get_gpio_in(s->uic, 23);
>     ppc4xx_gpt_init(0xef600000, gpt_irqs);
> -    /* PCI */
> -    /* Uses UIC IRQs 3, 16, 18 */
> +
>     /* MAL */
> -    mal_irqs[0] = qdev_get_gpio_in(uicdev, 11);
> -    mal_irqs[1] = qdev_get_gpio_in(uicdev, 12);
> -    mal_irqs[2] = qdev_get_gpio_in(uicdev, 13);
> -    mal_irqs[3] = qdev_get_gpio_in(uicdev, 14);
> +    mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
> +    mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
> +    mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
> +    mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
>     ppc4xx_mal_init(env, 4, 2, mal_irqs);
> +
>     /* Ethernet */
>     /* Uses UIC IRQs 9, 15, 17 */
> -    /* CPU control */
> -    ppc405ep_cpc_init(env, clk_setup, sysclk);
> -
> -    return cpu;
> -}
> -
> -static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> -{
> -    Ppc405SoCState *s = PPC405_SOC(dev);
> -    Error *err = NULL;
> -
> -    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
> -                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
> -    s->ram_bases[0] = 0;
> -    s->ram_sizes[0] = s->ram_size;
> -
> -    /* allocate SRAM */
> -    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
> -                           PPC405EP_SRAM_SIZE,  &err);
> -    if (err) {
> -        error_propagate(errp, err);
> -        return;
> -    }
> -    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
> -                                &s->sram);
> }
>
> static Property ppc405_soc_properties[] = {
>     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
>                      MemoryRegion *),
> +    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
> +    DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
>     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
>     DEFINE_PROP_END_OF_LIST(),
> };
>

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-03 13:28 ` [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC Cédric Le Goater
@ 2022-08-03 23:04   ` BALATON Zoltan
  2022-08-04  7:55     ` Mark Cave-Ayland
  2022-08-03 23:36   ` Daniel Henrique Barboza
  1 sibling, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 23:04 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 7025 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h    | 16 +++++++++++
> hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
> 2 files changed, 64 insertions(+), 23 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 1da34a7f10f3..1c7fe07b8084 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>
> typedef struct Ppc405SoCState Ppc405SoCState;
>
> +/* Peripheral controller */
> +#define TYPE_PPC405_EBC "ppc405-ebc"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
> +struct Ppc405EbcState {
> +    DeviceState parent_obj;
> +
> +    PowerPCCPU *cpu;
>
> +    uint32_t addr;
> +    uint32_t bcr[8];
> +    uint32_t bap[8];
> +    uint32_t bear;
> +    uint32_t besr0;
> +    uint32_t besr1;
> +    uint32_t cfg;
> +};
>
> /* DMA controller */
> #define TYPE_PPC405_DMA "ppc405-dma"
> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>     Ppc405OcmState ocm;
>     Ppc405GpioState gpio;
>     Ppc405DmaState dma;
> +    Ppc405EbcState ebc;
> };
>
> /* PowerPC 405 core */
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 6bd93c1cb90c..0166f3fc36da 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>
> /*****************************************************************************/
> /* Peripheral controller */
> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
> -struct ppc4xx_ebc_t {
> -    uint32_t addr;
> -    uint32_t bcr[8];
> -    uint32_t bap[8];
> -    uint32_t bear;
> -    uint32_t besr0;
> -    uint32_t besr1;
> -    uint32_t cfg;
> -};
> -
> enum {
>     EBC0_CFGADDR = 0x012,
>     EBC0_CFGDATA = 0x013,
> @@ -411,10 +400,9 @@ enum {
>
> static uint32_t dcr_read_ebc (void *opaque, int dcrn)
> {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>     uint32_t ret;
>
> -    ebc = opaque;

I think QOM casts are kind of expensive (maybe because we have quo-debug 
enabled by default even without --enable-debug and it does additional 
checks; I've tried to change this default once but it was thought to be 
better to have it enabled). So it's advised to use QOM casts sparingly, 
e.g. store the result in a local variable if you need it more than once 
and so. Therefore I tend to consider these read/write callbacks that the 
object itself registers with itself as the opaque pointer to be internal 
to the object and guaranteed to be passed the object pointer so no QOM 
cast is necessary and the direct assignment can be kept. This avoids 
potential overhead on every register access. Not sure if it's measurable 
but I think if an overhead can be avoided it probably should be.

>     switch (dcrn) {
>     case EBC0_CFGADDR:
>         ret = ebc->addr;
> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>
> static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
> {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>
> -    ebc = opaque;
>     switch (dcrn) {
>     case EBC0_CFGADDR:
>         ebc->addr = val;
> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>     }
> }
>
> -static void ebc_reset (void *opaque)
> +static void ppc405_ebc_reset(DeviceState *dev)
> {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(dev);

In this case the cast is OK as it's casting a different object so it's 
needed and also it's infrequently called so should not matter.

>     int i;
>
> -    ebc = opaque;
>     ebc->addr = 0x00000000;
>     ebc->bap[0] = 0x7F8FFE80;
>     ebc->bcr[0] = 0xFFE28000;
> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>     ebc->cfg = 0x80400000;
> }
>
> -void ppc405_ebc_init(CPUPPCState *env)
> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
> {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
> +    CPUPPCState *env;
> +
> +    assert(ebc->cpu);
> +
> +    env = &ebc->cpu->env;
>
> -    ebc = g_new0(ppc4xx_ebc_t, 1);
> -    qemu_register_reset(&ebc_reset, ebc);
>     ppc_dcr_register(env, EBC0_CFGADDR,
>                      ebc, &dcr_read_ebc, &dcr_write_ebc);
>     ppc_dcr_register(env, EBC0_CFGDATA,
>                      ebc, &dcr_read_ebc, &dcr_write_ebc);
> }
>
> +static Property ppc405_ebc_properties[] = {
> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
> +                     PowerPCCPU *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc405_ebc_realize;
> +    dc->user_creatable = false;
> +    dc->reset = ppc405_ebc_reset;
> +    device_class_set_props(dc, ppc405_ebc_properties);
> +}
> +
> +void ppc405_ebc_init(CPUPPCState *env)
> +{
> +    PowerPCCPU *cpu = env_archcpu(env);
> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
> +
> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
> +}
> +
> /*****************************************************************************/
> /* DMA controller */
> enum {
> @@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
>     object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
>
>     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
> +
> +    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
> }
>
> static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> @@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>                       s->ram_bases, s->ram_sizes, s->do_dram_init);
>
>     /* External bus controller */
> -    ppc405_ebc_init(env);
> +    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
> +                             &error_abort);

I wonder if this link to cpu could be avoided somehow? Maybe assuming that 
this device and the cpu is part of the same SoC it could get it's parent 
and access the cpu field of the parent or if that's not possible adding a 
method to the SoC to get it could avoid this link?

Regards,
BALATON Zoltan

> +    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
> +        return;
> +    }
>
>     /* DMA controller */
>     object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
> @@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>
> static const TypeInfo ppc405_types[] = {
>     {
> +        .name           = TYPE_PPC405_EBC,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(Ppc405EbcState),
> +        .class_init     = ppc405_ebc_class_init,
> +    }, {
>         .name           = TYPE_PPC405_DMA,
>         .parent         = TYPE_SYS_BUS_DEVICE,
>         .instance_size  = sizeof(Ppc405DmaState),
>

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

* Re: [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC
  2022-08-03 13:28 ` [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC Cédric Le Goater
@ 2022-08-03 23:26   ` BALATON Zoltan
  0 siblings, 0 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 23:26 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5514 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h    |  3 ++-
> hw/ppc/ppc405_uc.c | 26 +++++++++++++-------------
> 2 files changed, 15 insertions(+), 14 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 7d585a244d18..d29f738cd2d0 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -27,6 +27,7 @@
>
> #include "qom/object.h"
> #include "hw/ppc/ppc4xx.h"
> +#include "hw/intc/ppc-uic.h"
>
> #define PPC405EP_SDRAM_BASE 0x00000000
> #define PPC405EP_NVRAM_BASE 0xF0000000
> @@ -249,7 +250,7 @@ struct Ppc405SoCState {
>     hwaddr ram_size;
>
>     PowerPCCPU cpu;
> -    DeviceState *uic;
> +    PPCUIC uic;

So this patch is probably misnamed as nothing is QOMified here, the UIC is 
already a QOM object, what happens is rather embedding it in the SoC 
instead of only storing a reference. The advantage of embedding is likely 
that it does not have to be freed so we don't need an exit function but it 
adds a bunch of casts to other places. As said before you probably should 
do the casts once and store it in a local if you need it more than once or 
twice.

Regards,
BALATON Zoltan

>     Ppc405CpcState cpc;
>     Ppc405GptState gpt;
>     Ppc405OcmState ocm;
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index f39e0b44f9cc..5cd32e22b7ea 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1448,6 +1448,8 @@ static void ppc405_soc_instance_init(Object *obj)
>     object_initialize_child(obj, "cpu", &s->cpu,
>                             POWERPC_CPU_TYPE_NAME("405ep"));
>
> +    object_initialize_child(obj, "uic", &s->uic, TYPE_PPC_UIC);
> +
>     object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
>     object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
>
> @@ -1525,17 +1527,15 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>     sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
>
>     /* Universal interrupt controller */
> -    s->uic = qdev_new(TYPE_PPC_UIC);
> -
> -    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
> +    object_property_set_link(OBJECT(&s->uic), "cpu", OBJECT(&s->cpu),
>                              &error_fatal);
> -    if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->uic), errp)) {
>         return;
>     }
>
> -    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_INT,
>                        qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
> -    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_CINT,
>                        qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
>
>     /* SDRAM controller */
> @@ -1545,7 +1545,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>     s->ram_bases[0] = 0;
>     s->ram_sizes[0] = s->ram_size;
>
> -    ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17),
> +    ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17),
>                       ARRAY_SIZE(s->ram_memories), s->ram_memories,
>                       s->ram_bases, s->ram_sizes, s->do_dram_init);
>
> @@ -1565,12 +1565,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>
>     for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
>         sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
> -                           qdev_get_gpio_in(s->uic, 5 + i));
> +                           qdev_get_gpio_in(DEVICE(&s->uic), 5 + i));
>     }
>
>     /* I2C controller */
>     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
> -                         qdev_get_gpio_in(s->uic, 2));
> +                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
>
>     /* GPIO */
>     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
> @@ -1581,13 +1581,13 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>     /* Serial ports */
>     if (serial_hd(0) != NULL) {
>         serial_mm_init(get_system_memory(), 0xef600300, 0,
> -                       qdev_get_gpio_in(s->uic, 0),
> +                       qdev_get_gpio_in(DEVICE(&s->uic), 0),
>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
>                        DEVICE_BIG_ENDIAN);
>     }
>     if (serial_hd(1) != NULL) {
>         serial_mm_init(get_system_memory(), 0xef600400, 0,
> -                       qdev_get_gpio_in(s->uic, 1),
> +                       qdev_get_gpio_in(DEVICE(&s->uic), 1),
>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
>                        DEVICE_BIG_ENDIAN);
>     }
> @@ -1607,7 +1607,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>
>     for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {
>         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), i,
> -                           qdev_get_gpio_in(s->uic, 19 + i));
> +                           qdev_get_gpio_in(DEVICE(&s->uic), 19 + i));
>     }
>
>     /* MAL */
> @@ -1621,7 +1621,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>
>     for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
>         sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
> -                           qdev_get_gpio_in(s->uic, 11 + i));
> +                           qdev_get_gpio_in(DEVICE(&s->uic), 11 + i));
>     }
>
>     /* Ethernet */
>

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

* Re: [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C
  2022-08-03 13:28 ` [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C Cédric Le Goater
@ 2022-08-03 23:31   ` BALATON Zoltan
  2022-08-04  5:42     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-03 23:31 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2365 bytes --]

On Wed, 3 Aug 2022, Cédric Le Goater wrote:
> Having an explicit I2C model object will help if one day we want to
> add I2C devices on the bus.

Same here as with the UIC in previous patch, it's not QOMifying here 
either. As for why we may need I2C, on sam460ex the firmware detects RAM 
accessing the SPD data over I2C so that could be the reason but it may not 
be used here on 405.

Regards,
BALATON Zoltan

> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/ppc405.h    |  2 ++
> hw/ppc/ppc405_uc.c | 10 ++++++++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index d29f738cd2d0..d13624ae309c 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -28,6 +28,7 @@
> #include "qom/object.h"
> #include "hw/ppc/ppc4xx.h"
> #include "hw/intc/ppc-uic.h"
> +#include "hw/i2c/ppc4xx_i2c.h"
>
> #define PPC405EP_SDRAM_BASE 0x00000000
> #define PPC405EP_NVRAM_BASE 0xF0000000
> @@ -256,6 +257,7 @@ struct Ppc405SoCState {
>     Ppc405OcmState ocm;
>     Ppc405GpioState gpio;
>     Ppc405DmaState dma;
> +    PPC4xxI2CState i2c;
>     Ppc405EbcState ebc;
>     Ppc405OpbaState opba;
>     Ppc405PobState pob;
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 5cd32e22b7ea..8f0caa45f5f7 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
>
>     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>
> +    object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
> +
>     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>
>     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
> @@ -1569,8 +1571,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>     }
>
>     /* I2C controller */
> -    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
> -                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
> +                       qdev_get_gpio_in(DEVICE(&s->uic), 2));
>
>     /* GPIO */
>     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
>

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-03 13:28 ` [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC Cédric Le Goater
  2022-08-03 23:04   ` BALATON Zoltan
@ 2022-08-03 23:36   ` Daniel Henrique Barboza
  2022-08-04  5:14     ` Cédric Le Goater
  1 sibling, 1 reply; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-03 23:36 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan

Cedric,

On 8/3/22 10:28, Cédric Le Goater wrote:
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>   hw/ppc/ppc405.h    | 16 +++++++++++
>   hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>   2 files changed, 64 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 1da34a7f10f3..1c7fe07b8084 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>   
>   typedef struct Ppc405SoCState Ppc405SoCState;
>   
> +/* Peripheral controller */
> +#define TYPE_PPC405_EBC "ppc405-ebc"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
> +struct Ppc405EbcState {
> +    DeviceState parent_obj;
> +
> +    PowerPCCPU *cpu;
>   
> +    uint32_t addr;
> +    uint32_t bcr[8];
> +    uint32_t bap[8];
> +    uint32_t bear;
> +    uint32_t besr0;
> +    uint32_t besr1;
> +    uint32_t cfg;
> +};
>   
>   /* DMA controller */
>   #define TYPE_PPC405_DMA "ppc405-dma"
> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>       Ppc405OcmState ocm;
>       Ppc405GpioState gpio;
>       Ppc405DmaState dma;
> +    Ppc405EbcState ebc;
>   };
>   
>   /* PowerPC 405 core */
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 6bd93c1cb90c..0166f3fc36da 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>   
>   /*****************************************************************************/
>   /* Peripheral controller */
> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
> -struct ppc4xx_ebc_t {
> -    uint32_t addr;
> -    uint32_t bcr[8];
> -    uint32_t bap[8];
> -    uint32_t bear;
> -    uint32_t besr0;
> -    uint32_t besr1;
> -    uint32_t cfg;
> -};
> -
>   enum {
>       EBC0_CFGADDR = 0x012,
>       EBC0_CFGDATA = 0x013,
> @@ -411,10 +400,9 @@ enum {
>   
>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>   {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>       uint32_t ret;
>   
> -    ebc = opaque;
>       switch (dcrn) {
>       case EBC0_CFGADDR:
>           ret = ebc->addr;
> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>   
>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>   {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>   
> -    ebc = opaque;
>       switch (dcrn) {
>       case EBC0_CFGADDR:
>           ebc->addr = val;
> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>       }
>   }
>   
> -static void ebc_reset (void *opaque)
> +static void ppc405_ebc_reset(DeviceState *dev)
>   {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>       int i;
>   
> -    ebc = opaque;
>       ebc->addr = 0x00000000;
>       ebc->bap[0] = 0x7F8FFE80;
>       ebc->bcr[0] = 0xFFE28000;
> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>       ebc->cfg = 0x80400000;
>   }
>   
> -void ppc405_ebc_init(CPUPPCState *env)
> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>   {
> -    ppc4xx_ebc_t *ebc;
> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
> +    CPUPPCState *env;
> +
> +    assert(ebc->cpu);
> +
> +    env = &ebc->cpu->env;
>   
> -    ebc = g_new0(ppc4xx_ebc_t, 1);
> -    qemu_register_reset(&ebc_reset, ebc);
>       ppc_dcr_register(env, EBC0_CFGADDR,
>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>       ppc_dcr_register(env, EBC0_CFGDATA,
>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>   }
>   
> +static Property ppc405_ebc_properties[] = {
> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
> +                     PowerPCCPU *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc405_ebc_realize;
> +    dc->user_creatable = false;
> +    dc->reset = ppc405_ebc_reset;
> +    device_class_set_props(dc, ppc405_ebc_properties);
> +}
> +
> +void ppc405_ebc_init(CPUPPCState *env)
> +{
> +    PowerPCCPU *cpu = env_archcpu(env);
> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
> +
> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);

This line is breaking the boot of sam460ex:


  ./qemu-system-ppc64 -display none -M sam460ex
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
Aborted (core dumped)


I think you meant to link the cpu prop of the EBC obj to the CPU object,
not the cpu prop of the CPU obj to the EBC dev.


This fixes the issue:


$ git diff
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0166f3fc36..aac3a3f761 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -594,7 +594,7 @@ void ppc405_ebc_init(CPUPPCState *env)
      PowerPCCPU *cpu = env_archcpu(env);
      DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
  
-    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+    object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
      qdev_realize_and_unref(dev, NULL, &error_fatal);
  }


Daniel


> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
> +}
> +
>   /*****************************************************************************/
>   /* DMA controller */
>   enum {
> @@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
>       object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
>   
>       object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
> +
> +    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>   }
>   
>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> @@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>                         s->ram_bases, s->ram_sizes, s->do_dram_init);
>   
>       /* External bus controller */
> -    ppc405_ebc_init(env);
> +    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
> +                             &error_abort);
> +    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
> +        return;
> +    }
>   
>       /* DMA controller */
>       object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
> @@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>   
>   static const TypeInfo ppc405_types[] = {
>       {
> +        .name           = TYPE_PPC405_EBC,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(Ppc405EbcState),
> +        .class_init     = ppc405_ebc_class_init,
> +    }, {
>           .name           = TYPE_PPC405_DMA,
>           .parent         = TYPE_SYS_BUS_DEVICE,
>           .instance_size  = sizeof(Ppc405DmaState),


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

* Re: [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB
  2022-08-03 13:28 ` [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB Cédric Le Goater
@ 2022-08-03 23:38   ` Daniel Henrique Barboza
  0 siblings, 0 replies; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-03 23:38 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan



On 8/3/22 10:28, Cédric Le Goater wrote:
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>   hw/ppc/ppc405.h    | 14 ++++++++++
>   hw/ppc/ppc405_uc.c | 67 +++++++++++++++++++++++++++++++++-------------
>   2 files changed, 62 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 8acb90427596..8ca32f35ce67 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -65,6 +65,19 @@ struct ppc4xx_bd_info_t {
>   
>   typedef struct Ppc405SoCState Ppc405SoCState;
>   
> +/* Peripheral local bus arbitrer */
> +#define TYPE_PPC405_PLB "ppc405-plb"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PlbState, PPC405_PLB);
> +struct Ppc405PlbState {
> +    DeviceState parent_obj;
> +
> +    PowerPCCPU *cpu;
> +
> +    uint32_t acr;
> +    uint32_t bear;
> +    uint32_t besr;
> +};
> +
>   /* PLB to OPB bridge */
>   #define TYPE_PPC405_POB "ppc405-pob"
>   OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
> @@ -245,6 +258,7 @@ struct Ppc405SoCState {
>       Ppc405EbcState ebc;
>       Ppc405OpbaState opba;
>       Ppc405PobState pob;
> +    Ppc405PlbState plb;
>   };
>   
>   /* PowerPC 405 core */
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index ca214ee4d741..9bbd524ad5ea 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -148,19 +148,11 @@ enum {
>       PLB4A1_ACR = 0x089,
>   };
>   
> -typedef struct ppc4xx_plb_t ppc4xx_plb_t;
> -struct ppc4xx_plb_t {
> -    uint32_t acr;
> -    uint32_t bear;
> -    uint32_t besr;
> -};
> -
>   static uint32_t dcr_read_plb (void *opaque, int dcrn)
>   {
> -    ppc4xx_plb_t *plb;
> +    Ppc405PlbState *plb = PPC405_PLB(opaque);
>       uint32_t ret;
>   
> -    plb = opaque;
>       switch (dcrn) {
>       case PLB0_ACR:
>           ret = plb->acr;
> @@ -182,9 +174,8 @@ static uint32_t dcr_read_plb (void *opaque, int dcrn)
>   
>   static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
>   {
> -    ppc4xx_plb_t *plb;
> +    Ppc405PlbState *plb = PPC405_PLB(opaque);
>   
> -    plb = opaque;
>       switch (dcrn) {
>       case PLB0_ACR:
>           /* We don't care about the actual parameters written as
> @@ -202,28 +193,55 @@ static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
>       }
>   }
>   
> -static void ppc4xx_plb_reset (void *opaque)
> +static void ppc405_plb_reset(DeviceState *dev)
>   {
> -    ppc4xx_plb_t *plb;
> +    Ppc405PlbState *plb = PPC405_PLB(dev);
>   
> -    plb = opaque;
>       plb->acr = 0x00000000;
>       plb->bear = 0x00000000;
>       plb->besr = 0x00000000;
>   }
>   
> -void ppc4xx_plb_init(CPUPPCState *env)
> +static void ppc405_plb_realize(DeviceState *dev, Error **errp)
>   {
> -    ppc4xx_plb_t *plb;
> +    Ppc405PlbState *plb = PPC405_PLB(dev);
> +    CPUPPCState *env;
> +
> +    assert(plb->cpu);
> +
> +    env = &plb->cpu->env;
>   
> -    plb = g_new0(ppc4xx_plb_t, 1);
>       ppc_dcr_register(env, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
>       ppc_dcr_register(env, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
>       ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
>       ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
>       ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
>       ppc_dcr_register(env, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
> -    qemu_register_reset(ppc4xx_plb_reset, plb);
> +}
> +
> +static Property ppc405_plb_properties[] = {
> +    DEFINE_PROP_LINK("cpu", Ppc405PlbState, cpu, TYPE_POWERPC_CPU,
> +                     PowerPCCPU *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc405_plb_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc405_plb_realize;
> +    dc->user_creatable = false;
> +    dc->reset = ppc405_plb_reset;
> +    device_class_set_props(dc, ppc405_plb_properties);
> +}
> +
> +void ppc4xx_plb_init(CPUPPCState *env)
> +{
> +    PowerPCCPU *cpu = env_archcpu(env);
> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
> +
> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);

This causes the same problem that happened in patch 12:


$ ./qemu-system-ppc64 -display none -M sam460ex
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
Aborted (core dumped)


The same fix applies here as well:


$ git diff
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index dd3c05a28b..fd53cf38e5 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -240,7 +240,7 @@ void ppc4xx_plb_init(CPUPPCState *env)
      PowerPCCPU *cpu = env_archcpu(env);
      DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
  
-    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+    object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
      qdev_realize_and_unref(dev, NULL, &error_fatal);
  }
  

Daniel


> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
>   }
>   
>   /*****************************************************************************/
> @@ -1446,6 +1464,8 @@ static void ppc405_soc_instance_init(Object *obj)
>       object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
>   
>       object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
> +
> +    object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
>   }
>   
>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
> @@ -1484,7 +1504,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>       }
>   
>       /* PLB arbitrer */
> -    ppc4xx_plb_init(env);
> +    object_property_set_link(OBJECT(&s->plb), "cpu", OBJECT(&s->cpu),
> +                             &error_abort);
> +    if (!qdev_realize(DEVICE(&s->plb), NULL, errp)) {
> +        return;
> +    }
>   
>       /* PLB to OPB bridge */
>       object_property_set_link(OBJECT(&s->pob), "cpu", OBJECT(&s->cpu),
> @@ -1615,6 +1639,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>   
>   static const TypeInfo ppc405_types[] = {
>       {
> +        .name           = TYPE_PPC405_PLB,
> +        .parent         = TYPE_DEVICE,
> +        .instance_size  = sizeof(Ppc405PlbState),
> +        .class_init     = ppc405_plb_class_init,
> +    }, {
>           .name           = TYPE_PPC405_POB,
>           .parent         = TYPE_DEVICE,
>           .instance_size  = sizeof(Ppc405PobState),


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

* Re: [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL
  2022-08-03 13:28 ` [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL Cédric Le Goater
@ 2022-08-03 23:45   ` Daniel Henrique Barboza
  0 siblings, 0 replies; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-03 23:45 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan

This patch really broke sam460ex boot, but not because of the
QOMification. I managed to get it work by doing the following:

On 8/3/22 10:28, Cédric Le Goater wrote:
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>   hw/ppc/ppc405.h         |   1 +
>   include/hw/ppc/ppc4xx.h |  28 ++++++++++
>   hw/ppc/ppc405_uc.c      |  20 +++++--
>   hw/ppc/ppc4xx_devs.c    | 120 +++++++++++++++++++++++++---------------
>   4 files changed, 118 insertions(+), 51 deletions(-)
> 
> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
> index 8ca32f35ce67..7d585a244d18 100644
> --- a/hw/ppc/ppc405.h
> +++ b/hw/ppc/ppc405.h
> @@ -259,6 +259,7 @@ struct Ppc405SoCState {
>       Ppc405OpbaState opba;
>       Ppc405PobState pob;
>       Ppc405PlbState plb;
> +    Ppc4xxMalState mal;
>   };
>   
>   /* PowerPC 405 core */
> diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
> index 021376c2d260..c31219265273 100644
> --- a/include/hw/ppc/ppc4xx.h
> +++ b/include/hw/ppc/ppc4xx.h
> @@ -26,6 +26,7 @@
>   #define PPC4XX_H
>   
>   #include "hw/ppc/ppc.h"
> +#include "hw/sysbus.h"
>   #include "exec/memory.h"
>   
>   /* PowerPC 4xx core initialization */
> @@ -45,6 +46,33 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
>                           hwaddr *ram_sizes,
>                           int do_init);
>   
> +/* Memory Access Layer (MAL) */
> +#define TYPE_PPC4xx_MAL "ppc4xx-mal"
> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxMalState, PPC4xx_MAL);
> +struct Ppc4xxMalState {
> +    SysBusDevice parent_obj;
> +
> +    PowerPCCPU *cpu;
> +
> +    qemu_irq irqs[4];
> +    uint32_t cfg;
> +    uint32_t esr;
> +    uint32_t ier;
> +    uint32_t txcasr;
> +    uint32_t txcarr;
> +    uint32_t txeobisr;
> +    uint32_t txdeir;
> +    uint32_t rxcasr;
> +    uint32_t rxcarr;
> +    uint32_t rxeobisr;
> +    uint32_t rxdeir;
> +    uint32_t *txctpr;
> +    uint32_t *rxctpr;
> +    uint32_t *rcbs;
> +    uint8_t  txcnum;
> +    uint8_t  rxcnum;
> +};
> +
>   void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
>                        qemu_irq irqs[4]);
>   
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 9bbd524ad5ea..f39e0b44f9cc 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1466,12 +1466,13 @@ static void ppc405_soc_instance_init(Object *obj)
>       object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
>   
>       object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
> +
> +    object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL);
>   }
>   
>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>   {
>       Ppc405SoCState *s = PPC405_SOC(dev);
> -    qemu_irq mal_irqs[4];
>       CPUPPCState *env;
>       Error *err = NULL;
>       int i;
> @@ -1610,11 +1611,18 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>       }
>   
>       /* MAL */
> -    mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
> -    mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
> -    mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
> -    mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
> -    ppc4xx_mal_init(env, 4, 2, mal_irqs);
> +    object_property_set_int(OBJECT(&s->mal), "txc-num", 4, &error_abort);
> +    object_property_set_int(OBJECT(&s->mal), "rxc-num", 2, &error_abort);
> +    object_property_set_link(OBJECT(&s->mal), "cpu", OBJECT(&s->cpu),
> +                             &error_abort);
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->mal), errp)) {
> +        return;
> +    }
> +
> +    for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
> +                           qdev_get_gpio_in(s->uic, 11 + i));
> +    }
>   
>       /* Ethernet */
>       /* Uses UIC IRQs 9, 15, 17 */
> diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
> index f20098cf417c..0e97347e2839 100644
> --- a/hw/ppc/ppc4xx_devs.c
> +++ b/hw/ppc/ppc4xx_devs.c
> @@ -491,32 +491,10 @@ enum {
>       MAL0_RCBS1    = 0x1E1,
>   };
>   
> -typedef struct ppc4xx_mal_t ppc4xx_mal_t;
> -struct ppc4xx_mal_t {
> -    qemu_irq irqs[4];
> -    uint32_t cfg;
> -    uint32_t esr;
> -    uint32_t ier;
> -    uint32_t txcasr;
> -    uint32_t txcarr;
> -    uint32_t txeobisr;
> -    uint32_t txdeir;
> -    uint32_t rxcasr;
> -    uint32_t rxcarr;
> -    uint32_t rxeobisr;
> -    uint32_t rxdeir;
> -    uint32_t *txctpr;
> -    uint32_t *rxctpr;
> -    uint32_t *rcbs;
> -    uint8_t  txcnum;
> -    uint8_t  rxcnum;
> -};
> -
> -static void ppc4xx_mal_reset(void *opaque)
> +static void ppc4xx_mal_reset(DeviceState *dev)
>   {
> -    ppc4xx_mal_t *mal;
> +    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
>   
> -    mal = opaque;
>       mal->cfg = 0x0007C000;
>       mal->esr = 0x00000000;
>       mal->ier = 0x00000000;
> @@ -530,10 +508,9 @@ static void ppc4xx_mal_reset(void *opaque)
>   
>   static uint32_t dcr_read_mal(void *opaque, int dcrn)
>   {
> -    ppc4xx_mal_t *mal;
> +    Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
>       uint32_t ret;
>   
> -    mal = opaque;
>       switch (dcrn) {
>       case MAL0_CFG:
>           ret = mal->cfg;
> @@ -587,13 +564,12 @@ static uint32_t dcr_read_mal(void *opaque, int dcrn)
>   
>   static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
>   {
> -    ppc4xx_mal_t *mal;
> +    Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
>   
> -    mal = opaque;
>       switch (dcrn) {
>       case MAL0_CFG:
>           if (val & 0x80000000) {
> -            ppc4xx_mal_reset(mal);
> +            ppc4xx_mal_reset(DEVICE(mal));
>           }
>           mal->cfg = val & 0x00FFC087;
>           break;
> @@ -644,23 +620,30 @@ static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
>       }
>   }
>   
> -void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
> -                     qemu_irq irqs[4])
> +static void ppc4xx_mal_realize(DeviceState *dev, Error **errp)
>   {
> -    ppc4xx_mal_t *mal;
> +    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    CPUPPCState *env;
>       int i;
>   
> -    assert(txcnum <= 32 && rxcnum <= 32);
> -    mal = g_malloc0(sizeof(*mal));
> -    mal->txcnum = txcnum;
> -    mal->rxcnum = rxcnum;
> -    mal->txctpr = g_new0(uint32_t, txcnum);
> -    mal->rxctpr = g_new0(uint32_t, rxcnum);
> -    mal->rcbs = g_new0(uint32_t, rxcnum);
> -    for (i = 0; i < 4; i++) {
> -        mal->irqs[i] = irqs[i];
> +    assert(mal->cpu);
> +
> +    env = &mal->cpu->env;
> +
> +    if (mal->txcnum > 32 || mal->rxcnum > 32) {
> +        error_setg(errp, "invalid TXC/RXC number");
> +        return;
>       }
> -    qemu_register_reset(&ppc4xx_mal_reset, mal);
> +
> +    mal->txctpr = g_new0(uint32_t, mal->txcnum);
> +    mal->rxctpr = g_new0(uint32_t, mal->rxcnum);
> +    mal->rcbs = g_new0(uint32_t, mal->rxcnum);
> +
> +    for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
> +        sysbus_init_irq(sbd, &mal->irqs[i]);
> +    }
> +
>       ppc_dcr_register(env, MAL0_CFG,
>                        mal, &dcr_read_mal, &dcr_write_mal);
>       ppc_dcr_register(env, MAL0_ESR,
> @@ -683,16 +666,63 @@ void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
>                        mal, &dcr_read_mal, &dcr_write_mal);
>       ppc_dcr_register(env, MAL0_RXDEIR,
>                        mal, &dcr_read_mal, &dcr_write_mal);
> -    for (i = 0; i < txcnum; i++) {
> +    for (i = 0; i < mal->txcnum; i++) {
>           ppc_dcr_register(env, MAL0_TXCTP0R + i,
>                            mal, &dcr_read_mal, &dcr_write_mal);
>       }
> -    for (i = 0; i < rxcnum; i++) {
> +    for (i = 0; i < mal->rxcnum; i++) {
>           ppc_dcr_register(env, MAL0_RXCTP0R + i,
>                            mal, &dcr_read_mal, &dcr_write_mal);
>       }
> -    for (i = 0; i < rxcnum; i++) {
> +    for (i = 0; i < mal->rxcnum; i++) {
>           ppc_dcr_register(env, MAL0_RCBS0 + i,
>                            mal, &dcr_read_mal, &dcr_write_mal);
>       }
>   }
> +
> +static Property ppc4xx_mal_properties[] = {
> +    DEFINE_PROP_UINT8("txc-num", Ppc4xxMalState, txcnum, 0),
> +    DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0),
> +    DEFINE_PROP_LINK("cpu", Ppc4xxMalState, cpu, TYPE_POWERPC_CPU,
> +                     PowerPCCPU *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ppc4xx_mal_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = ppc4xx_mal_realize;
> +    dc->user_creatable = false;
> +    dc->reset = ppc4xx_mal_reset;
> +    device_class_set_props(dc, ppc4xx_mal_properties);
> +}
> +
> +void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
> +                     qemu_irq irqs[4])
> +{
> +    PowerPCCPU *cpu = env_archcpu(env);
> +    DeviceState *dev = qdev_new(TYPE_PPC4xx_MAL);
> +    Ppc4xxMalState *mal = PPC4xx_MAL(dev);
> +    int i;
> +
> +    qdev_prop_set_uint32(dev, "txc-num", txcnum);
> +    qdev_prop_set_uint32(dev, "rxc-num", rxcnum);
> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);

Changed this to:

      object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);


> +    qdev_realize_and_unref(dev, NULL, &error_fatal);

Changed this to:

     sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

Because qdev complained that MAL is a sysbus device.


> +
> +    for (i = 0; i < ARRAY_SIZE(mal->irqs); i++) {
> +        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irqs[i]);
> +    }

And this line broke sam460ex because, back in sam460ex.c, we're not storing
all the GPIO lines in sam460ex_init():


      for (i = 0; i < ARRAY_SIZE(mal_irqs); i++) {
         mal_irqs[0] = qdev_get_gpio_in(uic[2], 3 + i);
      }
      ppc4xx_mal_init(env, 4, 16, mal_irqs);

We're just storing the last line in mal_irqs[0]. sysbus_connect_irq() gets really
upset about it.


Since this is a separated bug (which is eligible for the freeze) I sent a patch
to fix it standalone. Your series can then be rebased on top of that fix.



Daniel

> +}
> +
> +static const TypeInfo ppc4xx_types[] = {
> +    {
> +        .name           = TYPE_PPC4xx_MAL,
> +        .parent         = TYPE_SYS_BUS_DEVICE,
> +        .instance_size  = sizeof(Ppc4xxMalState),
> +        .class_init     = ppc4xx_mal_class_init,
> +    }
> +};
> +
> +DEFINE_TYPES(ppc4xx_types)


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

* Re: [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC
  2022-08-03 17:16   ` BALATON Zoltan
@ 2022-08-04  5:09     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  5:09 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 8/3/22 19:16, BALATON Zoltan wrote:
> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> Introduce a QOM property "cpu" to initialize the DCR handlers. This is
>> a pattern that we will reuse for the all other 405 devices needing it.
>>
>> Now that all clock settings are handled at the CPC level, change the
>> SoC "sys-clk" property to be an alias on the same property in the CPC
>> model.
>>
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405.h    |  39 +++++++++++++++-
>> hw/ppc/ppc405_uc.c | 109 +++++++++++++++++++--------------------------
>> 2 files changed, 85 insertions(+), 63 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>> index ae64549537c6..88c63774d9ba 100644
>> --- a/hw/ppc/ppc405.h
>> +++ b/hw/ppc/ppc405.h
>> @@ -63,6 +63,43 @@ struct ppc4xx_bd_info_t {
>>     uint32_t bi_iic_fast[2];
>> };
>>
>> +typedef struct Ppc405SoCState Ppc405SoCState;

That's a left over from previous experiment passing the SoC to
the device model to initialize the DCR handlers. Passing the CPU
is enough.

We can drop the forward declaration.

Thanks,

C.


> 
> This typedef is already done by the OBJECT_DECLARE_SIMPLE_TYPE macro below. Could some compilers complain about double typedef? There may be some circular dependencies here so to avoid a separate typedef you may need to bring the OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC); line up here to the front while keeping the actual declaration of the state struct and rest of the object later which separates them but adding a comment may explain that. I'm not sure if it's better to do that or repeating the typedef in advance as done here is better but declaring the object in advance is probably a bit cleaner than repeating part of its internals just in case this implementation detail ever changes.
> 
> Regards,
> BALATON Zoltan
> 
>> +
>> +#define TYPE_PPC405_CPC "ppc405-cpc"
>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
>> +
>> +enum {
>> +    PPC405EP_CPU_CLK   = 0,
>> +    PPC405EP_PLB_CLK   = 1,
>> +    PPC405EP_OPB_CLK   = 2,
>> +    PPC405EP_EBC_CLK   = 3,
>> +    PPC405EP_MAL_CLK   = 4,
>> +    PPC405EP_PCI_CLK   = 5,
>> +    PPC405EP_UART0_CLK = 6,
>> +    PPC405EP_UART1_CLK = 7,
>> +    PPC405EP_CLK_NB    = 8,
>> +};
>> +
>> +struct Ppc405CpcState {
>> +    DeviceState parent_obj;
>> +
>> +    PowerPCCPU *cpu;
>> +
>> +    uint32_t sysclk;
>> +    clk_setup_t clk_setup[PPC405EP_CLK_NB];
>> +    uint32_t boot;
>> +    uint32_t epctl;
>> +    uint32_t pllmr[2];
>> +    uint32_t ucr;
>> +    uint32_t srr;
>> +    uint32_t jtagid;
>> +    uint32_t pci;
>> +    /* Clock and power management */
>> +    uint32_t er;
>> +    uint32_t fr;
>> +    uint32_t sr;
>> +};
>> +
>> #define TYPE_PPC405_SOC "ppc405-soc"
>> OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
>>
>> @@ -79,9 +116,9 @@ struct Ppc405SoCState {
>>     MemoryRegion *dram_mr;
>>     hwaddr ram_size;
>>
>> -    uint32_t sysclk;
>>     PowerPCCPU cpu;
>>     DeviceState *uic;
>> +    Ppc405CpcState cpc;
>> };
>>
>> /* PowerPC 405 core */
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 013dccee898b..32bfc9480bc6 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -1178,36 +1178,7 @@ enum {
>> #endif
>> };
>>
>> -enum {
>> -    PPC405EP_CPU_CLK   = 0,
>> -    PPC405EP_PLB_CLK   = 1,
>> -    PPC405EP_OPB_CLK   = 2,
>> -    PPC405EP_EBC_CLK   = 3,
>> -    PPC405EP_MAL_CLK   = 4,
>> -    PPC405EP_PCI_CLK   = 5,
>> -    PPC405EP_UART0_CLK = 6,
>> -    PPC405EP_UART1_CLK = 7,
>> -    PPC405EP_CLK_NB    = 8,
>> -};
>> -
>> -typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
>> -struct ppc405ep_cpc_t {
>> -    uint32_t sysclk;
>> -    clk_setup_t clk_setup[PPC405EP_CLK_NB];
>> -    uint32_t boot;
>> -    uint32_t epctl;
>> -    uint32_t pllmr[2];
>> -    uint32_t ucr;
>> -    uint32_t srr;
>> -    uint32_t jtagid;
>> -    uint32_t pci;
>> -    /* Clock and power management */
>> -    uint32_t er;
>> -    uint32_t fr;
>> -    uint32_t sr;
>> -};
>> -
>> -static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
>> +static void ppc405ep_compute_clocks(Ppc405CpcState *cpc)
>> {
>>     uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
>>     uint32_t UART0_clk, UART1_clk;
>> @@ -1302,10 +1273,9 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
>>
>> static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
>> {
>> -    ppc405ep_cpc_t *cpc;
>> +    Ppc405CpcState *cpc = PPC405_CPC(opaque);
>>     uint32_t ret;
>>
>> -    cpc = opaque;
>>     switch (dcrn) {
>>     case PPC405EP_CPC0_BOOT:
>>         ret = cpc->boot;
>> @@ -1342,9 +1312,8 @@ static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
>>
>> static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
>> {
>> -    ppc405ep_cpc_t *cpc;
>> +    Ppc405CpcState *cpc = PPC405_CPC(opaque);
>>
>> -    cpc = opaque;
>>     switch (dcrn) {
>>     case PPC405EP_CPC0_BOOT:
>>         /* Read-only register */
>> @@ -1377,9 +1346,9 @@ static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
>>     }
>> }
>>
>> -static void ppc405ep_cpc_reset (void *opaque)
>> +static void ppc405_cpc_reset(DeviceState *dev)
>> {
>> -    ppc405ep_cpc_t *cpc = opaque;
>> +    Ppc405CpcState *cpc = PPC405_CPC(dev);
>>
>>     cpc->boot = 0x00000010;     /* Boot from PCI - IIC EEPROM disabled */
>>     cpc->epctl = 0x00000000;
>> @@ -1391,21 +1360,24 @@ static void ppc405ep_cpc_reset (void *opaque)
>>     cpc->er = 0x00000000;
>>     cpc->fr = 0x00000000;
>>     cpc->sr = 0x00000000;
>> +    cpc->jtagid = 0x20267049;
>>     ppc405ep_compute_clocks(cpc);
>> }
>>
>> /* XXX: sysclk should be between 25 and 100 MHz */
>> -static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
>> -                               uint32_t sysclk)
>> +static void ppc405_cpc_realize(DeviceState *dev, Error **errp)
>> {
>> -    ppc405ep_cpc_t *cpc;
>> +    Ppc405CpcState *cpc = PPC405_CPC(dev);
>> +    CPUPPCState *env;
>> +
>> +    assert(cpc->cpu);
>> +
>> +    env = &cpc->cpu->env;
>> +
>> +    cpc->clk_setup[PPC405EP_CPU_CLK].cb =
>> +        ppc_40x_timers_init(env, cpc->sysclk, PPC_INTERRUPT_PIT);
>> +    cpc->clk_setup[PPC405EP_CPU_CLK].opaque = env;
>>
>> -    cpc = g_new0(ppc405ep_cpc_t, 1);
>> -    memcpy(cpc->clk_setup, clk_setup,
>> -           PPC405EP_CLK_NB * sizeof(clk_setup_t));
>> -    cpc->jtagid = 0x20267049;
>> -    cpc->sysclk = sysclk;
>> -    qemu_register_reset(&ppc405ep_cpc_reset, cpc);
>>     ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
>>                      &dcr_read_epcpc, &dcr_write_epcpc);
>>     ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
>> @@ -1422,14 +1394,23 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
>>                      &dcr_read_epcpc, &dcr_write_epcpc);
>>     ppc_dcr_register(env, PPC405EP_CPC0_PCI, cpc,
>>                      &dcr_read_epcpc, &dcr_write_epcpc);
>> -#if 0
>> -    ppc_dcr_register(env, PPC405EP_CPC0_ER, cpc,
>> -                     &dcr_read_epcpc, &dcr_write_epcpc);
>> -    ppc_dcr_register(env, PPC405EP_CPC0_FR, cpc,
>> -                     &dcr_read_epcpc, &dcr_write_epcpc);
>> -    ppc_dcr_register(env, PPC405EP_CPC0_SR, cpc,
>> -                     &dcr_read_epcpc, &dcr_write_epcpc);
>> -#endif
>> +}
>> +
>> +static Property ppc405_cpc_properties[] = {
>> +    DEFINE_PROP_LINK("cpu", Ppc405CpcState, cpu, TYPE_POWERPC_CPU,
>> +                     PowerPCCPU *),
>> +    DEFINE_PROP_UINT32("sys-clk", Ppc405CpcState, sysclk, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void ppc405_cpc_class_init(ObjectClass *oc, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>> +
>> +    dc->realize = ppc405_cpc_realize;
>> +    dc->user_creatable = false;
>> +    dc->reset = ppc405_cpc_reset;
>> +    device_class_set_props(dc, ppc405_cpc_properties);
>> }
>>
>> static void ppc405_soc_instance_init(Object *obj)
>> @@ -1438,12 +1419,14 @@ static void ppc405_soc_instance_init(Object *obj)
>>
>>     object_initialize_child(obj, "cpu", &s->cpu,
>>                             POWERPC_CPU_TYPE_NAME("405ep"));
>> +
>> +    object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
>> +    object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
>> }
>>
>> static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>> {
>>     Ppc405SoCState *s = PPC405_SOC(dev);
>> -    clk_setup_t clk_setup[PPC405EP_CLK_NB];
>>     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
>>     CPUPPCState *env;
>>     Error *err = NULL;
>> @@ -1458,8 +1441,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>     memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
>>                                 &s->sram);
>>
>> -    memset(clk_setup, 0, sizeof(clk_setup));
>> -
>>     /* init CPUs */
>>     if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
>>         return;
>> @@ -1468,14 +1449,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>
>>     env = &s->cpu.env;
>>
>> -    clk_setup[PPC405EP_CPU_CLK].cb =
>> -        ppc_40x_timers_init(env, s->sysclk, PPC_INTERRUPT_PIT);
>> -    clk_setup[PPC405EP_CPU_CLK].opaque = env;
>> -
>>     ppc_dcr_init(env, NULL, NULL);
>>
>>     /* CPU control */
>> -    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
>> +    object_property_set_link(OBJECT(&s->cpc), "cpu", OBJECT(&s->cpu),
>> +                             &error_abort);
>> +    if (!qdev_realize(DEVICE(&s->cpc), NULL, errp)) {
>> +        return;
>> +    }
>>
>>     /* PLB arbitrer */
>>     ppc4xx_plb_init(env);
>> @@ -1566,7 +1547,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>> static Property ppc405_soc_properties[] = {
>>     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
>>                      MemoryRegion *),
>> -    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
>>     DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
>>     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
>>     DEFINE_PROP_END_OF_LIST(),
>> @@ -1583,6 +1563,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>>
>> static const TypeInfo ppc405_types[] = {
>>     {
>> +        .name           = TYPE_PPC405_CPC,
>> +        .parent         = TYPE_DEVICE,
>> +        .instance_size  = sizeof(Ppc405CpcState),
>> +        .class_init     = ppc405_cpc_class_init,
>> +    }, {
>>         .name           = TYPE_PPC405_SOC,
>>         .parent         = TYPE_DEVICE,
>>         .instance_size  = sizeof(Ppc405SoCState),
>>



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-03 23:36   ` Daniel Henrique Barboza
@ 2022-08-04  5:14     ` Cédric Le Goater
  2022-08-04 12:09       ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  5:14 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan

On 8/4/22 01:36, Daniel Henrique Barboza wrote:
> Cedric,
> 
> On 8/3/22 10:28, Cédric Le Goater wrote:
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>   hw/ppc/ppc405.h    | 16 +++++++++++
>>   hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>>   2 files changed, 64 insertions(+), 23 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>> index 1da34a7f10f3..1c7fe07b8084 100644
>> --- a/hw/ppc/ppc405.h
>> +++ b/hw/ppc/ppc405.h
>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>   typedef struct Ppc405SoCState Ppc405SoCState;
>> +/* Peripheral controller */
>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>> +struct Ppc405EbcState {
>> +    DeviceState parent_obj;
>> +
>> +    PowerPCCPU *cpu;
>> +    uint32_t addr;
>> +    uint32_t bcr[8];
>> +    uint32_t bap[8];
>> +    uint32_t bear;
>> +    uint32_t besr0;
>> +    uint32_t besr1;
>> +    uint32_t cfg;
>> +};
>>   /* DMA controller */
>>   #define TYPE_PPC405_DMA "ppc405-dma"
>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>       Ppc405OcmState ocm;
>>       Ppc405GpioState gpio;
>>       Ppc405DmaState dma;
>> +    Ppc405EbcState ebc;
>>   };
>>   /* PowerPC 405 core */
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 6bd93c1cb90c..0166f3fc36da 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>   /*****************************************************************************/
>>   /* Peripheral controller */
>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>> -struct ppc4xx_ebc_t {
>> -    uint32_t addr;
>> -    uint32_t bcr[8];
>> -    uint32_t bap[8];
>> -    uint32_t bear;
>> -    uint32_t besr0;
>> -    uint32_t besr1;
>> -    uint32_t cfg;
>> -};
>> -
>>   enum {
>>       EBC0_CFGADDR = 0x012,
>>       EBC0_CFGDATA = 0x013,
>> @@ -411,10 +400,9 @@ enum {
>>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>   {
>> -    ppc4xx_ebc_t *ebc;
>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>       uint32_t ret;
>> -    ebc = opaque;
>>       switch (dcrn) {
>>       case EBC0_CFGADDR:
>>           ret = ebc->addr;
>> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>   {
>> -    ppc4xx_ebc_t *ebc;
>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>> -    ebc = opaque;
>>       switch (dcrn) {
>>       case EBC0_CFGADDR:
>>           ebc->addr = val;
>> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>       }
>>   }
>> -static void ebc_reset (void *opaque)
>> +static void ppc405_ebc_reset(DeviceState *dev)
>>   {
>> -    ppc4xx_ebc_t *ebc;
>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>       int i;
>> -    ebc = opaque;
>>       ebc->addr = 0x00000000;
>>       ebc->bap[0] = 0x7F8FFE80;
>>       ebc->bcr[0] = 0xFFE28000;
>> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>>       ebc->cfg = 0x80400000;
>>   }
>> -void ppc405_ebc_init(CPUPPCState *env)
>> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>>   {
>> -    ppc4xx_ebc_t *ebc;
>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>> +    CPUPPCState *env;
>> +
>> +    assert(ebc->cpu);
>> +
>> +    env = &ebc->cpu->env;
>> -    ebc = g_new0(ppc4xx_ebc_t, 1);
>> -    qemu_register_reset(&ebc_reset, ebc);
>>       ppc_dcr_register(env, EBC0_CFGADDR,
>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>       ppc_dcr_register(env, EBC0_CFGDATA,
>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>   }
>> +static Property ppc405_ebc_properties[] = {
>> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
>> +                     PowerPCCPU *),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>> +
>> +    dc->realize = ppc405_ebc_realize;
>> +    dc->user_creatable = false;
>> +    dc->reset = ppc405_ebc_reset;
>> +    device_class_set_props(dc, ppc405_ebc_properties);
>> +}
>> +
>> +void ppc405_ebc_init(CPUPPCState *env)
>> +{
>> +    PowerPCCPU *cpu = env_archcpu(env);
>> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>> +
>> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
> 
> This line is breaking the boot of sam460ex:
> 
> 
>   ./qemu-system-ppc64 -display none -M sam460ex
> Unexpected error in object_property_find_err() at ../qom/object.c:1304:
> qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
> Aborted (core dumped)
> 
> 
> I think you meant to link the cpu prop of the EBC obj to the CPU object,
> not the cpu prop of the CPU obj to the EBC dev.

Yes. ppc405_ebc_init() has only one user left, the sam460ex, which I didn't
test :/

Thanks,

C.
  
> 
> This fixes the issue:
> 
> 
> $ git diff
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index 0166f3fc36..aac3a3f761 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -594,7 +594,7 @@ void ppc405_ebc_init(CPUPPCState *env)
>       PowerPCCPU *cpu = env_archcpu(env);
>       DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
> 
> -    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
> +    object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
>       qdev_realize_and_unref(dev, NULL, &error_fatal);
>   }
>
> 
> Daniel
> 
> 
>> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
>> +}
>> +
>>   /*****************************************************************************/
>>   /* DMA controller */
>>   enum {
>> @@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>       object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
>>       object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>> +
>> +    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>   }
>>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>> @@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>                         s->ram_bases, s->ram_sizes, s->do_dram_init);
>>       /* External bus controller */
>> -    ppc405_ebc_init(env);
>> +    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
>> +                             &error_abort);
>> +    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
>> +        return;
>> +    }
>>       /* DMA controller */
>>       object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
>> @@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>>   static const TypeInfo ppc405_types[] = {
>>       {
>> +        .name           = TYPE_PPC405_EBC,
>> +        .parent         = TYPE_DEVICE,
>> +        .instance_size  = sizeof(Ppc405EbcState),
>> +        .class_init     = ppc405_ebc_class_init,
>> +    }, {
>>           .name           = TYPE_PPC405_DMA,
>>           .parent         = TYPE_SYS_BUS_DEVICE,
>>           .instance_size  = sizeof(Ppc405DmaState),



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

* Re: [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine
  2022-08-03 22:07   ` BALATON Zoltan
@ 2022-08-04  5:40     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  5:40 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 8/4/22 00:07, BALATON Zoltan wrote:
> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> We will use this machine as a base to define the ref405ep and possibly
>> the PPC405 hotfoot board as found in the Linux kernel.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405_boards.c | 31 ++++++++++++++++++++++++++++---
>> 1 file changed, 28 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
>> index 1a4e7588c584..4c269b6526a5 100644
>> --- a/hw/ppc/ppc405_boards.c
>> +++ b/hw/ppc/ppc405_boards.c
>> @@ -50,6 +50,15 @@
>>
>> #define USE_FLASH_BIOS
>>
>> +struct Ppc405MachineState {
>> +    /* Private */
>> +    MachineState parent_obj;
>> +    /* Public */
>> +};
>> +
>> +#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
>> +
>> /*****************************************************************************/
>> /* PPC405EP reference board (IBM) */
>> /* Standalone board with:
>> @@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void *data)
>>
>>     mc->desc = "ref405ep";
>>     mc->init = ref405ep_init;
>> -    mc->default_ram_size = 0x08000000;
>> -    mc->default_ram_id = "ef405ep.ram";
>> }
>>
>> static const TypeInfo ref405ep_type = {
>>     .name = MACHINE_TYPE_NAME("ref405ep"),
>> -    .parent = TYPE_MACHINE,
>> +    .parent = TYPE_PPC405_MACHINE,
>>     .class_init = ref405ep_class_init,
>> };
>>
>> +static void ppc405_machine_class_init(ObjectClass *oc, void *data)
>> +{
>> +    MachineClass *mc = MACHINE_CLASS(oc);
>> +
>> +    mc->desc = "PPC405 generic machine";
>> +    mc->default_ram_size = 0x08000000;
>> +    mc->default_ram_id = "ppc405.ram";
> 
> Is the default RAM size a property of specific boards or the PPC405? I think it could be different for different boards so don't see why it's moved to the generic machine but maybe it has something to do with how other parts of QEMU handles this or I'm not getting what the generic PPC405 machine is for.

Well, the two QEMU PPC405 machines had 128M, so they were sharing the same
definition. This can be overridden in a child class if needed but I doubt
there will be any new PPC405 machines in QEMU. Let's keep it here.
  
> 
> Would it be clearer to just write 128 * MiB instead of a long hex number with extra zeros that's hard to read? It would be a good opportunity to change it here.

agree.

Thanks,

C.

> 
> Regards,
> BALATON Zoltan
> 
>> +}
>> +
>> +static const TypeInfo ppc405_machine_type = {
>> +    .name = TYPE_PPC405_MACHINE,
>> +    .parent = TYPE_MACHINE,
>> +    .instance_size = sizeof(Ppc405MachineState),
>> +    .class_init = ppc405_machine_class_init,
>> +    .abstract = true,
>> +};
>> +
>> static void ppc405_machine_init(void)
>> {
>> +    type_register_static(&ppc405_machine_type);
>>     type_register_static(&ref405ep_type);
>> }
>>
>>



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

* Re: [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C
  2022-08-03 23:31   ` BALATON Zoltan
@ 2022-08-04  5:42     ` Cédric Le Goater
  2022-08-04 11:21       ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  5:42 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 8/4/22 01:31, BALATON Zoltan wrote:
> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> Having an explicit I2C model object will help if one day we want to
>> add I2C devices on the bus.
> 
> Same here as with the UIC in previous patch, it's not QOMifying here either. As for why we may need I2C, on sam460ex the firmware detects RAM accessing the SPD data over I2C so that could be the reason but it may not be used here on 405.

You can still plug I2C devices on the PPC405 command line if you want to.

Thanks,

C.

> 
> Regards,
> BALATON Zoltan
> 
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405.h    |  2 ++
>> hw/ppc/ppc405_uc.c | 10 ++++++++--
>> 2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>> index d29f738cd2d0..d13624ae309c 100644
>> --- a/hw/ppc/ppc405.h
>> +++ b/hw/ppc/ppc405.h
>> @@ -28,6 +28,7 @@
>> #include "qom/object.h"
>> #include "hw/ppc/ppc4xx.h"
>> #include "hw/intc/ppc-uic.h"
>> +#include "hw/i2c/ppc4xx_i2c.h"
>>
>> #define PPC405EP_SDRAM_BASE 0x00000000
>> #define PPC405EP_NVRAM_BASE 0xF0000000
>> @@ -256,6 +257,7 @@ struct Ppc405SoCState {
>>     Ppc405OcmState ocm;
>>     Ppc405GpioState gpio;
>>     Ppc405DmaState dma;
>> +    PPC4xxI2CState i2c;
>>     Ppc405EbcState ebc;
>>     Ppc405OpbaState opba;
>>     Ppc405PobState pob;
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 5cd32e22b7ea..8f0caa45f5f7 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>
>>     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>>
>> +    object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
>> +
>>     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>
>>     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
>> @@ -1569,8 +1571,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>     }
>>
>>     /* I2C controller */
>> -    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
>> -                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
>> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
>> +        return;
>> +    }
>> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
>> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
>> +                       qdev_get_gpio_in(DEVICE(&s->uic), 2));
>>
>>     /* GPIO */
>>     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
>>



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

* Re: [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC
  2022-08-03 22:23   ` BALATON Zoltan
@ 2022-08-04  6:00     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  6:00 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 8/4/22 00:23, BALATON Zoltan wrote:
> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> This moves all the code previously done in the ppc405ep_init() routine
>> under ppc405_soc_realize(). We can also adjust the number of banks now
>> that we have control on ppc4xx_sdram_init().
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405.h        |  16 ++---
>> hw/ppc/ppc405_boards.c |  12 ++--
>> hw/ppc/ppc405_uc.c     | 144 ++++++++++++++++++++---------------------
>> 3 files changed, 83 insertions(+), 89 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>> index c8cddb71733a..2c912b328eaf 100644
>> --- a/hw/ppc/ppc405.h
>> +++ b/hw/ppc/ppc405.h
>> @@ -72,11 +72,16 @@ struct Ppc405SoCState {
>>
>>     /* Public */
>>     MemoryRegion sram;
>> -    MemoryRegion ram_memories[2];
>> -    hwaddr ram_bases[2], ram_sizes[2];
>> +    MemoryRegion ram_memories[1];
>> +    hwaddr ram_bases[1], ram_sizes[1];
>> +    bool do_dram_init;
> 
> I'm not sure about this. First of all what's the point having a 1 element array instead of just a normal field if you don't need more than one of these? 

because ppc405ep_init() interface was :

     PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
                             MemoryRegion ram_memories[2],
                             hwaddr ram_bases[2],
                             hwaddr ram_sizes[2],
                             uint32_t sysclk, DeviceState **uicdev,
                             int do_init);

and I didn't refresh the structures.

It is true that the 405 has 2 SDRAM banks. May be we should keep it
that way. I will see if I can come with something better in v3.

The main issue is the ppc4xx_sdram_init() interface. It has been
around for 15 years minimum and it should be reworked, but not now.

Thanks,

C.

> (But then the names in plural become a misnomer too.) On the other hand the SoC likely has two banks, it's just that the board only has one socket and thus only uses one of it but other boards could have two sockets and use both. If the SoC model already has this I'd keep it for that cases or to emulate the SoC more precisely. But I may be wrong, I haven't checked the chip docs and only dimly remember how this was on 460EX.
> 
> Regards,
> BALATON Zoltan
> 
>>
>>     MemoryRegion *dram_mr;
>>     hwaddr ram_size;
>> +
>> +    uint32_t sysclk;
>> +    PowerPCCPU *cpu;
>> +    DeviceState *uic;
>> };
>>
>> /* PowerPC 405 core */
>> @@ -85,11 +90,4 @@ ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
>> void ppc4xx_plb_init(CPUPPCState *env);
>> void ppc405_ebc_init(CPUPPCState *env);
>>
>> -PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
>> -                        MemoryRegion ram_memories[2],
>> -                        hwaddr ram_bases[2],
>> -                        hwaddr ram_sizes[2],
>> -                        uint32_t sysclk, DeviceState **uicdev,
>> -                        int do_init);
>> -
>> #endif /* PPC405_H */
>> diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
>> index 96db52c5a309..363cb0770506 100644
>> --- a/hw/ppc/ppc405_boards.c
>> +++ b/hw/ppc/ppc405_boards.c
>> @@ -237,9 +237,7 @@ static void ppc405_init(MachineState *machine)
>>     Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
>>     MachineClass *mc = MACHINE_GET_CLASS(machine);
>>     const char *kernel_filename = machine->kernel_filename;
>> -    PowerPCCPU *cpu;
>>     MemoryRegion *sysmem = get_system_memory();
>> -    DeviceState *uicdev;
>>
>>     if (machine->ram_size != mc->default_ram_size) {
>>         char *sz = size_to_str(mc->default_ram_size);
>> @@ -254,12 +252,12 @@ static void ppc405_init(MachineState *machine)
>>                              machine->ram_size, &error_fatal);
>>     object_property_set_link(OBJECT(&ppc405->soc), "dram",
>>                              OBJECT(machine->ram), &error_abort);
>> +    object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
>> +                             !(kernel_filename == NULL), &error_abort);
>> +    object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", 33333333,
>> +                             &error_abort);
>>     qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
>>
>> -    cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, ppc405->soc.ram_bases,
>> -                        ppc405->soc.ram_sizes,
>> -                        33333333, &uicdev, kernel_filename == NULL ? 0 : 1);
>> -
>>     /* allocate and load BIOS */
>>     if (machine->firmware) {
>>         MemoryRegion *bios = g_new(MemoryRegion, 1);
>> @@ -315,7 +313,7 @@ static void ppc405_init(MachineState *machine)
>>
>>     /* Load ELF kernel and rootfs.cpio */
>>     } else if (kernel_filename && !machine->firmware) {
>> -        boot_from_kernel(machine, cpu);
>> +        boot_from_kernel(machine, ppc405->soc.cpu);
>>     }
>> }
>>
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 7033bac6bf3f..ed1099e08bbd 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -1432,130 +1432,128 @@ static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
>> #endif
>> }
>>
>> -PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
>> -                        MemoryRegion ram_memories[2],
>> -                        hwaddr ram_bases[2],
>> -                        hwaddr ram_sizes[2],
>> -                        uint32_t sysclk, DeviceState **uicdevp,
>> -                        int do_init)
>> +static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>> {
>> +    Ppc405SoCState *s = PPC405_SOC(dev);
>>     clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
>>     qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
>> -    PowerPCCPU *cpu;
>>     CPUPPCState *env;
>> -    DeviceState *uicdev;
>> -    SysBusDevice *uicsbd;
>> +    Error *err = NULL;
>> +
>> +    /* allocate SRAM */
>> +    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
>> +                           PPC405EP_SRAM_SIZE,  &err);
>> +    if (err) {
>> +        error_propagate(errp, err);
>> +        return;
>> +    }
>> +    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
>> +                                &s->sram);
>>
>>     memset(clk_setup, 0, sizeof(clk_setup));
>> +
>>     /* init CPUs */
>> -    cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
>> +    s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
>>                       &clk_setup[PPC405EP_CPU_CLK],
>> -                      &tlb_clk_setup, sysclk);
>> -    env = &cpu->env;
>> +                      &tlb_clk_setup, s->sysclk);
>> +    env = &s->cpu->env;
>>     clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
>>     clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
>> -    /* Internal devices init */
>> -    /* Memory mapped devices registers */
>> +
>> +    /* CPU control */
>> +    ppc405ep_cpc_init(env, clk_setup, s->sysclk);
>> +
>>     /* PLB arbitrer */
>>     ppc4xx_plb_init(env);
>> +
>>     /* PLB to OPB bridge */
>>     ppc4xx_pob_init(env);
>> +
>>     /* OBP arbitrer */
>>     ppc4xx_opba_init(0xef600600);
>> +
>>     /* Universal interrupt controller */
>> -    uicdev = qdev_new(TYPE_PPC_UIC);
>> -    uicsbd = SYS_BUS_DEVICE(uicdev);
>> +    s->uic = qdev_new(TYPE_PPC_UIC);
>>
>> -    object_property_set_link(OBJECT(uicdev), "cpu", OBJECT(cpu),
>> +    object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(s->cpu),
>>                              &error_fatal);
>> -    sysbus_realize_and_unref(uicsbd, &error_fatal);
>> -
>> -    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT,
>> -                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT));
>> -    sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT,
>> -                       qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
>> +    if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
>> +        return;
>> +    }
>>
>> -    *uicdevp = uicdev;
>> +    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
>> +                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_INT));
>> +    sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
>> +                       qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_CINT));
>>
>>     /* SDRAM controller */
>> -        /* XXX 405EP has no ECC interrupt */
>> -    ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 17), 2, ram_memories,
>> -                      ram_bases, ram_sizes, do_init);
>> +    /* XXX 405EP has no ECC interrupt */
>> +    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
>> +                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
>> +    s->ram_bases[0] = 0;
>> +    s->ram_sizes[0] = s->ram_size;
>> +
>> +    ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17),
>> +                      ARRAY_SIZE(s->ram_memories), s->ram_memories,
>> +                      s->ram_bases, s->ram_sizes, s->do_dram_init);
>> +
>>     /* External bus controller */
>>     ppc405_ebc_init(env);
>> +
>>     /* DMA controller */
>> -    dma_irqs[0] = qdev_get_gpio_in(uicdev, 5);
>> -    dma_irqs[1] = qdev_get_gpio_in(uicdev, 6);
>> -    dma_irqs[2] = qdev_get_gpio_in(uicdev, 7);
>> -    dma_irqs[3] = qdev_get_gpio_in(uicdev, 8);
>> +    dma_irqs[0] = qdev_get_gpio_in(s->uic, 5);
>> +    dma_irqs[1] = qdev_get_gpio_in(s->uic, 6);
>> +    dma_irqs[2] = qdev_get_gpio_in(s->uic, 7);
>> +    dma_irqs[3] = qdev_get_gpio_in(s->uic, 8);
>>     ppc405_dma_init(env, dma_irqs);
>> -    /* IIC controller */
>> +
>> +    /* I2C controller */
>>     sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
>> -                         qdev_get_gpio_in(uicdev, 2));
>> +                         qdev_get_gpio_in(s->uic, 2));
>>     /* GPIO */
>>     ppc405_gpio_init(0xef600700);
>> +
>>     /* Serial ports */
>>     if (serial_hd(0) != NULL) {
>> -        serial_mm_init(address_space_mem, 0xef600300, 0,
>> -                       qdev_get_gpio_in(uicdev, 0),
>> +        serial_mm_init(get_system_memory(), 0xef600300, 0,
>> +                       qdev_get_gpio_in(s->uic, 0),
>>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
>>                        DEVICE_BIG_ENDIAN);
>>     }
>>     if (serial_hd(1) != NULL) {
>> -        serial_mm_init(address_space_mem, 0xef600400, 0,
>> -                       qdev_get_gpio_in(uicdev, 1),
>> +        serial_mm_init(get_system_memory(), 0xef600400, 0,
>> +                       qdev_get_gpio_in(s->uic, 1),
>>                        PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
>>                        DEVICE_BIG_ENDIAN);
>>     }
>> +
>>     /* OCM */
>>     ppc405_ocm_init(env);
>> +
>>     /* GPT */
>> -    gpt_irqs[0] = qdev_get_gpio_in(uicdev, 19);
>> -    gpt_irqs[1] = qdev_get_gpio_in(uicdev, 20);
>> -    gpt_irqs[2] = qdev_get_gpio_in(uicdev, 21);
>> -    gpt_irqs[3] = qdev_get_gpio_in(uicdev, 22);
>> -    gpt_irqs[4] = qdev_get_gpio_in(uicdev, 23);
>> +    gpt_irqs[0] = qdev_get_gpio_in(s->uic, 19);
>> +    gpt_irqs[1] = qdev_get_gpio_in(s->uic, 20);
>> +    gpt_irqs[2] = qdev_get_gpio_in(s->uic, 21);
>> +    gpt_irqs[3] = qdev_get_gpio_in(s->uic, 22);
>> +    gpt_irqs[4] = qdev_get_gpio_in(s->uic, 23);
>>     ppc4xx_gpt_init(0xef600000, gpt_irqs);
>> -    /* PCI */
>> -    /* Uses UIC IRQs 3, 16, 18 */
>> +
>>     /* MAL */
>> -    mal_irqs[0] = qdev_get_gpio_in(uicdev, 11);
>> -    mal_irqs[1] = qdev_get_gpio_in(uicdev, 12);
>> -    mal_irqs[2] = qdev_get_gpio_in(uicdev, 13);
>> -    mal_irqs[3] = qdev_get_gpio_in(uicdev, 14);
>> +    mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
>> +    mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
>> +    mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
>> +    mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
>>     ppc4xx_mal_init(env, 4, 2, mal_irqs);
>> +
>>     /* Ethernet */
>>     /* Uses UIC IRQs 9, 15, 17 */
>> -    /* CPU control */
>> -    ppc405ep_cpc_init(env, clk_setup, sysclk);
>> -
>> -    return cpu;
>> -}
>> -
>> -static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>> -{
>> -    Ppc405SoCState *s = PPC405_SOC(dev);
>> -    Error *err = NULL;
>> -
>> -    memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
>> -                             "ppc405.ram.alias", s->dram_mr, 0, s->ram_size);
>> -    s->ram_bases[0] = 0;
>> -    s->ram_sizes[0] = s->ram_size;
>> -
>> -    /* allocate SRAM */
>> -    memory_region_init_ram(&s->sram, OBJECT(s), "ppc405.sram",
>> -                           PPC405EP_SRAM_SIZE,  &err);
>> -    if (err) {
>> -        error_propagate(errp, err);
>> -        return;
>> -    }
>> -    memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
>> -                                &s->sram);
>> }
>>
>> static Property ppc405_soc_properties[] = {
>>     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
>>                      MemoryRegion *),
>> +    DEFINE_PROP_UINT32("sys-clk", Ppc405SoCState, sysclk, 0),
>> +    DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
>>     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
>>     DEFINE_PROP_END_OF_LIST(),
>> };
>>



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

* Re: [PATCH v2 00/20] ppc: QOM'ify 405 board
  2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
                   ` (19 preceding siblings ...)
  2022-08-03 13:28 ` [PATCH v2 20/20] ppc/ppc4xx: Fix sdram trace events Cédric Le Goater
@ 2022-08-04  6:07 ` Cédric Le Goater
  2022-08-04 10:07   ` Daniel Henrique Barboza
  20 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04  6:07 UTC (permalink / raw)
  To: qemu-ppc; +Cc: Daniel Henrique Barboza, qemu-devel, BALATON Zoltan

Daniel,

On 8/3/22 15:28, Cédric Le Goater wrote:
> Hello,
> 
> Here is large series QOM'ifying the PPC405 board. It introduces a new
> generic machine and SoC models, converts the current device models to
> QOM and populates the SoC. The process is quite mechanical without too
> much issues to handle. The noisy part is the initial patch introducing
> the SoC realize routine.
>
> What's left ?
> 
> * The DCR read/writre handlers are attached in table to the CPU
>    instance. We could probably rework the whole with a specific address
>    space and memory regions handling the implemented registers. I don't
>    think this is necessary.
> 
> * the SDRAM mappings are very baroque and certainly could be simplified.
>    I think we should QOMify the ppc440 machines before addressing this
>    part.


I will resend a v3 taking into account the comments (and fixes) from you
and Zoltan.

Also, the PPC405 controller has 2 SDRAM banks, I should try to model
that with a single bank default. The ppc4xx_sdram_init() routine is
a bit of a pain to do anything clean really.


Thanks,
  
C.


  
> Changes in v2 :
> 
>   - docs/about/removed-features.rst update
>   - Fix compile breakage (uic)
>   - Fix CPU reset, which breaking u-boot boot
>   - Changed prefix of memory regions to "ppc405"
>   - Reduced the number of RAM banks to 1. Second was a dummy one to
>     please ppc405ep_init()
> 
> Cédric Le Goater (20):
>    ppc/ppc405: Remove taihu machine
>    ppc/ppc405: Introduce a PPC405 generic machine
>    ppc/ppc405: Move devices under the ref405ep machine
>    ppc/ppc405: Introduce a PPC405 SoC
>    ppc/ppc405: Start QOMification of the SoC
>    ppc/ppc405: QOM'ify CPU
>    ppc/ppc405: QOM'ify CPC
>    ppc/ppc405: QOM'ify GPT
>    ppc/ppc405: QOM'ify OCM
>    ppc/ppc405: QOM'ify GPIO
>    ppc/ppc405: QOM'ify DMA
>    ppc/ppc405: QOM'ify EBC
>    ppc/ppc405: QOM'ify OPBA
>    ppc/ppc405: QOM'ify POB
>    ppc/ppc405: QOM'ify PLB
>    ppc/ppc405: QOM'ify MAL
>    ppc/ppc405: QOM'ify FPGA
>    ppc/ppc405: QOM'ify UIC
>    ppc/ppc405: QOM'ify I2C
>    ppc/ppc4xx: Fix sdram trace events
> 
>   docs/about/deprecated.rst       |   9 -
>   docs/about/removed-features.rst |   6 +
>   docs/system/ppc/embedded.rst    |   1 -
>   hw/ppc/ppc405.h                 | 210 ++++++++-
>   include/hw/ppc/ppc4xx.h         |  29 ++
>   hw/ppc/ppc405_boards.c          | 366 ++++-----------
>   hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------
>   hw/ppc/ppc4xx_devs.c            | 124 +++--
>   MAINTAINERS                     |   2 +-
>   9 files changed, 894 insertions(+), 652 deletions(-)
> 



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-03 23:04   ` BALATON Zoltan
@ 2022-08-04  7:55     ` Mark Cave-Ayland
  2022-08-04 10:58       ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Mark Cave-Ayland @ 2022-08-04  7:55 UTC (permalink / raw)
  To: BALATON Zoltan, Cédric Le Goater
  Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 04/08/2022 00:04, BALATON Zoltan wrote:

> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/ppc405.h    | 16 +++++++++++
>> hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>> 2 files changed, 64 insertions(+), 23 deletions(-)
>>
>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>> index 1da34a7f10f3..1c7fe07b8084 100644
>> --- a/hw/ppc/ppc405.h
>> +++ b/hw/ppc/ppc405.h
>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>
>> typedef struct Ppc405SoCState Ppc405SoCState;
>>
>> +/* Peripheral controller */
>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>> +struct Ppc405EbcState {
>> +    DeviceState parent_obj;
>> +
>> +    PowerPCCPU *cpu;
>>
>> +    uint32_t addr;
>> +    uint32_t bcr[8];
>> +    uint32_t bap[8];
>> +    uint32_t bear;
>> +    uint32_t besr0;
>> +    uint32_t besr1;
>> +    uint32_t cfg;
>> +};
>>
>> /* DMA controller */
>> #define TYPE_PPC405_DMA "ppc405-dma"
>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>     Ppc405OcmState ocm;
>>     Ppc405GpioState gpio;
>>     Ppc405DmaState dma;
>> +    Ppc405EbcState ebc;
>> };
>>
>> /* PowerPC 405 core */
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 6bd93c1cb90c..0166f3fc36da 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>
>> /*****************************************************************************/
>> /* Peripheral controller */
>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>> -struct ppc4xx_ebc_t {
>> -    uint32_t addr;
>> -    uint32_t bcr[8];
>> -    uint32_t bap[8];
>> -    uint32_t bear;
>> -    uint32_t besr0;
>> -    uint32_t besr1;
>> -    uint32_t cfg;
>> -};
>> -
>> enum {
>>     EBC0_CFGADDR = 0x012,
>>     EBC0_CFGDATA = 0x013,
>> @@ -411,10 +400,9 @@ enum {
>>
>> static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>> {
>> -    ppc4xx_ebc_t *ebc;
>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>     uint32_t ret;
>>
>> -    ebc = opaque;
> 
> I think QOM casts are kind of expensive (maybe because we have quo-debug enabled by 
> default even without --enable-debug and it does additional checks; I've tried to 
> change this default once but it was thought to be better to have it enabled). So it's 
> advised to use QOM casts sparingly, e.g. store the result in a local variable if you 
> need it more than once and so. Therefore I tend to consider these read/write 
> callbacks that the object itself registers with itself as the opaque pointer to be 
> internal to the object and guaranteed to be passed the object pointer so no QOM cast 
> is necessary and the direct assignment can be kept. This avoids potential overhead on 
> every register access. Not sure if it's measurable but I think if an overhead can be 
> avoided it probably should be.

Can you provide any evidence for this? IIRC the efficiency of the QOM cast macros 
without --enable-debug was improved several years ago to the point where their impact 
is minimal (note: this does not include object_dynamic_cast()). From memory the 
previous discussions concluded that whilst the QOM cast did add some runtime 
overhead, it was dwarfed by the cost of breaking out of emulation to handle the MMIO 
access itself. If something has changed here then that sounds like a bug.

I think it's worth keeping the QOM casts in place unless there is a good reason not 
to, simply because they have helped me many times in past catch out refactoring 
mistakes. For example I can certainly imagine that the recent PHB series would have 
been a lot more painful without having them.


ATB,

Mark.


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

* Re: [PATCH v2 00/20] ppc: QOM'ify 405 board
  2022-08-04  6:07 ` [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
@ 2022-08-04 10:07   ` Daniel Henrique Barboza
  2022-08-04 12:26     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: Daniel Henrique Barboza @ 2022-08-04 10:07 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan



On 8/4/22 03:07, Cédric Le Goater wrote:
> Daniel,
> 
> On 8/3/22 15:28, Cédric Le Goater wrote:
>> Hello,
>>
>> Here is large series QOM'ifying the PPC405 board. It introduces a new
>> generic machine and SoC models, converts the current device models to
>> QOM and populates the SoC. The process is quite mechanical without too
>> much issues to handle. The noisy part is the initial patch introducing
>> the SoC realize routine.
>>
>> What's left ?
>>
>> * The DCR read/writre handlers are attached in table to the CPU
>>    instance. We could probably rework the whole with a specific address
>>    space and memory regions handling the implemented registers. I don't
>>    think this is necessary.
>>
>> * the SDRAM mappings are very baroque and certainly could be simplified.
>>    I think we should QOMify the ppc440 machines before addressing this
>>    part.
> 
> 
> I will resend a v3 taking into account the comments (and fixes) from you
> and Zoltan.

I'll get whatever pending fixes we have for the freeze and send a PR including
the mal_irqs[] fix today. I'll be less stuff to worry about for this series.


Daniel

> 
> Also, the PPC405 controller has 2 SDRAM banks, I should try to model
> that with a single bank default. The ppc4xx_sdram_init() routine is
> a bit of a pain to do anything clean really.
> 
> 
> Thanks,
> 
> C.
> 
> 
> 
>> Changes in v2 :
>>
>>   - docs/about/removed-features.rst update
>>   - Fix compile breakage (uic)
>>   - Fix CPU reset, which breaking u-boot boot
>>   - Changed prefix of memory regions to "ppc405"
>>   - Reduced the number of RAM banks to 1. Second was a dummy one to
>>     please ppc405ep_init()
>>
>> Cédric Le Goater (20):
>>    ppc/ppc405: Remove taihu machine
>>    ppc/ppc405: Introduce a PPC405 generic machine
>>    ppc/ppc405: Move devices under the ref405ep machine
>>    ppc/ppc405: Introduce a PPC405 SoC
>>    ppc/ppc405: Start QOMification of the SoC
>>    ppc/ppc405: QOM'ify CPU
>>    ppc/ppc405: QOM'ify CPC
>>    ppc/ppc405: QOM'ify GPT
>>    ppc/ppc405: QOM'ify OCM
>>    ppc/ppc405: QOM'ify GPIO
>>    ppc/ppc405: QOM'ify DMA
>>    ppc/ppc405: QOM'ify EBC
>>    ppc/ppc405: QOM'ify OPBA
>>    ppc/ppc405: QOM'ify POB
>>    ppc/ppc405: QOM'ify PLB
>>    ppc/ppc405: QOM'ify MAL
>>    ppc/ppc405: QOM'ify FPGA
>>    ppc/ppc405: QOM'ify UIC
>>    ppc/ppc405: QOM'ify I2C
>>    ppc/ppc4xx: Fix sdram trace events
>>
>>   docs/about/deprecated.rst       |   9 -
>>   docs/about/removed-features.rst |   6 +
>>   docs/system/ppc/embedded.rst    |   1 -
>>   hw/ppc/ppc405.h                 | 210 ++++++++-
>>   include/hw/ppc/ppc4xx.h         |  29 ++
>>   hw/ppc/ppc405_boards.c          | 366 ++++-----------
>>   hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------
>>   hw/ppc/ppc4xx_devs.c            | 124 +++--
>>   MAINTAINERS                     |   2 +-
>>   9 files changed, 894 insertions(+), 652 deletions(-)
>>
> 


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04  7:55     ` Mark Cave-Ayland
@ 2022-08-04 10:58       ` BALATON Zoltan
  0 siblings, 0 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-04 10:58 UTC (permalink / raw)
  To: Mark Cave-Ayland
  Cc: Cédric Le Goater, qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 6229 bytes --]

On Thu, 4 Aug 2022, Mark Cave-Ayland wrote:
> On 04/08/2022 00:04, BALATON Zoltan wrote:
>> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>> ---
>>> hw/ppc/ppc405.h    | 16 +++++++++++
>>> hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>>> 2 files changed, 64 insertions(+), 23 deletions(-)
>>> 
>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>> index 1da34a7f10f3..1c7fe07b8084 100644
>>> --- a/hw/ppc/ppc405.h
>>> +++ b/hw/ppc/ppc405.h
>>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>> 
>>> typedef struct Ppc405SoCState Ppc405SoCState;
>>> 
>>> +/* Peripheral controller */
>>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>>> +struct Ppc405EbcState {
>>> +    DeviceState parent_obj;
>>> +
>>> +    PowerPCCPU *cpu;
>>> 
>>> +    uint32_t addr;
>>> +    uint32_t bcr[8];
>>> +    uint32_t bap[8];
>>> +    uint32_t bear;
>>> +    uint32_t besr0;
>>> +    uint32_t besr1;
>>> +    uint32_t cfg;
>>> +};
>>> 
>>> /* DMA controller */
>>> #define TYPE_PPC405_DMA "ppc405-dma"
>>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>>     Ppc405OcmState ocm;
>>>     Ppc405GpioState gpio;
>>>     Ppc405DmaState dma;
>>> +    Ppc405EbcState ebc;
>>> };
>>> 
>>> /* PowerPC 405 core */
>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>> index 6bd93c1cb90c..0166f3fc36da 100644
>>> --- a/hw/ppc/ppc405_uc.c
>>> +++ b/hw/ppc/ppc405_uc.c
>>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>> 
>>> /*****************************************************************************/
>>> /* Peripheral controller */
>>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>>> -struct ppc4xx_ebc_t {
>>> -    uint32_t addr;
>>> -    uint32_t bcr[8];
>>> -    uint32_t bap[8];
>>> -    uint32_t bear;
>>> -    uint32_t besr0;
>>> -    uint32_t besr1;
>>> -    uint32_t cfg;
>>> -};
>>> -
>>> enum {
>>>     EBC0_CFGADDR = 0x012,
>>>     EBC0_CFGDATA = 0x013,
>>> @@ -411,10 +400,9 @@ enum {
>>> 
>>> static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>> {
>>> -    ppc4xx_ebc_t *ebc;
>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>     uint32_t ret;
>>> 
>>> -    ebc = opaque;
>> 
>> I think QOM casts are kind of expensive (maybe because we have quo-debug 
>> enabled by default even without --enable-debug and it does additional 
>> checks; I've tried to change this default once but it was thought to be 
>> better to have it enabled). So it's advised to use QOM casts sparingly, 
>> e.g. store the result in a local variable if you need it more than once and 
>> so. Therefore I tend to consider these read/write callbacks that the object 
>> itself registers with itself as the opaque pointer to be internal to the 
>> object and guaranteed to be passed the object pointer so no QOM cast is 
>> necessary and the direct assignment can be kept. This avoids potential 
>> overhead on every register access. Not sure if it's measurable but I think 
>> if an overhead can be avoided it probably should be.
>
> Can you provide any evidence for this? IIRC the efficiency of the QOM cast 
> macros without --enable-debug was improved several years ago to the point 
> where their impact is minimal (note: this does not include 
> object_dynamic_cast()). From memory the previous discussions concluded that

It probably could be measured on a slower machine when something does a 
lot of register access but I did not have any concrete numbers to prove it 
and in this particular case not sure how often this device is accessed if 
it does anything at all. But this is a general remark for all devices. An 
IDE device could be accessed a lot of times for example so I generally 
try to avoid unnecessary overhead.

AFAIK (which could well be wrong) a QOM cast is optimised down to a simple 
cast if qom-debug is disabled. Problem is it's never disabled unless 
somebody explicitly compiles with --disable-qom-cast-debug as this is 
enabled by default, even in release builds without --enable-debug. At 
least that was the case when this was in configure, I don't know where it 
went during meson conversion but I think the default haven't changed. With 
qom-cast-debug a QOM cast is ultimately calling object_dynamic_cast_assert 
in OBJECT_CHECK.

Here is the discussion when I've tried to change this:

https://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg03371.html

> whilst the QOM cast did add some runtime overhead, it was dwarfed by the cost 
> of breaking out of emulation to handle the MMIO access itself. If something 
> has changed here then that sounds like a bug.

Not saying it has changed but having something already slow is not an 
argument to make it even slower if that additional overhead can be 
avoided. Maybe that makes it a little less slow even if the main reason 
for slowness is not this.

> I think it's worth keeping the QOM casts in place unless there is a good 
> reason not to, simply because they have helped me many times in past catch 
> out refactoring mistakes. For example I can certainly imagine that the recent 
> PHB series would have been a lot more painful without having them.

A good reason in my opinion is that these are read/write callbacks of the 
object whith are registered in the realize method with the object itself 
as the opaque parameter which was already QOM cast from the realize 
method's device parameter so there's no way these read/wtite callbacks are 
called with an unchecked object. Therefore the QOM cast with check is 
unnecessary here and we can safely assign it to the appropriate type 
without checcking it again at every register access. Because of this, I 
always avoid QOM casts in these callback functions as this can only make 
things better and unlikely to make it worse.

The QOM casts are warranted in the object methods such as realize or init 
that maybe somehow could be called with a wrong object (I'm not sure why 
if these are object methods but maybe through a subclass or something) but 
not needed in register access callbacks that are internal to the object 
and only passed already checked objects.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C
  2022-08-04  5:42     ` Cédric Le Goater
@ 2022-08-04 11:21       ` BALATON Zoltan
  2022-08-04 14:14         ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-04 11:21 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 3260 bytes --]

On Thu, 4 Aug 2022, Cédric Le Goater wrote:
> On 8/4/22 01:31, BALATON Zoltan wrote:
>> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>>> Having an explicit I2C model object will help if one day we want to
>>> add I2C devices on the bus.
>> 
>> Same here as with the UIC in previous patch, it's not QOMifying here 
>> either. As for why we may need I2C, on sam460ex the firmware detects RAM 
>> accessing the SPD data over I2C so that could be the reason but it may not 
>> be used here on 405.
>
> You can still plug I2C devices on the PPC405 command line if you want to.

Yes true, I just remembered the reson to bother to implement I2C on 
sam460ex was that the firmware would not work without it so I thought it 
may be the same reason here but we don't have the firmware for this board 
so I don't know. Maybe the original goal was that or the firmware was used 
for testing but then it was unfinished. Anyway, having more accurate 
emulation of the hardware is always good so if this matches real hardware 
then it should stay.

Regards,
BALATON Zoltan

>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>> ---
>>> hw/ppc/ppc405.h    |  2 ++
>>> hw/ppc/ppc405_uc.c | 10 ++++++++--
>>> 2 files changed, 10 insertions(+), 2 deletions(-)
>>> 
>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>> index d29f738cd2d0..d13624ae309c 100644
>>> --- a/hw/ppc/ppc405.h
>>> +++ b/hw/ppc/ppc405.h
>>> @@ -28,6 +28,7 @@
>>> #include "qom/object.h"
>>> #include "hw/ppc/ppc4xx.h"
>>> #include "hw/intc/ppc-uic.h"
>>> +#include "hw/i2c/ppc4xx_i2c.h"
>>> 
>>> #define PPC405EP_SDRAM_BASE 0x00000000
>>> #define PPC405EP_NVRAM_BASE 0xF0000000
>>> @@ -256,6 +257,7 @@ struct Ppc405SoCState {
>>>     Ppc405OcmState ocm;
>>>     Ppc405GpioState gpio;
>>>     Ppc405DmaState dma;
>>> +    PPC4xxI2CState i2c;
>>>     Ppc405EbcState ebc;
>>>     Ppc405OpbaState opba;
>>>     Ppc405PobState pob;
>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>> index 5cd32e22b7ea..8f0caa45f5f7 100644
>>> --- a/hw/ppc/ppc405_uc.c
>>> +++ b/hw/ppc/ppc405_uc.c
>>> @@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>> 
>>>     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>>> 
>>> +    object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
>>> +
>>>     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>> 
>>>     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
>>> @@ -1569,8 +1571,12 @@ static void ppc405_soc_realize(DeviceState *dev, 
>>> Error **errp)
>>>     }
>>> 
>>>     /* I2C controller */
>>> -    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
>>> -                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
>>> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
>>> +        return;
>>> +    }
>>> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
>>> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
>>> +                       qdev_get_gpio_in(DEVICE(&s->uic), 2));
>>> 
>>>     /* GPIO */
>>>     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
>>> 
>
>
>

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04  5:14     ` Cédric Le Goater
@ 2022-08-04 12:09       ` BALATON Zoltan
  2022-08-04 16:21         ` Cédric Le Goater
       [not found]         ` <3b1bc6c5-a363-0a42-f0dc-eafc14376fe2@kaod.org>
  0 siblings, 2 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-04 12:09 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: Daniel Henrique Barboza, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 9150 bytes --]

On Thu, 4 Aug 2022, Cédric Le Goater wrote:
> On 8/4/22 01:36, Daniel Henrique Barboza wrote:
>> Cedric,
>> 
>> On 8/3/22 10:28, Cédric Le Goater wrote:
>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>> ---
>>>   hw/ppc/ppc405.h    | 16 +++++++++++
>>>   hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>>>   2 files changed, 64 insertions(+), 23 deletions(-)
>>> 
>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>> index 1da34a7f10f3..1c7fe07b8084 100644
>>> --- a/hw/ppc/ppc405.h
>>> +++ b/hw/ppc/ppc405.h
>>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>>   typedef struct Ppc405SoCState Ppc405SoCState;
>>> +/* Peripheral controller */
>>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>>> +struct Ppc405EbcState {
>>> +    DeviceState parent_obj;
>>> +
>>> +    PowerPCCPU *cpu;
>>> +    uint32_t addr;
>>> +    uint32_t bcr[8];
>>> +    uint32_t bap[8];
>>> +    uint32_t bear;
>>> +    uint32_t besr0;
>>> +    uint32_t besr1;
>>> +    uint32_t cfg;
>>> +};
>>>   /* DMA controller */
>>>   #define TYPE_PPC405_DMA "ppc405-dma"
>>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>>       Ppc405OcmState ocm;
>>>       Ppc405GpioState gpio;
>>>       Ppc405DmaState dma;
>>> +    Ppc405EbcState ebc;
>>>   };
>>>   /* PowerPC 405 core */
>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>> index 6bd93c1cb90c..0166f3fc36da 100644
>>> --- a/hw/ppc/ppc405_uc.c
>>> +++ b/hw/ppc/ppc405_uc.c
>>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>>   
>>> /*****************************************************************************/
>>>   /* Peripheral controller */
>>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>>> -struct ppc4xx_ebc_t {
>>> -    uint32_t addr;
>>> -    uint32_t bcr[8];
>>> -    uint32_t bap[8];
>>> -    uint32_t bear;
>>> -    uint32_t besr0;
>>> -    uint32_t besr1;
>>> -    uint32_t cfg;
>>> -};
>>> -
>>>   enum {
>>>       EBC0_CFGADDR = 0x012,
>>>       EBC0_CFGDATA = 0x013,
>>> @@ -411,10 +400,9 @@ enum {
>>>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>   {
>>> -    ppc4xx_ebc_t *ebc;
>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>       uint32_t ret;
>>> -    ebc = opaque;
>>>       switch (dcrn) {
>>>       case EBC0_CFGADDR:
>>>           ret = ebc->addr;
>>> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>   {
>>> -    ppc4xx_ebc_t *ebc;
>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>> -    ebc = opaque;
>>>       switch (dcrn) {
>>>       case EBC0_CFGADDR:
>>>           ebc->addr = val;
>>> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, 
>>> uint32_t val)
>>>       }
>>>   }
>>> -static void ebc_reset (void *opaque)
>>> +static void ppc405_ebc_reset(DeviceState *dev)
>>>   {
>>> -    ppc4xx_ebc_t *ebc;
>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>       int i;
>>> -    ebc = opaque;
>>>       ebc->addr = 0x00000000;
>>>       ebc->bap[0] = 0x7F8FFE80;
>>>       ebc->bcr[0] = 0xFFE28000;
>>> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>>>       ebc->cfg = 0x80400000;
>>>   }
>>> -void ppc405_ebc_init(CPUPPCState *env)
>>> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>>>   {
>>> -    ppc4xx_ebc_t *ebc;
>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>> +    CPUPPCState *env;
>>> +
>>> +    assert(ebc->cpu);
>>> +
>>> +    env = &ebc->cpu->env;
>>> -    ebc = g_new0(ppc4xx_ebc_t, 1);
>>> -    qemu_register_reset(&ebc_reset, ebc);
>>>       ppc_dcr_register(env, EBC0_CFGADDR,
>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>       ppc_dcr_register(env, EBC0_CFGDATA,
>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>   }
>>> +static Property ppc405_ebc_properties[] = {
>>> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
>>> +                     PowerPCCPU *),
>>> +    DEFINE_PROP_END_OF_LIST(),
>>> +};
>>> +
>>> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
>>> +{
>>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>>> +
>>> +    dc->realize = ppc405_ebc_realize;
>>> +    dc->user_creatable = false;
>>> +    dc->reset = ppc405_ebc_reset;
>>> +    device_class_set_props(dc, ppc405_ebc_properties);
>>> +}
>>> +
>>> +void ppc405_ebc_init(CPUPPCState *env)
>>> +{
>>> +    PowerPCCPU *cpu = env_archcpu(env);
>>> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>>> +
>>> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), 
>>> &error_abort);
>> 
>> This line is breaking the boot of sam460ex:
>> 
>>
>>   ./qemu-system-ppc64 -display none -M sam460ex
>> Unexpected error in object_property_find_err() at ../qom/object.c:1304:
>> qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
>> Aborted (core dumped)
>> 
>> 
>> I think you meant to link the cpu prop of the EBC obj to the CPU object,
>> not the cpu prop of the CPU obj to the EBC dev.
>
> Yes. ppc405_ebc_init() has only one user left, the sam460ex, which I didn't
> test :/

This patch changes ppc405_ebc_init to a realize method so shouldn't the 
sam460ex be changed to create the new object instead of calling 
ppc405_ebc_init too instead? Is the only reason the keep ppc405_ebc_init 
to add the cpu link? As I noted before it would be nice to get rid of this 
link somehow, it would allow dropping this init func and a bunch of 
property descriptors where this cpu link is the only object. It should be 
possble to get from a QOM object to its parent and the cpu from there but 
I could not find out how. Maybe somehow with object_resolve_path() or 
object_resolve_path_type() but I don't know QOM enough and did not find 
anything in docs. Does somebody know how to do that? Or maybe the paths 
are always the same so it could resolve an absolute path. Don't know how 
it looks buth something like /machine/soc/cpu or similar to get to the cpu 
to get the env. This could work as long as we assume we only have one cpu 
but these SoC all have. Then no cpu link is needed and could get rid of a 
lot of boilerplate code. Does this make sense?

Regards,
BALATON Zoltan

> Thanks,
>
> C.
> 
>> 
>> This fixes the issue:
>> 
>> 
>> $ git diff
>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>> index 0166f3fc36..aac3a3f761 100644
>> --- a/hw/ppc/ppc405_uc.c
>> +++ b/hw/ppc/ppc405_uc.c
>> @@ -594,7 +594,7 @@ void ppc405_ebc_init(CPUPPCState *env)
>>       PowerPCCPU *cpu = env_archcpu(env);
>>       DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>> 
>> -    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), 
>> &error_abort);
>> +    object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), 
>> &error_abort);
>>       qdev_realize_and_unref(dev, NULL, &error_fatal);
>>   }
>> 
>> 
>> Daniel
>> 
>> 
>>> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
>>> +}
>>> +
>>>   
>>> /*****************************************************************************/
>>>   /* DMA controller */
>>>   enum {
>>> @@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>>       object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
>>>       object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>>> +
>>> +    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>>   }
>>>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>> @@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, 
>>> Error **errp)
>>>                         s->ram_bases, s->ram_sizes, s->do_dram_init);
>>>       /* External bus controller */
>>> -    ppc405_ebc_init(env);
>>> +    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
>>> +                             &error_abort);
>>> +    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
>>> +        return;
>>> +    }
>>>       /* DMA controller */
>>>       object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
>>> @@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, 
>>> void *data)
>>>   static const TypeInfo ppc405_types[] = {
>>>       {
>>> +        .name           = TYPE_PPC405_EBC,
>>> +        .parent         = TYPE_DEVICE,
>>> +        .instance_size  = sizeof(Ppc405EbcState),
>>> +        .class_init     = ppc405_ebc_class_init,
>>> +    }, {
>>>           .name           = TYPE_PPC405_DMA,
>>>           .parent         = TYPE_SYS_BUS_DEVICE,
>>>           .instance_size  = sizeof(Ppc405DmaState),
>
>
>

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

* Re: [PATCH v2 00/20] ppc: QOM'ify 405 board
  2022-08-04 10:07   ` Daniel Henrique Barboza
@ 2022-08-04 12:26     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04 12:26 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-ppc; +Cc: qemu-devel, BALATON Zoltan

On 8/4/22 12:07, Daniel Henrique Barboza wrote:
> 
> 
> On 8/4/22 03:07, Cédric Le Goater wrote:
>> Daniel,
>>
>> On 8/3/22 15:28, Cédric Le Goater wrote:
>>> Hello,
>>>
>>> Here is large series QOM'ifying the PPC405 board. It introduces a new
>>> generic machine and SoC models, converts the current device models to
>>> QOM and populates the SoC. The process is quite mechanical without too
>>> much issues to handle. The noisy part is the initial patch introducing
>>> the SoC realize routine.
>>>
>>> What's left ?
>>>
>>> * The DCR read/writre handlers are attached in table to the CPU
>>>    instance. We could probably rework the whole with a specific address
>>>    space and memory regions handling the implemented registers. I don't
>>>    think this is necessary.
>>>
>>> * the SDRAM mappings are very baroque and certainly could be simplified.
>>>    I think we should QOMify the ppc440 machines before addressing this
>>>    part.
>>
>>
>> I will resend a v3 taking into account the comments (and fixes) from you
>> and Zoltan.
> 
> I'll get whatever pending fixes we have for the freeze and send a PR including
> the mal_irqs[] fix today. 

Yes. Please do that. The mal_irqs[] issue is clearly a "for-7.1" fix.

> I'll be less stuff to worry about for this series.

I think I am going to add some extras to remove the plb/ebc/mal init
routines while I am at changing things.

Thanks,

C.

> 
> Daniel
> 
>>
>> Also, the PPC405 controller has 2 SDRAM banks, I should try to model
>> that with a single bank default. The ppc4xx_sdram_init() routine is
>> a bit of a pain to do anything clean really.
>>
>>
>> Thanks,
>>
>> C.
>>
>>
>>
>>> Changes in v2 :
>>>
>>>   - docs/about/removed-features.rst update
>>>   - Fix compile breakage (uic)
>>>   - Fix CPU reset, which breaking u-boot boot
>>>   - Changed prefix of memory regions to "ppc405"
>>>   - Reduced the number of RAM banks to 1. Second was a dummy one to
>>>     please ppc405ep_init()
>>>
>>> Cédric Le Goater (20):
>>>    ppc/ppc405: Remove taihu machine
>>>    ppc/ppc405: Introduce a PPC405 generic machine
>>>    ppc/ppc405: Move devices under the ref405ep machine
>>>    ppc/ppc405: Introduce a PPC405 SoC
>>>    ppc/ppc405: Start QOMification of the SoC
>>>    ppc/ppc405: QOM'ify CPU
>>>    ppc/ppc405: QOM'ify CPC
>>>    ppc/ppc405: QOM'ify GPT
>>>    ppc/ppc405: QOM'ify OCM
>>>    ppc/ppc405: QOM'ify GPIO
>>>    ppc/ppc405: QOM'ify DMA
>>>    ppc/ppc405: QOM'ify EBC
>>>    ppc/ppc405: QOM'ify OPBA
>>>    ppc/ppc405: QOM'ify POB
>>>    ppc/ppc405: QOM'ify PLB
>>>    ppc/ppc405: QOM'ify MAL
>>>    ppc/ppc405: QOM'ify FPGA
>>>    ppc/ppc405: QOM'ify UIC
>>>    ppc/ppc405: QOM'ify I2C
>>>    ppc/ppc4xx: Fix sdram trace events
>>>
>>>   docs/about/deprecated.rst       |   9 -
>>>   docs/about/removed-features.rst |   6 +
>>>   docs/system/ppc/embedded.rst    |   1 -
>>>   hw/ppc/ppc405.h                 | 210 ++++++++-
>>>   include/hw/ppc/ppc4xx.h         |  29 ++
>>>   hw/ppc/ppc405_boards.c          | 366 ++++-----------
>>>   hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------
>>>   hw/ppc/ppc4xx_devs.c            | 124 +++--
>>>   MAINTAINERS                     |   2 +-
>>>   9 files changed, 894 insertions(+), 652 deletions(-)
>>>
>>



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

* Re: [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C
  2022-08-04 11:21       ` BALATON Zoltan
@ 2022-08-04 14:14         ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04 14:14 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: qemu-ppc, Daniel Henrique Barboza, qemu-devel

On 8/4/22 13:21, BALATON Zoltan wrote:
> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>> On 8/4/22 01:31, BALATON Zoltan wrote:
>>> On Wed, 3 Aug 2022, Cédric Le Goater wrote:
>>>> Having an explicit I2C model object will help if one day we want to
>>>> add I2C devices on the bus.
>>>
>>> Same here as with the UIC in previous patch, it's not QOMifying here either. As for why we may need I2C, on sam460ex the firmware detects RAM accessing the SPD data over I2C so that could be the reason but it may not be used here on 405.
>>
>> You can still plug I2C devices on the PPC405 command line if you want to.
> 
> Yes true, I just remembered the reson to bother to implement I2C on sam460ex was that the firmware would not work without it so I thought it may be the same reason here but we don't have the firmware for this board so I don't know.
>
> Maybe the original goal was that or the firmware was used for testing but then it was unfinished. Anyway, having more accurate emulation of the hardware is always good so if this matches real hardware then it should stay.

Adding I2C devices works fine. I also have a hotfoot machine variant
with PCI and network but that's for later.

Thanks,

c.

> 
> Regards,
> BALATON Zoltan
> 
>>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>> ---
>>>> hw/ppc/ppc405.h    |  2 ++
>>>> hw/ppc/ppc405_uc.c | 10 ++++++++--
>>>> 2 files changed, 10 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>>> index d29f738cd2d0..d13624ae309c 100644
>>>> --- a/hw/ppc/ppc405.h
>>>> +++ b/hw/ppc/ppc405.h
>>>> @@ -28,6 +28,7 @@
>>>> #include "qom/object.h"
>>>> #include "hw/ppc/ppc4xx.h"
>>>> #include "hw/intc/ppc-uic.h"
>>>> +#include "hw/i2c/ppc4xx_i2c.h"
>>>>
>>>> #define PPC405EP_SDRAM_BASE 0x00000000
>>>> #define PPC405EP_NVRAM_BASE 0xF0000000
>>>> @@ -256,6 +257,7 @@ struct Ppc405SoCState {
>>>>     Ppc405OcmState ocm;
>>>>     Ppc405GpioState gpio;
>>>>     Ppc405DmaState dma;
>>>> +    PPC4xxI2CState i2c;
>>>>     Ppc405EbcState ebc;
>>>>     Ppc405OpbaState opba;
>>>>     Ppc405PobState pob;
>>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>>> index 5cd32e22b7ea..8f0caa45f5f7 100644
>>>> --- a/hw/ppc/ppc405_uc.c
>>>> +++ b/hw/ppc/ppc405_uc.c
>>>> @@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>>>
>>>>     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>>>>
>>>> +    object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
>>>> +
>>>>     object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>>>
>>>>     object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
>>>> @@ -1569,8 +1571,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>>>     }
>>>>
>>>>     /* I2C controller */
>>>> -    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
>>>> -                         qdev_get_gpio_in(DEVICE(&s->uic), 2));
>>>> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
>>>> +        return;
>>>> +    }
>>>> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
>>>> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
>>>> +                       qdev_get_gpio_in(DEVICE(&s->uic), 2));
>>>>
>>>>     /* GPIO */
>>>>     if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
>>>>
>>
>>
>>



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04 12:09       ` BALATON Zoltan
@ 2022-08-04 16:21         ` Cédric Le Goater
       [not found]         ` <3b1bc6c5-a363-0a42-f0dc-eafc14376fe2@kaod.org>
  1 sibling, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04 16:21 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Daniel Henrique Barboza, QEMU Developers, list@suse.de:PowerPC

[ Resending to all ]

On 8/4/22 14:09, BALATON Zoltan wrote:
> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>> On 8/4/22 01:36, Daniel Henrique Barboza wrote:
>>> Cedric,
>>>
>>> On 8/3/22 10:28, Cédric Le Goater wrote:
>>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>> ---
>>>>   hw/ppc/ppc405.h    | 16 +++++++++++
>>>>   hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>>>>   2 files changed, 64 insertions(+), 23 deletions(-)
>>>>
>>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>>> index 1da34a7f10f3..1c7fe07b8084 100644
>>>> --- a/hw/ppc/ppc405.h
>>>> +++ b/hw/ppc/ppc405.h
>>>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>>>   typedef struct Ppc405SoCState Ppc405SoCState;
>>>> +/* Peripheral controller */
>>>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>>>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>>>> +struct Ppc405EbcState {
>>>> +    DeviceState parent_obj;
>>>> +
>>>> +    PowerPCCPU *cpu;
>>>> +    uint32_t addr;
>>>> +    uint32_t bcr[8];
>>>> +    uint32_t bap[8];
>>>> +    uint32_t bear;
>>>> +    uint32_t besr0;
>>>> +    uint32_t besr1;
>>>> +    uint32_t cfg;
>>>> +};
>>>>   /* DMA controller */
>>>>   #define TYPE_PPC405_DMA "ppc405-dma"
>>>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>>>       Ppc405OcmState ocm;
>>>>       Ppc405GpioState gpio;
>>>>       Ppc405DmaState dma;
>>>> +    Ppc405EbcState ebc;
>>>>   };
>>>>   /* PowerPC 405 core */
>>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>>> index 6bd93c1cb90c..0166f3fc36da 100644
>>>> --- a/hw/ppc/ppc405_uc.c
>>>> +++ b/hw/ppc/ppc405_uc.c
>>>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>>> /*****************************************************************************/
>>>>   /* Peripheral controller */
>>>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>>>> -struct ppc4xx_ebc_t {
>>>> -    uint32_t addr;
>>>> -    uint32_t bcr[8];
>>>> -    uint32_t bap[8];
>>>> -    uint32_t bear;
>>>> -    uint32_t besr0;
>>>> -    uint32_t besr1;
>>>> -    uint32_t cfg;
>>>> -};
>>>> -
>>>>   enum {
>>>>       EBC0_CFGADDR = 0x012,
>>>>       EBC0_CFGDATA = 0x013,
>>>> @@ -411,10 +400,9 @@ enum {
>>>>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>>   {
>>>> -    ppc4xx_ebc_t *ebc;
>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>>       uint32_t ret;
>>>> -    ebc = opaque;
>>>>       switch (dcrn) {
>>>>       case EBC0_CFGADDR:
>>>>           ret = ebc->addr;
>>>> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>>   {
>>>> -    ppc4xx_ebc_t *ebc;
>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>> -    ebc = opaque;
>>>>       switch (dcrn) {
>>>>       case EBC0_CFGADDR:
>>>>           ebc->addr = val;
>>>> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>>       }
>>>>   }
>>>> -static void ebc_reset (void *opaque)
>>>> +static void ppc405_ebc_reset(DeviceState *dev)
>>>>   {
>>>> -    ppc4xx_ebc_t *ebc;
>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>>       int i;
>>>> -    ebc = opaque;
>>>>       ebc->addr = 0x00000000;
>>>>       ebc->bap[0] = 0x7F8FFE80;
>>>>       ebc->bcr[0] = 0xFFE28000;
>>>> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>>>>       ebc->cfg = 0x80400000;
>>>>   }
>>>> -void ppc405_ebc_init(CPUPPCState *env)
>>>> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>>>>   {
>>>> -    ppc4xx_ebc_t *ebc;
>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>> +    CPUPPCState *env;
>>>> +
>>>> +    assert(ebc->cpu);
>>>> +
>>>> +    env = &ebc->cpu->env;
>>>> -    ebc = g_new0(ppc4xx_ebc_t, 1);
>>>> -    qemu_register_reset(&ebc_reset, ebc);
>>>>       ppc_dcr_register(env, EBC0_CFGADDR,
>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>       ppc_dcr_register(env, EBC0_CFGDATA,
>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>   }
>>>> +static Property ppc405_ebc_properties[] = {
>>>> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
>>>> +                     PowerPCCPU *),
>>>> +    DEFINE_PROP_END_OF_LIST(),
>>>> +};
>>>> +
>>>> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
>>>> +{
>>>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>>>> +
>>>> +    dc->realize = ppc405_ebc_realize;
>>>> +    dc->user_creatable = false;
>>>> +    dc->reset = ppc405_ebc_reset;
>>>> +    device_class_set_props(dc, ppc405_ebc_properties);
>>>> +}
>>>> +
>>>> +void ppc405_ebc_init(CPUPPCState *env)
>>>> +{
>>>> +    PowerPCCPU *cpu = env_archcpu(env);
>>>> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>>>> +
>>>> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
>>>
>>> This line is breaking the boot of sam460ex:
>>>
>>>
>>>   ./qemu-system-ppc64 -display none -M sam460ex
>>> Unexpected error in object_property_find_err() at ../qom/object.c:1304:
>>> qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
>>> Aborted (core dumped)
>>>
>>>
>>> I think you meant to link the cpu prop of the EBC obj to the CPU object,
>>> not the cpu prop of the CPU obj to the EBC dev.
>>
>> Yes. ppc405_ebc_init() has only one user left, the sam460ex, which I didn't
>> test :/
> 
> This patch changes ppc405_ebc_init to a realize method so shouldn't the sam460ex be changed to create the new object instead of calling ppc405_ebc_init too instead? 

Sure.

First step was to make sure nothing was broken. I can add some extra
patches in v3 to convert ppc405_ebc_init(), ppc4xx_plb_init() and
ppc4xx_mal_init() in the ppc4x machines. I don't think that would be
too much work. It's a good opportunity to modernize a bit the ppc4xx
machines also.

> Is the only reason the keep ppc405_ebc_init to add the cpu link? 

Yes. That's all there is to it really: convert the routines
parameters in object properties.

> As I noted before it would be nice to get rid of this link somehow, 
> it would allow dropping this init func and a bunch of property 
> descriptors where this cpu link is the only object. 

We should introduce a DCR namespace instead and use DCR memory regions
but that's much more work.
  
> It should be possble to get from a QOM object to its parent and the 
> cpu from there but I could not find out how. Maybe somehow with 
> object_resolve_path() or object_resolve_path_type() but I don't know 
> QOM enough and did not find anything in docs.
>
> Does somebody know how to do that? 

One way, would be to introduce a base class DCRDeviceState with a "cpu"
link and a class handler to install the DCR read/write ops. But I think
it's not worth the time and effort. Adding DCR namespace and DCR memory
regions would be better.

Thanks,

C.



> Or maybe the paths are always the same so it could resolve an absolute path. Don't know how it looks buth something like /machine/soc/cpu or similar to get to the cpu to get the env. This could work as long as we assume we only have one cpu but these SoC all have. Then no cpu link is needed and 
> could get rid of a lot of boilerplate code. Does this make sense?
> 
> Regards,
> BALATON Zoltan
> 
>> Thanks,
>>
>> C.
>>
>>>
>>> This fixes the issue:
>>>
>>>
>>> $ git diff
>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>> index 0166f3fc36..aac3a3f761 100644
>>> --- a/hw/ppc/ppc405_uc.c
>>> +++ b/hw/ppc/ppc405_uc.c
>>> @@ -594,7 +594,7 @@ void ppc405_ebc_init(CPUPPCState *env)
>>>       PowerPCCPU *cpu = env_archcpu(env);
>>>       DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>>>
>>> -    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
>>> +    object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
>>>       qdev_realize_and_unref(dev, NULL, &error_fatal);
>>>   }
>>>
>>>
>>> Daniel
>>>
>>>
>>>> +    qdev_realize_and_unref(dev, NULL, &error_fatal);
>>>> +}
>>>> +
>>>> /*****************************************************************************/
>>>>   /* DMA controller */
>>>>   enum {
>>>> @@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
>>>>       object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
>>>>       object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
>>>> +
>>>> +    object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
>>>>   }
>>>>   static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>>> @@ -1490,7 +1506,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
>>>>                         s->ram_bases, s->ram_sizes, s->do_dram_init);
>>>>       /* External bus controller */
>>>> -    ppc405_ebc_init(env);
>>>> +    object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
>>>> +                             &error_abort);
>>>> +    if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
>>>> +        return;
>>>> +    }
>>>>       /* DMA controller */
>>>>       object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
>>>> @@ -1576,6 +1596,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
>>>>   static const TypeInfo ppc405_types[] = {
>>>>       {
>>>> +        .name           = TYPE_PPC405_EBC,
>>>> +        .parent         = TYPE_DEVICE,
>>>> +        .instance_size  = sizeof(Ppc405EbcState),
>>>> +        .class_init     = ppc405_ebc_class_init,
>>>> +    }, {
>>>>           .name           = TYPE_PPC405_DMA,
>>>>           .parent         = TYPE_SYS_BUS_DEVICE,
>>>>           .instance_size  = sizeof(Ppc405DmaState),
>>
>>
>>



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
       [not found]           ` <1e6be2f3-4c7a-2432-5034-fa012c662df@eik.bme.hu>
@ 2022-08-04 16:31             ` Cédric Le Goater
  2022-08-04 18:00               ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-04 16:31 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Daniel Henrique Barboza, list@suse.de:PowerPC, QEMU Developers

[ Replying to all ]

On 8/4/22 16:26, BALATON Zoltan wrote:
> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>> On 8/4/22 14:09, BALATON Zoltan wrote:
>>> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>>>> On 8/4/22 01:36, Daniel Henrique Barboza wrote:
>>>>> Cedric,
>>>>>
>>>>> On 8/3/22 10:28, Cédric Le Goater wrote:
>>>>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>>>> ---
>>>>>>   hw/ppc/ppc405.h    | 16 +++++++++++
>>>>>>   hw/ppc/ppc405_uc.c | 71 +++++++++++++++++++++++++++++++---------------
>>>>>>   2 files changed, 64 insertions(+), 23 deletions(-)
>>>>>>
>>>>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>>>>> index 1da34a7f10f3..1c7fe07b8084 100644
>>>>>> --- a/hw/ppc/ppc405.h
>>>>>> +++ b/hw/ppc/ppc405.h
>>>>>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>>>>>   typedef struct Ppc405SoCState Ppc405SoCState;
>>>>>> +/* Peripheral controller */
>>>>>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>>>>>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>>>>>> +struct Ppc405EbcState {
>>>>>> +    DeviceState parent_obj;
>>>>>> +
>>>>>> +    PowerPCCPU *cpu;
>>>>>> +    uint32_t addr;
>>>>>> +    uint32_t bcr[8];
>>>>>> +    uint32_t bap[8];
>>>>>> +    uint32_t bear;
>>>>>> +    uint32_t besr0;
>>>>>> +    uint32_t besr1;
>>>>>> +    uint32_t cfg;
>>>>>> +};
>>>>>>   /* DMA controller */
>>>>>>   #define TYPE_PPC405_DMA "ppc405-dma"
>>>>>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>>>>>       Ppc405OcmState ocm;
>>>>>>       Ppc405GpioState gpio;
>>>>>>       Ppc405DmaState dma;
>>>>>> +    Ppc405EbcState ebc;
>>>>>>   };
>>>>>>   /* PowerPC 405 core */
>>>>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>>>>> index 6bd93c1cb90c..0166f3fc36da 100644
>>>>>> --- a/hw/ppc/ppc405_uc.c
>>>>>> +++ b/hw/ppc/ppc405_uc.c
>>>>>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>>>>> /*****************************************************************************/
>>>>>>   /* Peripheral controller */
>>>>>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>>>>>> -struct ppc4xx_ebc_t {
>>>>>> -    uint32_t addr;
>>>>>> -    uint32_t bcr[8];
>>>>>> -    uint32_t bap[8];
>>>>>> -    uint32_t bear;
>>>>>> -    uint32_t besr0;
>>>>>> -    uint32_t besr1;
>>>>>> -    uint32_t cfg;
>>>>>> -};
>>>>>> -
>>>>>>   enum {
>>>>>>       EBC0_CFGADDR = 0x012,
>>>>>>       EBC0_CFGDATA = 0x013,
>>>>>> @@ -411,10 +400,9 @@ enum {
>>>>>>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>>>>   {
>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>>>>       uint32_t ret;
>>>>>> -    ebc = opaque;
>>>>>>       switch (dcrn) {
>>>>>>       case EBC0_CFGADDR:
>>>>>>           ret = ebc->addr;
>>>>>> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>>>>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>>>>   {
>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>>>> -    ebc = opaque;
>>>>>>       switch (dcrn) {
>>>>>>       case EBC0_CFGADDR:
>>>>>>           ebc->addr = val;
>>>>>> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>>>>       }
>>>>>>   }
>>>>>> -static void ebc_reset (void *opaque)
>>>>>> +static void ppc405_ebc_reset(DeviceState *dev)
>>>>>>   {
>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>>>>       int i;
>>>>>> -    ebc = opaque;
>>>>>>       ebc->addr = 0x00000000;
>>>>>>       ebc->bap[0] = 0x7F8FFE80;
>>>>>>       ebc->bcr[0] = 0xFFE28000;
>>>>>> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>>>>>>       ebc->cfg = 0x80400000;
>>>>>>   }
>>>>>> -void ppc405_ebc_init(CPUPPCState *env)
>>>>>> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>>>>>>   {
>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>>>> +    CPUPPCState *env;
>>>>>> +
>>>>>> +    assert(ebc->cpu);
>>>>>> +
>>>>>> +    env = &ebc->cpu->env;
>>>>>> -    ebc = g_new0(ppc4xx_ebc_t, 1);
>>>>>> -    qemu_register_reset(&ebc_reset, ebc);
>>>>>>       ppc_dcr_register(env, EBC0_CFGADDR,
>>>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>>>       ppc_dcr_register(env, EBC0_CFGDATA,
>>>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>>>   }
>>>>>> +static Property ppc405_ebc_properties[] = {
>>>>>> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
>>>>>> +                     PowerPCCPU *),
>>>>>> +    DEFINE_PROP_END_OF_LIST(),
>>>>>> +};
>>>>>> +
>>>>>> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
>>>>>> +{
>>>>>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>>>>>> +
>>>>>> +    dc->realize = ppc405_ebc_realize;
>>>>>> +    dc->user_creatable = false;
>>>>>> +    dc->reset = ppc405_ebc_reset;
>>>>>> +    device_class_set_props(dc, ppc405_ebc_properties);
>>>>>> +}
>>>>>> +
>>>>>> +void ppc405_ebc_init(CPUPPCState *env)
>>>>>> +{
>>>>>> +    PowerPCCPU *cpu = env_archcpu(env);
>>>>>> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>>>>>> +
>>>>>> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
>>>>>
>>>>> This line is breaking the boot of sam460ex:
>>>>>
>>>>>
>>>>>   ./qemu-system-ppc64 -display none -M sam460ex
>>>>> Unexpected error in object_property_find_err() at ../qom/object.c:1304:
>>>>> qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
>>>>> Aborted (core dumped)
>>>>>
>>>>>
>>>>> I think you meant to link the cpu prop of the EBC obj to the CPU object,
>>>>> not the cpu prop of the CPU obj to the EBC dev.
>>>>
>>>> Yes. ppc405_ebc_init() has only one user left, the sam460ex, which I didn't
>>>> test :/
>>>
>>> This patch changes ppc405_ebc_init to a realize method so shouldn't the sam460ex be changed to create the new object instead of calling ppc405_ebc_init too instead? 
>>
>> Sure.
>>
>> First step was to make sure nothing was broken. I can add some extra
>> patches in v3 to convert ppc405_ebc_init(), ppc4xx_plb_init() and
>> ppc4xx_mal_init() in the ppc4x machines. I don't think that would be
>> too much work. It's a good opportunity to modernize a bit the ppc4xx
>> machines also.
> 
> OK, I did not mean to impose too much additional work but if a legacy init function only has one caller left maybe it's a good time to get rid of it at the same time when you converted the other caller. Those which have more users left could be addressed later if it would be too much work.
> 
>>> Is the only reason the keep ppc405_ebc_init to add the cpu link? 
>>
>> Yes. That's all there is to it really: convert the routines
>> parameters in object properties.
>>
>>> As I noted before it would be nice to get rid of this link somehow, it would allow dropping this init func and a bunch of property descriptors where this cpu link is the only object. 
>>
>> We should introduce a DCR namespace instead and use DCR memory regions
>> but that's much more work.
> 
> Maybe that's a more complete solution but I think we could make it simpler even without going there yet.
> 
>>> It should be possble to get from a QOM object to its parent and the cpu from there but I could not find out how. Maybe somehow with object_resolve_path() or object_resolve_path_type() but I don't know QOM enough and did not find anything in docs.
>>>
>>> Does somebody know how to do that? 
>>
>> One way, would be to introduce a base class DCRDeviceState with a "cpu"
>> link and a class handler to install the DCR read/write ops. But I think
>> it's not worth the time and effort. Adding DCR namespace and DCR memory
>> regions would be better.
> 
> Is this really necessary? Why do we have a qom-tree if objects can't navigate it? I think it should be possible to get to the cpu object from these soc devices without needing a link property for that. Ideally it should be able to get "../cpu" or shouldn't something like object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL) return the cpu object? 

Yes. We could. I find it cleaner to use a property.

It is true that "cpu" is only used at realize time to install the DCR
handlers in the DCR table of the CPU. So there is not much value in
keeping a pointer to the CPU under the device state struct. Once the
DCR handlers are installed. We are done.


> (Assiming there's only one which is true for these SoCs.) Then you could do this in the realize method and store the cpu in the state struct of the soc device 

The CPU is already under the 405 SoC device, or you mean any SoC device ?
I am not sure I am following. Send a code example !

Thanks,

C.


> so it does not have to be looked up every time or set externally via a property? That way no cpu link property is needed for all these soc devices only that they are added to a soc that already has a cpu added before.
>
> 
> We do have the parent field in the Object struct so you could theoretically just do object_resolve_path_at(obj->parent, "cpu") but all those fields are marked private and I could not find out what's the preferred way to get to this then. Could somebody with more knowledge about QOM chime in please?
> 
> Regards,
> BALATON Zoltan



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04 16:31             ` Cédric Le Goater
@ 2022-08-04 18:00               ` BALATON Zoltan
  2022-08-04 18:18                 ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-04 18:00 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Daniel Henrique Barboza, list@suse.de:PowerPC, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 11814 bytes --]

On Thu, 4 Aug 2022, Cédric Le Goater wrote:
> [ Replying to all ]
>
> On 8/4/22 16:26, BALATON Zoltan wrote:
>> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>>> On 8/4/22 14:09, BALATON Zoltan wrote:
>>>> On Thu, 4 Aug 2022, Cédric Le Goater wrote:
>>>>> On 8/4/22 01:36, Daniel Henrique Barboza wrote:
>>>>>> Cedric,
>>>>>> 
>>>>>> On 8/3/22 10:28, Cédric Le Goater wrote:
>>>>>>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>>>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>>>>> ---
>>>>>>>   hw/ppc/ppc405.h    | 16 +++++++++++
>>>>>>>   hw/ppc/ppc405_uc.c | 71 
>>>>>>> +++++++++++++++++++++++++++++++---------------
>>>>>>>   2 files changed, 64 insertions(+), 23 deletions(-)
>>>>>>> 
>>>>>>> diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
>>>>>>> index 1da34a7f10f3..1c7fe07b8084 100644
>>>>>>> --- a/hw/ppc/ppc405.h
>>>>>>> +++ b/hw/ppc/ppc405.h
>>>>>>> @@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
>>>>>>>   typedef struct Ppc405SoCState Ppc405SoCState;
>>>>>>> +/* Peripheral controller */
>>>>>>> +#define TYPE_PPC405_EBC "ppc405-ebc"
>>>>>>> +OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
>>>>>>> +struct Ppc405EbcState {
>>>>>>> +    DeviceState parent_obj;
>>>>>>> +
>>>>>>> +    PowerPCCPU *cpu;
>>>>>>> +    uint32_t addr;
>>>>>>> +    uint32_t bcr[8];
>>>>>>> +    uint32_t bap[8];
>>>>>>> +    uint32_t bear;
>>>>>>> +    uint32_t besr0;
>>>>>>> +    uint32_t besr1;
>>>>>>> +    uint32_t cfg;
>>>>>>> +};
>>>>>>>   /* DMA controller */
>>>>>>>   #define TYPE_PPC405_DMA "ppc405-dma"
>>>>>>> @@ -203,6 +218,7 @@ struct Ppc405SoCState {
>>>>>>>       Ppc405OcmState ocm;
>>>>>>>       Ppc405GpioState gpio;
>>>>>>>       Ppc405DmaState dma;
>>>>>>> +    Ppc405EbcState ebc;
>>>>>>>   };
>>>>>>>   /* PowerPC 405 core */
>>>>>>> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
>>>>>>> index 6bd93c1cb90c..0166f3fc36da 100644
>>>>>>> --- a/hw/ppc/ppc405_uc.c
>>>>>>> +++ b/hw/ppc/ppc405_uc.c
>>>>>>> @@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
>>>>>>> /*****************************************************************************/
>>>>>>>   /* Peripheral controller */
>>>>>>> -typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
>>>>>>> -struct ppc4xx_ebc_t {
>>>>>>> -    uint32_t addr;
>>>>>>> -    uint32_t bcr[8];
>>>>>>> -    uint32_t bap[8];
>>>>>>> -    uint32_t bear;
>>>>>>> -    uint32_t besr0;
>>>>>>> -    uint32_t besr1;
>>>>>>> -    uint32_t cfg;
>>>>>>> -};
>>>>>>> -
>>>>>>>   enum {
>>>>>>>       EBC0_CFGADDR = 0x012,
>>>>>>>       EBC0_CFGDATA = 0x013,
>>>>>>> @@ -411,10 +400,9 @@ enum {
>>>>>>>   static uint32_t dcr_read_ebc (void *opaque, int dcrn)
>>>>>>>   {
>>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>>>>>       uint32_t ret;
>>>>>>> -    ebc = opaque;
>>>>>>>       switch (dcrn) {
>>>>>>>       case EBC0_CFGADDR:
>>>>>>>           ret = ebc->addr;
>>>>>>> @@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int 
>>>>>>> dcrn)
>>>>>>>   static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
>>>>>>>   {
>>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(opaque);
>>>>>>> -    ebc = opaque;
>>>>>>>       switch (dcrn) {
>>>>>>>       case EBC0_CFGADDR:
>>>>>>>           ebc->addr = val;
>>>>>>> @@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int 
>>>>>>> dcrn, uint32_t val)
>>>>>>>       }
>>>>>>>   }
>>>>>>> -static void ebc_reset (void *opaque)
>>>>>>> +static void ppc405_ebc_reset(DeviceState *dev)
>>>>>>>   {
>>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>>>>>       int i;
>>>>>>> -    ebc = opaque;
>>>>>>>       ebc->addr = 0x00000000;
>>>>>>>       ebc->bap[0] = 0x7F8FFE80;
>>>>>>>       ebc->bcr[0] = 0xFFE28000;
>>>>>>> @@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
>>>>>>>       ebc->cfg = 0x80400000;
>>>>>>>   }
>>>>>>> -void ppc405_ebc_init(CPUPPCState *env)
>>>>>>> +static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
>>>>>>>   {
>>>>>>> -    ppc4xx_ebc_t *ebc;
>>>>>>> +    Ppc405EbcState *ebc = PPC405_EBC(dev);
>>>>>>> +    CPUPPCState *env;
>>>>>>> +
>>>>>>> +    assert(ebc->cpu);
>>>>>>> +
>>>>>>> +    env = &ebc->cpu->env;
>>>>>>> -    ebc = g_new0(ppc4xx_ebc_t, 1);
>>>>>>> -    qemu_register_reset(&ebc_reset, ebc);
>>>>>>>       ppc_dcr_register(env, EBC0_CFGADDR,
>>>>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>>>>       ppc_dcr_register(env, EBC0_CFGDATA,
>>>>>>>                        ebc, &dcr_read_ebc, &dcr_write_ebc);
>>>>>>>   }
>>>>>>> +static Property ppc405_ebc_properties[] = {
>>>>>>> +    DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
>>>>>>> +                     PowerPCCPU *),
>>>>>>> +    DEFINE_PROP_END_OF_LIST(),
>>>>>>> +};
>>>>>>> +
>>>>>>> +static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
>>>>>>> +{
>>>>>>> +    DeviceClass *dc = DEVICE_CLASS(oc);
>>>>>>> +
>>>>>>> +    dc->realize = ppc405_ebc_realize;
>>>>>>> +    dc->user_creatable = false;
>>>>>>> +    dc->reset = ppc405_ebc_reset;
>>>>>>> +    device_class_set_props(dc, ppc405_ebc_properties);
>>>>>>> +}
>>>>>>> +
>>>>>>> +void ppc405_ebc_init(CPUPPCState *env)
>>>>>>> +{
>>>>>>> +    PowerPCCPU *cpu = env_archcpu(env);
>>>>>>> +    DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
>>>>>>> +
>>>>>>> +    object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), 
>>>>>>> &error_abort);
>>>>>> 
>>>>>> This line is breaking the boot of sam460ex:
>>>>>> 
>>>>>> 
>>>>>>   ./qemu-system-ppc64 -display none -M sam460ex
>>>>>> Unexpected error in object_property_find_err() at ../qom/object.c:1304:
>>>>>> qemu-system-ppc64: Property '460exb-powerpc64-cpu.cpu' not found
>>>>>> Aborted (core dumped)
>>>>>> 
>>>>>> 
>>>>>> I think you meant to link the cpu prop of the EBC obj to the CPU 
>>>>>> object,
>>>>>> not the cpu prop of the CPU obj to the EBC dev.
>>>>> 
>>>>> Yes. ppc405_ebc_init() has only one user left, the sam460ex, which I 
>>>>> didn't
>>>>> test :/
>>>> 
>>>> This patch changes ppc405_ebc_init to a realize method so shouldn't the 
>>>> sam460ex be changed to create the new object instead of calling 
>>>> ppc405_ebc_init too instead? 
>>> 
>>> Sure.
>>> 
>>> First step was to make sure nothing was broken. I can add some extra
>>> patches in v3 to convert ppc405_ebc_init(), ppc4xx_plb_init() and
>>> ppc4xx_mal_init() in the ppc4x machines. I don't think that would be
>>> too much work. It's a good opportunity to modernize a bit the ppc4xx
>>> machines also.
>> 
>> OK, I did not mean to impose too much additional work but if a legacy init 
>> function only has one caller left maybe it's a good time to get rid of it 
>> at the same time when you converted the other caller. Those which have more 
>> users left could be addressed later if it would be too much work.
>> 
>>>> Is the only reason the keep ppc405_ebc_init to add the cpu link? 
>>> 
>>> Yes. That's all there is to it really: convert the routines
>>> parameters in object properties.
>>> 
>>>> As I noted before it would be nice to get rid of this link somehow, it 
>>>> would allow dropping this init func and a bunch of property descriptors 
>>>> where this cpu link is the only object. 
>>> 
>>> We should introduce a DCR namespace instead and use DCR memory regions
>>> but that's much more work.
>> 
>> Maybe that's a more complete solution but I think we could make it simpler 
>> even without going there yet.
>> 
>>>> It should be possble to get from a QOM object to its parent and the cpu 
>>>> from there but I could not find out how. Maybe somehow with 
>>>> object_resolve_path() or object_resolve_path_type() but I don't know QOM 
>>>> enough and did not find anything in docs.
>>>> 
>>>> Does somebody know how to do that? 
>>> 
>>> One way, would be to introduce a base class DCRDeviceState with a "cpu"
>>> link and a class handler to install the DCR read/write ops. But I think
>>> it's not worth the time and effort. Adding DCR namespace and DCR memory
>>> regions would be better.
>> 
>> Is this really necessary? Why do we have a qom-tree if objects can't 
>> navigate it? I think it should be possible to get to the cpu object from 
>> these soc devices without needing a link property for that. Ideally it 
>> should be able to get "../cpu" or shouldn't something like 
>> object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL) return the cpu 
>> object? 
>
> Yes. We could. I find it cleaner to use a property.

I don't like the property because it adds a significant number of lines to 
some otherwise simple devices that don't have any properties now (adding a 
property is at least 5 lines of code) so I think avoiding it would 
simplify it enough to worth trying to do without the property.

> It is true that "cpu" is only used at realize time to install the DCR
> handlers in the DCR table of the CPU. So there is not much value in
> keeping a pointer to the CPU under the device state struct. Once the
> DCR handlers are installed. We are done.

Then it would even better to get somehow get the cpu object from the QOM 
tree in realize once then the state struct also does not need the cpu 
reference so at least one more line less. Also don't need to assign the 
property so callers are simpler too (and cannot make the mistake you did 
above).

>> (Assiming there's only one which is true for these SoCs.) Then you could do 
>> this in the realize method and store the cpu in the state struct of the soc 
>> device 
>
> The CPU is already under the 405 SoC device, or you mean any SoC device ?
> I am not sure I am following. Send a code example !

I was trying to find out how to do it but I don't understand QOM enough to 
answer the simple question of how to get the cpu object from QOM. My 
guesses are:

object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL)

or maybe

object_resolve_path_at(OBJECT(dev)->parent, "cpu")

or how do these functions work and what is the preferred way to retrieve 
an object from the QOM tree? This is what I hoped someone with more 
understanding of QOM could answer.

We know that the dev (the device whose realize method we're in and want to 
get to the cpu) is likely at the same level as the cpu object (either both 
are in a soc or part of the machine) so we somehow need to either go up to 
our parent and search for a cpu there or start from /machine and find a 
cpu (the only one these machines have) so if the above path resolve 
functions go down the tree it should find it. If it only searches one 
level than we may need to try twice, once at /machine/soc and maybe once 
at /machine as most ppc4xx machines don't have a soc object yet (or maybe 
they do after your patches? can you show how "info qom-tree" looks after 
your patches for these machines?).

Does it make more sense or should I try to explain it more?

Regards,
BALATON Zoltan

> Thanks,
>
> C.
>
>
>> so it does not have to be looked up every time or set externally via a 
>> property? That way no cpu link property is needed for all these soc devices 
>> only that they are added to a soc that already has a cpu added before.
>> 
>> 
>> We do have the parent field in the Object struct so you could theoretically 
>> just do object_resolve_path_at(obj->parent, "cpu") but all those fields are 
>> marked private and I could not find out what's the preferred way to get to 
>> this then. Could somebody with more knowledge about QOM chime in please?
>> 
>> Regards,
>> BALATON Zoltan
>
>
>

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04 18:00               ` BALATON Zoltan
@ 2022-08-04 18:18                 ` Peter Maydell
  2022-08-04 19:26                   ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2022-08-04 18:18 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

On Thu, 4 Aug 2022 at 19:03, BALATON Zoltan <balaton@eik.bme.hu> wrote:
> I was trying to find out how to do it but I don't understand QOM enough to
> answer the simple question of how to get the cpu object from QOM. My
> guesses are:
>
> object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL)
>
> or maybe
>
> object_resolve_path_at(OBJECT(dev)->parent, "cpu")
>
> or how do these functions work and what is the preferred way to retrieve
> an object from the QOM tree? This is what I hoped someone with more
> understanding of QOM could answer.

The standard approach that we use elsewhere in the tree for handling
"this device needs to have a pointer to a CPU object or whatever"
is "the device has a QOM link property, and the SoC sets that
property when it creates the device".

There are other ways it could in theory be done, but there is
benefit in consistency, and "define and set the property" is
straightforward. It also means the device object doesn't have
to know anything about the way the SoC container is laid out.

(It's usually worth looking at whether there are cleanups
that could mean the device doesn't have to have a pointer to
that other object at all -- but that isn't always the case,
or the cleanups would be a big job in their own right that
are better not tangled up with QOMification.)

thanks
-- PMM


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04 18:18                 ` Peter Maydell
@ 2022-08-04 19:26                   ` BALATON Zoltan
  2022-08-05  7:07                     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-04 19:26 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 3081 bytes --]

On Thu, 4 Aug 2022, Peter Maydell wrote:
> On Thu, 4 Aug 2022 at 19:03, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>> I was trying to find out how to do it but I don't understand QOM enough to
>> answer the simple question of how to get the cpu object from QOM. My
>> guesses are:
>>
>> object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL)

Out of curiosity would this work though to get the cpu or if not why not 
and what would be a preferred way? I could not find this out from reading 
the object.h comments, the docs/deve/qom.rst, nor searching the code.

>> or maybe
>>
>> object_resolve_path_at(OBJECT(dev)->parent, "cpu")
>>
>> or how do these functions work and what is the preferred way to retrieve
>> an object from the QOM tree? This is what I hoped someone with more
>> understanding of QOM could answer.
>
> The standard approach that we use elsewhere in the tree for handling
> "this device needs to have a pointer to a CPU object or whatever"
> is "the device has a QOM link property, and the SoC sets that
> property when it creates the device".
>
> There are other ways it could in theory be done, but there is
> benefit in consistency, and "define and set the property" is

If this is the preferred way then so be it, I just don't like it because I 
think this is too many boilerplate code that could be avoided. This series:

  9 files changed, 894 insertions(+), 652 deletions(-)

  and that's including removing all of the taihu machine; the file where 
the QOMification is done:

  hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------

Ideally introducing QOM should make it simpler not more complex. Four of 
the QOMified devices only have a property defined at all because of this 
cpu link that's only used once in the realize method to register DCRs. 
This is about 10 lines of code each. If there was a simple way to get the 
cpu object from these realize methods then we could get rid of all these 
properties and save about 40-50 lines and make these simpler.

> straightforward. It also means the device object doesn't have
> to know anything about the way the SoC container is laid out.

We only need the cpu object so we don't need to know the soc container if 
there's a way to get it otherwise I just don't know how QOM works and was 
trying to find a way to get to the cpu object. Maybe it's simpler than 
that.

If there's no simple way or you and Cédric think it isn't worth the effort 
then I'm also OK with it but if there's a way to make this simpler I'd be 
happy to get rid of things that make it harder to read and understand code 
or allow making mistakes more easily. I take whatever decision you make so 
won't say this again, I think I've explained my point now.

Regards,
BALATON Zoltan

> (It's usually worth looking at whether there are cleanups
> that could mean the device doesn't have to have a pointer to
> that other object at all -- but that isn't always the case,
> or the cleanups would be a big job in their own right that
> are better not tangled up with QOMification.)
>
> thanks
> -- PMM
>
>

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-04 19:26                   ` BALATON Zoltan
@ 2022-08-05  7:07                     ` Cédric Le Goater
  2022-08-05 12:55                       ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-05  7:07 UTC (permalink / raw)
  To: BALATON Zoltan, Peter Maydell
  Cc: Daniel Henrique Barboza, list@suse.de:PowerPC, QEMU Developers

On 8/4/22 21:26, BALATON Zoltan wrote:
> On Thu, 4 Aug 2022, Peter Maydell wrote:
>> On Thu, 4 Aug 2022 at 19:03, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>> I was trying to find out how to do it but I don't understand QOM enough to
>>> answer the simple question of how to get the cpu object from QOM. My
>>> guesses are:
>>>
>>> object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL)
> 
> Out of curiosity would this work though to get the cpu or if not why not and what would be a preferred way? I could not find this out from reading the object.h comments, the docs/deve/qom.rst, nor searching the code.

You could scan the object topology using object_child_foreach_recursive()
and use object_dynamic_cast() to find a POWERPC CPU object. A link is
much faster !

> 
>>> or maybe
>>>
>>> object_resolve_path_at(OBJECT(dev)->parent, "cpu")
>>>
>>> or how do these functions work and what is the preferred way to retrieve
>>> an object from the QOM tree? This is what I hoped someone with more
>>> understanding of QOM could answer.
>>
>> The standard approach that we use elsewhere in the tree for handling
>> "this device needs to have a pointer to a CPU object or whatever"
>> is "the device has a QOM link property, and the SoC sets that
>> property when it creates the device".
>>
>> There are other ways it could in theory be done, but there is
>> benefit in consistency, and "define and set the property" is
> 
> If this is the preferred way then so be it, I just don't like it because I think this is too many boilerplate code that could be avoided. This series:
> 
>   9 files changed, 894 insertions(+), 652 deletions(-)
> 
>   and that's including removing all of the taihu machine; the file where the QOMification is done:
> 
>   hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------

Yes. You should consider also that this code is > 15 years old and
serious shortcuts have been taken to "make things work". I think QOM
clarifies the models and represents better the HW topology. There is
a price in being explicit.

> 
> Ideally introducing QOM should make it simpler not more complex. Four of the QOMified devices only have a property defined at all because of this cpu link that's only used once in the realize method to register DCRs. This is about 10 lines of code each. If there was a simple way to get the cpu object from these realize methods then we could get rid of all these properties and save about 40-50 lines and make these simpler.

I tried several approaches and found this one was the simplest and not
too verbose really.

The DCRs are accessed by software through the use of the mtdcr and mfdcr
instructions. These are converted in transactions on a side band bus,
the DCR bus, which connects the on-SoC devices to the CPU. The "cpu" link
should be considered as modeling this little piece of HW logic connecting
the device to the DCR bus.

Thanks,

C.


>> straightforward. It also means the device object doesn't have
>> to know anything about the way the SoC container is laid out.
> 
> We only need the cpu object so we don't need to know the soc container if there's a way to get it otherwise I just don't know how QOM works and was trying to find a way to get to the cpu object. Maybe it's simpler than that.
> 
> If there's no simple way or you and Cédric think it isn't worth the effort then I'm also OK with it but if there's a way to make this simpler I'd be happy to get rid of things that make it harder to read and understand code or allow making mistakes more easily. I take whatever decision you make so won't say this again, I think I've explained my point now.
> 
> Regards,
> BALATON Zoltan
> 
>> (It's usually worth looking at whether there are cleanups
>> that could mean the device doesn't have to have a pointer to
>> that other object at all -- but that isn't always the case,
>> or the cleanups would be a big job in their own right that
>> are better not tangled up with QOMification.)
>>
>> thanks
>> -- PMM
>>
>>



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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05  7:07                     ` Cédric Le Goater
@ 2022-08-05 12:55                       ` BALATON Zoltan
  2022-08-05 13:16                         ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-05 12:55 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Daniel Henrique Barboza, list@suse.de:PowerPC,
	QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 4598 bytes --]

On Fri, 5 Aug 2022, Cédric Le Goater wrote:
> On 8/4/22 21:26, BALATON Zoltan wrote:
>> On Thu, 4 Aug 2022, Peter Maydell wrote:
>>> On Thu, 4 Aug 2022 at 19:03, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>>> I was trying to find out how to do it but I don't understand QOM enough 
>>>> to
>>>> answer the simple question of how to get the cpu object from QOM. My
>>>> guesses are:
>>>> 
>>>> object_resolve_path_type("/machine", TYPE_POWERPC_CPU, NULL)
>> 
>> Out of curiosity would this work though to get the cpu or if not why not 
>> and what would be a preferred way? I could not find this out from reading 
>> the object.h comments, the docs/deve/qom.rst, nor searching the code.
>
> You could scan the object topology using object_child_foreach_recursive()
> and use object_dynamic_cast() to find a POWERPC CPU object. A link is
> much faster !

Yes that sounds a lot slower, I hoped there's simple easy way to get to 
the cpu, then we could simplify this a bit.

One more idea, you've introduced the Ppc405MachineState which you can get 
to casting current_machine and so it's a convenient place to store a cpu 
pointer or even just use PPC405_MACHINE(current_machine)->soc.cpu. This 
works for these 405 machines you've changed in this series but other 
PPC4xx machines don't have this machine and soc states yet. Could these 
Ppc405MachineState and Ppc405SoCState be more generic as 
Ppc4xxMachineState and Ppc4xxSoCState considering that these chips are 
quite similar or maybe we need an abstract PPC4xxSoC class but machine 
state could be shared? (If you say this is too much cahnges for you now I 
may try to look at this later once your series is merged but going that 
way now could save some churn.) If we had a Ppc4xxMachineState that has a 
cpu pointer then we could easily add that to bamboo and sam460ex now and 
these QOMified devices could then use PPC4XX_MACHINE(current_machine)->cpu 
instead of a link property. What do you think?

>> If this is the preferred way then so be it, I just don't like it because I 
>> think this is too many boilerplate code that could be avoided. This series:
>>
>>   9 files changed, 894 insertions(+), 652 deletions(-)
>>
>>   and that's including removing all of the taihu machine; the file where 
>> the QOMification is done:
>>
>>   hw/ppc/ppc405_uc.c              | 799 +++++++++++++++++++-------------
>
> Yes. You should consider also that this code is > 15 years old and
> serious shortcuts have been taken to "make things work". I think QOM
> clarifies the models and represents better the HW topology. There is
> a price in being explicit.

I know this is a mess curently but QOM is full of boilerplate code which 
is confusing for new people and makes it hard to undestand the code. So 
cutting down the boilerplate and making things simpler would help people 
who want to get started with QEMU development. If adding a property was 
3-4 additional lines I wouldn't care but if it makes the code 
significantly more complex and thus harder to understand at a glance then 
I'd rather avoid it if possible and stick to simple terms. Verbosity is 
good if it explains things better but bad if it's hiding the important 
details between unneeded complexity due to having to use constructs that 
are not obvious. Also the property needs to be set which is additional 
lines and possibility for mistakes so if there's a way to avoid that I 
think that's better.

>> Ideally introducing QOM should make it simpler not more complex. Four of 
>> the QOMified devices only have a property defined at all because of this 
>> cpu link that's only used once in the realize method to register DCRs. This 
>> is about 10 lines of code each. If there was a simple way to get the cpu 
>> object from these realize methods then we could get rid of all these 
>> properties and save about 40-50 lines and make these simpler.
>
> I tried several approaches and found this one was the simplest and not
> too verbose really.
>
> The DCRs are accessed by software through the use of the mtdcr and mfdcr
> instructions. These are converted in transactions on a side band bus,
> the DCR bus, which connects the on-SoC devices to the CPU. The "cpu" link
> should be considered as modeling this little piece of HW logic connecting
> the device to the DCR bus.

I rather consider it an implementation detail and trying to find the 
simplest way. If we don't find anything simpler I'm OK with link 
properties but I'm not convinced yet there's no simpler solution to this 
problem that could avoid some of the additional complexity.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 12:55                       ` BALATON Zoltan
@ 2022-08-05 13:16                         ` Peter Maydell
  2022-08-05 16:50                           ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2022-08-05 13:16 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

On Fri, 5 Aug 2022 at 13:55, BALATON Zoltan <balaton@eik.bme.hu> wrote:
> I know this is a mess curently but QOM is full of boilerplate code which
> is confusing for new people and makes it hard to undestand the code. So
> cutting down the boilerplate and making things simpler would help people
> who want to get started with QEMU development. If adding a property was
> 3-4 additional lines I wouldn't care but if it makes the code
> significantly more complex and thus harder to understand at a glance then
> I'd rather avoid it if possible and stick to simple terms.

I agree that QOM's boilerplate is not nice at all, but if
you do something other than the "standard QOM boilerplate"
solution to a problem then you make it harder for people who
at least know what the standard QOM approach is to figure out
why the code is doing what it does.

-- PMM


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 13:16                         ` Peter Maydell
@ 2022-08-05 16:50                           ` BALATON Zoltan
  2022-08-05 16:55                             ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-05 16:50 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 3366 bytes --]

On Fri, 5 Aug 2022, Peter Maydell wrote:
> On Fri, 5 Aug 2022 at 13:55, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>> I know this is a mess curently but QOM is full of boilerplate code which
>> is confusing for new people and makes it hard to undestand the code. So
>> cutting down the boilerplate and making things simpler would help people
>> who want to get started with QEMU development. If adding a property was
>> 3-4 additional lines I wouldn't care but if it makes the code
>> significantly more complex and thus harder to understand at a glance then
>> I'd rather avoid it if possible and stick to simple terms.
>
> I agree that QOM's boilerplate is not nice at all, but if
> you do something other than the "standard QOM boilerplate"
> solution to a problem then you make it harder for people who
> at least know what the standard QOM approach is to figure out
> why the code is doing what it does.

True, unless what we do instead is simpler so it's obvious what it's 
doing. Also you've said that needing a link is often a sign that there's 
something wrong with the modeling so maybe it can be avoided changing how 
we model things. I think that's the case here. If we had:

struct PPC4xxMachineState { /* abstract */
     MachineState parent_obj;

     PPC4xxSoc soc;
}

which we use for all 4xx machnies that use the devices QOMified here and

struct PPC4xxSocState { /* abstract */
     DeviceState parent_obj;

     PowerPCCPU cpu;
     /* other common devices shared by 405 and 440
      * (probably most of them), may need to add int ram_banks to allow
      * different size ram_memories arrays, etc. but this can be done later
      * when doing 440 SoC state and only have the cpu here for now */
}

struct PPC405SocState {
     PPC4xxSocState parent_obj;

     /* devices specific to 405 same as proposed Ppc405SoCState */
}

and likewise for PPC440SocState which could be done in a different series 
taking care of 440 machines later. Then we could more cleanly model the 
sharing of code between 4xx SoCs (this series only considered 405 but this 
is enangled with 440 so we should take into account that too), This also 
allows to get the cpu without a link with something like:

PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu

This is pretty clear if you look at the object class definitions and 
avoids needing to link things together by hand.

If this is not clear yet or Cédric does not want to do it now I may try it 
once he publishes the latest version of this series or as a follow up once 
it's merged but if I could get across what I mean and not too much changes 
maybe it could be considered so we don't have too many iterations on this.

I understand Cédric may not want to touch bamboo or sam460ex and mostly 
cares for 405 to add hotfoot but what I propose does not need going all 
the way with the 440 machines, only introduce the QOM classes now so that 
it could be used later bur not break the 440 machines now. We may even get 
away with just adding a PowerPCCPU *cpu; to PPC4xxMachineState for now 
which can be set in the machine init func that creates the cpu before 
other devices, then we may not need PPC4xxSocState abstract class for now 
but maybe it's clearer with the abstract SoC class that can be filled in 
later with common stuff shared by all 4xx machines.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 16:50                           ` BALATON Zoltan
@ 2022-08-05 16:55                             ` Peter Maydell
  2022-08-05 17:03                               ` BALATON Zoltan
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2022-08-05 16:55 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

On Fri, 5 Aug 2022 at 17:50, BALATON Zoltan <balaton@eik.bme.hu> wrote:
> This also
> allows to get the cpu without a link with something like:
>
> PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu

...and now you have device code that's making assumptions about
the machine and SoC it's in.

Just do this the same standard way we do it elsewhere, please.

thanks
-- PMM


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 16:55                             ` Peter Maydell
@ 2022-08-05 17:03                               ` BALATON Zoltan
  2022-08-05 19:15                                 ` BALATON Zoltan
  2022-08-06  9:38                                 ` BALATON Zoltan
  0 siblings, 2 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-05 17:03 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 992 bytes --]

On Fri, 5 Aug 2022, Peter Maydell wrote:
> On Fri, 5 Aug 2022 at 17:50, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>> This also
>> allows to get the cpu without a link with something like:
>>
>> PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu
>
> ...and now you have device code that's making assumptions about
> the machine and SoC it's in.

Since these devices are strictly part of this SoC making this asumption 
should be OK. Making assumption about the machine may be a valid argument 
although this series already makes that asumption for 405 machines by 
introducing the machine state class. We need a way to share these device 
models between 4xx mahines so I think some assumptions will proabbly be 
needed.

> Just do this the same standard way we do it elsewhere, please.

OK looks like I could not convince you so I let you and Cédric decide what 
you do and leave this alone. Thanks for sharing insights it was a useful 
discussion.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 17:03                               ` BALATON Zoltan
@ 2022-08-05 19:15                                 ` BALATON Zoltan
  2022-08-06  9:38                                 ` BALATON Zoltan
  1 sibling, 0 replies; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-05 19:15 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

On Fri, 5 Aug 2022, BALATON Zoltan wrote:
> On Fri, 5 Aug 2022, Peter Maydell wrote:
>> On Fri, 5 Aug 2022 at 17:50, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>> This also
>>> allows to get the cpu without a link with something like:
>>> 
>>> PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu
>> 
>> ...and now you have device code that's making assumptions about
>> the machine and SoC it's in.
>
> Since these devices are strictly part of this SoC making this asumption 
> should be OK. Making assumption about the machine may be a valid argument 
> although this series already makes that asumption for 405 machines by 
> introducing the machine state class. We need a way to share these device 
> models between 4xx mahines so I think some assumptions will proabbly be 
> needed.

By the way the assumption that we have a machine with a soc object is only 
there because there seems to be no way to get from an object to its parent 
which is strange. The soc would simply be OBJECT(dev)->parent as these 
devices have to be in the soc beacuse they are part of that model but 
those Object fields are marked private (some places so access it 
nevertheless).but there's no function to get them. MemoryRegion has its 
own version. Why do we have these objects in a tree if there's no way to 
navigate it?

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-05 17:03                               ` BALATON Zoltan
  2022-08-05 19:15                                 ` BALATON Zoltan
@ 2022-08-06  9:38                                 ` BALATON Zoltan
  2022-08-08  6:42                                   ` Cédric Le Goater
  1 sibling, 1 reply; 61+ messages in thread
From: BALATON Zoltan @ 2022-08-06  9:38 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Cédric Le Goater, Daniel Henrique Barboza,
	list@suse.de:PowerPC, QEMU Developers

On Fri, 5 Aug 2022, BALATON Zoltan wrote:
> On Fri, 5 Aug 2022, Peter Maydell wrote:
>> On Fri, 5 Aug 2022 at 17:50, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>> This also
>>> allows to get the cpu without a link with something like:
>>> 
>>> PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu
>> 
>> ...and now you have device code that's making assumptions about
>> the machine and SoC it's in.
>
> Since these devices are strictly part of this SoC making this asumption 
> should be OK. Making assumption about the machine may be a valid argument

I think this is my really last comment on this topic but I can't stop 
thinking about this. If we can't user parent or get the cpu any other way 
and we have to use a link property then we probably need a PPC4xxSocDevice 
abstract class that has the cpu link and all these devices derive from 
that. That way the boilerplate for the link property is confined to this 
SocDevice class and does not have to be repeated in every other SoC 
device. Unless QOM properties don't work that way and they would need to 
be aliased in which case it does not bring anything.

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC
  2022-08-06  9:38                                 ` BALATON Zoltan
@ 2022-08-08  6:42                                   ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2022-08-08  6:42 UTC (permalink / raw)
  To: BALATON Zoltan, Peter Maydell
  Cc: Daniel Henrique Barboza, list@suse.de:PowerPC, QEMU Developers

On 8/6/22 11:38, BALATON Zoltan wrote:
> On Fri, 5 Aug 2022, BALATON Zoltan wrote:
>> On Fri, 5 Aug 2022, Peter Maydell wrote:
>>> On Fri, 5 Aug 2022 at 17:50, BALATON Zoltan <balaton@eik.bme.hu> wrote:
>>>> This also
>>>> allows to get the cpu without a link with something like:
>>>>
>>>> PPC4XX_MACHINE(current_machine /* or qdev_get_machine() */)->soc.cpu
>>>
>>> ...and now you have device code that's making assumptions about
>>> the machine and SoC it's in.
>>
>> Since these devices are strictly part of this SoC making this asumption should be OK. Making assumption about the machine may be a valid argument
> 
> I think this is my really last comment on this topic but I can't stop thinking about this. If we can't user parent or get the cpu any other way and we have to use a link property then we probably need a PPC4xxSocDevice abstract class that has the cpu link and all these devices derive from that. 

When experimenting, I added a PPC4xx_DCR_DEVICE implementing what
you are proposing. I didn't keep it because the benefits are limited
and adding a DCR address space would be a better change. If you think
it would help QOMifying the other PPC4xx parts, I can include it in v3.

See below,

> That way the boilerplate for the link property is confined to this SocDevice class and does not have to be repeated in every other SoC device. Unless QOM properties don't work that way and they would need to be aliased in which case it does not bring anything.

You still have to set the object link before "realizing" each object.

Thanks,

C.


#define TYPE_PPC4xx_DCR_DEVICE "ppc4xx-dcr"
OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxDcrDeviceState, PPC4xx_DCR_DEVICE);
struct Ppc4xxDcrDeviceState {
     SysBusDevice parent_obj;

     PowerPCCPU *cpu;
};

void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn,
                          dcr_read_cb dcr_read, dcr_write_cb dcr_write)
{
     CPUPPCState *env;

     assert(dev->cpu);

     env = &dev->cpu->env;

     ppc_dcr_register(env, dcrn, dev, dcr_read, dcr_write);
}

static Property ppc4xx_dcr_properties[] = {
     DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU,
                      PowerPCCPU *),
     DEFINE_PROP_END_OF_LIST(),
};

static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
{
     DeviceClass *dc = DEVICE_CLASS(oc);

     dc->user_creatable = false;
     device_class_set_props(dc, ppc4xx_dcr_properties);
}

static const TypeInfo ppc4xx_types[] = {
    {
         .name           = TYPE_PPC4xx_DCR_DEVICE,
         .parent         = TYPE_SYS_BUS_DEVICE,
         .instance_size  = sizeof(Ppc4xxDcrDeviceState),
         .class_init     = ppc4xx_dcr_class_init,
         .abstract       = true,
    }
};


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

end of thread, other threads:[~2022-08-08  6:44 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-03 13:28 [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 01/20] ppc/ppc405: Remove taihu machine Cédric Le Goater
2022-08-03 17:16   ` Daniel Henrique Barboza
2022-08-03 13:28 ` [PATCH v2 02/20] ppc/ppc405: Introduce a PPC405 generic machine Cédric Le Goater
2022-08-03 17:03   ` BALATON Zoltan
2022-08-03 17:35     ` Daniel Henrique Barboza
2022-08-03 22:07   ` BALATON Zoltan
2022-08-04  5:40     ` Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 03/20] ppc/ppc405: Move devices under the ref405ep machine Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 04/20] ppc/ppc405: Introduce a PPC405 SoC Cédric Le Goater
2022-08-03 22:13   ` BALATON Zoltan
2022-08-03 13:28 ` [PATCH v2 05/20] ppc/ppc405: Start QOMification of the SoC Cédric Le Goater
2022-08-03 22:23   ` BALATON Zoltan
2022-08-04  6:00     ` Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 06/20] ppc/ppc405: QOM'ify CPU Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 07/20] ppc/ppc405: QOM'ify CPC Cédric Le Goater
2022-08-03 17:16   ` BALATON Zoltan
2022-08-04  5:09     ` Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 08/20] ppc/ppc405: QOM'ify GPT Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 09/20] ppc/ppc405: QOM'ify OCM Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 10/20] ppc/ppc405: QOM'ify GPIO Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 11/20] ppc/ppc405: QOM'ify DMA Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 12/20] ppc/ppc405: QOM'ify EBC Cédric Le Goater
2022-08-03 23:04   ` BALATON Zoltan
2022-08-04  7:55     ` Mark Cave-Ayland
2022-08-04 10:58       ` BALATON Zoltan
2022-08-03 23:36   ` Daniel Henrique Barboza
2022-08-04  5:14     ` Cédric Le Goater
2022-08-04 12:09       ` BALATON Zoltan
2022-08-04 16:21         ` Cédric Le Goater
     [not found]         ` <3b1bc6c5-a363-0a42-f0dc-eafc14376fe2@kaod.org>
     [not found]           ` <1e6be2f3-4c7a-2432-5034-fa012c662df@eik.bme.hu>
2022-08-04 16:31             ` Cédric Le Goater
2022-08-04 18:00               ` BALATON Zoltan
2022-08-04 18:18                 ` Peter Maydell
2022-08-04 19:26                   ` BALATON Zoltan
2022-08-05  7:07                     ` Cédric Le Goater
2022-08-05 12:55                       ` BALATON Zoltan
2022-08-05 13:16                         ` Peter Maydell
2022-08-05 16:50                           ` BALATON Zoltan
2022-08-05 16:55                             ` Peter Maydell
2022-08-05 17:03                               ` BALATON Zoltan
2022-08-05 19:15                                 ` BALATON Zoltan
2022-08-06  9:38                                 ` BALATON Zoltan
2022-08-08  6:42                                   ` Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 13/20] ppc/ppc405: QOM'ify OPBA Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 14/20] ppc/ppc405: QOM'ify POB Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 15/20] ppc/ppc405: QOM'ify PLB Cédric Le Goater
2022-08-03 23:38   ` Daniel Henrique Barboza
2022-08-03 13:28 ` [PATCH v2 16/20] ppc/ppc405: QOM'ify MAL Cédric Le Goater
2022-08-03 23:45   ` Daniel Henrique Barboza
2022-08-03 13:28 ` [PATCH v2 17/20] ppc/ppc405: QOM'ify FPGA Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 18/20] ppc/ppc405: QOM'ify UIC Cédric Le Goater
2022-08-03 23:26   ` BALATON Zoltan
2022-08-03 13:28 ` [PATCH v2 19/20] ppc/ppc405: QOM'ify I2C Cédric Le Goater
2022-08-03 23:31   ` BALATON Zoltan
2022-08-04  5:42     ` Cédric Le Goater
2022-08-04 11:21       ` BALATON Zoltan
2022-08-04 14:14         ` Cédric Le Goater
2022-08-03 13:28 ` [PATCH v2 20/20] ppc/ppc4xx: Fix sdram trace events Cédric Le Goater
2022-08-04  6:07 ` [PATCH v2 00/20] ppc: QOM'ify 405 board Cédric Le Goater
2022-08-04 10:07   ` Daniel Henrique Barboza
2022-08-04 12:26     ` Cédric Le Goater

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.