Changes to PCI and two new functions to accomodate the VIA MVP3 chipset.
This commit is contained in:
69
src/pci.c
69
src/pci.c
@@ -8,15 +8,15 @@
|
|||||||
*
|
*
|
||||||
* Implementation the PCI bus.
|
* Implementation the PCI bus.
|
||||||
*
|
*
|
||||||
* Version: @(#)pci.c 1.0.4 2019/11/06
|
* Version: @(#)pci.c 1.0.6 2020/01/11
|
||||||
*
|
*
|
||||||
* 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-2019 Miran Grca.
|
* Copyright 2016-2020 Miran Grca.
|
||||||
* Copyright 2017-2019 Fred N. van Kempen.
|
* Copyright 2017-2020 Fred N. van Kempen.
|
||||||
* Copyright 2008-2019 Sarah Walker.
|
* Copyright 2008-2020 Sarah Walker.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -58,7 +58,7 @@ static pci_card_t pci_cards[32];
|
|||||||
static uint8_t last_pci_card = 0;
|
static uint8_t last_pci_card = 0;
|
||||||
static uint8_t pci_card_to_slot_mapping[32];
|
static uint8_t pci_card_to_slot_mapping[32];
|
||||||
static uint8_t elcr[2] = { 0, 0 };
|
static uint8_t elcr[2] = { 0, 0 };
|
||||||
static uint8_t pci_irqs[4];
|
static uint8_t pci_irqs[4], pci_irq_level[4];
|
||||||
static uint64_t pci_irq_hold[16];
|
static uint64_t pci_irq_hold[16];
|
||||||
static pci_mirq_t pci_mirqs[3];
|
static pci_mirq_t pci_mirqs[3];
|
||||||
static int pci_type,
|
static int pci_type,
|
||||||
@@ -68,7 +68,7 @@ static int pci_type,
|
|||||||
pci_bus,
|
pci_bus,
|
||||||
pci_enable,
|
pci_enable,
|
||||||
pci_key;
|
pci_key;
|
||||||
static int trc_reg = 0;
|
static int trc_reg = 0, elcr_enabled = 1;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_PCI_LOG
|
#ifdef ENABLE_PCI_LOG
|
||||||
@@ -278,6 +278,13 @@ pci_set_irq_routing(int pci_int, int irq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
pci_set_irq_level(int pci_int, int level)
|
||||||
|
{
|
||||||
|
pci_irq_level[pci_int - 1] = !!level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pci_enable_mirq(int mirq)
|
pci_enable_mirq(int mirq)
|
||||||
{
|
{
|
||||||
@@ -297,13 +304,20 @@ pci_irq_is_level(int irq)
|
|||||||
{
|
{
|
||||||
int real_irq = irq & 7;
|
int real_irq = irq & 7;
|
||||||
|
|
||||||
if ((irq <= 2) || (irq == 8) || (irq == 13))
|
if (elcr_enabled) {
|
||||||
return 0;
|
if ((irq <= 2) || (irq == 8) || (irq == 13))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (irq > 7)
|
if (irq > 7)
|
||||||
return !!(elcr[1] & (1 << real_irq));
|
return !!(elcr[1] & (1 << real_irq));
|
||||||
|
|
||||||
return !!(elcr[0] & (1 << real_irq));
|
return !!(elcr[0] & (1 << real_irq));
|
||||||
|
} else {
|
||||||
|
if (irq < 8)
|
||||||
|
return (pic.icw1 & 8) ? 1 : 0;
|
||||||
|
else
|
||||||
|
return (pic2.icw1 & 8) ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -401,6 +415,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
|
|||||||
pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
|
pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
|
||||||
|
|
||||||
irq_line = pci_irqs[irq_routing];
|
irq_line = pci_irqs[irq_routing];
|
||||||
|
level = pci_irq_level[irq_routing];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq_line > 0x0f) {
|
if (irq_line > 0x0f) {
|
||||||
@@ -416,10 +431,6 @@ 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)
|
|
||||||
level = 0; /* PCI without IRQ steering - IRQ always edge. */
|
|
||||||
else
|
|
||||||
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 ");
|
||||||
|
|
||||||
@@ -433,7 +444,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the IRQ is level-triggered, mark that this card is holding it. */
|
/* If the IRQ is level-triggered, mark that this card is holding it. */
|
||||||
if (pci_irq_is_level(irq_line)) {
|
if (level) {
|
||||||
pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int);
|
pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int);
|
||||||
pci_irq_hold[irq_line] |= (1ULL << card);
|
pci_irq_hold[irq_line] |= (1ULL << card);
|
||||||
} else {
|
} else {
|
||||||
@@ -522,6 +533,7 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
|
|||||||
pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
|
pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
|
||||||
|
|
||||||
irq_line = pci_irqs[irq_routing];
|
irq_line = pci_irqs[irq_routing];
|
||||||
|
level = pci_irq_level[irq_routing];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq_line > 0x0f) {
|
if (irq_line > 0x0f) {
|
||||||
@@ -531,17 +543,12 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
|
|||||||
|
|
||||||
pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line);
|
pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line);
|
||||||
|
|
||||||
if (pci_irq_is_level(irq_line) &&
|
if (level && !(pci_irq_hold[irq_line] & (1ULL << card))) {
|
||||||
!(pci_irq_hold[irq_line] & (1ULL << card))) {
|
|
||||||
/* IRQ not held, do nothing. */
|
/* IRQ not held, do nothing. */
|
||||||
pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int);
|
pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_type & PCI_NO_IRQ_STEERING)
|
|
||||||
level = 0; /* PCI without IRQ steering - IRQ always edge. */
|
|
||||||
else
|
|
||||||
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);
|
||||||
@@ -559,6 +566,13 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
pci_elcr_set_enabled(int enabled)
|
||||||
|
{
|
||||||
|
elcr_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pci_reset(void)
|
pci_reset(void)
|
||||||
{
|
{
|
||||||
@@ -635,7 +649,10 @@ trc_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
if (!(trc_reg & 4) && (val & 4))
|
if (!(trc_reg & 4) && (val & 4))
|
||||||
trc_reset(val);
|
trc_reset(val);
|
||||||
|
|
||||||
trc_reg = val & 0xfb;
|
trc_reg = val & 0xfd;
|
||||||
|
|
||||||
|
if (val & 2)
|
||||||
|
trc_reg &= 0xfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -681,13 +698,17 @@ pci_init(int type)
|
|||||||
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
|
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 0; c < 4; c++)
|
for (c = 0; c < 4; c++) {
|
||||||
pci_irqs[c] = PCI_IRQ_DISABLED;
|
pci_irqs[c] = PCI_IRQ_DISABLED;
|
||||||
|
pci_irq_level[c] = (type & PCI_NO_IRQ_STEERING) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (c = 0; c < 3; c++) {
|
for (c = 0; c < 3; c++) {
|
||||||
pci_mirqs[c].enabled = 0;
|
pci_mirqs[c].enabled = 0;
|
||||||
pci_mirqs[c].irq_line = PCI_IRQ_DISABLED;
|
pci_mirqs[c].irq_line = PCI_IRQ_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elcr_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
10
src/pci.h
10
src/pci.h
@@ -8,15 +8,15 @@
|
|||||||
*
|
*
|
||||||
* Definitions for the PCI handler module.
|
* Definitions for the PCI handler module.
|
||||||
*
|
*
|
||||||
* Version: @(#)pci.h 1.0.1 2019/10/30
|
* Version: @(#)pci.h 1.0.2 2020/01/11
|
||||||
*
|
*
|
||||||
* 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-2019 Miran Grca.
|
* Copyright 2016-2020 Miran Grca.
|
||||||
* Copyright 2017-2019 Fred N. van Kempen.
|
* Copyright 2017-2020 Fred N. van Kempen.
|
||||||
* Copyright 2008-2019 Sarah Walker.
|
* Copyright 2008-2020 Sarah Walker.
|
||||||
*/
|
*/
|
||||||
#ifndef EMU_PCI_H
|
#ifndef EMU_PCI_H
|
||||||
# define EMU_PCI_H
|
# define EMU_PCI_H
|
||||||
@@ -68,6 +68,7 @@ extern int pci_burst_time,
|
|||||||
|
|
||||||
|
|
||||||
extern void pci_set_irq_routing(int pci_int, int irq);
|
extern void pci_set_irq_routing(int pci_int, int irq);
|
||||||
|
extern void pci_set_irq_level(int pci_int, int level);
|
||||||
|
|
||||||
extern void pci_enable_mirq(int mirq);
|
extern void pci_enable_mirq(int mirq);
|
||||||
extern void pci_set_mirq_routing(int mirq, int irq);
|
extern void pci_set_mirq_routing(int mirq, int irq);
|
||||||
@@ -89,6 +90,7 @@ extern void pci_close(void);
|
|||||||
extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||||
|
|
||||||
extern void trc_init(void);
|
extern void trc_init(void);
|
||||||
|
extern void pci_elcr_set_enabled(int enabled);
|
||||||
|
|
||||||
|
|
||||||
#endif /*EMU_PCI_H*/
|
#endif /*EMU_PCI_H*/
|
||||||
|
|||||||
Reference in New Issue
Block a user