PCI PIRQ's are now always level when PCI IRQ steering is present, and MIRQ's are now edge/level according to the device that issues them, per the Intel datasheets, fixes annoyingly long wait at POST on PCI Pentium AMI BIOS'es because of secondary IDE.

This commit is contained in:
OBattler
2019-10-30 04:26:36 +01:00
parent 13402ff207
commit ddbecb039a
3 changed files with 27 additions and 31 deletions

View File

@@ -10,13 +10,13 @@
* word 0 - base address * word 0 - base address
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer * word 1 - bits 1-15 = byte count, bit 31 = end of transfer
* *
* Version: @(#)hdc_ide_sff8038i.c 1.0.0 2019/05/12 * Version: @(#)hdc_ide_sff8038i.c 1.0.1 2019/10/30
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* *
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2018 Miran Grca. * Copyright 2016-2019 Miran Grca.
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
@@ -371,12 +371,12 @@ sff_bus_master_set_irq(int channel, void *priv)
channel &= 0x01; channel &= 0x01;
if (dev->status & 0x04) { if (dev->status & 0x04) {
if (channel && pci_use_mirq(0)) if (channel && pci_use_mirq(0))
pci_set_mirq(0); pci_set_mirq(0, 0);
else else
picint(1 << (14 + channel)); picint(1 << (14 + channel));
} else { } else {
if ((channel & 1) && pci_use_mirq(0)) if ((channel & 1) && pci_use_mirq(0))
pci_clear_mirq(0); pci_clear_mirq(0, 0);
else else
picintc(1 << (14 + channel)); picintc(1 << (14 + channel));
} }

View File

@@ -8,15 +8,15 @@
* *
* Implementation the PCI bus. * Implementation the PCI bus.
* *
* Version: @(#)pci.c 1.0.1 2018/11/05 * Version: @(#)pci.c 1.0.2 2019/10/30
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * Sarah Walker, <tommowalker@tommowalker.co.uk>
* *
* Copyright 2016-2018 Miran Grca. * Copyright 2016-2019 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen. * Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
@@ -321,10 +321,9 @@ pci_use_mirq(uint8_t mirq)
void void
pci_set_mirq(uint8_t mirq) pci_set_mirq(uint8_t mirq, int level)
{ {
uint8_t irq_line = 0; uint8_t irq_line = 0;
uint8_t level = 0;
if (! pci_mirqs[mirq].enabled) { if (! pci_mirqs[mirq].enabled) {
pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq);
@@ -339,20 +338,21 @@ pci_set_mirq(uint8_t mirq)
irq_line = pci_mirqs[mirq].irq_line; irq_line = pci_mirqs[mirq].irq_line;
pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line); pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
if (pci_irq_is_level(irq_line) && if (level && (pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
/* IRQ already held, do nothing. */ /* IRQ already held, do nothing. */
pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq); pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq);
return; return;
} }
pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq); pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq);
level = pci_irq_is_level(irq_line);
if (!level || !pci_irq_hold[irq_line]) { if (!level || !pci_irq_hold[irq_line]) {
pci_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); pci_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
picintlevel(1 << irq_line); if (level)
picintlevel(1 << irq_line);
else
picint(1 << irq_line);
} else if (level && pci_irq_hold[irq_line]) { } else if (level && pci_irq_hold[irq_line]) {
pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq); pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq);
} }
@@ -376,7 +376,6 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
uint8_t irq_line = 0; uint8_t irq_line = 0;
uint8_t level = 0; uint8_t level = 0;
if (! last_pci_card) { if (! last_pci_card) {
pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int);
return; return;
@@ -418,9 +417,9 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int); pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int);
if (pci_type & PCI_NO_IRQ_STEERING) if (pci_type & PCI_NO_IRQ_STEERING)
level = 0; level = 0; /* PCI without IRQ steering - IRQ always edge. */
else else
level = pci_irq_is_level(irq_line); level = 1; /* PCI with IRQ steering - IRQ always level per the Intel datasheets. */
if (!level || !pci_irq_hold[irq_line]) { if (!level || !pci_irq_hold[irq_line]) {
pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
@@ -444,10 +443,9 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
void void
pci_clear_mirq(uint8_t mirq) pci_clear_mirq(uint8_t mirq, int level)
{ {
uint8_t irq_line = 0; uint8_t irq_line = 0;
uint8_t level = 0;
if (mirq > 1) { if (mirq > 1) {
pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq);
@@ -467,14 +465,12 @@ pci_clear_mirq(uint8_t mirq)
irq_line = pci_mirqs[mirq].irq_line; irq_line = pci_mirqs[mirq].irq_line;
pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line); pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
if (pci_irq_is_level(irq_line) && if (level && !(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
!(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
/* IRQ not held, do nothing. */ /* IRQ not held, do nothing. */
pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq); pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq);
return; return;
} }
level = pci_irq_is_level(irq_line);
if (level) { if (level) {
pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq); pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq);
pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq)); pci_irq_hold[irq_line] &= ~(1 << (0x1E + mirq));
@@ -543,9 +539,9 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
} }
if (pci_type & PCI_NO_IRQ_STEERING) if (pci_type & PCI_NO_IRQ_STEERING)
level = 0; level = 0; /* PCI without IRQ steering - IRQ always edge. */
else else
level = pci_irq_is_level(irq_line); level = 1; /* PCI with IRQ steering - IRQ always level per the Intel datasheets. */
if (level) { if (level) {
pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int); pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int);
pci_irq_hold[irq_line] &= ~(1 << card); pci_irq_hold[irq_line] &= ~(1 << card);

View File

@@ -8,15 +8,15 @@
* *
* Definitions for the PCI handler module. * Definitions for the PCI handler module.
* *
* Version: @(#)pci.h 1.0.0 2018/10/21 * Version: @(#)pci.h 1.0.1 2019/10/30
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * Sarah Walker, <tommowalker@tommowalker.co.uk>
* *
* Copyright 2016-2018 Miran Grca. * Copyright 2016-2019 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen. * Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2019 Sarah Walker.
*/ */
#ifndef EMU_PCI_H #ifndef EMU_PCI_H
# define EMU_PCI_H # define EMU_PCI_H
@@ -76,9 +76,9 @@ extern uint8_t pci_use_mirq(uint8_t mirq);
extern int pci_irq_is_level(int irq); extern int pci_irq_is_level(int irq);
extern void pci_set_mirq(uint8_t mirq); extern void pci_set_mirq(uint8_t mirq, int level);
extern void pci_set_irq(uint8_t card, uint8_t pci_int); extern void pci_set_irq(uint8_t card, uint8_t pci_int);
extern void pci_clear_mirq(uint8_t mirq); extern void pci_clear_mirq(uint8_t mirq, int level);
extern void pci_clear_irq(uint8_t card, uint8_t pci_int); extern void pci_clear_irq(uint8_t card, uint8_t pci_int);
extern void pci_reset(void); extern void pci_reset(void);