PCI/AGP bridge support, part 3

This commit is contained in:
RichardG867
2020-09-20 19:13:09 -03:00
parent f459c676c4
commit eb79cb1782
7 changed files with 88 additions and 63 deletions

View File

@@ -108,7 +108,7 @@ via_apollo_setup(via_apollo_t *dev)
dev->pci_conf[0x34] = 0xa0;
if (dev->id == 0x0691) {
dev->pci_conf[0x56] = 0x01;
dev->pci_conf[0x56] = 0x01;
dev->pci_conf[0x57] = 0x01;
}
dev->pci_conf[0x5a] = 0x01;
@@ -448,12 +448,19 @@ via_apollo_init(const device_t *info)
dev->id = info->local;
if (dev->id == 0x0597)
device_add(&via_vp3_agp_device);
else if (dev->id == 0x0598)
device_add(&via_mvp3_agp_device);
else if (dev->id == 0x0691)
device_add(&via_apro_agp_device);
switch (dev->id) {
case 0x0597:
device_add(&via_vp3_agp_device);
break;
case 0x0598:
device_add(&via_mvp3_agp_device);
break;
case 0x0691:
device_add(&via_apro_agp_device);
break;
}
via_apollo_setup(dev);
via_apollo_reset(dev);

View File

@@ -40,7 +40,7 @@
#define AGP_BRIDGE_VIA_598 0x11068598
#define AGP_BRIDGE_VIA_691 0x11068691
#define AGP_BRIDGE_VIA(x) (((x) >> 4) == 0x1106)
#define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106)
#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_VIA_597)
@@ -110,11 +110,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x19:
/* Set our bus number. */
pci_bridge_log("PCI Bridge %d: switching from bus %02X to %02X\n", dev->bus_index, dev->regs[addr], val);
if (dev->regs[addr])
pci_bus_number_to_index_mapping[dev->regs[addr]] = 0xff;
if (val)
pci_bus_number_to_index_mapping[val] = dev->bus_index;
pci_bridge_log("PCI Bridge %d: remapping from bus %02X to %02X\n", dev->bus_index, dev->regs[addr], val);
pci_remap_bus(dev->bus_index, val);
break;
case 0x1c: case 0x1d: case 0x20: case 0x22:
@@ -208,6 +205,7 @@ pci_bridge_reset(void *priv)
dev->regs[0x02] = dev->local;
dev->regs[0x03] = dev->local >> 8;
/* command and status */
switch (dev->local) {
case PCI_BRIDGE_DEC_21150:
dev->regs[0x06] = 0x80;
@@ -227,6 +225,7 @@ pci_bridge_reset(void *priv)
break;
case AGP_BRIDGE_VIA_597:
case AGP_BRIDGE_VIA_598:
case AGP_BRIDGE_VIA_691:
dev->regs[0x04] = 0x07;
dev->regs[0x06] = 0x20;
@@ -234,17 +233,16 @@ pci_bridge_reset(void *priv)
break;
}
/* class */
dev->regs[0x0a] = 0x04; /* PCI-PCI bridge */
dev->regs[0x0b] = 0x06; /* bridge device */
dev->regs[0x0e] = 0x01;
dev->regs[0x0e] = 0x01; /* bridge header */
/* IO BARs */
if (AGP_BRIDGE(dev->local)) {
if (AGP_BRIDGE(dev->local))
dev->regs[0x1c] = 0xf0;
} else {
else
dev->regs[0x1c] = dev->regs[0x1d] = 0x01;
}
if (!AGP_BRIDGE_VIA(dev->local)) {
dev->regs[0x1e] = AGP_BRIDGE(dev->local) ? 0xa0 : 0x80;
@@ -259,9 +257,7 @@ pci_bridge_reset(void *priv)
dev->regs[0x24] = dev->regs[0x26] = 0x01;
}
if (dev->local == AGP_BRIDGE_INTEL_440LX)
dev->regs[0x3e] = 0x80;
/* power management */
if (dev->local == PCI_BRIDGE_DEC_21150) {
dev->regs[0x34] = 0xdc;
dev->regs[0x43] = 0x02;
@@ -279,7 +275,7 @@ pci_bridge_init(const device_t *info)
memset(dev, 0, sizeof(pci_bridge_t));
dev->local = info->local;
dev->bus_index = last_pci_bus++;
dev->bus_index = pci_register_bus();
pci_bridge_log("PCI Bridge %d: init()\n", dev->bus_index);
pci_bridge_reset(dev);
@@ -299,7 +295,8 @@ pci_bridge_init(const device_t *info)
for (i = 0; i < slot_count; i++) {
/* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */
pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]);
pci_register_bus_slot(dev->bus_index, i, /*AGP_BRIDGE(dev->local) ? PCI_CARD_SPECIAL : */PCI_CARD_NORMAL,
/* Use _NOBRIDGE for VIA AGP bridges, as they don't like PCI bridges under them. */
pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE_VIA(dev->local) ? PCI_CARD_NORMAL_NOBRIDGE : PCI_CARD_NORMAL,
interrupts[i & interrupt_mask],
interrupts[(i + 1) & interrupt_mask],
interrupts[(i + 2) & interrupt_mask],
@@ -328,7 +325,7 @@ const device_t dec21150_device =
/* AGP bridges */
const device_t i440lx_agp_device =
{
"Intel 82443LX AGP Bridge",
"Intel 82443LX/EX AGP Bridge",
DEVICE_PCI,
AGP_BRIDGE_INTEL_440LX,
pci_bridge_init,
@@ -342,7 +339,7 @@ const device_t i440lx_agp_device =
const device_t i440bx_agp_device =
{
"Intel 82443BX AGP Bridge",
"Intel 82443BX/ZX AGP Bridge",
DEVICE_PCI,
AGP_BRIDGE_INTEL_440BX,
pci_bridge_init,

View File

@@ -97,8 +97,8 @@
#define IDS_2121 2121 // "Save changes\nThis will hard..."
#define IDS_2122 2122 // "Discard changes\nAll changes..."
#define IDS_2123 2123 // "Cancel\nGo back to the..."
#define IDS_2124 2124 // "About " EMU_NAME
#define IDS_2125 2125 // EMU_NAME " v" EMU_VERSION
#define IDS_2124 2124 // "About 86Box"
#define IDS_2125 2125 // "86Box v" EMU_VERSION
#define IDS_2126 2126 // "An emulator of old computers..."
#define IDS_2127 2127 // "OK"
#define IDS_2128 2128 // "Hardware not available"

View File

@@ -29,6 +29,7 @@
#define PCI_NO_IRQ_STEERING 0x8000
#define PCI_CAN_SWITCH_TYPE 0x10000
#define PCI_NO_BRIDGES 0x20000
#define PCI_CONFIG_TYPE_1 1
#define PCI_CONFIG_TYPE_2 2
@@ -50,6 +51,7 @@ enum {
PCI_CARD_NORTHBRIDGE = 0,
PCI_CARD_SOUTHBRIDGE,
PCI_CARD_NORMAL,
PCI_CARD_NORMAL_NOBRIDGE,
PCI_CARD_ONBOARD,
PCI_CARD_SCSI,
PCI_CARD_SOUND,
@@ -76,8 +78,6 @@ typedef union {
extern int pci_burst_time,
pci_nonburst_time;
extern uint8_t last_pci_bus;
extern uint8_t pci_bus_number_to_index_mapping[256];
extern void pci_set_irq_routing(int pci_int, int irq);
@@ -91,19 +91,21 @@ 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, int level);
extern void pci_set_irq(int 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, int level);
extern void pci_clear_irq(int card, uint8_t pci_int);
extern uint8_t pci_get_int(int card, uint8_t pci_int);
extern void pci_clear_irq(uint8_t card, uint8_t pci_int);
extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int);
extern void pci_reset(void);
extern void pci_init(int type);
extern uint8_t pci_register_bus();
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
extern void pci_register_slot(int card, int type,
int inta, int intb, int intc, int intd);
extern void pci_register_bus_slot(int bus, int card, int type,
int inta, int intb, int intc, int intd);
extern void pci_close(void);
extern int 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);

View File

@@ -1064,11 +1064,13 @@ machine_at_ficpa2012_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x01, PCI_CARD_SPECIAL, 1, 2, 3, 4);
device_add(&via_vp3_device);
device_add(&via_vt82c586b_device);
device_add(&keyboard_ps2_pci_device);

View File

@@ -53,12 +53,10 @@ typedef struct {
int pci_burst_time,
pci_nonburst_time;
uint8_t last_pci_bus = 1;
uint8_t pci_bus_number_to_index_mapping[256];
static pci_card_t pci_cards[32];
static uint8_t pci_pmc = 0, last_pci_card = 0, last_normal_pci_card = 0;
static uint8_t pci_card_to_slot_mapping[256][32];
static uint8_t pci_pmc = 0, last_pci_card = 0, last_normal_pci_card = 0, last_pci_bus = 1;
static uint8_t pci_card_to_slot_mapping[256][32], pci_bus_number_to_index_mapping[256];
static uint8_t elcr[2] = { 0, 0 };
static uint8_t pci_irqs[4], pci_irq_level[4];
static uint64_t pci_irq_hold[16];
@@ -444,7 +442,7 @@ pci_set_mirq(uint8_t mirq, int level)
void
pci_set_irq(int card, uint8_t pci_int)
pci_set_irq(uint8_t card, uint8_t pci_int)
{
uint8_t slot = 0;
uint8_t irq_routing = 0;
@@ -458,7 +456,7 @@ pci_set_irq(int card, uint8_t pci_int)
}
pci_log("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card);
slot = pci_card_to_slot_mapping[(card >> 5) & 0xff][card & 31];
slot = card;
if (slot == 0xff) {
pci_log("pci_set_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int);
return;
@@ -562,7 +560,7 @@ pci_clear_mirq(uint8_t mirq, int level)
void
pci_clear_irq(int card, uint8_t pci_int)
pci_clear_irq(uint8_t card, uint8_t pci_int)
{
uint8_t slot = 0;
uint8_t irq_routing = 0;
@@ -576,7 +574,7 @@ pci_clear_irq(int card, uint8_t pci_int)
}
pci_log("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card);
slot = pci_card_to_slot_mapping[(card >> 5) & 0xff][card & 31];
slot = card;
if (slot == 0xff) {
pci_log("pci_clear_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int);
return;
@@ -629,12 +627,8 @@ pci_clear_irq(int card, uint8_t pci_int)
uint8_t
pci_get_int(int card, uint8_t pci_int)
pci_get_int(uint8_t slot, uint8_t pci_int)
{
uint8_t slot = pci_card_to_slot_mapping[(card >> 5) & 0xff][card & 31];
if (slot == 0xff)
return 0xff;
return pci_cards[slot].irq_routing[pci_int - PCI_INTA];
}
@@ -710,10 +704,11 @@ pci_slots_clear(void)
uint8_t i, j;
last_pci_card = last_normal_pci_card = 0;
last_pci_bus = 1;
for (i = 0; i < 32; i++) {
pci_cards[i].id = 0xFF;
pci_cards[i].type = 0xFF;
pci_cards[i].id = 0xff;
pci_cards[i].type = 0xff;
for (j = 0; j < 4; j++)
pci_cards[i].irq_routing[j] = 0;
@@ -726,8 +721,8 @@ pci_slots_clear(void)
i = 0;
do {
for (j = 0; j < 32; j++)
pci_card_to_slot_mapping[i][j] = 0xFF;
pci_bus_number_to_index_mapping[i] = 0xFF;
pci_card_to_slot_mapping[i][j] = 0xff;
pci_bus_number_to_index_mapping[i] = 0xff;
} while (i++ < 0xff);
pci_bus_number_to_index_mapping[0] = 0; /* always map bus 0 to index 0 */
@@ -868,6 +863,27 @@ pci_init(int type)
}
uint8_t
pci_register_bus()
{
return last_pci_bus++;
}
void
pci_remap_bus(uint8_t bus_index, uint8_t bus_number)
{
uint8_t i = 1;
do {
if (pci_bus_number_to_index_mapping[i] == bus_index)
pci_bus_number_to_index_mapping[i] = 0xff;
} while (i++ < 0xff);
if ((bus_number > 0) && (bus_number < 0xff))
pci_bus_number_to_index_mapping[bus_number] = bus_index;
}
void
pci_register_slot(int card, int type, int inta, int intb, int intc, int intd)
{
@@ -900,7 +916,7 @@ pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc,
}
int
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)
{
pci_card_t *dev;
@@ -911,12 +927,12 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
if (! PCI) {
pci_log("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))));
return 0xffff;
return 0xff;
}
if (! last_pci_card) {
pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))));
return 0xffff;
return 0xff;
}
for (i = 0; i < last_pci_card; i++) {
@@ -924,6 +940,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
if (!dev->read && !dev->write) {
if (((dev->type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) ||
((dev->type == PCI_CARD_NORMAL_NOBRIDGE) && (add_type >= PCI_ADD_NORMAL) && (add_type != PCI_ADD_BRIDGE)) ||
((dev->type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) ||
((dev->type == PCI_CARD_SCSI) && (add_type == PCI_ADD_SCSI)) ||
((dev->type == PCI_CARD_SOUND) && (add_type == PCI_ADD_SOUND)) ||
@@ -931,9 +948,9 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
((dev->type == PCI_CARD_NORTHBRIDGE) && (add_type == PCI_ADD_NORTHBRIDGE)) ||
((dev->type == PCI_CARD_SOUTHBRIDGE) && (add_type == PCI_ADD_SOUTHBRIDGE)) ||
((dev->bus == 0) && (dev->id == add_type) && (add_type < PCI_ADD_NORTHBRIDGE))) {
/* Add DEC 21150 PCI bridge if this is the last available NORMAL slot and
the machine supports IRQ steering (the bridge code requires steering). */
if (!(pci_type & PCI_NO_IRQ_STEERING) && (dev->type == PCI_CARD_NORMAL) && (add_type != PCI_ADD_BRIDGE) && (i == last_normal_pci_card)) {
/* Add DEC 21150 PCI bridge if this is the last available NORMAL
slot, unless PCI bridges are blocked for this machine. */
if (!(pci_type & PCI_NO_BRIDGES) && (dev->type == PCI_CARD_NORMAL) && (add_type != PCI_ADD_BRIDGE) && (i == last_normal_pci_card)) {
pci_log("pci_add_card(): Reached last NORMAL slot, adding bridge to pci_cards[%i]\n", i);
device_add_inst(&dec21150_device, last_pci_bus);
continue;
@@ -943,12 +960,12 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
dev->write = write;
dev->priv = priv;
pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (bus %02X slot %02X) [%s]\n", i, dev->bus, dev->id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))));
return (dev->bus << 5) | dev->id;
return i;
}
}
}
pci_log("pci_add_card(): Adding PCI CARD failed (unable to find a suitable PCI slot) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))));
return 0xffff;
return 0xff;
}

View File

@@ -990,7 +990,7 @@ BEGIN
IDS_2122 "Discard changes\nAll changes made to the settings will be lost."
IDS_2123 "Cancel\nGo back to the Settings window."
IDS_2124 "About 86Box"
IDS_2125 "86Box v2.10"
IDS_2125 "86Box v" EMU_VERSION
IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information."
IDS_2127 "OK"
IDS_2128 "Hardware not available"