From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44598) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fEh5f-0006jC-FD for qemu-devel@nongnu.org; Fri, 04 May 2018 16:14:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fEh5c-0006xR-6a for qemu-devel@nongnu.org; Fri, 04 May 2018 16:14:03 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:29065) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1fEh5b-0006wD-PC for qemu-devel@nongnu.org; Fri, 04 May 2018 16:14:00 -0400 From: Alistair Francis Date: Fri, 4 May 2018 13:13:47 -0700 Message-Id: <18aa905475ab9a2dd5d8b7cd04cd037bb01a4e64.1525464177.git.alistair.francis@wdc.com> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PATCH v1 4/4] hw/riscv/sifive_e: Create a E31 SoC object List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: alistair.francis@wdc.com, alistair23@gmail.com, palmer@sifive.com, mjc@sifive.com Signed-off-by: Alistair Francis --- hw/riscv/sifive_e.c | 97 +++++++++++++++++++++++++++---------- include/hw/riscv/sifive_e.h | 16 +++++- 2 files changed, 86 insertions(+), 27 deletions(-) diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index e4ecb7aa4b..0ab5e3ca45 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -102,18 +102,12 @@ static void riscv_sifive_e_init(MachineState *machine) SiFiveEState *s = g_new0(SiFiveEState, 1); MemoryRegion *sys_mem = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); - MemoryRegion *mask_rom = g_new(MemoryRegion, 1); - MemoryRegion *xip_mem = g_new(MemoryRegion, 1); int i; - /* Initialize SOC */ - object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); + /* Initialize SoC */ + object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_E31_SOC); object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc), &error_abort); - object_property_set_str(OBJECT(&s->soc), SIFIVE_E_CPU, "cpu-type", - &error_abort); - object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts", - &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); @@ -123,11 +117,57 @@ static void riscv_sifive_e_init(MachineState *machine) memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_DTIM].base, main_mem); + /* Mask ROM reset vector */ + uint32_t reset_vec[2] = { + 0x204002b7, /* 0x1000: lui t0,0x20400 */ + 0x00028067, /* 0x1004: jr t0 */ + }; + + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SIFIVE_E_MROM].base, &address_space_memory); + + if (machine->kernel_filename) { + load_kernel(machine->kernel_filename); + } +} + +static void riscv_sifive_e31_init(Object *obj) +{ + const struct MemmapEntry *memmap = sifive_e_memmap; + + SiFiveE31State *s = RISCV_E31_SOC(obj); + MemoryRegion *sys_mem = get_system_memory(); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); + + object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY); + object_property_add_child(obj, "cpus", OBJECT(&s->cpus), + &error_abort); + object_property_set_str(OBJECT(&s->cpus), SIFIVE_E_CPU, "cpu-type", + &error_abort); + object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts", + &error_abort); + /* Mask ROM */ memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom", memmap[SIFIVE_E_MROM].size, &error_fatal); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_MROM].base, mask_rom); +} + +static void riscv_sifive_e31_realize(DeviceState *dev, Error **errp) +{ + const struct MemmapEntry *memmap = sifive_e_memmap; + + SiFiveE31State *s = RISCV_E31_SOC(dev); + MemoryRegion *sys_mem = get_system_memory(); + MemoryRegion *xip_mem = g_new(MemoryRegion, 1); + + object_property_set_bool(OBJECT(&s->cpus), true, "realized", + &error_abort); /* MMIO */ s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base, @@ -171,23 +211,6 @@ static void riscv_sifive_e_init(MachineState *machine) memmap[SIFIVE_E_XIP].size, &error_fatal); memory_region_set_readonly(xip_mem, true); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, xip_mem); - - /* Mask ROM reset vector */ - uint32_t reset_vec[2] = { - 0x204002b7, /* 0x1000: lui t0,0x20400 */ - 0x00028067, /* 0x1004: jr t0 */ - }; - - /* copy in the reset vector in little_endian byte order */ - for (i = 0; i < sizeof(reset_vec) >> 2; i++) { - reset_vec[i] = cpu_to_le32(reset_vec[i]); - } - rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), - memmap[SIFIVE_E_MROM].base, &address_space_memory); - - if (machine->kernel_filename) { - load_kernel(machine->kernel_filename); - } } static void riscv_sifive_e_machine_init(MachineClass *mc) @@ -198,3 +221,27 @@ static void riscv_sifive_e_machine_init(MachineClass *mc) } DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init) + +static void riscv_sifive_e31_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = riscv_sifive_e31_realize; + /* Reason: Uses serial_hds in realize function, thus can't be used twice */ + dc->user_creatable = false; +} + +static const TypeInfo riscv_sifive_e31_type_info = { + .name = TYPE_RISCV_E31_SOC, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SiFiveE31State), + .instance_init = riscv_sifive_e31_init, + .class_init = riscv_sifive_e31_class_init, +}; + +static void riscv_sifive_e31_register_types(void) +{ + type_register_static(&riscv_sifive_e31_type_info); +} + +type_init(riscv_sifive_e31_register_types) diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h index 12ad6d2ebb..5cb19cd564 100644 --- a/include/hw/riscv/sifive_e.h +++ b/include/hw/riscv/sifive_e.h @@ -19,13 +19,25 @@ #ifndef HW_SIFIVE_E_H #define HW_SIFIVE_E_H -typedef struct SiFiveEState { +#define TYPE_RISCV_E31_SOC "riscv.sifive.e31" +#define RISCV_E31_SOC(obj) \ + OBJECT_CHECK(SiFiveE31State, (obj), TYPE_RISCV_E31_SOC) + +typedef struct SiFiveE31State { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ - RISCVHartArrayState soc; + RISCVHartArrayState cpus; DeviceState *plic; +} SiFiveE31State; + +typedef struct SiFiveEState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + SiFiveE31State soc; } SiFiveEState; enum { -- 2.17.0