Improved PCI IRQ steering a bit and made the PCI IDE IRQ operation correct.
This commit is contained in:
@@ -172,16 +172,9 @@ void ide_irq_raise(IDE *ide)
|
||||
|
||||
if (!(ide->fdisk&2))
|
||||
{
|
||||
if (PCI && (ide->board < 2))
|
||||
if (PCI && (ide->board < 2) && ide_bus_master_set_irq)
|
||||
{
|
||||
if (pci_irq_is_level(ide_irq[ide->board]))
|
||||
{
|
||||
picintlevel(1 << ide_irq[ide->board]);
|
||||
}
|
||||
else
|
||||
{
|
||||
picint(1 << ide_irq[ide->board]);
|
||||
}
|
||||
pci_ide_set_irq(ide->board, ide_irq[ide->board]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -211,7 +204,14 @@ void ide_irq_lower(IDE *ide)
|
||||
|
||||
ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board);
|
||||
|
||||
picintc(1 << ide_irq[ide->board]);
|
||||
if (PCI && (ide->board < 2) && ide_bus_master_set_irq)
|
||||
{
|
||||
pci_ide_clear_irq(ide->board, ide_irq[ide->board]);
|
||||
}
|
||||
else
|
||||
{
|
||||
picintc(1 << ide_irq[ide->board]);
|
||||
}
|
||||
ide->irqstat=0;
|
||||
}
|
||||
|
||||
@@ -233,11 +233,25 @@ void ide_irq_update(IDE *ide)
|
||||
|
||||
if (ide->irqstat && !pending && !(ide->fdisk & 2))
|
||||
{
|
||||
picint(1 << ide_irq[ide->board]);
|
||||
if (PCI && (ide->board < 2) && ide_bus_master_set_irq)
|
||||
{
|
||||
pci_ide_set_irq(ide->board, ide_irq[ide->board]);
|
||||
}
|
||||
else
|
||||
{
|
||||
picint(1 << ide_irq[ide->board]);
|
||||
}
|
||||
}
|
||||
else if (pending)
|
||||
{
|
||||
picintc(1 << ide_irq[ide->board]);
|
||||
if (PCI && (ide->board < 2) && ide_bus_master_set_irq)
|
||||
{
|
||||
pci_ide_clear_irq(ide->board, ide_irq[ide->board]);
|
||||
}
|
||||
else
|
||||
{
|
||||
picintc(1 << ide_irq[ide->board]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
||||
53
src/pci.c
53
src/pci.c
@@ -12,7 +12,7 @@ static int pci_irq_routing[32];
|
||||
/* static int pci_irq_active[32]; */
|
||||
static int pci_irqs[4];
|
||||
static int pci_card_valid[32];
|
||||
static int pci_irq_hold[16];
|
||||
static uint64_t pci_irq_hold[16];
|
||||
|
||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
|
||||
int pci_burst_time, pci_nonburst_time;
|
||||
@@ -187,15 +187,46 @@ void pci_issue_irq(int irq)
|
||||
}
|
||||
}
|
||||
|
||||
void pci_ide_set_irq(int ide_board, int irq)
|
||||
{
|
||||
if (pci_irq_is_level(irq) && (pci_irq_hold[irq] & (1LL << (0x20LL + ide_board))))
|
||||
{
|
||||
/* IRQ already held, do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pci_irq_is_level(irq) || !pci_irq_hold[irq])
|
||||
{
|
||||
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
|
||||
pci_issue_irq(irq);
|
||||
}
|
||||
|
||||
/* If the IRQ is level-triggered, mark that this card is holding it. */
|
||||
if (pci_irq_is_level(irq))
|
||||
{
|
||||
pci_irq_hold[irq] |= (1LL << (0x20LL + ide_board));
|
||||
}
|
||||
}
|
||||
|
||||
void pci_set_irq(int card, int pci_int)
|
||||
{
|
||||
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
|
||||
|
||||
if (pci_irq_routing[card] && (pci_irqs[irq] != PCI_IRQ_DISABLED))
|
||||
{
|
||||
pci_issue_irq(pci_irqs[irq]);
|
||||
if (pci_irq_is_level(pci_irqs[irq]) && (pci_irq_hold[pci_irqs[irq]] & (1 << card)))
|
||||
{
|
||||
/* IRQ already held, do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the IRQ is set to edge, there is no need to hold it. */
|
||||
if (!pci_irq_is_level(pci_irqs[irq]) || !pci_irq_hold[pci_irqs[irq]])
|
||||
{
|
||||
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
|
||||
pci_issue_irq(pci_irqs[irq]);
|
||||
}
|
||||
|
||||
/* If the IRQ is level-triggered, mark that this card is holding it. */
|
||||
if (pci_irq_is_level(pci_irqs[irq]))
|
||||
{
|
||||
pci_irq_hold[pci_irqs[irq]] |= (1 << card);
|
||||
@@ -203,6 +234,22 @@ void pci_set_irq(int card, int pci_int)
|
||||
}
|
||||
}
|
||||
|
||||
void pci_ide_clear_irq(int ide_board, int irq)
|
||||
{
|
||||
if (pci_irq_is_level(irq))
|
||||
{
|
||||
pci_irq_hold[irq] &= ~(1LL << (0x20LL + ide_board));
|
||||
if (!pci_irq_hold[irq])
|
||||
{
|
||||
picintc(1 << irq);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
picintc(1 << irq);
|
||||
}
|
||||
}
|
||||
|
||||
void pci_clear_irq(int card, int pci_int)
|
||||
{
|
||||
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
|
||||
|
||||
@@ -6,7 +6,9 @@ void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv),
|
||||
int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
void pci_set_irq_routing(int card, int irq);
|
||||
void pci_set_card_routing(int card, int pci_int);
|
||||
void pci_ide_set_irq(int ide_board, int irq);
|
||||
void pci_set_irq(int card, int pci_int);
|
||||
void pci_ide_clear_irq(int ide_board, int irq);
|
||||
void pci_clear_irq(int card, int pci_int);
|
||||
int pci_irq_is_level(int irq);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user