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:
@@ -10,13 +10,13 @@
|
||||
* word 0 - base address
|
||||
* 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/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -371,12 +371,12 @@ sff_bus_master_set_irq(int channel, void *priv)
|
||||
channel &= 0x01;
|
||||
if (dev->status & 0x04) {
|
||||
if (channel && pci_use_mirq(0))
|
||||
pci_set_mirq(0);
|
||||
pci_set_mirq(0, 0);
|
||||
else
|
||||
picint(1 << (14 + channel));
|
||||
} else {
|
||||
if ((channel & 1) && pci_use_mirq(0))
|
||||
pci_clear_mirq(0);
|
||||
pci_clear_mirq(0, 0);
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
}
|
||||
|
34
src/pci.c
34
src/pci.c
@@ -8,15 +8,15 @@
|
||||
*
|
||||
* 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>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -321,10 +321,9 @@ pci_use_mirq(uint8_t mirq)
|
||||
|
||||
|
||||
void
|
||||
pci_set_mirq(uint8_t mirq)
|
||||
pci_set_mirq(uint8_t mirq, int level)
|
||||
{
|
||||
uint8_t irq_line = 0;
|
||||
uint8_t level = 0;
|
||||
|
||||
if (! pci_mirqs[mirq].enabled) {
|
||||
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;
|
||||
pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
|
||||
|
||||
if (pci_irq_is_level(irq_line) &&
|
||||
(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
if (level && (pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
/* IRQ already held, do nothing. */
|
||||
pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq);
|
||||
return;
|
||||
}
|
||||
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]) {
|
||||
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. */
|
||||
if (level)
|
||||
picintlevel(1 << irq_line);
|
||||
else
|
||||
picint(1 << irq_line);
|
||||
} else if (level && pci_irq_hold[irq_line]) {
|
||||
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 level = 0;
|
||||
|
||||
|
||||
if (! last_pci_card) {
|
||||
pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int);
|
||||
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);
|
||||
|
||||
if (pci_type & PCI_NO_IRQ_STEERING)
|
||||
level = 0;
|
||||
level = 0; /* PCI without IRQ steering - IRQ always edge. */
|
||||
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]) {
|
||||
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
|
||||
pci_clear_mirq(uint8_t mirq)
|
||||
pci_clear_mirq(uint8_t mirq, int level)
|
||||
{
|
||||
uint8_t irq_line = 0;
|
||||
uint8_t level = 0;
|
||||
|
||||
if (mirq > 1) {
|
||||
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;
|
||||
pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line);
|
||||
|
||||
if (pci_irq_is_level(irq_line) &&
|
||||
!(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
if (level && !(pci_irq_hold[irq_line] & (1ULL << (0x1E + mirq)))) {
|
||||
/* IRQ not held, do nothing. */
|
||||
pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq);
|
||||
return;
|
||||
}
|
||||
|
||||
level = pci_irq_is_level(irq_line);
|
||||
if (level) {
|
||||
pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", 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)
|
||||
level = 0;
|
||||
level = 0; /* PCI without IRQ steering - IRQ always edge. */
|
||||
else
|
||||
level = pci_irq_is_level(irq_line);
|
||||
level = 1; /* PCI with IRQ steering - IRQ always level per the Intel datasheets. */
|
||||
if (level) {
|
||||
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);
|
||||
|
12
src/pci.h
12
src/pci.h
@@ -8,15 +8,15 @@
|
||||
*
|
||||
* 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>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
*/
|
||||
#ifndef 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 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_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_reset(void);
|
||||
|
Reference in New Issue
Block a user