Revision 9a87ce9b
b/hw/slavio_intctl.c | ||
---|---|---|
68 | 68 |
#define INTCTLM_MAXADDR 0x13 |
69 | 69 |
#define INTCTLM_SIZE (INTCTLM_MAXADDR + 1) |
70 | 70 |
#define INTCTLM_MASK 0x1f |
71 |
#define MASTER_IRQ_MASK ~0x4fb2007f |
|
72 |
#define MASTER_DISABLE 0x80000000 |
|
73 |
#define CPU_IRQ_MASK 0xfffe0000 |
|
74 |
#define CPU_IRQ_INT15_IN 0x0004000 |
|
75 |
#define CPU_IRQ_INT15_MASK 0x80000000 |
|
76 |
|
|
71 | 77 |
static void slavio_check_interrupts(void *opaque); |
72 | 78 |
|
73 | 79 |
// per-cpu interrupt controller |
... | ... | |
103 | 109 |
DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, val); |
104 | 110 |
switch (saddr) { |
105 | 111 |
case 1: // clear pending softints |
106 |
if (val & 0x4000)
|
|
107 |
val |= 80000000;
|
|
108 |
val &= 0xfffe0000;
|
|
112 |
if (val & CPU_IRQ_INT15_IN)
|
|
113 |
val |= CPU_IRQ_INT15_MASK;
|
|
114 |
val &= CPU_IRQ_MASK;
|
|
109 | 115 |
s->intreg_pending[cpu] &= ~val; |
110 | 116 |
slavio_check_interrupts(s); |
111 | 117 |
DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
112 | 118 |
break; |
113 | 119 |
case 2: // set softint |
114 |
val &= 0xfffe0000;
|
|
120 |
val &= CPU_IRQ_MASK;
|
|
115 | 121 |
s->intreg_pending[cpu] |= val; |
116 | 122 |
slavio_check_interrupts(s); |
117 | 123 |
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); |
... | ... | |
142 | 148 |
saddr = (addr & INTCTLM_MAXADDR) >> 2; |
143 | 149 |
switch (saddr) { |
144 | 150 |
case 0: |
145 |
ret = s->intregm_pending & 0x7fffffff;
|
|
151 |
ret = s->intregm_pending & ~MASTER_DISABLE;
|
|
146 | 152 |
break; |
147 | 153 |
case 1: |
148 | 154 |
ret = s->intregm_disabled; |
... | ... | |
169 | 175 |
switch (saddr) { |
170 | 176 |
case 2: // clear (enable) |
171 | 177 |
// Force clear unused bits |
172 |
val &= ~0x4fb2007f;
|
|
178 |
val &= MASTER_IRQ_MASK;
|
|
173 | 179 |
s->intregm_disabled &= ~val; |
174 | 180 |
DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); |
175 | 181 |
slavio_check_interrupts(s); |
176 | 182 |
break; |
177 | 183 |
case 3: // set (disable, clear pending) |
178 | 184 |
// Force clear unused bits |
179 |
val &= ~0x4fb2007f;
|
|
185 |
val &= MASTER_IRQ_MASK;
|
|
180 | 186 |
s->intregm_disabled |= val; |
181 | 187 |
s->intregm_pending &= ~val; |
182 | 188 |
slavio_check_interrupts(s); |
... | ... | |
244 | 250 |
DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled); |
245 | 251 |
for (i = 0; i < MAX_CPUS; i++) { |
246 | 252 |
pil_pending = 0; |
247 |
if (pending && !(s->intregm_disabled & 0x80000000) &&
|
|
253 |
if (pending && !(s->intregm_disabled & MASTER_DISABLE) &&
|
|
248 | 254 |
(i == s->target_cpu)) { |
249 | 255 |
for (j = 0; j < 32; j++) { |
250 | 256 |
if (pending & (1 << j)) |
251 | 257 |
pil_pending |= 1 << s->intbit_to_level[j]; |
252 | 258 |
} |
253 | 259 |
} |
254 |
pil_pending |= (s->intreg_pending[i] >> 16) & 0xfffe;
|
|
260 |
pil_pending |= (s->intreg_pending[i] & CPU_IRQ_MASK) >> 16;
|
|
255 | 261 |
|
256 | 262 |
for (j = 0; j < MAX_PILS; j++) { |
257 | 263 |
if (pil_pending & (1 << j)) { |
... | ... | |
346 | 352 |
for (i = 0; i < MAX_CPUS; i++) { |
347 | 353 |
s->intreg_pending[i] = 0; |
348 | 354 |
} |
349 |
s->intregm_disabled = ~0xffb2007f;
|
|
355 |
s->intregm_disabled = ~MASTER_IRQ_MASK;
|
|
350 | 356 |
s->intregm_pending = 0; |
351 | 357 |
s->target_cpu = 0; |
352 | 358 |
slavio_check_interrupts(s); |
Also available in: Unified diff