For now derive directly from Object. Move CPU-independent initialization to an initfn. Add a "cpu" link<superh-cpu> property and move CPU-dependent init code to sh7750_realize().
Update SHIX and R2D boards accordingly. Add the CPU as /cpu so that it can be set as link target, and add the SoC as /sh7750 to inspect it. Signed-off-by: Andreas Färber <afaer...@suse.de> --- hw/r2d.c | 9 ++++++++- hw/sh.h | 6 ++++-- hw/sh7750.c | 43 +++++++++++++++++++++++++++++++++++-------- hw/shix.c | 8 +++++++- 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/hw/r2d.c b/hw/r2d.c index c55de01..509bc69 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -224,6 +224,7 @@ static void r2d_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { + SuperHCPU *cpu; CPUSH4State *env; ResetData *reset_info; struct SH7750State *s; @@ -243,6 +244,9 @@ static void r2d_init(ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + cpu = sh_env_get_cpu(env); + object_property_add_child(object_get_root(), "cpu", OBJECT(cpu), NULL); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; reset_info->vector = env->pc; @@ -253,7 +257,10 @@ static void r2d_init(ram_addr_t ram_size, vmstate_register_ram_global(sdram); memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram); /* Register peripherals */ - s = sh7750_init(env, address_space_mem); + s = SH7750(object_new(TYPE_SH7750)); + object_property_add_child(object_get_root(), "sh7750", OBJECT(s), NULL); + object_property_set_link(OBJECT(s), OBJECT(cpu), "cpu", NULL); + sh7750_realize(s); irq = r2d_fpga_init(address_space_mem, 0x04000000, sh7750_irl(s)); dev = qdev_create(NULL, "sh_pci"); diff --git a/hw/sh.h b/hw/sh.h index 40df18c..b39881e 100644 --- a/hw/sh.h +++ b/hw/sh.h @@ -8,10 +8,12 @@ #define P4ADDR(x) ((x) | 0xe0000000) /* sh7750.c */ -struct SH7750State; +#define TYPE_SH7750 "sh7750-soc" +#define SH7750(obj) OBJECT_CHECK(SH7750State, (obj), TYPE_SH7750) +typedef struct SH7750State SH7750State; struct MemoryRegion; -struct SH7750State *sh7750_init(CPUSH4State * cpu, struct MemoryRegion *sysmem); +void sh7750_realize(SH7750State *s); typedef struct { /* The callback will be triggered if any of the designated lines change */ diff --git a/hw/sh7750.c b/hw/sh7750.c index c3cea9f..80c63fa 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -35,6 +35,10 @@ #define NB_DEVICES 4 typedef struct SH7750State { + /*< private >*/ + Object parent_obj; + /*< public >*/ + MemoryRegion iomem; MemoryRegion iomem_1f0; MemoryRegion iomem_ff0; @@ -720,13 +724,16 @@ static const MemoryRegionOps sh7750_mmct_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem) +static void sh7750_initfn(Object *obj) { - SH7750State *s; + SH7750State *s = SH7750(obj); + MemoryRegion *sysmem = get_system_memory(); + + object_property_add_link(obj, "cpu", TYPE_SUPERH_CPU, + (Object **)&s->cpu, NULL); + + s->periph_freq = 60000000; /* 60MHz */ - s = g_malloc0(sizeof(SH7750State)); - s->cpu = sh_env_get_cpu(cpu); - s->periph_freq = 60000000; /* 60MHz */ memory_region_init_io(&s->iomem, &sh7750_mem_ops, s, "memory", 0x1fc01000); @@ -766,8 +773,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem) _INTC_ARRAY(vectors), _INTC_ARRAY(groups)); - cpu->intc_handle = &s->intc; - sh_serial_init(sysmem, 0x1fe00000, 0, s->periph_freq, serial_hds[0], s->intc.irqs[SCI1_ERI], @@ -791,6 +796,14 @@ SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem) s->intc.irqs[TMU1], s->intc.irqs[TMU2_TUNI], s->intc.irqs[TMU2_TICPI]); +} + +void sh7750_realize(SH7750State *s) +{ + MemoryRegion *sysmem = get_system_memory(); + CPUSH4State *cpu = &s->cpu->env; + + cpu->intc_handle = &s->intc; if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) { sh_intc_register_sources(&s->intc, @@ -829,7 +842,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem) sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_irl), _INTC_ARRAY(groups_irl)); - return s; } qemu_irq sh7750_irl(SH7750State *s) @@ -838,3 +850,18 @@ qemu_irq sh7750_irl(SH7750State *s) return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL), 1)[0]; } + +static const TypeInfo sh7750_info = { + .name = TYPE_SH7750, + .parent = TYPE_OBJECT, + .instance_size = sizeof(SH7750State), + .instance_init = sh7750_initfn, + .class_size = sizeof(ObjectClass), +}; + +static void sh7750_register_types(void) +{ + type_register_static(&sh7750_info); +} + +type_init(sh7750_register_types) diff --git a/hw/shix.c b/hw/shix.c index dd9ce17..66c749a 100644 --- a/hw/shix.c +++ b/hw/shix.c @@ -43,6 +43,7 @@ static void shix_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { int ret; + SuperHCPU *cpu; CPUSH4State *env; struct SH7750State *s; MemoryRegion *sysmem = get_system_memory(); @@ -54,6 +55,8 @@ static void shix_init(ram_addr_t ram_size, printf("Initializing CPU\n"); env = cpu_init(cpu_model); + cpu = sh_env_get_cpu(env); + object_property_add_child(object_get_root(), "cpu", OBJECT(cpu), NULL); /* Allocate memory space */ printf("Allocating ROM\n"); @@ -83,7 +86,10 @@ static void shix_init(ram_addr_t ram_size, } /* Register peripherals */ - s = sh7750_init(env, sysmem); + s = SH7750(object_new(TYPE_SH7750)); + object_property_add_child(object_get_root(), "sh7750", OBJECT(s), NULL); + object_property_set_link(OBJECT(s), OBJECT(cpu), "cpu", NULL); + sh7750_realize(s); /* XXXXX Check success */ tc58128_init(s, "shix_linux_nand.bin", NULL); fprintf(stderr, "initialization terminated\n"); -- 1.7.7