Skip to content

Commit 64a5a17

Browse files
heathrow: fix interrupt masking.
Use int_mask1/int_mask2 directly without changing int_events1/int_events2. That permits interrupt generation on int_mask1/int_mask2 changes.
1 parent a649a68 commit 64a5a17

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed

devices/ioctrl/heathrow.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
316316
switch (offset & 0xFC) {
317317
case MIO_INT_MASK2:
318318
this->int_mask2 |= BYTESWAP_32(value) & ~MACIO_INT_MODE;
319+
this->signal_cpu_int();
319320
break;
320321
case MIO_INT_CLEAR2:
321322
this->int_events2 &= ~(BYTESWAP_32(value) & 0x7FFFFFFFUL);
@@ -325,6 +326,7 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
325326
this->int_mask1 = BYTESWAP_32(value);
326327
// copy IntMode bit to InterruptMask2 register
327328
this->int_mask2 = (this->int_mask2 & ~MACIO_INT_MODE) | (this->int_mask1 & MACIO_INT_MODE);
329+
this->signal_cpu_int();
328330
break;
329331
case MIO_INT_CLEAR1:
330332
if ((this->int_mask1 & MACIO_INT_MODE) && (value & MACIO_INT_CLR)) {
@@ -455,7 +457,6 @@ void HeathrowIC::ack_int(uint32_t irq_id, uint8_t irq_line_state)
455457
} else {
456458
this->int_events2 &= ~irq_id;
457459
}
458-
this->int_events2 &= this->int_mask2;
459460
// update IRQ line state
460461
if (irq_line_state) {
461462
this->int_levels2 |= irq_id;
@@ -476,7 +477,6 @@ void HeathrowIC::ack_int(uint32_t irq_id, uint8_t irq_line_state)
476477
} else {
477478
this->int_events1 &= ~irq_id;
478479
}
479-
this->int_events1 &= this->int_mask1;
480480
// update IRQ line state
481481
if (irq_line_state) {
482482
this->int_levels1 |= irq_id;
@@ -531,7 +531,6 @@ void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state)
531531
} else {
532532
this->int_events2 &= ~irq_id;
533533
}
534-
this->int_events2 &= this->int_mask2;
535534
// update IRQ line state
536535
if (irq_line_state) {
537536
this->int_levels2 |= irq_id;
@@ -548,7 +547,6 @@ void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state)
548547
} else {
549548
this->int_events1 &= ~irq_id;
550549
}
551-
this->int_events1 &= this->int_mask1;
552550
// update IRQ line state
553551
if (irq_line_state) {
554552
this->int_levels1 |= irq_id;
@@ -591,7 +589,7 @@ void HeathrowIC::ack_dma_int(uint32_t irq_id, uint8_t irq_line_state)
591589
}
592590

593591
void HeathrowIC::signal_cpu_int() {
594-
if (this->int_events1 || this->int_events2) {
592+
if ((this->int_events1 & this->int_mask1) || (this->int_events2 & this->int_mask2)) {
595593
if (!this->cpu_int_latch) {
596594
this->cpu_int_latch = true;
597595
ppc_assert_int();
@@ -603,7 +601,8 @@ void HeathrowIC::signal_cpu_int() {
603601

604602
void HeathrowIC::clear_cpu_int()
605603
{
606-
if (!this->int_events1 && !this->int_events2) {
604+
if (!(this->int_events1 & this->int_mask1) && !(this->int_events2 & this->int_mask2) &&
605+
this->cpu_int_latch) {
607606
this->cpu_int_latch = false;
608607
ppc_release_int();
609608
LOG_F(5, "Heathrow: CPU INT latch cleared");

0 commit comments

Comments
 (0)