qemu/hw/arm_gic_common.c
<<
>>
Prefs
   1/*
   2 * ARM GIC support - common bits of emulated and KVM kernel model
   3 *
   4 * Copyright (c) 2012 Linaro Limited
   5 * Written by Peter Maydell
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation, either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "arm_gic_internal.h"
  22
  23static void gic_save(QEMUFile *f, void *opaque)
  24{
  25    GICState *s = (GICState *)opaque;
  26    int i;
  27    int j;
  28
  29    qemu_put_be32(f, s->enabled);
  30    for (i = 0; i < s->num_cpu; i++) {
  31        qemu_put_be32(f, s->cpu_enabled[i]);
  32        for (j = 0; j < GIC_INTERNAL; j++) {
  33            qemu_put_be32(f, s->priority1[j][i]);
  34        }
  35        for (j = 0; j < s->num_irq; j++) {
  36            qemu_put_be32(f, s->last_active[j][i]);
  37        }
  38        qemu_put_be32(f, s->priority_mask[i]);
  39        qemu_put_be32(f, s->running_irq[i]);
  40        qemu_put_be32(f, s->running_priority[i]);
  41        qemu_put_be32(f, s->current_pending[i]);
  42    }
  43    for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
  44        qemu_put_be32(f, s->priority2[i]);
  45    }
  46    for (i = 0; i < s->num_irq; i++) {
  47        qemu_put_be32(f, s->irq_target[i]);
  48        qemu_put_byte(f, s->irq_state[i].enabled);
  49        qemu_put_byte(f, s->irq_state[i].pending);
  50        qemu_put_byte(f, s->irq_state[i].active);
  51        qemu_put_byte(f, s->irq_state[i].level);
  52        qemu_put_byte(f, s->irq_state[i].model);
  53        qemu_put_byte(f, s->irq_state[i].trigger);
  54    }
  55}
  56
  57static int gic_load(QEMUFile *f, void *opaque, int version_id)
  58{
  59    GICState *s = (GICState *)opaque;
  60    int i;
  61    int j;
  62
  63    if (version_id != 3) {
  64        return -EINVAL;
  65    }
  66
  67    s->enabled = qemu_get_be32(f);
  68    for (i = 0; i < s->num_cpu; i++) {
  69        s->cpu_enabled[i] = qemu_get_be32(f);
  70        for (j = 0; j < GIC_INTERNAL; j++) {
  71            s->priority1[j][i] = qemu_get_be32(f);
  72        }
  73        for (j = 0; j < s->num_irq; j++) {
  74            s->last_active[j][i] = qemu_get_be32(f);
  75        }
  76        s->priority_mask[i] = qemu_get_be32(f);
  77        s->running_irq[i] = qemu_get_be32(f);
  78        s->running_priority[i] = qemu_get_be32(f);
  79        s->current_pending[i] = qemu_get_be32(f);
  80    }
  81    for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
  82        s->priority2[i] = qemu_get_be32(f);
  83    }
  84    for (i = 0; i < s->num_irq; i++) {
  85        s->irq_target[i] = qemu_get_be32(f);
  86        s->irq_state[i].enabled = qemu_get_byte(f);
  87        s->irq_state[i].pending = qemu_get_byte(f);
  88        s->irq_state[i].active = qemu_get_byte(f);
  89        s->irq_state[i].level = qemu_get_byte(f);
  90        s->irq_state[i].model = qemu_get_byte(f);
  91        s->irq_state[i].trigger = qemu_get_byte(f);
  92    }
  93
  94    return 0;
  95}
  96
  97static int arm_gic_common_init(SysBusDevice *dev)
  98{
  99    GICState *s = FROM_SYSBUS(GICState, dev);
 100    int num_irq = s->num_irq;
 101
 102    if (s->num_cpu > NCPU) {
 103        hw_error("requested %u CPUs exceeds GIC maximum %d\n",
 104                 s->num_cpu, NCPU);
 105    }
 106    s->num_irq += GIC_BASE_IRQ;
 107    if (s->num_irq > GIC_MAXIRQ) {
 108        hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
 109                 num_irq, GIC_MAXIRQ);
 110    }
 111    /* ITLinesNumber is represented as (N / 32) - 1 (see
 112     * gic_dist_readb) so this is an implementation imposed
 113     * restriction, not an architectural one:
 114     */
 115    if (s->num_irq < 32 || (s->num_irq % 32)) {
 116        hw_error("%d interrupt lines unsupported: not divisible by 32\n",
 117                 num_irq);
 118    }
 119
 120    register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
 121    return 0;
 122}
 123
 124static void arm_gic_common_reset(DeviceState *dev)
 125{
 126    GICState *s = FROM_SYSBUS(GICState, SYS_BUS_DEVICE(dev));
 127    int i;
 128    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
 129    for (i = 0 ; i < s->num_cpu; i++) {
 130        if (s->revision == REV_11MPCORE) {
 131            s->priority_mask[i] = 0xf0;
 132        } else {
 133            s->priority_mask[i] = 0;
 134        }
 135        s->current_pending[i] = 1023;
 136        s->running_irq[i] = 1023;
 137        s->running_priority[i] = 0x100;
 138        s->cpu_enabled[i] = 0;
 139    }
 140    for (i = 0; i < 16; i++) {
 141        GIC_SET_ENABLED(i, ALL_CPU_MASK);
 142        GIC_SET_TRIGGER(i);
 143    }
 144    if (s->num_cpu == 1) {
 145        /* For uniprocessor GICs all interrupts always target the sole CPU */
 146        for (i = 0; i < GIC_MAXIRQ; i++) {
 147            s->irq_target[i] = 1;
 148        }
 149    }
 150    s->enabled = 0;
 151}
 152
 153static Property arm_gic_common_properties[] = {
 154    DEFINE_PROP_UINT32("num-cpu", GICState, num_cpu, 1),
 155    DEFINE_PROP_UINT32("num-irq", GICState, num_irq, 32),
 156    /* Revision can be 1 or 2 for GIC architecture specification
 157     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
 158     * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
 159     */
 160    DEFINE_PROP_UINT32("revision", GICState, revision, 1),
 161    DEFINE_PROP_END_OF_LIST(),
 162};
 163
 164static void arm_gic_common_class_init(ObjectClass *klass, void *data)
 165{
 166    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
 167    DeviceClass *dc = DEVICE_CLASS(klass);
 168    dc->reset = arm_gic_common_reset;
 169    dc->props = arm_gic_common_properties;
 170    dc->no_user = 1;
 171    sc->init = arm_gic_common_init;
 172}
 173
 174static const TypeInfo arm_gic_common_type = {
 175    .name = TYPE_ARM_GIC_COMMON,
 176    .parent = TYPE_SYS_BUS_DEVICE,
 177    .instance_size = sizeof(GICState),
 178    .class_size = sizeof(ARMGICCommonClass),
 179    .class_init = arm_gic_common_class_init,
 180    .abstract = true,
 181};
 182
 183static void register_types(void)
 184{
 185    type_register_static(&arm_gic_common_type);
 186}
 187
 188type_init(register_types)
 189