Statistics
| Branch: | Revision:

root / hw / slavio_intctl.c @ b8c18e4c

History | View | Annotate | Download (12.1 kB)

1 e80cfcfc bellard
/*
2 e80cfcfc bellard
 * QEMU Sparc SLAVIO interrupt controller emulation
3 5fafdf24 ths
 *
4 66321a11 bellard
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5fafdf24 ths
 *
6 e80cfcfc bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 e80cfcfc bellard
 * of this software and associated documentation files (the "Software"), to deal
8 e80cfcfc bellard
 * in the Software without restriction, including without limitation the rights
9 e80cfcfc bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 e80cfcfc bellard
 * copies of the Software, and to permit persons to whom the Software is
11 e80cfcfc bellard
 * furnished to do so, subject to the following conditions:
12 e80cfcfc bellard
 *
13 e80cfcfc bellard
 * The above copyright notice and this permission notice shall be included in
14 e80cfcfc bellard
 * all copies or substantial portions of the Software.
15 e80cfcfc bellard
 *
16 e80cfcfc bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 e80cfcfc bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 e80cfcfc bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 e80cfcfc bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 e80cfcfc bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 e80cfcfc bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 e80cfcfc bellard
 * THE SOFTWARE.
23 e80cfcfc bellard
 */
24 87ecb68b pbrook
#include "hw.h"
25 87ecb68b pbrook
#include "sun4m.h"
26 376253ec aliguori
#include "monitor.h"
27 87ecb68b pbrook
28 e80cfcfc bellard
//#define DEBUG_IRQ_COUNT
29 66321a11 bellard
//#define DEBUG_IRQ
30 66321a11 bellard
31 66321a11 bellard
#ifdef DEBUG_IRQ
32 66321a11 bellard
#define DPRINTF(fmt, args...) \
33 66321a11 bellard
do { printf("IRQ: " fmt , ##args); } while (0)
34 66321a11 bellard
#else
35 66321a11 bellard
#define DPRINTF(fmt, args...)
36 66321a11 bellard
#endif
37 e80cfcfc bellard
38 e80cfcfc bellard
/*
39 e80cfcfc bellard
 * Registers of interrupt controller in sun4m.
40 e80cfcfc bellard
 *
41 e80cfcfc bellard
 * This is the interrupt controller part of chip STP2001 (Slave I/O), also
42 e80cfcfc bellard
 * produced as NCR89C105. See
43 e80cfcfc bellard
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
44 e80cfcfc bellard
 *
45 e80cfcfc bellard
 * There is a system master controller and one for each cpu.
46 5fafdf24 ths
 *
47 e80cfcfc bellard
 */
48 e80cfcfc bellard
49 e80cfcfc bellard
#define MAX_CPUS 16
50 b3a23197 blueswir1
#define MAX_PILS 16
51 e80cfcfc bellard
52 a8f48dcc blueswir1
struct SLAVIO_CPUINTCTLState;
53 a8f48dcc blueswir1
54 e80cfcfc bellard
typedef struct SLAVIO_INTCTLState {
55 e80cfcfc bellard
    uint32_t intregm_pending;
56 e80cfcfc bellard
    uint32_t intregm_disabled;
57 e80cfcfc bellard
    uint32_t target_cpu;
58 e80cfcfc bellard
#ifdef DEBUG_IRQ_COUNT
59 e80cfcfc bellard
    uint64_t irq_count[32];
60 e80cfcfc bellard
#endif
61 b3a23197 blueswir1
    qemu_irq *cpu_irqs[MAX_CPUS];
62 e0353fe2 blueswir1
    const uint32_t *intbit_to_level;
63 e3a79bca blueswir1
    uint32_t cputimer_lbit, cputimer_mbit;
64 b3a23197 blueswir1
    uint32_t pil_out[MAX_CPUS];
65 a8f48dcc blueswir1
    struct SLAVIO_CPUINTCTLState *slaves[MAX_CPUS];
66 e80cfcfc bellard
} SLAVIO_INTCTLState;
67 e80cfcfc bellard
68 a8f48dcc blueswir1
typedef struct SLAVIO_CPUINTCTLState {
69 a8f48dcc blueswir1
    uint32_t intreg_pending;
70 a8f48dcc blueswir1
    SLAVIO_INTCTLState *master;
71 a8f48dcc blueswir1
    uint32_t cpu;
72 a8f48dcc blueswir1
} SLAVIO_CPUINTCTLState;
73 a8f48dcc blueswir1
74 e80cfcfc bellard
#define INTCTL_MAXADDR 0xf
75 5aca8c3b blueswir1
#define INTCTL_SIZE (INTCTL_MAXADDR + 1)
76 a8f48dcc blueswir1
#define INTCTLM_SIZE 0x14
77 80be36b8 blueswir1
#define MASTER_IRQ_MASK ~0x0fa2007f
78 9a87ce9b blueswir1
#define MASTER_DISABLE 0x80000000
79 6341fdcb blueswir1
#define CPU_SOFTIRQ_MASK 0xfffe0000
80 6341fdcb blueswir1
#define CPU_HARDIRQ_MASK 0x0000fffe
81 9a87ce9b blueswir1
#define CPU_IRQ_INT15_IN 0x0004000
82 9a87ce9b blueswir1
#define CPU_IRQ_INT15_MASK 0x80000000
83 9a87ce9b blueswir1
84 a8f48dcc blueswir1
static void slavio_check_interrupts(SLAVIO_INTCTLState *s);
85 e80cfcfc bellard
86 e80cfcfc bellard
// per-cpu interrupt controller
87 e80cfcfc bellard
static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
88 e80cfcfc bellard
{
89 a8f48dcc blueswir1
    SLAVIO_CPUINTCTLState *s = opaque;
90 dd4131b3 blueswir1
    uint32_t saddr, ret;
91 e80cfcfc bellard
92 a8f48dcc blueswir1
    saddr = addr >> 2;
93 e80cfcfc bellard
    switch (saddr) {
94 e80cfcfc bellard
    case 0:
95 a8f48dcc blueswir1
        ret = s->intreg_pending;
96 dd4131b3 blueswir1
        break;
97 e80cfcfc bellard
    default:
98 dd4131b3 blueswir1
        ret = 0;
99 dd4131b3 blueswir1
        break;
100 e80cfcfc bellard
    }
101 3c4cf535 blueswir1
    DPRINTF("read cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, ret);
102 dd4131b3 blueswir1
103 dd4131b3 blueswir1
    return ret;
104 e80cfcfc bellard
}
105 e80cfcfc bellard
106 77f193da blueswir1
static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr,
107 77f193da blueswir1
                                     uint32_t val)
108 e80cfcfc bellard
{
109 a8f48dcc blueswir1
    SLAVIO_CPUINTCTLState *s = opaque;
110 e80cfcfc bellard
    uint32_t saddr;
111 e80cfcfc bellard
112 a8f48dcc blueswir1
    saddr = addr >> 2;
113 3c4cf535 blueswir1
    DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, val);
114 e80cfcfc bellard
    switch (saddr) {
115 e80cfcfc bellard
    case 1: // clear pending softints
116 9a87ce9b blueswir1
        if (val & CPU_IRQ_INT15_IN)
117 9a87ce9b blueswir1
            val |= CPU_IRQ_INT15_MASK;
118 6341fdcb blueswir1
        val &= CPU_SOFTIRQ_MASK;
119 a8f48dcc blueswir1
        s->intreg_pending &= ~val;
120 a8f48dcc blueswir1
        slavio_check_interrupts(s->master);
121 a8f48dcc blueswir1
        DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val,
122 a8f48dcc blueswir1
                s->intreg_pending);
123 f930d07e blueswir1
        break;
124 e80cfcfc bellard
    case 2: // set softint
125 6341fdcb blueswir1
        val &= CPU_SOFTIRQ_MASK;
126 a8f48dcc blueswir1
        s->intreg_pending |= val;
127 a8f48dcc blueswir1
        slavio_check_interrupts(s->master);
128 a8f48dcc blueswir1
        DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val,
129 a8f48dcc blueswir1
                s->intreg_pending);
130 f930d07e blueswir1
        break;
131 e80cfcfc bellard
    default:
132 f930d07e blueswir1
        break;
133 e80cfcfc bellard
    }
134 e80cfcfc bellard
}
135 e80cfcfc bellard
136 e80cfcfc bellard
static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = {
137 7c560456 blueswir1
    NULL,
138 7c560456 blueswir1
    NULL,
139 e80cfcfc bellard
    slavio_intctl_mem_readl,
140 e80cfcfc bellard
};
141 e80cfcfc bellard
142 e80cfcfc bellard
static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = {
143 7c560456 blueswir1
    NULL,
144 7c560456 blueswir1
    NULL,
145 e80cfcfc bellard
    slavio_intctl_mem_writel,
146 e80cfcfc bellard
};
147 e80cfcfc bellard
148 e80cfcfc bellard
// master system interrupt controller
149 e80cfcfc bellard
static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr)
150 e80cfcfc bellard
{
151 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
152 dd4131b3 blueswir1
    uint32_t saddr, ret;
153 e80cfcfc bellard
154 a8f48dcc blueswir1
    saddr = addr >> 2;
155 e80cfcfc bellard
    switch (saddr) {
156 e80cfcfc bellard
    case 0:
157 9a87ce9b blueswir1
        ret = s->intregm_pending & ~MASTER_DISABLE;
158 dd4131b3 blueswir1
        break;
159 e80cfcfc bellard
    case 1:
160 80be36b8 blueswir1
        ret = s->intregm_disabled & MASTER_IRQ_MASK;
161 dd4131b3 blueswir1
        break;
162 e80cfcfc bellard
    case 4:
163 dd4131b3 blueswir1
        ret = s->target_cpu;
164 dd4131b3 blueswir1
        break;
165 e80cfcfc bellard
    default:
166 dd4131b3 blueswir1
        ret = 0;
167 dd4131b3 blueswir1
        break;
168 e80cfcfc bellard
    }
169 1569fc29 blueswir1
    DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
170 dd4131b3 blueswir1
171 dd4131b3 blueswir1
    return ret;
172 e80cfcfc bellard
}
173 e80cfcfc bellard
174 77f193da blueswir1
static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
175 77f193da blueswir1
                                      uint32_t val)
176 e80cfcfc bellard
{
177 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
178 e80cfcfc bellard
    uint32_t saddr;
179 e80cfcfc bellard
180 a8f48dcc blueswir1
    saddr = addr >> 2;
181 1569fc29 blueswir1
    DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
182 e80cfcfc bellard
    switch (saddr) {
183 e80cfcfc bellard
    case 2: // clear (enable)
184 f930d07e blueswir1
        // Force clear unused bits
185 9a87ce9b blueswir1
        val &= MASTER_IRQ_MASK;
186 f930d07e blueswir1
        s->intregm_disabled &= ~val;
187 77f193da blueswir1
        DPRINTF("Enabled master irq mask %x, curmask %x\n", val,
188 77f193da blueswir1
                s->intregm_disabled);
189 f930d07e blueswir1
        slavio_check_interrupts(s);
190 f930d07e blueswir1
        break;
191 e80cfcfc bellard
    case 3: // set (disable, clear pending)
192 f930d07e blueswir1
        // Force clear unused bits
193 9a87ce9b blueswir1
        val &= MASTER_IRQ_MASK;
194 f930d07e blueswir1
        s->intregm_disabled |= val;
195 f930d07e blueswir1
        s->intregm_pending &= ~val;
196 327ac2e7 blueswir1
        slavio_check_interrupts(s);
197 77f193da blueswir1
        DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
198 77f193da blueswir1
                s->intregm_disabled);
199 f930d07e blueswir1
        break;
200 e80cfcfc bellard
    case 4:
201 f930d07e blueswir1
        s->target_cpu = val & (MAX_CPUS - 1);
202 327ac2e7 blueswir1
        slavio_check_interrupts(s);
203 f930d07e blueswir1
        DPRINTF("Set master irq cpu %d\n", s->target_cpu);
204 f930d07e blueswir1
        break;
205 e80cfcfc bellard
    default:
206 f930d07e blueswir1
        break;
207 e80cfcfc bellard
    }
208 e80cfcfc bellard
}
209 e80cfcfc bellard
210 e80cfcfc bellard
static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = {
211 7c560456 blueswir1
    NULL,
212 7c560456 blueswir1
    NULL,
213 e80cfcfc bellard
    slavio_intctlm_mem_readl,
214 e80cfcfc bellard
};
215 e80cfcfc bellard
216 e80cfcfc bellard
static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = {
217 7c560456 blueswir1
    NULL,
218 7c560456 blueswir1
    NULL,
219 e80cfcfc bellard
    slavio_intctlm_mem_writel,
220 e80cfcfc bellard
};
221 e80cfcfc bellard
222 376253ec aliguori
void slavio_pic_info(Monitor *mon, void *opaque)
223 e80cfcfc bellard
{
224 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
225 e80cfcfc bellard
    int i;
226 e80cfcfc bellard
227 e80cfcfc bellard
    for (i = 0; i < MAX_CPUS; i++) {
228 376253ec aliguori
        monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
229 376253ec aliguori
                       s->slaves[i]->intreg_pending);
230 e80cfcfc bellard
    }
231 376253ec aliguori
    monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
232 376253ec aliguori
                   s->intregm_pending, s->intregm_disabled);
233 e80cfcfc bellard
}
234 e80cfcfc bellard
235 376253ec aliguori
void slavio_irq_info(Monitor *mon, void *opaque)
236 e80cfcfc bellard
{
237 e80cfcfc bellard
#ifndef DEBUG_IRQ_COUNT
238 376253ec aliguori
    monitor_printf(mon, "irq statistic code not compiled.\n");
239 e80cfcfc bellard
#else
240 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
241 e80cfcfc bellard
    int i;
242 e80cfcfc bellard
    int64_t count;
243 e80cfcfc bellard
244 376253ec aliguori
    monitor_printf(mon, "IRQ statistics:\n");
245 e80cfcfc bellard
    for (i = 0; i < 32; i++) {
246 e80cfcfc bellard
        count = s->irq_count[i];
247 e80cfcfc bellard
        if (count > 0)
248 376253ec aliguori
            monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
249 e80cfcfc bellard
    }
250 e80cfcfc bellard
#endif
251 e80cfcfc bellard
}
252 e80cfcfc bellard
253 a8f48dcc blueswir1
static void slavio_check_interrupts(SLAVIO_INTCTLState *s)
254 66321a11 bellard
{
255 327ac2e7 blueswir1
    uint32_t pending = s->intregm_pending, pil_pending;
256 327ac2e7 blueswir1
    unsigned int i, j;
257 66321a11 bellard
258 66321a11 bellard
    pending &= ~s->intregm_disabled;
259 66321a11 bellard
260 b3a23197 blueswir1
    DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled);
261 ba3c64fb bellard
    for (i = 0; i < MAX_CPUS; i++) {
262 327ac2e7 blueswir1
        pil_pending = 0;
263 9a87ce9b blueswir1
        if (pending && !(s->intregm_disabled & MASTER_DISABLE) &&
264 b3a23197 blueswir1
            (i == s->target_cpu)) {
265 b3a23197 blueswir1
            for (j = 0; j < 32; j++) {
266 327ac2e7 blueswir1
                if (pending & (1 << j))
267 327ac2e7 blueswir1
                    pil_pending |= 1 << s->intbit_to_level[j];
268 b3a23197 blueswir1
            }
269 b3a23197 blueswir1
        }
270 a8f48dcc blueswir1
        pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
271 327ac2e7 blueswir1
272 327ac2e7 blueswir1
        for (j = 0; j < MAX_PILS; j++) {
273 327ac2e7 blueswir1
            if (pil_pending & (1 << j)) {
274 327ac2e7 blueswir1
                if (!(s->pil_out[i] & (1 << j)))
275 327ac2e7 blueswir1
                    qemu_irq_raise(s->cpu_irqs[i][j]);
276 327ac2e7 blueswir1
            } else {
277 327ac2e7 blueswir1
                if (s->pil_out[i] & (1 << j))
278 327ac2e7 blueswir1
                    qemu_irq_lower(s->cpu_irqs[i][j]);
279 ba3c64fb bellard
            }
280 ba3c64fb bellard
        }
281 327ac2e7 blueswir1
        s->pil_out[i] = pil_pending;
282 ba3c64fb bellard
    }
283 66321a11 bellard
}
284 66321a11 bellard
285 e80cfcfc bellard
/*
286 e80cfcfc bellard
 * "irq" here is the bit number in the system interrupt register to
287 e80cfcfc bellard
 * separate serial and keyboard interrupts sharing a level.
288 e80cfcfc bellard
 */
289 d7edfd27 blueswir1
static void slavio_set_irq(void *opaque, int irq, int level)
290 e80cfcfc bellard
{
291 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
292 b3a23197 blueswir1
    uint32_t mask = 1 << irq;
293 b3a23197 blueswir1
    uint32_t pil = s->intbit_to_level[irq];
294 b3a23197 blueswir1
295 b3a23197 blueswir1
    DPRINTF("Set cpu %d irq %d -> pil %d level %d\n", s->target_cpu, irq, pil,
296 b3a23197 blueswir1
            level);
297 b3a23197 blueswir1
    if (pil > 0) {
298 b3a23197 blueswir1
        if (level) {
299 327ac2e7 blueswir1
#ifdef DEBUG_IRQ_COUNT
300 327ac2e7 blueswir1
            s->irq_count[pil]++;
301 327ac2e7 blueswir1
#endif
302 b3a23197 blueswir1
            s->intregm_pending |= mask;
303 a8f48dcc blueswir1
            s->slaves[s->target_cpu]->intreg_pending |= 1 << pil;
304 b3a23197 blueswir1
        } else {
305 b3a23197 blueswir1
            s->intregm_pending &= ~mask;
306 a8f48dcc blueswir1
            s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil);
307 b3a23197 blueswir1
        }
308 b3a23197 blueswir1
        slavio_check_interrupts(s);
309 e80cfcfc bellard
    }
310 e80cfcfc bellard
}
311 e80cfcfc bellard
312 d7edfd27 blueswir1
static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
313 ba3c64fb bellard
{
314 ba3c64fb bellard
    SLAVIO_INTCTLState *s = opaque;
315 ba3c64fb bellard
316 b3a23197 blueswir1
    DPRINTF("Set cpu %d local timer level %d\n", cpu, level);
317 d7edfd27 blueswir1
318 e3a79bca blueswir1
    if (level) {
319 e3a79bca blueswir1
        s->intregm_pending |= s->cputimer_mbit;
320 a8f48dcc blueswir1
        s->slaves[cpu]->intreg_pending |= s->cputimer_lbit;
321 e3a79bca blueswir1
    } else {
322 e3a79bca blueswir1
        s->intregm_pending &= ~s->cputimer_mbit;
323 a8f48dcc blueswir1
        s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit;
324 e3a79bca blueswir1
    }
325 d7edfd27 blueswir1
326 ba3c64fb bellard
    slavio_check_interrupts(s);
327 ba3c64fb bellard
}
328 ba3c64fb bellard
329 e80cfcfc bellard
static void slavio_intctl_save(QEMUFile *f, void *opaque)
330 e80cfcfc bellard
{
331 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
332 e80cfcfc bellard
    int i;
333 3b46e624 ths
334 e80cfcfc bellard
    for (i = 0; i < MAX_CPUS; i++) {
335 a8f48dcc blueswir1
        qemu_put_be32s(f, &s->slaves[i]->intreg_pending);
336 e80cfcfc bellard
    }
337 e80cfcfc bellard
    qemu_put_be32s(f, &s->intregm_pending);
338 e80cfcfc bellard
    qemu_put_be32s(f, &s->intregm_disabled);
339 e80cfcfc bellard
    qemu_put_be32s(f, &s->target_cpu);
340 e80cfcfc bellard
}
341 e80cfcfc bellard
342 e80cfcfc bellard
static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id)
343 e80cfcfc bellard
{
344 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
345 e80cfcfc bellard
    int i;
346 e80cfcfc bellard
347 e80cfcfc bellard
    if (version_id != 1)
348 e80cfcfc bellard
        return -EINVAL;
349 e80cfcfc bellard
350 e80cfcfc bellard
    for (i = 0; i < MAX_CPUS; i++) {
351 a8f48dcc blueswir1
        qemu_get_be32s(f, &s->slaves[i]->intreg_pending);
352 e80cfcfc bellard
    }
353 e80cfcfc bellard
    qemu_get_be32s(f, &s->intregm_pending);
354 e80cfcfc bellard
    qemu_get_be32s(f, &s->intregm_disabled);
355 e80cfcfc bellard
    qemu_get_be32s(f, &s->target_cpu);
356 327ac2e7 blueswir1
    slavio_check_interrupts(s);
357 e80cfcfc bellard
    return 0;
358 e80cfcfc bellard
}
359 e80cfcfc bellard
360 e80cfcfc bellard
static void slavio_intctl_reset(void *opaque)
361 e80cfcfc bellard
{
362 e80cfcfc bellard
    SLAVIO_INTCTLState *s = opaque;
363 e80cfcfc bellard
    int i;
364 e80cfcfc bellard
365 e80cfcfc bellard
    for (i = 0; i < MAX_CPUS; i++) {
366 a8f48dcc blueswir1
        s->slaves[i]->intreg_pending = 0;
367 e80cfcfc bellard
    }
368 9a87ce9b blueswir1
    s->intregm_disabled = ~MASTER_IRQ_MASK;
369 e80cfcfc bellard
    s->intregm_pending = 0;
370 e80cfcfc bellard
    s->target_cpu = 0;
371 327ac2e7 blueswir1
    slavio_check_interrupts(s);
372 e80cfcfc bellard
}
373 e80cfcfc bellard
374 5dcb6b91 blueswir1
void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
375 d537cf6c pbrook
                         const uint32_t *intbit_to_level,
376 d7edfd27 blueswir1
                         qemu_irq **irq, qemu_irq **cpu_irq,
377 b3a23197 blueswir1
                         qemu_irq **parent_irq, unsigned int cputimer)
378 e80cfcfc bellard
{
379 e80cfcfc bellard
    int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
380 e80cfcfc bellard
    SLAVIO_INTCTLState *s;
381 a8f48dcc blueswir1
    SLAVIO_CPUINTCTLState *slave;
382 e80cfcfc bellard
383 e80cfcfc bellard
    s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
384 e80cfcfc bellard
385 e0353fe2 blueswir1
    s->intbit_to_level = intbit_to_level;
386 e80cfcfc bellard
    for (i = 0; i < MAX_CPUS; i++) {
387 a8f48dcc blueswir1
        slave = qemu_mallocz(sizeof(SLAVIO_CPUINTCTLState));
388 a8f48dcc blueswir1
389 a8f48dcc blueswir1
        slave->cpu = i;
390 a8f48dcc blueswir1
        slave->master = s;
391 a8f48dcc blueswir1
392 77f193da blueswir1
        slavio_intctl_io_memory = cpu_register_io_memory(0,
393 77f193da blueswir1
                                                         slavio_intctl_mem_read,
394 77f193da blueswir1
                                                         slavio_intctl_mem_write,
395 a8f48dcc blueswir1
                                                         slave);
396 a8f48dcc blueswir1
        cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
397 a8f48dcc blueswir1
                                     slavio_intctl_io_memory);
398 a8f48dcc blueswir1
399 a8f48dcc blueswir1
        s->slaves[i] = slave;
400 b3a23197 blueswir1
        s->cpu_irqs[i] = parent_irq[i];
401 e80cfcfc bellard
    }
402 e80cfcfc bellard
403 77f193da blueswir1
    slavio_intctlm_io_memory = cpu_register_io_memory(0,
404 77f193da blueswir1
                                                      slavio_intctlm_mem_read,
405 77f193da blueswir1
                                                      slavio_intctlm_mem_write,
406 77f193da blueswir1
                                                      s);
407 5aca8c3b blueswir1
    cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
408 e80cfcfc bellard
409 77f193da blueswir1
    register_savevm("slavio_intctl", addr, 1, slavio_intctl_save,
410 77f193da blueswir1
                    slavio_intctl_load, s);
411 e80cfcfc bellard
    qemu_register_reset(slavio_intctl_reset, s);
412 d537cf6c pbrook
    *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
413 d7edfd27 blueswir1
414 d7edfd27 blueswir1
    *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS);
415 e3a79bca blueswir1
    s->cputimer_mbit = 1 << cputimer;
416 e3a79bca blueswir1
    s->cputimer_lbit = 1 << intbit_to_level[cputimer];
417 e80cfcfc bellard
    slavio_intctl_reset(s);
418 e80cfcfc bellard
    return s;
419 e80cfcfc bellard
}