Add part of GCR Block which Linux Kernel utilises and it is enough to bring the GIC up.
Signed-off-by: Yongbok Kim <yongbok....@imgtec.com> --- hw/mips/Makefile.objs | 2 +- hw/mips/mips_gcr.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/mips/mips_gcr.h | 57 +++++++++++++++++++++++ 3 files changed, 178 insertions(+), 1 deletions(-) create mode 100644 hw/mips/mips_gcr.c create mode 100644 hw/mips/mips_gcr.h diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs index 9633f3a..d247d95 100644 --- a/hw/mips/Makefile.objs +++ b/hw/mips/Makefile.objs @@ -1,5 +1,5 @@ obj-y += mips_r4k.o mips_malta.o mips_mipssim.o -obj-y += addr.o cputimer.o mips_int.o +obj-y += addr.o cputimer.o mips_int.o mips_gcr.o obj-$(CONFIG_JAZZ) += mips_jazz.o obj-$(CONFIG_FULONG) += mips_fulong2e.o obj-y += gt64xxx_pci.o diff --git a/hw/mips/mips_gcr.c b/hw/mips/mips_gcr.c new file mode 100644 index 0000000..088ddef --- /dev/null +++ b/hw/mips/mips_gcr.c @@ -0,0 +1,120 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Authors: Sanjay Lal <sanj...@kymasys.com> + * + * Copyright (C) 2015 Imagination Technologies + */ + +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "sysemu/sysemu.h" +#include "hw/mips/mips_gcr.h" + +/* Read GCR registers */ +static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) +{ + MIPSGCRState *gcr = (MIPSGCRState *) opaque; + + switch (addr) { + /* Global Control Block Register */ + case GCR_CONFIG_OFS: + /* Set PCORES to 0 */ + return 0; + case GCR_BASE_OFS: + return GCR_BASE_ADDR; + case GCR_REV_OFS: + return gcr->gcr_rev; + case GCR_GIC_BASE_OFS: + return gcr->gcr_gic_base; + case GCR_GIC_STATUS_OFS: + return GCR_GIC_STATUS_GICEX_MSK; + case GCR_CPC_STATUS_OFS: + return 0; + case GCR_L2_CONFIG_OFS: + /* L2 BYPASS */ + return GCR_L2_CONFIG_BYPASS_MSK; + + /* Core-Local and Core-Other Control Blocks */ + case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS: + case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: + /* Set PVP to # cores - 1 */ + return smp_cpus - 1; + case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: + return 0; + + default: + qemu_log_mask(LOG_UNIMP, + "Warning *** unimplemented GCR read at offset 0x%" PRIx64 "\n", + addr); + return 0; + } + return 0ULL; +} + +/* Write GCR registers */ +static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) +{ + /* + * MIPSGCRState *gcr = (MIPSGCRState *) opaque; + * */ + + switch (addr) { + case GCR_GIC_BASE_OFS: + break; + default: + qemu_log_mask(LOG_UNIMP, + "Warning *** unimplemented GCR write at offset 0x%" PRIx64 "\n", + addr); + break; + } +} + +static const MemoryRegionOps gcr_ops = { + .read = gcr_read, + .write = gcr_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .max_access_size = 8, + }, +}; + +static void mips_gcr_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + MIPSGCRState *s = MIPS_GCR(obj); + + memory_region_init_io(&s->gcr_mem, OBJECT(s), &gcr_ops, s, + "mips-gcr", GCR_ADDRSPACE_SZ); + sysbus_init_mmio(sbd, &s->gcr_mem); +} + +static Property mips_gcr_properties[] = { + DEFINE_PROP_INT32("num-cpu", MIPSGCRState, num_cpu, 1), + DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800), + DEFINE_PROP_END_OF_LIST(), +}; + +static void mips_gcr_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + dc->props = mips_gcr_properties; +} + +static const TypeInfo mips_gcr_info = { + .name = TYPE_MIPS_GCR, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MIPSGCRState), + .instance_init = mips_gcr_init, + .class_init = mips_gcr_class_init, +}; + +static void mips_gcr_register_types(void) +{ + type_register_static(&mips_gcr_info); +} + +type_init(mips_gcr_register_types) diff --git a/hw/mips/mips_gcr.h b/hw/mips/mips_gcr.h new file mode 100644 index 0000000..2a9e1c0 --- /dev/null +++ b/hw/mips/mips_gcr.h @@ -0,0 +1,57 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2015 Imagination Technologies + * + */ + +#ifndef _MIPS_GCR_H +#define _MIPS_GCR_H + +#define TYPE_MIPS_GCR "mips-gcr" +#define MIPS_GCR(obj) OBJECT_CHECK(MIPSGCRState, (obj), TYPE_MIPS_GCR) + +#define GCR_BASE_ADDR 0x1fbf8000ULL +#define GCR_ADDRSPACE_SZ 0x8000 + +/* Offsets to register blocks */ +#define MIPS_GCB_OFS 0x0000 /* Global Control Block */ +#define MIPS_CLCB_OFS 0x2000 /* Core Local Control Block */ +#define MIPS_COCB_OFS 0x4000 /* Core Other Control Block */ +#define MIPS_GDB_OFS 0x6000 /* Global Debug Block */ + +/* Global Control Block Register Map */ +#define GCR_CONFIG_OFS 0x0000 +#define GCR_BASE_OFS 0x0008 +#define GCR_REV_OFS 0x0030 +#define GCR_GIC_BASE_OFS 0x0080 +#define GCR_GIC_STATUS_OFS 0x00D0 +#define GCR_CPC_STATUS_OFS 0x00F0 +#define GCR_L2_CONFIG_OFS 0x0130 + +/* Core Local and Core Other Block Register Map */ +#define GCR_CL_CONFIG_OFS 0x0010 +#define GCR_CL_OTHER_OFS 0x0018 + +/* GCR_GIC_STATUS register fields */ +#define GCR_GIC_STATUS_GICEX_SHF 0 +#define GCR_GIC_STATUS_GICEX_MSK ((0x1ULL) << GCR_GIC_STATUS_GICEX_SHF) + +/* GCR_L2_CONFIG register fields */ +#define GCR_L2_CONFIG_BYPASS_SHF 20 +#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF) + + +typedef struct MIPSGCRState MIPSGCRState; +struct MIPSGCRState { + SysBusDevice parent_obj; + + target_ulong gcr_gic_base; + int32_t gcr_rev; + int32_t num_cpu; + MemoryRegion gcr_mem; +} ; + +#endif /* _MIPS_GCR_H */ -- 1.7.1