Statistics
| Branch: | Revision:

root / hw / grlib_irqmp.c @ 9bfa659e

History | View | Annotate | Download (9.6 kB)

1 3f10bcbb Fabien Chouteau
/*
2 3f10bcbb Fabien Chouteau
 * QEMU GRLIB IRQMP Emulator
3 3f10bcbb Fabien Chouteau
 *
4 3f10bcbb Fabien Chouteau
 * (Multiprocessor and extended interrupt not supported)
5 3f10bcbb Fabien Chouteau
 *
6 3f10bcbb Fabien Chouteau
 * Copyright (c) 2010-2011 AdaCore
7 3f10bcbb Fabien Chouteau
 *
8 3f10bcbb Fabien Chouteau
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 3f10bcbb Fabien Chouteau
 * of this software and associated documentation files (the "Software"), to deal
10 3f10bcbb Fabien Chouteau
 * in the Software without restriction, including without limitation the rights
11 3f10bcbb Fabien Chouteau
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 3f10bcbb Fabien Chouteau
 * copies of the Software, and to permit persons to whom the Software is
13 3f10bcbb Fabien Chouteau
 * furnished to do so, subject to the following conditions:
14 3f10bcbb Fabien Chouteau
 *
15 3f10bcbb Fabien Chouteau
 * The above copyright notice and this permission notice shall be included in
16 3f10bcbb Fabien Chouteau
 * all copies or substantial portions of the Software.
17 3f10bcbb Fabien Chouteau
 *
18 3f10bcbb Fabien Chouteau
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 3f10bcbb Fabien Chouteau
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 3f10bcbb Fabien Chouteau
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 3f10bcbb Fabien Chouteau
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 3f10bcbb Fabien Chouteau
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 3f10bcbb Fabien Chouteau
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 3f10bcbb Fabien Chouteau
 * THE SOFTWARE.
25 3f10bcbb Fabien Chouteau
 */
26 3f10bcbb Fabien Chouteau
27 3f10bcbb Fabien Chouteau
#include "sysbus.h"
28 3f10bcbb Fabien Chouteau
#include "cpu.h"
29 3f10bcbb Fabien Chouteau
30 3f10bcbb Fabien Chouteau
#include "grlib.h"
31 3f10bcbb Fabien Chouteau
32 3f10bcbb Fabien Chouteau
#include "trace.h"
33 3f10bcbb Fabien Chouteau
34 3f10bcbb Fabien Chouteau
#define IRQMP_MAX_CPU 16
35 3f10bcbb Fabien Chouteau
#define IRQMP_REG_SIZE 256      /* Size of memory mapped registers */
36 3f10bcbb Fabien Chouteau
37 3f10bcbb Fabien Chouteau
/* Memory mapped register offsets */
38 3f10bcbb Fabien Chouteau
#define LEVEL_OFFSET     0x00
39 3f10bcbb Fabien Chouteau
#define PENDING_OFFSET   0x04
40 3f10bcbb Fabien Chouteau
#define FORCE0_OFFSET    0x08
41 3f10bcbb Fabien Chouteau
#define CLEAR_OFFSET     0x0C
42 3f10bcbb Fabien Chouteau
#define MP_STATUS_OFFSET 0x10
43 3f10bcbb Fabien Chouteau
#define BROADCAST_OFFSET 0x14
44 3f10bcbb Fabien Chouteau
#define MASK_OFFSET      0x40
45 3f10bcbb Fabien Chouteau
#define FORCE_OFFSET     0x80
46 3f10bcbb Fabien Chouteau
#define EXTENDED_OFFSET  0xC0
47 3f10bcbb Fabien Chouteau
48 3f10bcbb Fabien Chouteau
typedef struct IRQMPState IRQMPState;
49 3f10bcbb Fabien Chouteau
50 3f10bcbb Fabien Chouteau
typedef struct IRQMP {
51 3f10bcbb Fabien Chouteau
    SysBusDevice busdev;
52 847b52c1 Avi Kivity
    MemoryRegion iomem;
53 3f10bcbb Fabien Chouteau
54 3f10bcbb Fabien Chouteau
    void *set_pil_in;
55 3f10bcbb Fabien Chouteau
    void *set_pil_in_opaque;
56 3f10bcbb Fabien Chouteau
57 3f10bcbb Fabien Chouteau
    IRQMPState *state;
58 3f10bcbb Fabien Chouteau
} IRQMP;
59 3f10bcbb Fabien Chouteau
60 3f10bcbb Fabien Chouteau
struct IRQMPState {
61 3f10bcbb Fabien Chouteau
    uint32_t level;
62 3f10bcbb Fabien Chouteau
    uint32_t pending;
63 3f10bcbb Fabien Chouteau
    uint32_t clear;
64 3f10bcbb Fabien Chouteau
    uint32_t broadcast;
65 3f10bcbb Fabien Chouteau
66 3f10bcbb Fabien Chouteau
    uint32_t mask[IRQMP_MAX_CPU];
67 3f10bcbb Fabien Chouteau
    uint32_t force[IRQMP_MAX_CPU];
68 3f10bcbb Fabien Chouteau
    uint32_t extended[IRQMP_MAX_CPU];
69 3f10bcbb Fabien Chouteau
70 3f10bcbb Fabien Chouteau
    IRQMP    *parent;
71 3f10bcbb Fabien Chouteau
};
72 3f10bcbb Fabien Chouteau
73 3f10bcbb Fabien Chouteau
static void grlib_irqmp_check_irqs(IRQMPState *state)
74 3f10bcbb Fabien Chouteau
{
75 3f10bcbb Fabien Chouteau
    uint32_t      pend   = 0;
76 3f10bcbb Fabien Chouteau
    uint32_t      level0 = 0;
77 3f10bcbb Fabien Chouteau
    uint32_t      level1 = 0;
78 3f10bcbb Fabien Chouteau
    set_pil_in_fn set_pil_in;
79 3f10bcbb Fabien Chouteau
80 3f10bcbb Fabien Chouteau
    assert(state != NULL);
81 3f10bcbb Fabien Chouteau
    assert(state->parent != NULL);
82 3f10bcbb Fabien Chouteau
83 3f10bcbb Fabien Chouteau
    /* IRQ for CPU 0 (no SMP support) */
84 3f10bcbb Fabien Chouteau
    pend = (state->pending | state->force[0])
85 3f10bcbb Fabien Chouteau
        & state->mask[0];
86 3f10bcbb Fabien Chouteau
87 3f10bcbb Fabien Chouteau
    level0 = pend & ~state->level;
88 3f10bcbb Fabien Chouteau
    level1 = pend &  state->level;
89 3f10bcbb Fabien Chouteau
90 3f10bcbb Fabien Chouteau
    trace_grlib_irqmp_check_irqs(state->pending, state->force[0],
91 3f10bcbb Fabien Chouteau
                                 state->mask[0], level1, level0);
92 3f10bcbb Fabien Chouteau
93 3f10bcbb Fabien Chouteau
    set_pil_in = (set_pil_in_fn)state->parent->set_pil_in;
94 3f10bcbb Fabien Chouteau
95 3f10bcbb Fabien Chouteau
    /* Trigger level1 interrupt first and level0 if there is no level1 */
96 3f10bcbb Fabien Chouteau
    if (level1 != 0) {
97 3f10bcbb Fabien Chouteau
        set_pil_in(state->parent->set_pil_in_opaque, level1);
98 3f10bcbb Fabien Chouteau
    } else {
99 3f10bcbb Fabien Chouteau
        set_pil_in(state->parent->set_pil_in_opaque, level0);
100 3f10bcbb Fabien Chouteau
    }
101 3f10bcbb Fabien Chouteau
}
102 3f10bcbb Fabien Chouteau
103 3f10bcbb Fabien Chouteau
void grlib_irqmp_ack(DeviceState *dev, int intno)
104 3f10bcbb Fabien Chouteau
{
105 3f10bcbb Fabien Chouteau
    SysBusDevice *sdev;
106 3f10bcbb Fabien Chouteau
    IRQMP        *irqmp;
107 3f10bcbb Fabien Chouteau
    IRQMPState   *state;
108 3f10bcbb Fabien Chouteau
    uint32_t      mask;
109 3f10bcbb Fabien Chouteau
110 3f10bcbb Fabien Chouteau
    assert(dev != NULL);
111 3f10bcbb Fabien Chouteau
112 3f10bcbb Fabien Chouteau
    sdev = sysbus_from_qdev(dev);
113 3f10bcbb Fabien Chouteau
    assert(sdev != NULL);
114 3f10bcbb Fabien Chouteau
115 3f10bcbb Fabien Chouteau
    irqmp = FROM_SYSBUS(typeof(*irqmp), sdev);
116 3f10bcbb Fabien Chouteau
    assert(irqmp != NULL);
117 3f10bcbb Fabien Chouteau
118 3f10bcbb Fabien Chouteau
    state = irqmp->state;
119 3f10bcbb Fabien Chouteau
    assert(state != NULL);
120 3f10bcbb Fabien Chouteau
121 3f10bcbb Fabien Chouteau
    intno &= 15;
122 3f10bcbb Fabien Chouteau
    mask = 1 << intno;
123 3f10bcbb Fabien Chouteau
124 3f10bcbb Fabien Chouteau
    trace_grlib_irqmp_ack(intno);
125 3f10bcbb Fabien Chouteau
126 3f10bcbb Fabien Chouteau
    /* Clear registers */
127 3f10bcbb Fabien Chouteau
    state->pending  &= ~mask;
128 3f10bcbb Fabien Chouteau
    state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
129 3f10bcbb Fabien Chouteau
130 3f10bcbb Fabien Chouteau
    grlib_irqmp_check_irqs(state);
131 3f10bcbb Fabien Chouteau
}
132 3f10bcbb Fabien Chouteau
133 3f10bcbb Fabien Chouteau
void grlib_irqmp_set_irq(void *opaque, int irq, int level)
134 3f10bcbb Fabien Chouteau
{
135 3f10bcbb Fabien Chouteau
    IRQMP      *irqmp;
136 3f10bcbb Fabien Chouteau
    IRQMPState *s;
137 3f10bcbb Fabien Chouteau
    int         i = 0;
138 3f10bcbb Fabien Chouteau
139 3f10bcbb Fabien Chouteau
    assert(opaque != NULL);
140 3f10bcbb Fabien Chouteau
141 3f10bcbb Fabien Chouteau
    irqmp = FROM_SYSBUS(typeof(*irqmp), sysbus_from_qdev(opaque));
142 3f10bcbb Fabien Chouteau
    assert(irqmp != NULL);
143 3f10bcbb Fabien Chouteau
144 3f10bcbb Fabien Chouteau
    s = irqmp->state;
145 3f10bcbb Fabien Chouteau
    assert(s         != NULL);
146 3f10bcbb Fabien Chouteau
    assert(s->parent != NULL);
147 3f10bcbb Fabien Chouteau
148 3f10bcbb Fabien Chouteau
149 3f10bcbb Fabien Chouteau
    if (level) {
150 3f10bcbb Fabien Chouteau
        trace_grlib_irqmp_set_irq(irq);
151 3f10bcbb Fabien Chouteau
152 3f10bcbb Fabien Chouteau
        if (s->broadcast & 1 << irq) {
153 3f10bcbb Fabien Chouteau
            /* Broadcasted IRQ */
154 3f10bcbb Fabien Chouteau
            for (i = 0; i < IRQMP_MAX_CPU; i++) {
155 3f10bcbb Fabien Chouteau
                s->force[i] |= 1 << irq;
156 3f10bcbb Fabien Chouteau
            }
157 3f10bcbb Fabien Chouteau
        } else {
158 3f10bcbb Fabien Chouteau
            s->pending |= 1 << irq;
159 3f10bcbb Fabien Chouteau
        }
160 3f10bcbb Fabien Chouteau
        grlib_irqmp_check_irqs(s);
161 3f10bcbb Fabien Chouteau
162 3f10bcbb Fabien Chouteau
    }
163 3f10bcbb Fabien Chouteau
}
164 3f10bcbb Fabien Chouteau
165 847b52c1 Avi Kivity
static uint64_t grlib_irqmp_read(void *opaque, target_phys_addr_t addr,
166 847b52c1 Avi Kivity
                                 unsigned size)
167 3f10bcbb Fabien Chouteau
{
168 3f10bcbb Fabien Chouteau
    IRQMP      *irqmp = opaque;
169 3f10bcbb Fabien Chouteau
    IRQMPState *state;
170 3f10bcbb Fabien Chouteau
171 3f10bcbb Fabien Chouteau
    assert(irqmp != NULL);
172 3f10bcbb Fabien Chouteau
    state = irqmp->state;
173 3f10bcbb Fabien Chouteau
    assert(state != NULL);
174 3f10bcbb Fabien Chouteau
175 3f10bcbb Fabien Chouteau
    addr &= 0xff;
176 3f10bcbb Fabien Chouteau
177 3f10bcbb Fabien Chouteau
    /* global registers */
178 3f10bcbb Fabien Chouteau
    switch (addr) {
179 3f10bcbb Fabien Chouteau
    case LEVEL_OFFSET:
180 3f10bcbb Fabien Chouteau
        return state->level;
181 3f10bcbb Fabien Chouteau
182 3f10bcbb Fabien Chouteau
    case PENDING_OFFSET:
183 3f10bcbb Fabien Chouteau
        return state->pending;
184 3f10bcbb Fabien Chouteau
185 3f10bcbb Fabien Chouteau
    case FORCE0_OFFSET:
186 3f10bcbb Fabien Chouteau
        /* This register is an "alias" for the force register of CPU 0 */
187 3f10bcbb Fabien Chouteau
        return state->force[0];
188 3f10bcbb Fabien Chouteau
189 3f10bcbb Fabien Chouteau
    case CLEAR_OFFSET:
190 3f10bcbb Fabien Chouteau
    case MP_STATUS_OFFSET:
191 3f10bcbb Fabien Chouteau
        /* Always read as 0 */
192 3f10bcbb Fabien Chouteau
        return 0;
193 3f10bcbb Fabien Chouteau
194 3f10bcbb Fabien Chouteau
    case BROADCAST_OFFSET:
195 3f10bcbb Fabien Chouteau
        return state->broadcast;
196 3f10bcbb Fabien Chouteau
197 3f10bcbb Fabien Chouteau
    default:
198 3f10bcbb Fabien Chouteau
        break;
199 3f10bcbb Fabien Chouteau
    }
200 3f10bcbb Fabien Chouteau
201 3f10bcbb Fabien Chouteau
    /* mask registers */
202 3f10bcbb Fabien Chouteau
    if (addr >= MASK_OFFSET && addr < FORCE_OFFSET) {
203 3f10bcbb Fabien Chouteau
        int cpu = (addr - MASK_OFFSET) / 4;
204 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
205 3f10bcbb Fabien Chouteau
206 3f10bcbb Fabien Chouteau
        return state->mask[cpu];
207 3f10bcbb Fabien Chouteau
    }
208 3f10bcbb Fabien Chouteau
209 3f10bcbb Fabien Chouteau
    /* force registers */
210 3f10bcbb Fabien Chouteau
    if (addr >= FORCE_OFFSET && addr < EXTENDED_OFFSET) {
211 3f10bcbb Fabien Chouteau
        int cpu = (addr - FORCE_OFFSET) / 4;
212 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
213 3f10bcbb Fabien Chouteau
214 3f10bcbb Fabien Chouteau
        return state->force[cpu];
215 3f10bcbb Fabien Chouteau
    }
216 3f10bcbb Fabien Chouteau
217 3f10bcbb Fabien Chouteau
    /* extended (not supported) */
218 3f10bcbb Fabien Chouteau
    if (addr >= EXTENDED_OFFSET && addr < IRQMP_REG_SIZE) {
219 3f10bcbb Fabien Chouteau
        int cpu = (addr - EXTENDED_OFFSET) / 4;
220 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
221 3f10bcbb Fabien Chouteau
222 3f10bcbb Fabien Chouteau
        return state->extended[cpu];
223 3f10bcbb Fabien Chouteau
    }
224 3f10bcbb Fabien Chouteau
225 b4548fcc Stefan Hajnoczi
    trace_grlib_irqmp_readl_unknown(addr);
226 3f10bcbb Fabien Chouteau
    return 0;
227 3f10bcbb Fabien Chouteau
}
228 3f10bcbb Fabien Chouteau
229 847b52c1 Avi Kivity
static void grlib_irqmp_write(void *opaque, target_phys_addr_t addr,
230 847b52c1 Avi Kivity
                              uint64_t value, unsigned size)
231 3f10bcbb Fabien Chouteau
{
232 3f10bcbb Fabien Chouteau
    IRQMP      *irqmp = opaque;
233 3f10bcbb Fabien Chouteau
    IRQMPState *state;
234 3f10bcbb Fabien Chouteau
235 3f10bcbb Fabien Chouteau
    assert(irqmp != NULL);
236 3f10bcbb Fabien Chouteau
    state = irqmp->state;
237 3f10bcbb Fabien Chouteau
    assert(state != NULL);
238 3f10bcbb Fabien Chouteau
239 3f10bcbb Fabien Chouteau
    addr &= 0xff;
240 3f10bcbb Fabien Chouteau
241 3f10bcbb Fabien Chouteau
    /* global registers */
242 3f10bcbb Fabien Chouteau
    switch (addr) {
243 3f10bcbb Fabien Chouteau
    case LEVEL_OFFSET:
244 3f10bcbb Fabien Chouteau
        value &= 0xFFFF << 1; /* clean up the value */
245 3f10bcbb Fabien Chouteau
        state->level = value;
246 3f10bcbb Fabien Chouteau
        return;
247 3f10bcbb Fabien Chouteau
248 3f10bcbb Fabien Chouteau
    case PENDING_OFFSET:
249 3f10bcbb Fabien Chouteau
        /* Read Only */
250 3f10bcbb Fabien Chouteau
        return;
251 3f10bcbb Fabien Chouteau
252 3f10bcbb Fabien Chouteau
    case FORCE0_OFFSET:
253 3f10bcbb Fabien Chouteau
        /* This register is an "alias" for the force register of CPU 0 */
254 3f10bcbb Fabien Chouteau
255 3f10bcbb Fabien Chouteau
        value &= 0xFFFE; /* clean up the value */
256 3f10bcbb Fabien Chouteau
        state->force[0] = value;
257 3f10bcbb Fabien Chouteau
        grlib_irqmp_check_irqs(irqmp->state);
258 3f10bcbb Fabien Chouteau
        return;
259 3f10bcbb Fabien Chouteau
260 3f10bcbb Fabien Chouteau
    case CLEAR_OFFSET:
261 3f10bcbb Fabien Chouteau
        value &= ~1; /* clean up the value */
262 3f10bcbb Fabien Chouteau
        state->pending &= ~value;
263 3f10bcbb Fabien Chouteau
        return;
264 3f10bcbb Fabien Chouteau
265 3f10bcbb Fabien Chouteau
    case MP_STATUS_OFFSET:
266 3f10bcbb Fabien Chouteau
        /* Read Only (no SMP support) */
267 3f10bcbb Fabien Chouteau
        return;
268 3f10bcbb Fabien Chouteau
269 3f10bcbb Fabien Chouteau
    case BROADCAST_OFFSET:
270 3f10bcbb Fabien Chouteau
        value &= 0xFFFE; /* clean up the value */
271 3f10bcbb Fabien Chouteau
        state->broadcast = value;
272 3f10bcbb Fabien Chouteau
        return;
273 3f10bcbb Fabien Chouteau
274 3f10bcbb Fabien Chouteau
    default:
275 3f10bcbb Fabien Chouteau
        break;
276 3f10bcbb Fabien Chouteau
    }
277 3f10bcbb Fabien Chouteau
278 3f10bcbb Fabien Chouteau
    /* mask registers */
279 3f10bcbb Fabien Chouteau
    if (addr >= MASK_OFFSET && addr < FORCE_OFFSET) {
280 3f10bcbb Fabien Chouteau
        int cpu = (addr - MASK_OFFSET) / 4;
281 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
282 3f10bcbb Fabien Chouteau
283 3f10bcbb Fabien Chouteau
        value &= ~1; /* clean up the value */
284 3f10bcbb Fabien Chouteau
        state->mask[cpu] = value;
285 3f10bcbb Fabien Chouteau
        grlib_irqmp_check_irqs(irqmp->state);
286 3f10bcbb Fabien Chouteau
        return;
287 3f10bcbb Fabien Chouteau
    }
288 3f10bcbb Fabien Chouteau
289 3f10bcbb Fabien Chouteau
    /* force registers */
290 3f10bcbb Fabien Chouteau
    if (addr >= FORCE_OFFSET && addr < EXTENDED_OFFSET) {
291 3f10bcbb Fabien Chouteau
        int cpu = (addr - FORCE_OFFSET) / 4;
292 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
293 3f10bcbb Fabien Chouteau
294 3f10bcbb Fabien Chouteau
        uint32_t force = value & 0xFFFE;
295 3f10bcbb Fabien Chouteau
        uint32_t clear = (value >> 16) & 0xFFFE;
296 3f10bcbb Fabien Chouteau
        uint32_t old   = state->force[cpu];
297 3f10bcbb Fabien Chouteau
298 3f10bcbb Fabien Chouteau
        state->force[cpu] = (old | force) & ~clear;
299 3f10bcbb Fabien Chouteau
        grlib_irqmp_check_irqs(irqmp->state);
300 3f10bcbb Fabien Chouteau
        return;
301 3f10bcbb Fabien Chouteau
    }
302 3f10bcbb Fabien Chouteau
303 3f10bcbb Fabien Chouteau
    /* extended (not supported) */
304 3f10bcbb Fabien Chouteau
    if (addr >= EXTENDED_OFFSET && addr < IRQMP_REG_SIZE) {
305 3f10bcbb Fabien Chouteau
        int cpu = (addr - EXTENDED_OFFSET) / 4;
306 3f10bcbb Fabien Chouteau
        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);
307 3f10bcbb Fabien Chouteau
308 3f10bcbb Fabien Chouteau
        value &= 0xF; /* clean up the value */
309 3f10bcbb Fabien Chouteau
        state->extended[cpu] = value;
310 3f10bcbb Fabien Chouteau
        return;
311 3f10bcbb Fabien Chouteau
    }
312 3f10bcbb Fabien Chouteau
313 b4548fcc Stefan Hajnoczi
    trace_grlib_irqmp_writel_unknown(addr, value);
314 3f10bcbb Fabien Chouteau
}
315 3f10bcbb Fabien Chouteau
316 847b52c1 Avi Kivity
static const MemoryRegionOps grlib_irqmp_ops = {
317 847b52c1 Avi Kivity
    .read = grlib_irqmp_read,
318 847b52c1 Avi Kivity
    .write = grlib_irqmp_write,
319 847b52c1 Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
320 847b52c1 Avi Kivity
    .valid = {
321 847b52c1 Avi Kivity
        .min_access_size = 4,
322 847b52c1 Avi Kivity
        .max_access_size = 4,
323 847b52c1 Avi Kivity
    },
324 3f10bcbb Fabien Chouteau
};
325 3f10bcbb Fabien Chouteau
326 3f10bcbb Fabien Chouteau
static void grlib_irqmp_reset(DeviceState *d)
327 3f10bcbb Fabien Chouteau
{
328 3f10bcbb Fabien Chouteau
    IRQMP *irqmp = container_of(d, IRQMP, busdev.qdev);
329 3f10bcbb Fabien Chouteau
    assert(irqmp        != NULL);
330 3f10bcbb Fabien Chouteau
    assert(irqmp->state != NULL);
331 3f10bcbb Fabien Chouteau
332 3f10bcbb Fabien Chouteau
    memset(irqmp->state, 0, sizeof *irqmp->state);
333 3f10bcbb Fabien Chouteau
    irqmp->state->parent = irqmp;
334 3f10bcbb Fabien Chouteau
}
335 3f10bcbb Fabien Chouteau
336 3f10bcbb Fabien Chouteau
static int grlib_irqmp_init(SysBusDevice *dev)
337 3f10bcbb Fabien Chouteau
{
338 3f10bcbb Fabien Chouteau
    IRQMP *irqmp = FROM_SYSBUS(typeof(*irqmp), dev);
339 3f10bcbb Fabien Chouteau
340 3f10bcbb Fabien Chouteau
    assert(irqmp != NULL);
341 3f10bcbb Fabien Chouteau
342 3f10bcbb Fabien Chouteau
    /* Check parameters */
343 3f10bcbb Fabien Chouteau
    if (irqmp->set_pil_in == NULL) {
344 3f10bcbb Fabien Chouteau
        return -1;
345 3f10bcbb Fabien Chouteau
    }
346 3f10bcbb Fabien Chouteau
347 847b52c1 Avi Kivity
    memory_region_init_io(&irqmp->iomem, &grlib_irqmp_ops, irqmp,
348 847b52c1 Avi Kivity
                          "irqmp", IRQMP_REG_SIZE);
349 3f10bcbb Fabien Chouteau
350 7267c094 Anthony Liguori
    irqmp->state = g_malloc0(sizeof *irqmp->state);
351 3f10bcbb Fabien Chouteau
352 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &irqmp->iomem);
353 3f10bcbb Fabien Chouteau
354 3f10bcbb Fabien Chouteau
    return 0;
355 3f10bcbb Fabien Chouteau
}
356 3f10bcbb Fabien Chouteau
357 999e12bb Anthony Liguori
static Property grlib_irqmp_properties[] = {
358 999e12bb Anthony Liguori
    DEFINE_PROP_PTR("set_pil_in", IRQMP, set_pil_in),
359 999e12bb Anthony Liguori
    DEFINE_PROP_PTR("set_pil_in_opaque", IRQMP, set_pil_in_opaque),
360 999e12bb Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
361 999e12bb Anthony Liguori
};
362 999e12bb Anthony Liguori
363 999e12bb Anthony Liguori
static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
364 999e12bb Anthony Liguori
{
365 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
366 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
367 999e12bb Anthony Liguori
368 999e12bb Anthony Liguori
    k->init = grlib_irqmp_init;
369 39bffca2 Anthony Liguori
    dc->reset = grlib_irqmp_reset;
370 39bffca2 Anthony Liguori
    dc->props = grlib_irqmp_properties;
371 999e12bb Anthony Liguori
}
372 999e12bb Anthony Liguori
373 39bffca2 Anthony Liguori
static TypeInfo grlib_irqmp_info = {
374 39bffca2 Anthony Liguori
    .name          = "grlib,irqmp",
375 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
376 39bffca2 Anthony Liguori
    .instance_size = sizeof(IRQMP),
377 39bffca2 Anthony Liguori
    .class_init    = grlib_irqmp_class_init,
378 3f10bcbb Fabien Chouteau
};
379 3f10bcbb Fabien Chouteau
380 83f7d43a Andreas Färber
static void grlib_irqmp_register_types(void)
381 3f10bcbb Fabien Chouteau
{
382 39bffca2 Anthony Liguori
    type_register_static(&grlib_irqmp_info);
383 3f10bcbb Fabien Chouteau
}
384 3f10bcbb Fabien Chouteau
385 83f7d43a Andreas Färber
type_init(grlib_irqmp_register_types)