Statistics
| Branch: | Revision:

root / hw / arm_gic_common.c @ 37952117

History | View | Annotate | Download (5.8 kB)

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

    
23
static void gic_save(QEMUFile *f, void *opaque)
24
{
25
    gic_state *s = (gic_state *)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

    
57
static int gic_load(QEMUFile *f, void *opaque, int version_id)
58
{
59
    gic_state *s = (gic_state *)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

    
97
static int arm_gic_common_init(SysBusDevice *dev)
98
{
99
    gic_state *s = FROM_SYSBUS(gic_state, 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

    
124
static void arm_gic_common_reset(DeviceState *dev)
125
{
126
    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(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
        s->priority_mask[i] = 0xf0;
131
        s->current_pending[i] = 1023;
132
        s->running_irq[i] = 1023;
133
        s->running_priority[i] = 0x100;
134
        s->cpu_enabled[i] = 0;
135
    }
136
    for (i = 0; i < 16; i++) {
137
        GIC_SET_ENABLED(i, ALL_CPU_MASK);
138
        GIC_SET_TRIGGER(i);
139
    }
140
    if (s->num_cpu == 1) {
141
        /* For uniprocessor GICs all interrupts always target the sole CPU */
142
        for (i = 0; i < GIC_MAXIRQ; i++) {
143
            s->irq_target[i] = 1;
144
        }
145
    }
146
    s->enabled = 0;
147
}
148

    
149
static Property arm_gic_common_properties[] = {
150
    DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
151
    DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
152
    /* Revision can be 1 or 2 for GIC architecture specification
153
     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
154
     * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
155
     */
156
    DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
157
    DEFINE_PROP_END_OF_LIST(),
158
};
159

    
160
static void arm_gic_common_class_init(ObjectClass *klass, void *data)
161
{
162
    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
163
    DeviceClass *dc = DEVICE_CLASS(klass);
164
    dc->reset = arm_gic_common_reset;
165
    dc->props = arm_gic_common_properties;
166
    dc->no_user = 1;
167
    sc->init = arm_gic_common_init;
168
}
169

    
170
static TypeInfo arm_gic_common_type = {
171
    .name = TYPE_ARM_GIC_COMMON,
172
    .parent = TYPE_SYS_BUS_DEVICE,
173
    .instance_size = sizeof(gic_state),
174
    .class_size = sizeof(ARMGICCommonClass),
175
    .class_init = arm_gic_common_class_init,
176
    .abstract = true,
177
};
178

    
179
static void register_types(void)
180
{
181
    type_register_static(&arm_gic_common_type);
182
}
183

    
184
type_init(register_types)