Extensively reworked the PCI bus emulation, fixes quite a few bugs, including incorrect IRQ routing for the last two slots on the Intel Advanced/ATX.

This commit is contained in:
OBattler
2017-08-30 04:49:20 +02:00
parent 18dbde0118
commit 0d84add8a3
25 changed files with 771 additions and 333 deletions

View File

@@ -181,7 +181,7 @@ static void i430fx_pci_reset(void)
void i430fx_init(void)
{
pci_add_specific(0, i430fx_read, i430fx_write, NULL);
pci_add_card(0, i430fx_read, i430fx_write, NULL);
i430fx_reset();

View File

@@ -169,7 +169,7 @@ static void i430hx_pci_reset(void)
void i430hx_init(void)
{
pci_add_specific(0, i430hx_read, i430hx_write, NULL);
pci_add_card(0, i430hx_read, i430hx_write, NULL);
i430hx_reset();

View File

@@ -166,7 +166,7 @@ static void i430lx_pci_reset(void)
void i430lx_init(void)
{
pci_add_specific(0, i430lx_read, i430lx_write, NULL);
pci_add_card(0, i430lx_read, i430lx_write, NULL);
i430lx_reset();

View File

@@ -164,7 +164,7 @@ static void i430nx_pci_reset(void)
void i430nx_init(void)
{
pci_add_specific(0, i430nx_read, i430nx_write, NULL);
pci_add_card(0, i430nx_read, i430nx_write, NULL);
i430nx_reset();

View File

@@ -172,7 +172,7 @@ static void i430vx_pci_reset(void)
void i430vx_init(void)
{
pci_add_specific(0, i430vx_read, i430vx_write, NULL);
pci_add_card(0, i430vx_read, i430vx_write, NULL);
i430vx_reset();

View File

@@ -173,7 +173,7 @@ static void i440fx_pci_reset(void)
void i440fx_init(void)
{
pci_add_specific(0, i440fx_read, i440fx_write, NULL);
pci_add_card(0, i440fx_read, i440fx_write, NULL);
i440fx_reset();

View File

@@ -50,6 +50,9 @@
#include "nvr.h"
#include "pc87306.h"
#include "pci.h"
#if 0
#include "pci_dummy.h"
#endif
#include "pic.h"
#include "piix.h"
#include "pit.h"
@@ -715,9 +718,11 @@ static void at_sis496_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xb);
pci_slot(0xd);
pci_slot(0xf);
pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
sis496_init();
trc_init();
}
@@ -735,10 +740,13 @@ static void at_premiere_common_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_2);
pci_slot(0xc);
pci_slot(0xe);
pci_slot(0x6);
sio_init(2, 0xc, 0xe, 0x6, 0);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0);
sio_init(2);
fdc37c665_init();
intel_batman_init();
device_add(&intel_flash_bxt_ami_device);
@@ -762,7 +770,7 @@ static void at_586mc1_init(void)
pci_slot(0xc);
pci_slot(0xe);
pci_slot(0x6);
sio_init(2, 0xc, 0xe, 0x6, 0);
sio_init(2);
device_add(&intel_flash_bxt_device);
secondary_ide_check();
}
@@ -781,12 +789,15 @@ static void at_endeavor_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xd);
pci_slot(0xe);
pci_slot(0xf);
pci_slot(0x10);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7, 0xd, 0xe, 0xf, 0x10);
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
@@ -797,11 +808,13 @@ static void at_zappa_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xd);
pci_slot(0xf);
pci_slot(0xe);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7, 0xd, 0xf, 0xe, 0);
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
@@ -811,12 +824,14 @@ static void at_mb500n_init(void)
{
at_ide_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x14);
pci_slot(0x13);
pci_slot(0x12);
pci_slot(0x11);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7, 0x14, 0x13, 0x12, 0x11);
piix_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
@@ -827,15 +842,14 @@ static void at_president_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(8);
pci_slot(9);
pci_slot(10);
pci_slot(11);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 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_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7, 8, 9, 10, 11);
#if 0
superio_detect_init();
#endif
piix_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
@@ -846,12 +860,14 @@ static void at_p54tp4xe_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(12);
pci_slot(11);
pci_slot(10);
pci_slot(9);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7, 12, 11, 10, 9);
piix_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
@@ -862,13 +878,15 @@ static void at_thor_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(8);
pci_slot(0xd);
pci_slot(0xe);
pci_slot(0xf);
pci_slot(0x10);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init_thor(7, 8, 0xd, 0xf, 0xe, 0x10);
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
@@ -880,12 +898,15 @@ static void at_ap53_init(void)
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x11);
pci_slot(0x12);
pci_slot(0x13);
pci_slot(0x14);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4);
i430hx_init();
piix3_init(7, 0x11, 0x12, 0x13, 0x14);
piix3_init(7);
fdc37c669_init();
device_add(&intel_flash_bxt_device);
}
@@ -897,12 +918,14 @@ static void at_p55t2s_init(void)
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x12);
pci_slot(0x11);
pci_slot(0x14);
pci_slot(0x13);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430hx_init();
piix3_init(7, 0x12, 0x11, 0x14, 0x13);
piix3_init(7);
pc87306_init();
device_add(&intel_flash_bxt_device);
}
@@ -913,12 +936,15 @@ static void at_acerm3a_init(void)
at_ide_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xc);
pci_slot(0xd);
pci_slot(0xe);
pci_slot(0xf);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0);
i430hx_init();
piix3_init(7, 0xc, 0xd, 0xe, 0xf);
piix3_init(7);
fdc37c932fr_init();
device_add(&intel_flash_bxb_device);
}
@@ -929,12 +955,15 @@ static void at_acerv35n_init(void)
at_ide_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x11);
pci_slot(0x12);
pci_slot(0x13);
pci_slot(0x14);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
i430hx_init();
piix3_init(7, 0x11, 0x12, 0x13, 0x14);
piix3_init(7);
fdc37c932fr_init();
device_add(&intel_flash_bxb_device);
}
@@ -945,33 +974,35 @@ static void at_p55t2p4_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(12);
pci_slot(11);
pci_slot(10);
pci_slot(9);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430hx_init();
piix3_init(7, 12, 11, 10, 9);
piix3_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
#if 0
static void at_i430vx_init(void)
{
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x11);
pci_slot(0x12);
pci_slot(0x13);
pci_slot(0x14);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7, 17, 18, 20, 19);
piix3_init(7);
um8669f_init();
device_add(&intel_flash_bxt_device);
}
#endif
static void at_p55tvp4_init(void)
@@ -979,42 +1010,31 @@ static void at_p55tvp4_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(12);
pci_slot(11);
pci_slot(10);
pci_slot(9);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7, 12, 11, 10, 9);
piix3_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
static void at_i430vx_init(void)
{
at_ide_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0x11);
pci_slot(0x12);
pci_slot(0x13);
pci_slot(0x14);
i430vx_init();
piix_init(7, 18, 17, 20, 19);
um8669f_init();
device_add(&intel_flash_bxt_device);
}
static void at_p55va_init(void)
{
at_ide_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(8);
pci_slot(9);
pci_slot(10);
pci_slot(11);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 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_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7, 8, 9, 10, 11);
piix3_init(7);
fdc37c932fr_init();
device_add(&intel_flash_bxt_device);
}
@@ -1025,12 +1045,15 @@ static void at_i440fx_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xe);
pci_slot(0xd);
pci_slot(0xc);
pci_slot(0xb);
i430vx_init();
piix3_init(7, 0xe, 0xd, 0xc, 0xb);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i440fx_init();
piix3_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
@@ -1041,12 +1064,15 @@ static void at_s1668_init(void)
at_ide_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_slot(0xe);
pci_slot(0xd);
pci_slot(0xc);
pci_slot(0xb);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
i440fx_init();
piix3_init(7, 0xe, 0xd, 0xc, 0xb);
piix3_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}

View File

@@ -49,13 +49,6 @@
#define PCI_REGSIZE 256 /* size of PCI space */
/* For PCI. */
typedef union {
uint32_t addr;
uint8_t addr_regs[4];
} bar_t;
/* Never completely fill the ne2k ring so that we never
hit the unclear completely full buffer condition. */
#define NE2K_NEVER_FULL_RING (1)
@@ -2018,7 +2011,7 @@ nic_init(int board)
dev->eeprom[0x7D] = (PCI_VENDID>>8);
/* Insert this device onto the PCI bus, keep its slot number. */
dev->card = pci_add(nic_pci_read, nic_pci_write, dev);
dev->card = pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev);
}
/* Set up our BIA. */

475
src/pci.c
View File

@@ -1,3 +1,5 @@
#include <stdarg.h>
#include "ibm.h"
#include "io.h"
#include "mem.h"
@@ -5,19 +7,46 @@
#include "pci.h"
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);
void *pci_priv[32];
static int pci_irq_routing[32];
/* static int pci_irq_active[32]; */
static int pci_irqs[4];
static int pci_card_valid[32];
static uint64_t pci_irq_hold[16];
typedef struct
{
uint8_t id, type;
uint8_t irq_routing[4];
void (*write) (int func, int addr, uint8_t val, void *priv);
uint8_t (*read) (int func, int addr, void *priv);
void * priv;
} pci_card_t;
static pci_card_t pci_cards[32];
static uint8_t last_pci_card = 0;
static uint8_t pci_card_to_slot_mapping[32];
static uint8_t elcr[2] = { 0, 0 };
static uint8_t pci_irqs[4];
static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key;
int pci_burst_time, pci_nonburst_time;
void pci_cf8_write(uint16_t port, uint32_t val, void *p)
int pci_do_log = 0;
void pci_log(const char *format, ...)
{
#ifdef ENABLE_PCI_LOG
if (pci_do_log)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
fflush(stdout);
}
#endif
}
static void pci_cf8_write(uint16_t port, uint32_t val, void *p)
{
pci_index = val & 0xff;
pci_func = (val >> 8) & 7;
@@ -26,83 +55,92 @@ void pci_cf8_write(uint16_t port, uint32_t val, void *p)
pci_enable = (val >> 31) & 1;
}
uint32_t pci_cf8_read(uint16_t port, void *p)
static uint32_t pci_cf8_read(uint16_t port, void *p)
{
return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31);
}
void pci_write(uint16_t port, uint8_t val, void *priv)
static void pci_write(uint16_t port, uint8_t val, void *priv)
{
uint8_t slot = 0;
switch (port)
{
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
if (!pci_enable)
return;
if (!pci_bus && pci_card_write[pci_card])
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
if (!pci_bus)
{
slot = pci_card_to_slot_mapping[pci_card];
if (slot != 0xFF)
{
if (pci_cards[slot].write)
{
/* pci_log("Reading PCI card on slot %02X (pci_cards[%i])...\n", pci_card, slot); */
pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv);
}
}
}
break;
}
}
uint8_t pci_read(uint16_t port, void *priv)
static uint8_t pci_read(uint16_t port, void *priv)
{
uint8_t slot = 0;
switch (port)
{
case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff:
if (!pci_enable)
return 0xff;
if (!pci_bus && pci_card_read[pci_card])
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
if (!pci_bus)
{
slot = pci_card_to_slot_mapping[pci_card];
if (slot != 0xFF)
{
if (pci_cards[slot].read)
{
return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
}
}
}
return 0xff;
}
return 0xff;
}
uint8_t elcr[2] = { 0, 0 };
void elcr_write(uint16_t port, uint8_t val, void *priv)
static void elcr_write(uint16_t port, uint8_t val, void *priv)
{
/* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */
/* pci_log("ELCR%i: WRITE %02X\n", 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)
static uint8_t elcr_read(uint16_t port, void *priv)
{
/* pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */
/* pci_log("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */
return elcr[port & 1];
}
void elcr_reset(void)
static void elcr_reset(void)
{
int i = 0;
pic_reset();
elcr[0] = elcr[1] = 0;
#if 0
for (i = 0; i < 32; i++)
{
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);
uint8_t pci_type2_read(uint16_t port, void *priv);
static void pci_type2_write(uint16_t port, uint8_t val, void *priv);
static uint8_t pci_type2_read(uint16_t port, void *priv);
void pci_type2_write(uint16_t port, uint8_t val, void *priv)
static void pci_type2_write(uint16_t port, uint8_t val, void *priv)
{
uint8_t slot = 0;
if (port == 0xcf8)
{
pci_func = (val >> 1) & 7;
@@ -121,13 +159,24 @@ void pci_type2_write(uint16_t port, uint8_t val, void *priv)
pci_card = (port >> 8) & 0xf;
pci_index = port & 0xff;
if (!pci_bus && pci_card_write[pci_card])
pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]);
if (!pci_bus)
{
slot = pci_card_to_slot_mapping[pci_card];
if (slot != 0xFF)
{
if (pci_cards[slot].write)
{
pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv);
}
}
}
}
}
uint8_t pci_type2_read(uint16_t port, void *priv)
static uint8_t pci_type2_read(uint16_t port, void *priv)
{
uint8_t slot = 0;
if (port == 0xcf8)
{
return pci_key | (pci_func << 1);
@@ -141,8 +190,17 @@ uint8_t pci_type2_read(uint16_t port, void *priv)
pci_card = (port >> 8) & 0xf;
pci_index = port & 0xff;
if (!pci_bus && pci_card_write[pci_card])
return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]);
if (!pci_bus)
{
slot = pci_card_to_slot_mapping[pci_card];
if (slot != 0xFF)
{
if (pci_cards[slot].read)
{
return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
}
}
}
}
return 0xff;
}
@@ -152,15 +210,9 @@ void pci_set_irq_routing(int pci_int, int irq)
pci_irqs[pci_int - 1] = irq;
}
void pci_set_card_routing(int card, int pci_int)
{
pci_irq_routing[card] = pci_int;
}
int pci_irq_is_level(int irq)
static int pci_irq_is_level(int irq)
{
int real_irq = irq & 7;
/* int irq_elcr = 0; */
if (irq > 7)
{
@@ -174,15 +226,15 @@ int pci_irq_is_level(int irq)
void pci_issue_irq(int irq)
{
/* pclog("Issuing PCI IRQ %i: ", irq); */
/* pci_log("Issuing PCI IRQ %i: ", irq); */
if (pci_irq_is_level(irq))
{
/* pclog("Level\n"); */
/* pci_log("Level\n"); */
picintlevel(1 << irq);
}
else
{
/* pclog("Edge\n"); */
/* pci_log("Edge\n"); */
picint(1 << irq);
}
}
@@ -208,30 +260,93 @@ void pci_ide_set_irq(int ide_board, int irq)
}
}
void pci_set_irq(int card, int pci_int)
void pci_set_irq(uint8_t card, uint8_t pci_int)
{
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
uint8_t slot = 0;
uint8_t irq_routing = 0;
uint8_t pci_int_index = pci_int - PCI_INTA;
uint8_t irq_line = 0;
uint8_t level = 0;
if (pci_irq_routing[card] && (pci_irqs[irq] != PCI_IRQ_DISABLED))
{
if (pci_irq_is_level(pci_irqs[irq]) && (pci_irq_hold[pci_irqs[irq]] & (1 << card)))
{
/* IRQ already held, do nothing. */
return;
}
if (!last_pci_card)
{
pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int);
return;
}
else
{
pci_log("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card);
}
if (!pci_irq_is_level(pci_irqs[irq]) || !pci_irq_hold[pci_irqs[irq]])
{
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
pci_issue_irq(pci_irqs[irq]);
}
slot = pci_card_to_slot_mapping[card];
/* If the IRQ is level-triggered, mark that this card is holding it. */
if (pci_irq_is_level(pci_irqs[irq]))
{
pci_irq_hold[pci_irqs[irq]] |= (1 << 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;
}
else
{
pci_log("pci_set_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot);
}
if (!pci_cards[slot].irq_routing[pci_int_index])
{
pci_log("pci_set_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int);
return;
}
else
{
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3;
pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
}
if (pci_irqs[irq_routing] > 0x0F)
{
pci_log("pci_set_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int);
return;
}
else
{
irq_line = pci_irqs[irq_routing];
pci_log("pci_set_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line);
}
if (pci_irq_is_level(irq_line) && (pci_irq_hold[irq_line] & (1 << card)))
{
/* IRQ already held, do nothing. */
pci_log("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int);
return;
}
else
{
pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int);
}
level = pci_irq_is_level(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 ");
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
pci_issue_irq(irq_line);
}
else if (level && pci_irq_hold[irq_line])
{
pci_log("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int);
}
/* If the IRQ is level-triggered, mark that this card is holding it. */
if (pci_irq_is_level(irq_line))
{
pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int);
pci_irq_hold[irq_line] |= (1 << card);
}
else
{
pci_log("pci_set_irq(%02X, %02X): Edge-triggered interrupt, not marking\n", card, pci_int);
}
}
void pci_ide_clear_irq(int ide_board, int irq)
@@ -250,36 +365,87 @@ void pci_ide_clear_irq(int ide_board, int irq)
}
}
void pci_clear_irq(int card, int pci_int)
void pci_clear_irq(uint8_t card, uint8_t pci_int)
{
int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3;
uint8_t slot = 0;
uint8_t irq_routing = 0;
uint8_t pci_int_index = pci_int - PCI_INTA;
uint8_t irq_line = 0;
uint8_t level = 0;
/* Do not clear the interrupt until we're the last card being serviced. */
if (pci_irq_routing[card] && (pci_irqs[irq] != PCI_IRQ_DISABLED))
{
/* pclog("Clearing PCI IRQ %i: ", pci_irqs[irq]); */
if (!last_pci_card)
{
pci_log("pci_clear_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int);
return;
}
else
{
pci_log("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card);
}
if (pci_irq_is_level(pci_irqs[irq]))
slot = pci_card_to_slot_mapping[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;
}
else
{
pci_log("pci_clear_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot);
}
if (!pci_cards[slot].irq_routing[pci_int_index])
{
pci_log("pci_clear_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int);
return;
}
else
{
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3;
pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
}
if (pci_irqs[irq_routing] > 0x0F)
{
pci_log("pci_clear_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int);
return;
}
else
{
irq_line = pci_irqs[irq_routing];
pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line);
}
if (pci_irq_is_level(irq_line) && !(pci_irq_hold[irq_line] & (1 << card)))
{
/* IRQ not held, do nothing. */
pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int);
return;
}
level = pci_irq_is_level(irq_line);
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);
if (!pci_irq_hold[irq_line])
{
pci_irq_hold[pci_irqs[irq]] &= ~(1 << card);
/* pclog("Level "); */
if (!pci_irq_hold[pci_irqs[irq]])
{
/* pclog("(clearing)\n"); */
picintc(1 << pci_irqs[irq]);
}
else
{
/* pclog("(held)\n"); */
}
pci_log("pci_clear_irq(%02X, %02X): IRQ no longer held by any card, clearing it\n", card, pci_int);
picintc(1 << irq_line);
}
else
{
/* pclog("Edge\n"); */
picintc(1 << pci_irqs[irq]);
pci_log("pci_clear_irq(%02X, %02X): IRQ is still being held\n", card, pci_int);
}
}
}
else
{
pci_log("pci_clear_irq(%02X, %02X): Clearing edge-triggered interrupt\n", card, pci_int);
picintc(1 << irq_line);
}
}
void pci_reset(void)
@@ -299,12 +465,39 @@ void pci_reset(void)
elcr_reset();
}
static void pci_slots_clear(void)
{
uint8_t i = 0;
uint8_t j = 0;
last_pci_card = 0;
for (i = 0; i < 32; i++)
{
pci_cards[i].id = 0xFF;
pci_cards[i].type = 0xFF;
for (j = 0; j < 4; j++)
{
pci_cards[i].irq_routing[j] = 0;
}
pci_cards[i].read = NULL;
pci_cards[i].write = NULL;
pci_cards[i].priv = NULL;
pci_card_to_slot_mapping[i] = 0xFF;
}
}
void pci_init(int type)
{
int c;
PCI = 1;
pci_slots_clear();
pci_reset();
io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL);
@@ -320,46 +513,66 @@ void pci_init(int type)
io_sethandler(0x0cfa, 0x0001, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
}
for (c = 0; c < 32; c++)
{
pci_card_read[c] = NULL;
pci_card_write[c] = NULL;
pci_priv[c] = NULL;
pci_irq_routing[c] = 0;
/* pci_irq_active[c] = 0; */
pci_card_valid[c] = 0;
}
for (c = 0; c < 4; c++)
pci_irqs[c] = PCI_IRQ_DISABLED;
for (c = 0; c < 4; c++)
{
pci_irqs[c] = PCI_IRQ_DISABLED;
}
}
void pci_slot(int card)
void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd)
{
pci_card_valid[card] = 1;
pci_cards[last_pci_card].id = card;
pci_cards[last_pci_card].type = type;
pci_cards[last_pci_card].irq_routing[0] = inta;
pci_cards[last_pci_card].irq_routing[1] = intb;
pci_cards[last_pci_card].irq_routing[2] = intc;
pci_cards[last_pci_card].irq_routing[3] = intd;
pci_cards[last_pci_card].read = NULL;
pci_cards[last_pci_card].write = NULL;
pci_cards[last_pci_card].priv = NULL;
pci_card_to_slot_mapping[card] = last_pci_card;
pci_log("pci_register_slot(): pci_cards[%i].id = %02X\n", last_pci_card, card);
last_pci_card++;
}
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv)
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_read[card] = read;
pci_card_write[card] = write;
pci_priv[card] = priv;
}
uint8_t i = 0;
int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv)
{
int c;
for (c = 0; c < 32; c++)
{
if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c])
{
pci_card_read[c] = read;
pci_card_write[c] = write;
pci_priv[c] = priv;
return c;
}
}
return -1;
if (add_type < PCI_ADD_NORMAL)
{
pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type);
}
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" : "SPECIFIC"));
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" : "SPECIFIC"));
return 0xFF;
}
for (i = 0; i < last_pci_card; i++)
{
if (!pci_cards[i].read && !pci_cards[i].write)
{
if (((pci_cards[i].type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) ||
((pci_cards[i].type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) ||
((pci_cards[i].id == add_type) && (add_type < PCI_ADD_NORMAL)))
{
pci_cards[i].read = read;
pci_cards[i].write = write;
pci_cards[i].priv = priv;
pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (slot %02X) [%s]\n", i, pci_cards[i].id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : "SPECIFIC"));
return pci_cards[i].id;
}
}
}
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" : "SPECIFIC"));
return 0xFF;
}

View File

@@ -1,17 +1,14 @@
void elcr_reset(void);
void pci_set_irq_routing(int pci_int, int irq);
void pci_init(int type);
void pci_slot(int card);
void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
void pci_set_irq_routing(int card, int irq);
void pci_set_card_routing(int card, int pci_int);
void pci_ide_set_irq(int ide_board, int irq);
void pci_set_irq(int card, int pci_int);
void pci_set_irq(uint8_t card, uint8_t pci_int);
void pci_ide_clear_irq(int ide_board, int irq);
void pci_clear_irq(int card, int pci_int);
int pci_irq_is_level(int irq);
void pci_clear_irq(uint8_t card, uint8_t pci_int);
void pci_reset(void);
void pci_init(int type);
void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd);
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);
#define PCI_REG_COMMAND 0x04
@@ -28,4 +25,20 @@ void pci_reset(void);
#define PCI_IRQ_DISABLED -1
enum
{
PCI_CARD_NORMAL = 0,
PCI_CARD_ONBOARD,
PCI_CARD_SPECIAL
};
#define PCI_ADD_NORMAL 0x80
#define PCI_ADD_VIDEO 0x81
extern int pci_burst_time, pci_nonburst_time;
typedef union {
uint32_t addr;
uint8_t addr_regs[4];
} bar_t;

238
src/pci_dummy.c Normal file
View File

@@ -0,0 +1,238 @@
/* This can also serve as a sample PCI device. */
#include "ibm.h"
#include "io.h"
#include "pci.h"
#include "pci_dummy.h"
static uint8_t pci_regs[256];
static bar_t pci_bar[2];
static uint8_t interrupt_on = 0x00;
static uint8_t card = 0;
static void pci_dummy_interrupt(int set)
{
if (set)
{
pci_set_irq(card, pci_regs[0x3D]);
}
else
{
pci_clear_irq(card, pci_regs[0x3D]);
}
}
static uint8_t pci_dummy_read(uint16_t Port, void *p)
{
uint8_t ret = 0;
switch(Port & 0x20)
{
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04:
return pci_regs[0x3C];
case 0x05:
return pci_regs[0x3D];
case 0x06:
ret = interrupt_on;
if (interrupt_on)
{
pci_dummy_interrupt(0);
interrupt_on = 0;
}
return ret;
default:
return 0x00;
}
}
static uint16_t pci_dummy_readw(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static uint32_t pci_dummy_readl(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static void pci_dummy_write(uint16_t Port, uint8_t Val, void *p)
{
switch(Port & 0x20)
{
case 0x06:
if (!interrupt_on)
{
interrupt_on = 1;
pci_dummy_interrupt(1);
}
return;
default:
return;
}
}
static void pci_dummy_writew(uint16_t Port, uint16_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void pci_dummy_writel(uint16_t Port, uint32_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void pci_dummy_io_remove(void)
{
io_removehandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static void pci_dummy_io_set(void)
{
io_sethandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static uint8_t pci_dummy_pci_read(int func, int addr, void *priv)
{
pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr);
switch(addr) {
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
break;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04: /* PCI_COMMAND_LO */
case 0x05: /* PCI_COMMAND_HI */
return pci_regs[addr];
case 0x06: /* PCI_STATUS_LO */
case 0x07: /* PCI_STATUS_HI */
return pci_regs[addr];
case 0x08:
case 0x09:
return 0x00;
case 0x0A:
return pci_regs[addr];
case 0x0B:
return pci_regs[addr];
case 0x10: /* PCI_BAR 7:5 */
return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01;
case 0x11: /* PCI_BAR 15:8 */
return pci_bar[0].addr_regs[1];
case 0x12: /* PCI_BAR 23:16 */
return pci_bar[0].addr_regs[2];
case 0x13: /* PCI_BAR 31:24 */
return pci_bar[0].addr_regs[3];
case 0x2C:
return 0x1A;
case 0x2D:
return 0x07;
case 0x2E:
return 0x0B;
case 0x2F:
return 0xAB;
case 0x3C: /* PCI_ILR */
return pci_regs[addr];
case 0x3D: /* PCI_IPR */
return pci_regs[addr];
default:
return 0x00;
}
}
static void pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv)
{
uint8_t valxor;
pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val);
switch(addr) {
case 0x04: /* PCI_COMMAND_LO */
valxor = (val & 0x03) ^ pci_regs[addr];
if (valxor & PCI_COMMAND_IO)
{
pci_dummy_io_remove();
if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO))
{
pci_dummy_io_set();
}
}
pci_regs[addr] = val & 0x03;
break;
case 0x10: /* PCI_BAR */
val &= 0xe0; /* 0xe0 acc to RTL DS */
val |= 0x01; /* re-enable IOIN bit */
/*FALLTHROUGH*/
case 0x11: /* PCI_BAR */
case 0x12: /* PCI_BAR */
case 0x13: /* PCI_BAR */
/* Remove old I/O. */
pci_dummy_io_remove();
/* Set new I/O as per PCI request. */
pci_bar[0].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
pci_bar[0].addr &= 0xffe0;
/* Log the new base. */
pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr);
/* We're done, so get out of the here. */
if (pci_regs[4] & PCI_COMMAND_IO)
{
if ((pci_bar[0].addr) != 0)
{
pci_dummy_io_set();
}
}
break;
case 0x3C: /* PCI_ILR */
pclog("AB0B:071A: IRQ now: %i\n", val);
pci_regs[addr] = val;
return;
}
}
void pci_dummy_init(void)
{
card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL);
pci_bar[0].addr_regs[0] = 0x01;
pci_regs[0x04] = 0x03;
pci_regs[0x3D] = PCI_INTD;
}

1
src/pci_dummy.h Normal file
View File

@@ -0,0 +1 @@
extern void pci_dummy_init(void);

View File

@@ -683,9 +683,9 @@ void piix3_reset(void)
card_piix_ide[0x44] = 0x00;
}
void piix_init_common(int card)
void piix_init(int card)
{
pci_add_specific(card, piix_read, piix_write, NULL);
pci_add_card(card, piix_read, piix_write, NULL);
piix_reset();
@@ -704,30 +704,9 @@ void piix_init_common(int card)
pci_reset_handler.pci_set_reset = piix_reset;
}
void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
void piix3_init(int card)
{
piix_init_common(card);
pci_set_card_routing(pci_a, PCI_INTA);
pci_set_card_routing(pci_b, PCI_INTB);
pci_set_card_routing(pci_c, PCI_INTC);
pci_set_card_routing(pci_d, PCI_INTD);
}
void piix_init_thor(int card, int pci_d_only, int pci_a, int pci_b, int pci_c, int pci_d)
{
piix_init_common(card);
pci_set_card_routing(pci_d_only, PCI_INTD);
pci_set_card_routing(pci_a, PCI_INTA);
pci_set_card_routing(pci_b, PCI_INTB);
pci_set_card_routing(pci_c, PCI_INTC);
pci_set_card_routing(pci_d, PCI_INTD);
}
void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
{
pci_add_specific(card, piix_read, piix_write, NULL);
pci_add_card(card, piix_read, piix_write, NULL);
piix3_reset();
@@ -744,9 +723,4 @@ void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
dma_alias_set();
pci_reset_handler.pci_set_reset = piix3_reset;
pci_set_card_routing(pci_a, PCI_INTA);
pci_set_card_routing(pci_b, PCI_INTB);
pci_set_card_routing(pci_c, PCI_INTC);
pci_set_card_routing(pci_d, PCI_INTD);
}

View File

@@ -16,10 +16,9 @@
* Copyright 2016,2017 Miran Grca.
*/
extern void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d);
extern void piix_init_thor(int card, int pci_d_only, int pci_a, int pci_b, int pci_c, int pci_d);
extern void piix_init(int card);
extern void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d);
extern void piix3_init(int card);
extern uint8_t piix_bus_master_read(uint16_t port, void *priv);
extern void piix_bus_master_write(uint16_t port, uint8_t val, void *priv);

View File

@@ -2561,12 +2561,6 @@ BuslogicCommandCallback(void *p)
}
typedef union {
uint32_t addr;
uint8_t addr_regs[4];
} bar_t;
uint8_t buslogic_pci_regs[256];
bar_t buslogic_pci_bar[3];
@@ -2933,7 +2927,7 @@ BuslogicInit(int chip)
&BuslogicCallback, &BuslogicCallback, bl);
if (bl->chip == CHIP_BUSLOGIC_PCI) {
bl->Card = pci_add(BuslogicPCIRead, BuslogicPCIWrite, bl);
bl->Card = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, bl);
buslogic_pci_bar[0].addr_regs[0] = 1;
buslogic_pci_bar[1].addr_regs[0] = 0;

View File

@@ -223,9 +223,9 @@ void sio_reset(void)
}
void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
void sio_init(int card)
{
pci_add_specific(card, sio_read, sio_write, NULL);
pci_add_card(card, sio_read, sio_write, NULL);
sio_reset();
@@ -238,13 +238,4 @@ void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
dma_alias_set();
pci_reset_handler.pci_set_reset = sio_reset;
if (pci_a)
pci_set_card_routing(pci_a, PCI_INTA);
if (pci_b)
pci_set_card_routing(pci_b, PCI_INTB);
if (pci_c)
pci_set_card_routing(pci_c, PCI_INTC);
if (pci_d)
pci_set_card_routing(pci_d, PCI_INTD);
}

View File

@@ -15,4 +15,4 @@
*/
void trc_init(void);
void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d);
void sio_init(int card);

View File

@@ -146,15 +146,11 @@ static void sis496_pci_reset(void)
void sis496_init(void)
{
pci_add_specific(5, sis496_read, sis496_write, NULL);
pci_add_card(5, sis496_read, sis496_write, NULL);
sis496_reset();
pci_reset_handler.pci_master_reset = sis496_pci_reset;
pci_set_card_routing(15, PCI_INTA);
pci_set_card_routing(13, PCI_INTD);
pci_set_card_routing(11, PCI_INTC);
}

View File

@@ -3315,7 +3315,7 @@ static void *mach64_common_init()
mach64_io_set(mach64);
mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64);
mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64);
mach64->pci_regs[PCI_REG_COMMAND] = 3;
mach64->pci_regs[0x30] = 0x00;

View File

@@ -1161,7 +1161,7 @@ void *et4000w32p_init()
et4000w32p_io_set(et4000);
pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000);
pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000);
/* Hardwired bits: 00000000 1xx0x0xx */
/* R/W bits: xx xxxx */

View File

@@ -2883,7 +2883,7 @@ void rivatnt_pgraph_ctx_switch(void *p)
riva128->pgraph.intr = 0;
riva128->ptimer.intr = 0;
riva128->pci_card = pci_add(riva128_pci_read, riva128_pci_write, riva128);
riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, riva128_pci_write, riva128);
riva128->ptimer.clock_mul = 1;
riva128->ptimer.clock_div = 1;
@@ -3109,7 +3109,7 @@ device_t riva128_device =
riva128->pfifo.intr = 0;
riva128->pgraph.intr = 0;
riva128->pci_card = pci_add(riva128_pci_read, rivatnt_pci_write, riva128);
riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128);
//Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway.
riva128->pramdac.m_m = 0x03;
@@ -3310,7 +3310,7 @@ device_t rivatnt_device =
riva128->pfifo.intr = 0;
riva128->pgraph.intr = 0;
riva128->pci_card = pci_add(riva128_pci_read, rivatnt_pci_write, riva128);
riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128);
//Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway.
riva128->pramdac.m_m = 0x03;

View File

@@ -2179,8 +2179,8 @@ static void *s3_init(wchar_t *bios_fn, int chip)
s3_io_set(s3);
s3->card = pci_add(s3_pci_read, s3_pci_write, s3);
s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3);
s3->pci_regs[0x04] = 7;
s3->pci_regs[0x30] = 0x00;

View File

@@ -3828,7 +3828,7 @@ static void *s3_virge_init()
virge->is_375 = 0;
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
virge->wake_render_thread = thread_create_event();
virge->wake_main_thread = thread_create_event();
@@ -3922,7 +3922,7 @@ static void *s3_virge_988_init()
virge->is_375 = 0;
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
virge->wake_render_thread = thread_create_event();
virge->wake_main_thread = thread_create_event();
@@ -4017,7 +4017,7 @@ static void *s3_virge_375_init(wchar_t *romfn)
virge->is_375 = 1;
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
virge->wake_render_thread = thread_create_event();
virge->wake_main_thread = thread_create_event();

View File

@@ -526,7 +526,7 @@ void *tgui9440_init()
io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
pci_add(tgui_pci_read, tgui_pci_write, tgui);
pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui);
tgui->wake_fifo_thread = thread_create_event();
tgui->fifo_not_full_event = thread_create_event();

View File

@@ -7492,7 +7492,7 @@ void *voodoo_card_init()
else
voodoo_generate_filter_v1(voodoo);
pci_add(voodoo_pci_read, voodoo_pci_write, voodoo);
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo);
mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);