Statistics
| Branch: | Revision:

root / hw / i8259.c @ b13ce26d

History | View | Annotate | Download (12.8 kB)

1 80cabfad bellard
/*
2 80cabfad bellard
 * QEMU 8259 interrupt controller emulation
3 5fafdf24 ths
 *
4 80cabfad bellard
 * Copyright (c) 2003-2004 Fabrice Bellard
5 5fafdf24 ths
 *
6 80cabfad bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 80cabfad bellard
 * of this software and associated documentation files (the "Software"), to deal
8 80cabfad bellard
 * in the Software without restriction, including without limitation the rights
9 80cabfad bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 80cabfad bellard
 * copies of the Software, and to permit persons to whom the Software is
11 80cabfad bellard
 * furnished to do so, subject to the following conditions:
12 80cabfad bellard
 *
13 80cabfad bellard
 * The above copyright notice and this permission notice shall be included in
14 80cabfad bellard
 * all copies or substantial portions of the Software.
15 80cabfad bellard
 *
16 80cabfad bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 80cabfad bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 80cabfad bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 80cabfad bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 80cabfad bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 80cabfad bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 80cabfad bellard
 * THE SOFTWARE.
23 80cabfad bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "pc.h"
26 87ecb68b pbrook
#include "isa.h"
27 376253ec aliguori
#include "monitor.h"
28 0bf9e31a Blue Swirl
#include "qemu-timer.h"
29 512709f5 Jan Kiszka
#include "i8259_internal.h"
30 80cabfad bellard
31 80cabfad bellard
/* debug PIC */
32 80cabfad bellard
//#define DEBUG_PIC
33 80cabfad bellard
34 8ac02ff8 Blue Swirl
#ifdef DEBUG_PIC
35 8ac02ff8 Blue Swirl
#define DPRINTF(fmt, ...)                                       \
36 8ac02ff8 Blue Swirl
    do { printf("pic: " fmt , ## __VA_ARGS__); } while (0)
37 8ac02ff8 Blue Swirl
#else
38 8ac02ff8 Blue Swirl
#define DPRINTF(fmt, ...)
39 8ac02ff8 Blue Swirl
#endif
40 8ac02ff8 Blue Swirl
41 b41a2cd1 bellard
//#define DEBUG_IRQ_LATENCY
42 4a0fb71e bellard
//#define DEBUG_IRQ_COUNT
43 b41a2cd1 bellard
44 81a02f93 Jan Kiszka
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
45 4a0fb71e bellard
static int irq_level[16];
46 4a0fb71e bellard
#endif
47 4a0fb71e bellard
#ifdef DEBUG_IRQ_COUNT
48 4a0fb71e bellard
static uint64_t irq_count[16];
49 4a0fb71e bellard
#endif
50 747c70af Jan Kiszka
#ifdef DEBUG_IRQ_LATENCY
51 747c70af Jan Kiszka
static int64_t irq_time[16];
52 747c70af Jan Kiszka
#endif
53 9aa78c42 Jan Kiszka
DeviceState *isa_pic;
54 512709f5 Jan Kiszka
static PICCommonState *slave_pic;
55 4a0fb71e bellard
56 80cabfad bellard
/* return the highest priority found in mask (highest = smallest
57 80cabfad bellard
   number). Return 8 if no irq */
58 512709f5 Jan Kiszka
static int get_priority(PICCommonState *s, int mask)
59 80cabfad bellard
{
60 80cabfad bellard
    int priority;
61 81a02f93 Jan Kiszka
62 81a02f93 Jan Kiszka
    if (mask == 0) {
63 80cabfad bellard
        return 8;
64 81a02f93 Jan Kiszka
    }
65 80cabfad bellard
    priority = 0;
66 81a02f93 Jan Kiszka
    while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) {
67 80cabfad bellard
        priority++;
68 81a02f93 Jan Kiszka
    }
69 80cabfad bellard
    return priority;
70 80cabfad bellard
}
71 80cabfad bellard
72 80cabfad bellard
/* return the pic wanted interrupt. return -1 if none */
73 512709f5 Jan Kiszka
static int pic_get_irq(PICCommonState *s)
74 80cabfad bellard
{
75 80cabfad bellard
    int mask, cur_priority, priority;
76 80cabfad bellard
77 80cabfad bellard
    mask = s->irr & ~s->imr;
78 80cabfad bellard
    priority = get_priority(s, mask);
79 81a02f93 Jan Kiszka
    if (priority == 8) {
80 80cabfad bellard
        return -1;
81 81a02f93 Jan Kiszka
    }
82 80cabfad bellard
    /* compute current priority. If special fully nested mode on the
83 80cabfad bellard
       master, the IRQ coming from the slave is not taken into account
84 80cabfad bellard
       for the priority computation. */
85 80cabfad bellard
    mask = s->isr;
86 81a02f93 Jan Kiszka
    if (s->special_mask) {
87 84678711 balrog
        mask &= ~s->imr;
88 81a02f93 Jan Kiszka
    }
89 25985396 Jan Kiszka
    if (s->special_fully_nested_mode && s->master) {
90 80cabfad bellard
        mask &= ~(1 << 2);
91 25985396 Jan Kiszka
    }
92 80cabfad bellard
    cur_priority = get_priority(s, mask);
93 80cabfad bellard
    if (priority < cur_priority) {
94 80cabfad bellard
        /* higher priority found: an irq should be generated */
95 80cabfad bellard
        return (priority + s->priority_add) & 7;
96 80cabfad bellard
    } else {
97 80cabfad bellard
        return -1;
98 80cabfad bellard
    }
99 80cabfad bellard
}
100 80cabfad bellard
101 b76750c1 Jan Kiszka
/* Update INT output. Must be called every time the output may have changed. */
102 512709f5 Jan Kiszka
static void pic_update_irq(PICCommonState *s)
103 80cabfad bellard
{
104 b76750c1 Jan Kiszka
    int irq;
105 80cabfad bellard
106 b76750c1 Jan Kiszka
    irq = pic_get_irq(s);
107 80cabfad bellard
    if (irq >= 0) {
108 b76750c1 Jan Kiszka
        DPRINTF("pic%d: imr=%x irr=%x padd=%d\n",
109 25985396 Jan Kiszka
                s->master ? 0 : 1, s->imr, s->irr, s->priority_add);
110 747c70af Jan Kiszka
        qemu_irq_raise(s->int_out[0]);
111 d96e1737 Jan Kiszka
    } else {
112 747c70af Jan Kiszka
        qemu_irq_lower(s->int_out[0]);
113 4de9b249 ths
    }
114 80cabfad bellard
}
115 80cabfad bellard
116 62026017 Jan Kiszka
/* set irq level. If an edge is detected, then the IRR is set to 1 */
117 747c70af Jan Kiszka
static void pic_set_irq(void *opaque, int irq, int level)
118 62026017 Jan Kiszka
{
119 512709f5 Jan Kiszka
    PICCommonState *s = opaque;
120 747c70af Jan Kiszka
    int mask = 1 << irq;
121 747c70af Jan Kiszka
122 747c70af Jan Kiszka
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) || \
123 747c70af Jan Kiszka
    defined(DEBUG_IRQ_LATENCY)
124 747c70af Jan Kiszka
    int irq_index = s->master ? irq : irq + 8;
125 747c70af Jan Kiszka
#endif
126 747c70af Jan Kiszka
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
127 747c70af Jan Kiszka
    if (level != irq_level[irq_index]) {
128 747c70af Jan Kiszka
        DPRINTF("pic_set_irq: irq=%d level=%d\n", irq_index, level);
129 747c70af Jan Kiszka
        irq_level[irq_index] = level;
130 747c70af Jan Kiszka
#ifdef DEBUG_IRQ_COUNT
131 747c70af Jan Kiszka
        if (level == 1) {
132 747c70af Jan Kiszka
            irq_count[irq_index]++;
133 747c70af Jan Kiszka
        }
134 747c70af Jan Kiszka
#endif
135 747c70af Jan Kiszka
    }
136 747c70af Jan Kiszka
#endif
137 747c70af Jan Kiszka
#ifdef DEBUG_IRQ_LATENCY
138 747c70af Jan Kiszka
    if (level) {
139 747c70af Jan Kiszka
        irq_time[irq_index] = qemu_get_clock_ns(vm_clock);
140 747c70af Jan Kiszka
    }
141 747c70af Jan Kiszka
#endif
142 747c70af Jan Kiszka
143 62026017 Jan Kiszka
    if (s->elcr & mask) {
144 62026017 Jan Kiszka
        /* level triggered */
145 62026017 Jan Kiszka
        if (level) {
146 62026017 Jan Kiszka
            s->irr |= mask;
147 62026017 Jan Kiszka
            s->last_irr |= mask;
148 62026017 Jan Kiszka
        } else {
149 62026017 Jan Kiszka
            s->irr &= ~mask;
150 62026017 Jan Kiszka
            s->last_irr &= ~mask;
151 62026017 Jan Kiszka
        }
152 62026017 Jan Kiszka
    } else {
153 62026017 Jan Kiszka
        /* edge triggered */
154 62026017 Jan Kiszka
        if (level) {
155 62026017 Jan Kiszka
            if ((s->last_irr & mask) == 0) {
156 62026017 Jan Kiszka
                s->irr |= mask;
157 62026017 Jan Kiszka
            }
158 62026017 Jan Kiszka
            s->last_irr |= mask;
159 62026017 Jan Kiszka
        } else {
160 62026017 Jan Kiszka
            s->last_irr &= ~mask;
161 62026017 Jan Kiszka
        }
162 62026017 Jan Kiszka
    }
163 b76750c1 Jan Kiszka
    pic_update_irq(s);
164 62026017 Jan Kiszka
}
165 62026017 Jan Kiszka
166 80cabfad bellard
/* acknowledge interrupt 'irq' */
167 512709f5 Jan Kiszka
static void pic_intack(PICCommonState *s, int irq)
168 80cabfad bellard
{
169 80cabfad bellard
    if (s->auto_eoi) {
170 81a02f93 Jan Kiszka
        if (s->rotate_on_auto_eoi) {
171 80cabfad bellard
            s->priority_add = (irq + 1) & 7;
172 81a02f93 Jan Kiszka
        }
173 80cabfad bellard
    } else {
174 80cabfad bellard
        s->isr |= (1 << irq);
175 80cabfad bellard
    }
176 0ecf89aa bellard
    /* We don't clear a level sensitive interrupt here */
177 81a02f93 Jan Kiszka
    if (!(s->elcr & (1 << irq))) {
178 0ecf89aa bellard
        s->irr &= ~(1 << irq);
179 81a02f93 Jan Kiszka
    }
180 b76750c1 Jan Kiszka
    pic_update_irq(s);
181 80cabfad bellard
}
182 80cabfad bellard
183 9aa78c42 Jan Kiszka
int pic_read_irq(DeviceState *d)
184 80cabfad bellard
{
185 512709f5 Jan Kiszka
    PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, d);
186 80cabfad bellard
    int irq, irq2, intno;
187 80cabfad bellard
188 c17725f4 Jan Kiszka
    irq = pic_get_irq(s);
189 15aeac38 bellard
    if (irq >= 0) {
190 15aeac38 bellard
        if (irq == 2) {
191 c17725f4 Jan Kiszka
            irq2 = pic_get_irq(slave_pic);
192 15aeac38 bellard
            if (irq2 >= 0) {
193 c17725f4 Jan Kiszka
                pic_intack(slave_pic, irq2);
194 15aeac38 bellard
            } else {
195 15aeac38 bellard
                /* spurious IRQ on slave controller */
196 15aeac38 bellard
                irq2 = 7;
197 15aeac38 bellard
            }
198 c17725f4 Jan Kiszka
            intno = slave_pic->irq_base + irq2;
199 15aeac38 bellard
        } else {
200 c17725f4 Jan Kiszka
            intno = s->irq_base + irq;
201 15aeac38 bellard
        }
202 c17725f4 Jan Kiszka
        pic_intack(s, irq);
203 15aeac38 bellard
    } else {
204 15aeac38 bellard
        /* spurious IRQ on host controller */
205 15aeac38 bellard
        irq = 7;
206 c17725f4 Jan Kiszka
        intno = s->irq_base + irq;
207 15aeac38 bellard
    }
208 3b46e624 ths
209 78ef2b69 Jan Kiszka
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY)
210 78ef2b69 Jan Kiszka
    if (irq == 2) {
211 78ef2b69 Jan Kiszka
        irq = irq2 + 8;
212 78ef2b69 Jan Kiszka
    }
213 78ef2b69 Jan Kiszka
#endif
214 80cabfad bellard
#ifdef DEBUG_IRQ_LATENCY
215 5fafdf24 ths
    printf("IRQ%d latency=%0.3fus\n",
216 5fafdf24 ths
           irq,
217 74475455 Paolo Bonzini
           (double)(qemu_get_clock_ns(vm_clock) -
218 6ee093c9 Juan Quintela
                    irq_time[irq]) * 1000000.0 / get_ticks_per_sec());
219 80cabfad bellard
#endif
220 8ac02ff8 Blue Swirl
    DPRINTF("pic_interrupt: irq=%d\n", irq);
221 80cabfad bellard
    return intno;
222 80cabfad bellard
}
223 80cabfad bellard
224 512709f5 Jan Kiszka
static void pic_init_reset(PICCommonState *s)
225 d7d02e3c bellard
{
226 512709f5 Jan Kiszka
    pic_reset_common(s);
227 b76750c1 Jan Kiszka
    pic_update_irq(s);
228 d7d02e3c bellard
}
229 d7d02e3c bellard
230 747c70af Jan Kiszka
static void pic_reset(DeviceState *dev)
231 86fbf97c Jan Kiszka
{
232 512709f5 Jan Kiszka
    PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, dev);
233 86fbf97c Jan Kiszka
234 86fbf97c Jan Kiszka
    s->elcr = 0;
235 aa24822b Jan Kiszka
    pic_init_reset(s);
236 86fbf97c Jan Kiszka
}
237 86fbf97c Jan Kiszka
238 a8170e5e Avi Kivity
static void pic_ioport_write(void *opaque, hwaddr addr64,
239 098d314a Richard Henderson
                             uint64_t val64, unsigned size)
240 80cabfad bellard
{
241 512709f5 Jan Kiszka
    PICCommonState *s = opaque;
242 098d314a Richard Henderson
    uint32_t addr = addr64;
243 098d314a Richard Henderson
    uint32_t val = val64;
244 d7d02e3c bellard
    int priority, cmd, irq;
245 80cabfad bellard
246 8ac02ff8 Blue Swirl
    DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);
247 80cabfad bellard
    if (addr == 0) {
248 80cabfad bellard
        if (val & 0x10) {
249 86fbf97c Jan Kiszka
            pic_init_reset(s);
250 80cabfad bellard
            s->init_state = 1;
251 80cabfad bellard
            s->init4 = val & 1;
252 2053152b ths
            s->single_mode = val & 2;
253 81a02f93 Jan Kiszka
            if (val & 0x08) {
254 80cabfad bellard
                hw_error("level sensitive irq not supported");
255 81a02f93 Jan Kiszka
            }
256 80cabfad bellard
        } else if (val & 0x08) {
257 81a02f93 Jan Kiszka
            if (val & 0x04) {
258 80cabfad bellard
                s->poll = 1;
259 81a02f93 Jan Kiszka
            }
260 81a02f93 Jan Kiszka
            if (val & 0x02) {
261 80cabfad bellard
                s->read_reg_select = val & 1;
262 81a02f93 Jan Kiszka
            }
263 81a02f93 Jan Kiszka
            if (val & 0x40) {
264 80cabfad bellard
                s->special_mask = (val >> 5) & 1;
265 81a02f93 Jan Kiszka
            }
266 80cabfad bellard
        } else {
267 80cabfad bellard
            cmd = val >> 5;
268 81a02f93 Jan Kiszka
            switch (cmd) {
269 80cabfad bellard
            case 0:
270 80cabfad bellard
            case 4:
271 80cabfad bellard
                s->rotate_on_auto_eoi = cmd >> 2;
272 80cabfad bellard
                break;
273 80cabfad bellard
            case 1: /* end of interrupt */
274 80cabfad bellard
            case 5:
275 80cabfad bellard
                priority = get_priority(s, s->isr);
276 80cabfad bellard
                if (priority != 8) {
277 80cabfad bellard
                    irq = (priority + s->priority_add) & 7;
278 80cabfad bellard
                    s->isr &= ~(1 << irq);
279 81a02f93 Jan Kiszka
                    if (cmd == 5) {
280 80cabfad bellard
                        s->priority_add = (irq + 1) & 7;
281 81a02f93 Jan Kiszka
                    }
282 b76750c1 Jan Kiszka
                    pic_update_irq(s);
283 80cabfad bellard
                }
284 80cabfad bellard
                break;
285 80cabfad bellard
            case 3:
286 80cabfad bellard
                irq = val & 7;
287 80cabfad bellard
                s->isr &= ~(1 << irq);
288 b76750c1 Jan Kiszka
                pic_update_irq(s);
289 80cabfad bellard
                break;
290 80cabfad bellard
            case 6:
291 80cabfad bellard
                s->priority_add = (val + 1) & 7;
292 b76750c1 Jan Kiszka
                pic_update_irq(s);
293 80cabfad bellard
                break;
294 80cabfad bellard
            case 7:
295 80cabfad bellard
                irq = val & 7;
296 80cabfad bellard
                s->isr &= ~(1 << irq);
297 80cabfad bellard
                s->priority_add = (irq + 1) & 7;
298 b76750c1 Jan Kiszka
                pic_update_irq(s);
299 80cabfad bellard
                break;
300 80cabfad bellard
            default:
301 80cabfad bellard
                /* no operation */
302 80cabfad bellard
                break;
303 80cabfad bellard
            }
304 80cabfad bellard
        }
305 80cabfad bellard
    } else {
306 81a02f93 Jan Kiszka
        switch (s->init_state) {
307 80cabfad bellard
        case 0:
308 80cabfad bellard
            /* normal mode */
309 80cabfad bellard
            s->imr = val;
310 b76750c1 Jan Kiszka
            pic_update_irq(s);
311 80cabfad bellard
            break;
312 80cabfad bellard
        case 1:
313 80cabfad bellard
            s->irq_base = val & 0xf8;
314 2bb081f7 ths
            s->init_state = s->single_mode ? (s->init4 ? 3 : 0) : 2;
315 80cabfad bellard
            break;
316 80cabfad bellard
        case 2:
317 80cabfad bellard
            if (s->init4) {
318 80cabfad bellard
                s->init_state = 3;
319 80cabfad bellard
            } else {
320 80cabfad bellard
                s->init_state = 0;
321 80cabfad bellard
            }
322 80cabfad bellard
            break;
323 80cabfad bellard
        case 3:
324 80cabfad bellard
            s->special_fully_nested_mode = (val >> 4) & 1;
325 80cabfad bellard
            s->auto_eoi = (val >> 1) & 1;
326 80cabfad bellard
            s->init_state = 0;
327 80cabfad bellard
            break;
328 80cabfad bellard
        }
329 80cabfad bellard
    }
330 80cabfad bellard
}
331 80cabfad bellard
332 a8170e5e Avi Kivity
static uint64_t pic_ioport_read(void *opaque, hwaddr addr,
333 098d314a Richard Henderson
                                unsigned size)
334 80cabfad bellard
{
335 512709f5 Jan Kiszka
    PICCommonState *s = opaque;
336 80cabfad bellard
    int ret;
337 80cabfad bellard
338 80cabfad bellard
    if (s->poll) {
339 8d484caa Jan Kiszka
        ret = pic_get_irq(s);
340 8d484caa Jan Kiszka
        if (ret >= 0) {
341 8d484caa Jan Kiszka
            pic_intack(s, ret);
342 8d484caa Jan Kiszka
            ret |= 0x80;
343 8d484caa Jan Kiszka
        } else {
344 8d484caa Jan Kiszka
            ret = 0;
345 8d484caa Jan Kiszka
        }
346 80cabfad bellard
        s->poll = 0;
347 80cabfad bellard
    } else {
348 80cabfad bellard
        if (addr == 0) {
349 81a02f93 Jan Kiszka
            if (s->read_reg_select) {
350 80cabfad bellard
                ret = s->isr;
351 81a02f93 Jan Kiszka
            } else {
352 80cabfad bellard
                ret = s->irr;
353 81a02f93 Jan Kiszka
            }
354 80cabfad bellard
        } else {
355 80cabfad bellard
            ret = s->imr;
356 80cabfad bellard
        }
357 80cabfad bellard
    }
358 08406b03 malc
    DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret);
359 80cabfad bellard
    return ret;
360 80cabfad bellard
}
361 80cabfad bellard
362 9aa78c42 Jan Kiszka
int pic_get_output(DeviceState *d)
363 d96e1737 Jan Kiszka
{
364 512709f5 Jan Kiszka
    PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, d);
365 9aa78c42 Jan Kiszka
366 c17725f4 Jan Kiszka
    return (pic_get_irq(s) >= 0);
367 d96e1737 Jan Kiszka
}
368 d96e1737 Jan Kiszka
369 a8170e5e Avi Kivity
static void elcr_ioport_write(void *opaque, hwaddr addr,
370 098d314a Richard Henderson
                              uint64_t val, unsigned size)
371 660de336 bellard
{
372 512709f5 Jan Kiszka
    PICCommonState *s = opaque;
373 660de336 bellard
    s->elcr = val & s->elcr_mask;
374 660de336 bellard
}
375 660de336 bellard
376 a8170e5e Avi Kivity
static uint64_t elcr_ioport_read(void *opaque, hwaddr addr,
377 098d314a Richard Henderson
                                 unsigned size)
378 660de336 bellard
{
379 512709f5 Jan Kiszka
    PICCommonState *s = opaque;
380 660de336 bellard
    return s->elcr;
381 660de336 bellard
}
382 660de336 bellard
383 098d314a Richard Henderson
static const MemoryRegionOps pic_base_ioport_ops = {
384 098d314a Richard Henderson
    .read = pic_ioport_read,
385 098d314a Richard Henderson
    .write = pic_ioport_write,
386 098d314a Richard Henderson
    .impl = {
387 098d314a Richard Henderson
        .min_access_size = 1,
388 098d314a Richard Henderson
        .max_access_size = 1,
389 098d314a Richard Henderson
    },
390 098d314a Richard Henderson
};
391 098d314a Richard Henderson
392 098d314a Richard Henderson
static const MemoryRegionOps pic_elcr_ioport_ops = {
393 098d314a Richard Henderson
    .read = elcr_ioport_read,
394 098d314a Richard Henderson
    .write = elcr_ioport_write,
395 098d314a Richard Henderson
    .impl = {
396 098d314a Richard Henderson
        .min_access_size = 1,
397 098d314a Richard Henderson
        .max_access_size = 1,
398 098d314a Richard Henderson
    },
399 098d314a Richard Henderson
};
400 098d314a Richard Henderson
401 512709f5 Jan Kiszka
static void pic_init(PICCommonState *s)
402 b0a21b53 bellard
{
403 098d314a Richard Henderson
    memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2);
404 098d314a Richard Henderson
    memory_region_init_io(&s->elcr_io, &pic_elcr_ioport_ops, s, "elcr", 1);
405 098d314a Richard Henderson
406 512709f5 Jan Kiszka
    qdev_init_gpio_out(&s->dev.qdev, s->int_out, ARRAY_SIZE(s->int_out));
407 512709f5 Jan Kiszka
    qdev_init_gpio_in(&s->dev.qdev, pic_set_irq, 8);
408 b0a21b53 bellard
}
409 b0a21b53 bellard
410 376253ec aliguori
void pic_info(Monitor *mon)
411 ba91cd80 bellard
{
412 ba91cd80 bellard
    int i;
413 512709f5 Jan Kiszka
    PICCommonState *s;
414 3b46e624 ths
415 81a02f93 Jan Kiszka
    if (!isa_pic) {
416 3de388f6 bellard
        return;
417 81a02f93 Jan Kiszka
    }
418 c17725f4 Jan Kiszka
    for (i = 0; i < 2; i++) {
419 512709f5 Jan Kiszka
        s = i == 0 ? DO_UPCAST(PICCommonState, dev.qdev, isa_pic) : slave_pic;
420 376253ec aliguori
        monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d "
421 376253ec aliguori
                       "irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
422 376253ec aliguori
                       i, s->irr, s->imr, s->isr, s->priority_add,
423 376253ec aliguori
                       s->irq_base, s->read_reg_select, s->elcr,
424 376253ec aliguori
                       s->special_fully_nested_mode);
425 ba91cd80 bellard
    }
426 ba91cd80 bellard
}
427 ba91cd80 bellard
428 376253ec aliguori
void irq_info(Monitor *mon)
429 4a0fb71e bellard
{
430 4a0fb71e bellard
#ifndef DEBUG_IRQ_COUNT
431 376253ec aliguori
    monitor_printf(mon, "irq statistic code not compiled.\n");
432 4a0fb71e bellard
#else
433 4a0fb71e bellard
    int i;
434 4a0fb71e bellard
    int64_t count;
435 4a0fb71e bellard
436 376253ec aliguori
    monitor_printf(mon, "IRQ statistics:\n");
437 4a0fb71e bellard
    for (i = 0; i < 16; i++) {
438 4a0fb71e bellard
        count = irq_count[i];
439 81a02f93 Jan Kiszka
        if (count > 0) {
440 376253ec aliguori
            monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
441 81a02f93 Jan Kiszka
        }
442 4a0fb71e bellard
    }
443 4a0fb71e bellard
#endif
444 4a0fb71e bellard
}
445 ba91cd80 bellard
446 48a18b3c Hervé Poussineau
qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
447 80cabfad bellard
{
448 747c70af Jan Kiszka
    qemu_irq *irq_set;
449 747c70af Jan Kiszka
    ISADevice *dev;
450 747c70af Jan Kiszka
    int i;
451 c17725f4 Jan Kiszka
452 747c70af Jan Kiszka
    irq_set = g_malloc(ISA_NUM_IRQS * sizeof(qemu_irq));
453 c17725f4 Jan Kiszka
454 512709f5 Jan Kiszka
    dev = i8259_init_chip("isa-i8259", bus, true);
455 c17725f4 Jan Kiszka
456 747c70af Jan Kiszka
    qdev_connect_gpio_out(&dev->qdev, 0, parent_irq);
457 747c70af Jan Kiszka
    for (i = 0 ; i < 8; i++) {
458 747c70af Jan Kiszka
        irq_set[i] = qdev_get_gpio_in(&dev->qdev, i);
459 747c70af Jan Kiszka
    }
460 747c70af Jan Kiszka
461 9aa78c42 Jan Kiszka
    isa_pic = &dev->qdev;
462 747c70af Jan Kiszka
463 512709f5 Jan Kiszka
    dev = i8259_init_chip("isa-i8259", bus, false);
464 747c70af Jan Kiszka
465 747c70af Jan Kiszka
    qdev_connect_gpio_out(&dev->qdev, 0, irq_set[2]);
466 747c70af Jan Kiszka
    for (i = 0 ; i < 8; i++) {
467 747c70af Jan Kiszka
        irq_set[i + 8] = qdev_get_gpio_in(&dev->qdev, i);
468 747c70af Jan Kiszka
    }
469 747c70af Jan Kiszka
470 512709f5 Jan Kiszka
    slave_pic = DO_UPCAST(PICCommonState, dev, dev);
471 c17725f4 Jan Kiszka
472 747c70af Jan Kiszka
    return irq_set;
473 747c70af Jan Kiszka
}
474 747c70af Jan Kiszka
475 8f04ee08 Anthony Liguori
static void i8259_class_init(ObjectClass *klass, void *data)
476 8f04ee08 Anthony Liguori
{
477 8f04ee08 Anthony Liguori
    PICCommonClass *k = PIC_COMMON_CLASS(klass);
478 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
479 8f04ee08 Anthony Liguori
480 8f04ee08 Anthony Liguori
    k->init = pic_init;
481 39bffca2 Anthony Liguori
    dc->reset = pic_reset;
482 8f04ee08 Anthony Liguori
}
483 8f04ee08 Anthony Liguori
484 39bffca2 Anthony Liguori
static TypeInfo i8259_info = {
485 39bffca2 Anthony Liguori
    .name       = "isa-i8259",
486 39bffca2 Anthony Liguori
    .instance_size = sizeof(PICCommonState),
487 39bffca2 Anthony Liguori
    .parent     = TYPE_PIC_COMMON,
488 8f04ee08 Anthony Liguori
    .class_init = i8259_class_init,
489 747c70af Jan Kiszka
};
490 747c70af Jan Kiszka
491 83f7d43a Andreas Färber
static void pic_register_types(void)
492 747c70af Jan Kiszka
{
493 39bffca2 Anthony Liguori
    type_register_static(&i8259_info);
494 80cabfad bellard
}
495 512709f5 Jan Kiszka
496 83f7d43a Andreas Färber
type_init(pic_register_types)