Fixed the PCI IRQ routing code so that it is aware of IRQ sharing.
This commit is contained in:
38
src/pci.c
38
src/pci.c
@@ -9,9 +9,10 @@ void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv);
|
|||||||
uint8_t (*pci_card_read[32])(int func, int addr, void *priv);
|
uint8_t (*pci_card_read[32])(int func, int addr, void *priv);
|
||||||
void *pci_priv[32];
|
void *pci_priv[32];
|
||||||
static int pci_irq_routing[32];
|
static int pci_irq_routing[32];
|
||||||
static int pci_irq_active[32];
|
/* static int pci_irq_active[32]; */
|
||||||
static int pci_irqs[4];
|
static int pci_irqs[4];
|
||||||
static int pci_card_valid[32];
|
static int pci_card_valid[32];
|
||||||
|
static int pci_irq_hold[16];
|
||||||
|
|
||||||
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
|
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
|
||||||
int pci_burst_time, pci_nonburst_time;
|
int pci_burst_time, pci_nonburst_time;
|
||||||
@@ -67,6 +68,8 @@ void elcr_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
/* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */
|
/* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */
|
||||||
elcr[port & 1] = val;
|
elcr[port & 1] = val;
|
||||||
|
|
||||||
|
printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E');
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t elcr_read(uint16_t port, void *priv)
|
uint8_t elcr_read(uint16_t port, void *priv)
|
||||||
@@ -82,10 +85,17 @@ void elcr_reset(void)
|
|||||||
pic_reset();
|
pic_reset();
|
||||||
elcr[0] = elcr[1] = 0;
|
elcr[0] = elcr[1] = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
pci_irq_active[i] = 0;
|
pci_irq_active[i] = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
pci_irq_hold[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||||
@@ -147,21 +157,24 @@ void pci_set_card_routing(int card, int pci_int)
|
|||||||
pci_irq_routing[card] = pci_int;
|
pci_irq_routing[card] = pci_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pci_issue_irq(int irq)
|
int pci_irq_is_level(int irq)
|
||||||
{
|
{
|
||||||
int real_irq = irq & 7;
|
int real_irq = irq & 7;
|
||||||
int irq_elcr = 0;
|
/* int irq_elcr = 0; */
|
||||||
|
|
||||||
if (irq > 7)
|
if (irq > 7)
|
||||||
{
|
{
|
||||||
irq_elcr = elcr[1] & (1 << real_irq);
|
return !!(elcr[1] & (1 << real_irq));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
irq_elcr = elcr[0] & (1 << real_irq);
|
return !!(elcr[0] & (1 << real_irq));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (irq_elcr)
|
void pci_issue_irq(int irq)
|
||||||
|
{
|
||||||
|
if (pci_irq_is_level(irq))
|
||||||
{
|
{
|
||||||
picintlevel(1 << irq);
|
picintlevel(1 << irq);
|
||||||
}
|
}
|
||||||
@@ -177,9 +190,10 @@ void pci_set_irq(int card, int pci_int)
|
|||||||
|
|
||||||
if (pci_irq_routing[card])
|
if (pci_irq_routing[card])
|
||||||
{
|
{
|
||||||
if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card])
|
if (pci_irqs[irq] != PCI_IRQ_DISABLED/* && !pci_irq_active[card] */)
|
||||||
pci_issue_irq(pci_irqs[irq]);
|
pci_issue_irq(pci_irqs[irq]);
|
||||||
pci_irq_active[card] = 1;
|
/* pci_irq_active[card] = 1; */
|
||||||
|
pci_irq_hold[pci_irqs[irq]] |= (1 << card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,11 +201,13 @@ void pci_clear_irq(int card, int pci_int)
|
|||||||
{
|
{
|
||||||
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
|
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
|
||||||
|
|
||||||
|
/* Do not clear the interrupt until we're the last card being serviced. */
|
||||||
if (pci_irq_routing[card])
|
if (pci_irq_routing[card])
|
||||||
{
|
{
|
||||||
if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card])
|
pci_irq_hold[pci_irqs[irq]] &= ~(1 << card);
|
||||||
|
if (pci_irqs[irq] != PCI_IRQ_DISABLED/* && pci_irq_active[card]*/ && !pci_irq_hold[pci_irqs[irq]])
|
||||||
picintc(1 << pci_irqs[irq]);
|
picintc(1 << pci_irqs[irq]);
|
||||||
pci_irq_active[card] = 0;
|
/* pci_irq_active[card] = 0; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +238,7 @@ void pci_init(int type)
|
|||||||
pci_card_write[c] = NULL;
|
pci_card_write[c] = NULL;
|
||||||
pci_priv[c] = NULL;
|
pci_priv[c] = NULL;
|
||||||
pci_irq_routing[c] = 0;
|
pci_irq_routing[c] = 0;
|
||||||
pci_irq_active[c] = 0;
|
/* pci_irq_active[c] = 0; */
|
||||||
pci_card_valid[c] = 0;
|
pci_card_valid[c] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user