1*8e7e8a5bSLeon Alrae /* 2*8e7e8a5bSLeon Alrae * Coherent Processing System emulation. 3*8e7e8a5bSLeon Alrae * 4*8e7e8a5bSLeon Alrae * Copyright (c) 2016 Imagination Technologies 5*8e7e8a5bSLeon Alrae * 6*8e7e8a5bSLeon Alrae * This library is free software; you can redistribute it and/or 7*8e7e8a5bSLeon Alrae * modify it under the terms of the GNU Lesser General Public 8*8e7e8a5bSLeon Alrae * License as published by the Free Software Foundation; either 9*8e7e8a5bSLeon Alrae * version 2 of the License, or (at your option) any later version. 10*8e7e8a5bSLeon Alrae * 11*8e7e8a5bSLeon Alrae * This library is distributed in the hope that it will be useful, 12*8e7e8a5bSLeon Alrae * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*8e7e8a5bSLeon Alrae * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*8e7e8a5bSLeon Alrae * Lesser General Public License for more details. 15*8e7e8a5bSLeon Alrae * 16*8e7e8a5bSLeon Alrae * You should have received a copy of the GNU Lesser General Public 17*8e7e8a5bSLeon Alrae * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18*8e7e8a5bSLeon Alrae */ 19*8e7e8a5bSLeon Alrae 20*8e7e8a5bSLeon Alrae #include "qemu/osdep.h" 21*8e7e8a5bSLeon Alrae #include "qapi/error.h" 22*8e7e8a5bSLeon Alrae #include "hw/mips/cps.h" 23*8e7e8a5bSLeon Alrae #include "hw/mips/mips.h" 24*8e7e8a5bSLeon Alrae #include "hw/mips/cpudevs.h" 25*8e7e8a5bSLeon Alrae 26*8e7e8a5bSLeon Alrae qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number) 27*8e7e8a5bSLeon Alrae { 28*8e7e8a5bSLeon Alrae MIPSCPU *cpu = MIPS_CPU(first_cpu); 29*8e7e8a5bSLeon Alrae CPUMIPSState *env = &cpu->env; 30*8e7e8a5bSLeon Alrae 31*8e7e8a5bSLeon Alrae assert(pin_number < s->num_irq); 32*8e7e8a5bSLeon Alrae 33*8e7e8a5bSLeon Alrae /* TODO: return GIC pins once implemented */ 34*8e7e8a5bSLeon Alrae return env->irq[pin_number]; 35*8e7e8a5bSLeon Alrae } 36*8e7e8a5bSLeon Alrae 37*8e7e8a5bSLeon Alrae static void mips_cps_init(Object *obj) 38*8e7e8a5bSLeon Alrae { 39*8e7e8a5bSLeon Alrae SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 40*8e7e8a5bSLeon Alrae MIPSCPSState *s = MIPS_CPS(obj); 41*8e7e8a5bSLeon Alrae 42*8e7e8a5bSLeon Alrae /* Cover entire address space as there do not seem to be any 43*8e7e8a5bSLeon Alrae * constraints for the base address of CPC and GIC. */ 44*8e7e8a5bSLeon Alrae memory_region_init(&s->container, obj, "mips-cps-container", UINT64_MAX); 45*8e7e8a5bSLeon Alrae sysbus_init_mmio(sbd, &s->container); 46*8e7e8a5bSLeon Alrae } 47*8e7e8a5bSLeon Alrae 48*8e7e8a5bSLeon Alrae static void main_cpu_reset(void *opaque) 49*8e7e8a5bSLeon Alrae { 50*8e7e8a5bSLeon Alrae MIPSCPU *cpu = opaque; 51*8e7e8a5bSLeon Alrae CPUState *cs = CPU(cpu); 52*8e7e8a5bSLeon Alrae 53*8e7e8a5bSLeon Alrae cpu_reset(cs); 54*8e7e8a5bSLeon Alrae 55*8e7e8a5bSLeon Alrae /* All VPs are halted on reset. Leave powering up to CPC. */ 56*8e7e8a5bSLeon Alrae cs->halted = 1; 57*8e7e8a5bSLeon Alrae } 58*8e7e8a5bSLeon Alrae 59*8e7e8a5bSLeon Alrae static void mips_cps_realize(DeviceState *dev, Error **errp) 60*8e7e8a5bSLeon Alrae { 61*8e7e8a5bSLeon Alrae MIPSCPSState *s = MIPS_CPS(dev); 62*8e7e8a5bSLeon Alrae CPUMIPSState *env; 63*8e7e8a5bSLeon Alrae MIPSCPU *cpu; 64*8e7e8a5bSLeon Alrae int i; 65*8e7e8a5bSLeon Alrae 66*8e7e8a5bSLeon Alrae for (i = 0; i < s->num_vp; i++) { 67*8e7e8a5bSLeon Alrae cpu = cpu_mips_init(s->cpu_model); 68*8e7e8a5bSLeon Alrae if (cpu == NULL) { 69*8e7e8a5bSLeon Alrae error_setg(errp, "%s: CPU initialization failed\n", __func__); 70*8e7e8a5bSLeon Alrae return; 71*8e7e8a5bSLeon Alrae } 72*8e7e8a5bSLeon Alrae env = &cpu->env; 73*8e7e8a5bSLeon Alrae 74*8e7e8a5bSLeon Alrae /* Init internal devices */ 75*8e7e8a5bSLeon Alrae cpu_mips_irq_init_cpu(env); 76*8e7e8a5bSLeon Alrae cpu_mips_clock_init(env); 77*8e7e8a5bSLeon Alrae qemu_register_reset(main_cpu_reset, cpu); 78*8e7e8a5bSLeon Alrae } 79*8e7e8a5bSLeon Alrae } 80*8e7e8a5bSLeon Alrae 81*8e7e8a5bSLeon Alrae static Property mips_cps_properties[] = { 82*8e7e8a5bSLeon Alrae DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1), 83*8e7e8a5bSLeon Alrae DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 8), 84*8e7e8a5bSLeon Alrae DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model), 85*8e7e8a5bSLeon Alrae DEFINE_PROP_END_OF_LIST() 86*8e7e8a5bSLeon Alrae }; 87*8e7e8a5bSLeon Alrae 88*8e7e8a5bSLeon Alrae static void mips_cps_class_init(ObjectClass *klass, void *data) 89*8e7e8a5bSLeon Alrae { 90*8e7e8a5bSLeon Alrae DeviceClass *dc = DEVICE_CLASS(klass); 91*8e7e8a5bSLeon Alrae 92*8e7e8a5bSLeon Alrae dc->realize = mips_cps_realize; 93*8e7e8a5bSLeon Alrae dc->props = mips_cps_properties; 94*8e7e8a5bSLeon Alrae } 95*8e7e8a5bSLeon Alrae 96*8e7e8a5bSLeon Alrae static const TypeInfo mips_cps_info = { 97*8e7e8a5bSLeon Alrae .name = TYPE_MIPS_CPS, 98*8e7e8a5bSLeon Alrae .parent = TYPE_SYS_BUS_DEVICE, 99*8e7e8a5bSLeon Alrae .instance_size = sizeof(MIPSCPSState), 100*8e7e8a5bSLeon Alrae .instance_init = mips_cps_init, 101*8e7e8a5bSLeon Alrae .class_init = mips_cps_class_init, 102*8e7e8a5bSLeon Alrae }; 103*8e7e8a5bSLeon Alrae 104*8e7e8a5bSLeon Alrae static void mips_cps_register_types(void) 105*8e7e8a5bSLeon Alrae { 106*8e7e8a5bSLeon Alrae type_register_static(&mips_cps_info); 107*8e7e8a5bSLeon Alrae } 108*8e7e8a5bSLeon Alrae 109*8e7e8a5bSLeon Alrae type_init(mips_cps_register_types) 110