1ff8f06eeSShlomo Pongratz /* 2ff8f06eeSShlomo Pongratz * ARM GICv3 support - common bits of emulated and KVM kernel model 3ff8f06eeSShlomo Pongratz * 4ff8f06eeSShlomo Pongratz * Copyright (c) 2012 Linaro Limited 5ff8f06eeSShlomo Pongratz * Copyright (c) 2015 Huawei. 6ff8f06eeSShlomo Pongratz * Written by Peter Maydell 7ff8f06eeSShlomo Pongratz * Extended to 64 cores by Shlomo Pongratz 8ff8f06eeSShlomo Pongratz * 9ff8f06eeSShlomo Pongratz * This program is free software; you can redistribute it and/or modify 10ff8f06eeSShlomo Pongratz * it under the terms of the GNU General Public License as published by 11ff8f06eeSShlomo Pongratz * the Free Software Foundation, either version 2 of the License, or 12ff8f06eeSShlomo Pongratz * (at your option) any later version. 13ff8f06eeSShlomo Pongratz * 14ff8f06eeSShlomo Pongratz * This program is distributed in the hope that it will be useful, 15ff8f06eeSShlomo Pongratz * but WITHOUT ANY WARRANTY; without even the implied warranty of 16ff8f06eeSShlomo Pongratz * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17ff8f06eeSShlomo Pongratz * GNU General Public License for more details. 18ff8f06eeSShlomo Pongratz * 19ff8f06eeSShlomo Pongratz * You should have received a copy of the GNU General Public License along 20ff8f06eeSShlomo Pongratz * with this program; if not, see <http://www.gnu.org/licenses/>. 21ff8f06eeSShlomo Pongratz */ 22ff8f06eeSShlomo Pongratz 238ef94f0bSPeter Maydell #include "qemu/osdep.h" 24*da34e65cSMarkus Armbruster #include "qapi/error.h" 25ff8f06eeSShlomo Pongratz #include "hw/intc/arm_gicv3_common.h" 26ff8f06eeSShlomo Pongratz 27ff8f06eeSShlomo Pongratz static void gicv3_pre_save(void *opaque) 28ff8f06eeSShlomo Pongratz { 29ff8f06eeSShlomo Pongratz GICv3State *s = (GICv3State *)opaque; 30ff8f06eeSShlomo Pongratz ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); 31ff8f06eeSShlomo Pongratz 32ff8f06eeSShlomo Pongratz if (c->pre_save) { 33ff8f06eeSShlomo Pongratz c->pre_save(s); 34ff8f06eeSShlomo Pongratz } 35ff8f06eeSShlomo Pongratz } 36ff8f06eeSShlomo Pongratz 37ff8f06eeSShlomo Pongratz static int gicv3_post_load(void *opaque, int version_id) 38ff8f06eeSShlomo Pongratz { 39ff8f06eeSShlomo Pongratz GICv3State *s = (GICv3State *)opaque; 40ff8f06eeSShlomo Pongratz ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s); 41ff8f06eeSShlomo Pongratz 42ff8f06eeSShlomo Pongratz if (c->post_load) { 43ff8f06eeSShlomo Pongratz c->post_load(s); 44ff8f06eeSShlomo Pongratz } 45ff8f06eeSShlomo Pongratz return 0; 46ff8f06eeSShlomo Pongratz } 47ff8f06eeSShlomo Pongratz 48ff8f06eeSShlomo Pongratz static const VMStateDescription vmstate_gicv3 = { 49ff8f06eeSShlomo Pongratz .name = "arm_gicv3", 50ff8f06eeSShlomo Pongratz .unmigratable = 1, 51ff8f06eeSShlomo Pongratz .pre_save = gicv3_pre_save, 52ff8f06eeSShlomo Pongratz .post_load = gicv3_post_load, 53ff8f06eeSShlomo Pongratz }; 54ff8f06eeSShlomo Pongratz 55ff8f06eeSShlomo Pongratz void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, 56ff8f06eeSShlomo Pongratz const MemoryRegionOps *ops) 57ff8f06eeSShlomo Pongratz { 58ff8f06eeSShlomo Pongratz SysBusDevice *sbd = SYS_BUS_DEVICE(s); 59ff8f06eeSShlomo Pongratz int i; 60ff8f06eeSShlomo Pongratz 61ff8f06eeSShlomo Pongratz /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. 62ff8f06eeSShlomo Pongratz * GPIO array layout is thus: 63ff8f06eeSShlomo Pongratz * [0..N-1] spi 64ff8f06eeSShlomo Pongratz * [N..N+31] PPIs for CPU 0 65ff8f06eeSShlomo Pongratz * [N+32..N+63] PPIs for CPU 1 66ff8f06eeSShlomo Pongratz * ... 67ff8f06eeSShlomo Pongratz */ 68ff8f06eeSShlomo Pongratz i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu; 69ff8f06eeSShlomo Pongratz qdev_init_gpio_in(DEVICE(s), handler, i); 70ff8f06eeSShlomo Pongratz 71ff8f06eeSShlomo Pongratz s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq)); 72ff8f06eeSShlomo Pongratz s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq)); 73ff8f06eeSShlomo Pongratz 74ff8f06eeSShlomo Pongratz for (i = 0; i < s->num_cpu; i++) { 75ff8f06eeSShlomo Pongratz sysbus_init_irq(sbd, &s->parent_irq[i]); 76ff8f06eeSShlomo Pongratz } 77ff8f06eeSShlomo Pongratz for (i = 0; i < s->num_cpu; i++) { 78ff8f06eeSShlomo Pongratz sysbus_init_irq(sbd, &s->parent_fiq[i]); 79ff8f06eeSShlomo Pongratz } 80ff8f06eeSShlomo Pongratz 81ff8f06eeSShlomo Pongratz memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s, 82ff8f06eeSShlomo Pongratz "gicv3_dist", 0x10000); 83ff8f06eeSShlomo Pongratz memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s, 84ff8f06eeSShlomo Pongratz "gicv3_redist", 0x20000 * s->num_cpu); 85ff8f06eeSShlomo Pongratz 86ff8f06eeSShlomo Pongratz sysbus_init_mmio(sbd, &s->iomem_dist); 87ff8f06eeSShlomo Pongratz sysbus_init_mmio(sbd, &s->iomem_redist); 88ff8f06eeSShlomo Pongratz } 89ff8f06eeSShlomo Pongratz 90ff8f06eeSShlomo Pongratz static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) 91ff8f06eeSShlomo Pongratz { 92ff8f06eeSShlomo Pongratz GICv3State *s = ARM_GICV3_COMMON(dev); 93ff8f06eeSShlomo Pongratz 94ff8f06eeSShlomo Pongratz /* revision property is actually reserved and currently used only in order 95ff8f06eeSShlomo Pongratz * to keep the interface compatible with GICv2 code, avoiding extra 96ff8f06eeSShlomo Pongratz * conditions. However, in future it could be used, for example, if we 97ff8f06eeSShlomo Pongratz * implement GICv4. 98ff8f06eeSShlomo Pongratz */ 99ff8f06eeSShlomo Pongratz if (s->revision != 3) { 100ff8f06eeSShlomo Pongratz error_setg(errp, "unsupported GIC revision %d", s->revision); 101ff8f06eeSShlomo Pongratz return; 102ff8f06eeSShlomo Pongratz } 103ff8f06eeSShlomo Pongratz } 104ff8f06eeSShlomo Pongratz 105ff8f06eeSShlomo Pongratz static void arm_gicv3_common_reset(DeviceState *dev) 106ff8f06eeSShlomo Pongratz { 107ff8f06eeSShlomo Pongratz /* TODO */ 108ff8f06eeSShlomo Pongratz } 109ff8f06eeSShlomo Pongratz 110ff8f06eeSShlomo Pongratz static Property arm_gicv3_common_properties[] = { 111ff8f06eeSShlomo Pongratz DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1), 112ff8f06eeSShlomo Pongratz DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32), 113ff8f06eeSShlomo Pongratz DEFINE_PROP_UINT32("revision", GICv3State, revision, 3), 114ff8f06eeSShlomo Pongratz DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0), 115ff8f06eeSShlomo Pongratz DEFINE_PROP_END_OF_LIST(), 116ff8f06eeSShlomo Pongratz }; 117ff8f06eeSShlomo Pongratz 118ff8f06eeSShlomo Pongratz static void arm_gicv3_common_class_init(ObjectClass *klass, void *data) 119ff8f06eeSShlomo Pongratz { 120ff8f06eeSShlomo Pongratz DeviceClass *dc = DEVICE_CLASS(klass); 121ff8f06eeSShlomo Pongratz 122ff8f06eeSShlomo Pongratz dc->reset = arm_gicv3_common_reset; 123ff8f06eeSShlomo Pongratz dc->realize = arm_gicv3_common_realize; 124ff8f06eeSShlomo Pongratz dc->props = arm_gicv3_common_properties; 125ff8f06eeSShlomo Pongratz dc->vmsd = &vmstate_gicv3; 126ff8f06eeSShlomo Pongratz } 127ff8f06eeSShlomo Pongratz 128ff8f06eeSShlomo Pongratz static const TypeInfo arm_gicv3_common_type = { 129ff8f06eeSShlomo Pongratz .name = TYPE_ARM_GICV3_COMMON, 130ff8f06eeSShlomo Pongratz .parent = TYPE_SYS_BUS_DEVICE, 131ff8f06eeSShlomo Pongratz .instance_size = sizeof(GICv3State), 132ff8f06eeSShlomo Pongratz .class_size = sizeof(ARMGICv3CommonClass), 133ff8f06eeSShlomo Pongratz .class_init = arm_gicv3_common_class_init, 134ff8f06eeSShlomo Pongratz .abstract = true, 135ff8f06eeSShlomo Pongratz }; 136ff8f06eeSShlomo Pongratz 137ff8f06eeSShlomo Pongratz static void register_types(void) 138ff8f06eeSShlomo Pongratz { 139ff8f06eeSShlomo Pongratz type_register_static(&arm_gicv3_common_type); 140ff8f06eeSShlomo Pongratz } 141ff8f06eeSShlomo Pongratz 142ff8f06eeSShlomo Pongratz type_init(register_types) 143