Commit 0d0a7e69e853639b123798877e019c3c7ee6634a
1 parent
15a1956a
Don't set IRQs on device reset and loadvm/savevm
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Showing
1 changed file
with
22 additions
and
18 deletions
hw/slavio_intctl.c
@@ -80,7 +80,7 @@ typedef struct SLAVIO_CPUINTCTLState { | @@ -80,7 +80,7 @@ typedef struct SLAVIO_CPUINTCTLState { | ||
80 | #define CPU_IRQ_INT15_IN 0x0004000 | 80 | #define CPU_IRQ_INT15_IN 0x0004000 |
81 | #define CPU_IRQ_INT15_MASK 0x80000000 | 81 | #define CPU_IRQ_INT15_MASK 0x80000000 |
82 | 82 | ||
83 | -static void slavio_check_interrupts(SLAVIO_INTCTLState *s); | 83 | +static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs); |
84 | 84 | ||
85 | // per-cpu interrupt controller | 85 | // per-cpu interrupt controller |
86 | static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr) | 86 | static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr) |
@@ -116,14 +116,14 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, | @@ -116,14 +116,14 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, | ||
116 | val |= CPU_IRQ_INT15_MASK; | 116 | val |= CPU_IRQ_INT15_MASK; |
117 | val &= CPU_SOFTIRQ_MASK; | 117 | val &= CPU_SOFTIRQ_MASK; |
118 | s->intreg_pending &= ~val; | 118 | s->intreg_pending &= ~val; |
119 | - slavio_check_interrupts(s->master); | 119 | + slavio_check_interrupts(s->master, 1); |
120 | DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val, | 120 | DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val, |
121 | s->intreg_pending); | 121 | s->intreg_pending); |
122 | break; | 122 | break; |
123 | case 2: // set softint | 123 | case 2: // set softint |
124 | val &= CPU_SOFTIRQ_MASK; | 124 | val &= CPU_SOFTIRQ_MASK; |
125 | s->intreg_pending |= val; | 125 | s->intreg_pending |= val; |
126 | - slavio_check_interrupts(s->master); | 126 | + slavio_check_interrupts(s->master, 1); |
127 | DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val, | 127 | DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val, |
128 | s->intreg_pending); | 128 | s->intreg_pending); |
129 | break; | 129 | break; |
@@ -185,20 +185,20 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, | @@ -185,20 +185,20 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, | ||
185 | s->intregm_disabled &= ~val; | 185 | s->intregm_disabled &= ~val; |
186 | DPRINTF("Enabled master irq mask %x, curmask %x\n", val, | 186 | DPRINTF("Enabled master irq mask %x, curmask %x\n", val, |
187 | s->intregm_disabled); | 187 | s->intregm_disabled); |
188 | - slavio_check_interrupts(s); | 188 | + slavio_check_interrupts(s, 1); |
189 | break; | 189 | break; |
190 | case 3: // set (disable, clear pending) | 190 | case 3: // set (disable, clear pending) |
191 | // Force clear unused bits | 191 | // Force clear unused bits |
192 | val &= MASTER_IRQ_MASK; | 192 | val &= MASTER_IRQ_MASK; |
193 | s->intregm_disabled |= val; | 193 | s->intregm_disabled |= val; |
194 | s->intregm_pending &= ~val; | 194 | s->intregm_pending &= ~val; |
195 | - slavio_check_interrupts(s); | 195 | + slavio_check_interrupts(s, 1); |
196 | DPRINTF("Disabled master irq mask %x, curmask %x\n", val, | 196 | DPRINTF("Disabled master irq mask %x, curmask %x\n", val, |
197 | s->intregm_disabled); | 197 | s->intregm_disabled); |
198 | break; | 198 | break; |
199 | case 4: | 199 | case 4: |
200 | s->target_cpu = val & (MAX_CPUS - 1); | 200 | s->target_cpu = val & (MAX_CPUS - 1); |
201 | - slavio_check_interrupts(s); | 201 | + slavio_check_interrupts(s, 1); |
202 | DPRINTF("Set master irq cpu %d\n", s->target_cpu); | 202 | DPRINTF("Set master irq cpu %d\n", s->target_cpu); |
203 | break; | 203 | break; |
204 | default: | 204 | default: |
@@ -249,7 +249,7 @@ void slavio_irq_info(Monitor *mon, void *opaque) | @@ -249,7 +249,7 @@ void slavio_irq_info(Monitor *mon, void *opaque) | ||
249 | #endif | 249 | #endif |
250 | } | 250 | } |
251 | 251 | ||
252 | -static void slavio_check_interrupts(SLAVIO_INTCTLState *s) | 252 | +static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs) |
253 | { | 253 | { |
254 | uint32_t pending = s->intregm_pending, pil_pending; | 254 | uint32_t pending = s->intregm_pending, pil_pending; |
255 | unsigned int i, j; | 255 | unsigned int i, j; |
@@ -268,13 +268,17 @@ static void slavio_check_interrupts(SLAVIO_INTCTLState *s) | @@ -268,13 +268,17 @@ static void slavio_check_interrupts(SLAVIO_INTCTLState *s) | ||
268 | } | 268 | } |
269 | pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16; | 269 | pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16; |
270 | 270 | ||
271 | - for (j = 0; j < MAX_PILS; j++) { | ||
272 | - if (pil_pending & (1 << j)) { | ||
273 | - if (!(s->pil_out[i] & (1 << j))) | ||
274 | - qemu_irq_raise(s->cpu_irqs[i][j]); | ||
275 | - } else { | ||
276 | - if (s->pil_out[i] & (1 << j)) | ||
277 | - qemu_irq_lower(s->cpu_irqs[i][j]); | 271 | + if (set_irqs) { |
272 | + for (j = 0; j < MAX_PILS; j++) { | ||
273 | + if (pil_pending & (1 << j)) { | ||
274 | + if (!(s->pil_out[i] & (1 << j))) { | ||
275 | + qemu_irq_raise(s->cpu_irqs[i][j]); | ||
276 | + } | ||
277 | + } else { | ||
278 | + if (s->pil_out[i] & (1 << j)) { | ||
279 | + qemu_irq_lower(s->cpu_irqs[i][j]); | ||
280 | + } | ||
281 | + } | ||
278 | } | 282 | } |
279 | } | 283 | } |
280 | s->pil_out[i] = pil_pending; | 284 | s->pil_out[i] = pil_pending; |
@@ -304,7 +308,7 @@ static void slavio_set_irq(void *opaque, int irq, int level) | @@ -304,7 +308,7 @@ static void slavio_set_irq(void *opaque, int irq, int level) | ||
304 | s->intregm_pending &= ~mask; | 308 | s->intregm_pending &= ~mask; |
305 | s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil); | 309 | s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil); |
306 | } | 310 | } |
307 | - slavio_check_interrupts(s); | 311 | + slavio_check_interrupts(s, 1); |
308 | } | 312 | } |
309 | } | 313 | } |
310 | 314 | ||
@@ -322,7 +326,7 @@ static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) | @@ -322,7 +326,7 @@ static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) | ||
322 | s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit; | 326 | s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit; |
323 | } | 327 | } |
324 | 328 | ||
325 | - slavio_check_interrupts(s); | 329 | + slavio_check_interrupts(s, 1); |
326 | } | 330 | } |
327 | 331 | ||
328 | static void slavio_intctl_save(QEMUFile *f, void *opaque) | 332 | static void slavio_intctl_save(QEMUFile *f, void *opaque) |
@@ -352,7 +356,7 @@ static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id) | @@ -352,7 +356,7 @@ static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id) | ||
352 | qemu_get_be32s(f, &s->intregm_pending); | 356 | qemu_get_be32s(f, &s->intregm_pending); |
353 | qemu_get_be32s(f, &s->intregm_disabled); | 357 | qemu_get_be32s(f, &s->intregm_disabled); |
354 | qemu_get_be32s(f, &s->target_cpu); | 358 | qemu_get_be32s(f, &s->target_cpu); |
355 | - slavio_check_interrupts(s); | 359 | + slavio_check_interrupts(s, 0); |
356 | return 0; | 360 | return 0; |
357 | } | 361 | } |
358 | 362 | ||
@@ -367,7 +371,7 @@ static void slavio_intctl_reset(void *opaque) | @@ -367,7 +371,7 @@ static void slavio_intctl_reset(void *opaque) | ||
367 | s->intregm_disabled = ~MASTER_IRQ_MASK; | 371 | s->intregm_disabled = ~MASTER_IRQ_MASK; |
368 | s->intregm_pending = 0; | 372 | s->intregm_pending = 0; |
369 | s->target_cpu = 0; | 373 | s->target_cpu = 0; |
370 | - slavio_check_interrupts(s); | 374 | + slavio_check_interrupts(s, 0); |
371 | } | 375 | } |
372 | 376 | ||
373 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, | 377 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, |