From 265587316251711e517b8c3e0f373329e720b8df Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 Jun 2020 05:23:49 +0200 Subject: [PATCH] A number of PCI fixes and P5MP3 corrections. --- src/chipset/intel_4x0.c | 25 +++++----- src/include/86box/pci.h | 1 + src/machine/m_at_socket4_5.c | 30 ++++++++---- src/pci.c | 90 ++++++++++++++++++++++++++++++++---- 4 files changed, 115 insertions(+), 31 deletions(-) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a65e06dd3..f34ca0013 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -350,8 +350,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_440LX: case INTEL_440EX: regs[0x34] = (val & 0xa0); - } break; + } + break; case 0x4f: switch (dev->type) { @@ -633,7 +634,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440ZX: default: regs[addr] = val; break; @@ -652,7 +653,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440GX: + case INTEL_440GX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -904,7 +905,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x7c] = val & 0x8f; break; case INTEL_440BX: case INTEL_440GX: - case INTEL_440ZX: + case INTEL_440ZX: regs[0x7c] = val & 0x1f; break; } @@ -912,7 +913,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: - regs[0x7c] = val & 0x32; + regs[0x7d] = val & 0x32; break; } case 0x7e: case 0x7f: @@ -1207,9 +1208,9 @@ i4x0_read(int func, int addr, void *priv) uint8_t ret = 0xff; uint8_t *regs = (uint8_t *) dev->regs[func]; - if (func > dev->max_func) + if (func > dev->max_func) ret = 0xff; - else { + else { ret = regs[addr]; /* Special behavior for 440FX register 0x93 which is basically TRC in PCI space with the addition of bits 3 and 0. */ @@ -1566,11 +1567,11 @@ static void regs = (uint8_t *) dev->regs[1]; regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */ - if(dev->type != INTEL_440GX){ - regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */ - } else { - regs[0x02] = 0xa1; regs[0x03] = 0x71; /* 82443GX (They seem to share the same deal*/ - } + if(dev->type != INTEL_440GX) { + regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */ + } else { + regs[0x02] = 0xa1; regs[0x03] = 0x71; /* 82443GX (They seem to share the same deal*/ + } regs[0x06] = 0x20; regs[0x07] = 0x02; regs[0x08] = 0x02; regs[0x0a] = 0x04; regs[0x0b] = 0x06; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index edb6a5e57..7fb118195 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -28,6 +28,7 @@ #define PCI_COMMAND_MEM 0x02 #define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 2bf904938..8137397f9 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -62,12 +62,12 @@ machine_at_excalibur_init(const machine_t *model) static void -machine_at_premiere_common_init(const machine_t *model) +machine_at_premiere_common_init(const machine_t *model, int pci_switch) { machine_at_common_init(model); device_add(&ide_pci_2ch_device); - pci_init(PCI_CONFIG_TYPE_2); + pci_init(PCI_CONFIG_TYPE_2 | pci_switch); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 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); @@ -98,7 +98,6 @@ machine_at_award_common_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&fdc_at_device); device_add(&keyboard_ps2_pci_device); - device_add(&sio_device); } @@ -113,7 +112,7 @@ machine_at_batman_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model); + machine_at_premiere_common_init(model, 0); device_add(&i430lx_device); @@ -132,7 +131,7 @@ machine_at_ambradp60_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model); + machine_at_premiere_common_init(model, 0); device_add(&i430lx_device); @@ -152,7 +151,7 @@ machine_at_valuepointp60_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model); + machine_at_premiere_common_init(model, 0); device_add(&i430lx_device); @@ -172,8 +171,19 @@ machine_at_p5mp3_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_award_common_init(model); + machine_at_common_init(model); + device_add(&ide_pci_device); + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 3 */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&fdc_at_device); + device_add(&keyboard_ps2_pci_device); + + device_add(&sio_zb_device); device_add(&catalyst_flash_device); device_add(&i430lx_device); @@ -194,6 +204,7 @@ machine_at_586mc1_init(const machine_t *model) machine_at_award_common_init(model); + device_add(&sio_device); device_add(&intel_flash_bxt_device); device_add(&i430lx_device); @@ -212,7 +223,7 @@ machine_at_plato_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model); + machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE); device_add(&i430nx_device); @@ -231,7 +242,7 @@ machine_at_ambradp90_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model); + machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE); device_add(&i430nx_device); @@ -252,6 +263,7 @@ machine_at_430nx_init(const machine_t *model) machine_at_award_common_init(model); + device_add(&sio_device); device_add(&intel_flash_bxt_device); device_add(&i430nx_device); diff --git a/src/pci.c b/src/pci.c index 4f5b40f66..ace9e14e5 100644 --- a/src/pci.c +++ b/src/pci.c @@ -55,13 +55,14 @@ int pci_burst_time, pci_nonburst_time; static pci_card_t pci_cards[32]; -static uint8_t last_pci_card = 0; +static uint8_t pci_pmc = 0, 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], pci_irq_level[4]; static uint64_t pci_irq_hold[16]; static pci_mirq_t pci_mirqs[3]; static int pci_type, + pci_switch, pci_index, pci_func, pci_card, @@ -71,6 +72,9 @@ static int pci_type, static int trc_reg = 0, elcr_enabled = 1; +static void pci_reset_regs(void); + + #ifdef ENABLE_PCI_LOG int pci_do_log = ENABLE_PCI_LOG; @@ -244,15 +248,39 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (!pci_key && (val & 0xf0)) io_sethandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, priv); - else + pci_type2_write, NULL, NULL, NULL); + else if (pci_key && !(val & 0xf0)) io_removehandler(0xc000, 0x1000, pci_type2_read, NULL, NULL, - pci_type2_write, NULL, NULL, priv); + pci_type2_write, NULL, NULL, NULL); pci_key = val & 0xf0; - } else if (port == 0xcfa) { + } else if (port == 0xcfa) pci_bus = val; + else if (port == 0xcfb) { + pci_reset_regs(); + + if (!pci_pmc && (val & 0x01)) { + io_removehandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_removehandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_sethandler(0x0cf8, 1, + NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); + io_sethandler(0x0cfc, 4, + pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + } else if (pci_pmc && !(val & 0x01)) { + io_removehandler(0x0cf8, 1, + NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); + io_removehandler(0x0cfc, 4, + pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + io_sethandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + } + + pci_pmc = (val & 0x01); } else { pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; @@ -283,9 +311,10 @@ pci_type2_read(uint16_t port, void *priv) if (port == 0xcf8) return pci_key | (pci_func << 1); - - if (port == 0xcfa) + else if (port == 0xcfa) return pci_bus; + else if (port == 0xcfb) + return pci_pmc; pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; @@ -612,11 +641,24 @@ pci_elcr_set_enabled(int enabled) } -void -pci_reset(void) +static void +pci_reset_regs(void) +{ + pci_index = pci_card = pci_func = pci_bus = pci_key = 0; + + io_removehandler(0xc000, 0x1000, + pci_type2_read, NULL, NULL, + pci_type2_write, NULL, NULL, NULL); +} + + +static void +pci_reset_hard(void) { int i; + pci_reset_regs(); + for (i = 0; i < 16; i++) { if (pci_irq_hold[i]) { pci_irq_hold[i] = 0; @@ -629,6 +671,26 @@ pci_reset(void) } +void +pci_reset(void) +{ + if (pci_switch) { + pci_pmc = 0x00; + + io_removehandler(0x0cf8, 1, + NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); + io_removehandler(0x0cfc, 4, + pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + io_sethandler(0x0cf8, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + io_sethandler(0x0cfa, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + } + + pci_reset_hard(); +} + + static void pci_slots_clear(void) { @@ -741,11 +803,19 @@ pci_init(int type) pci_slots_clear(); - pci_reset(); + pci_reset_hard(); trc_init(); pci_type = type; + pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); + + if (pci_switch) { + pci_pmc = 0x00; + + io_sethandler(0x0cfb, 1, + pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + } if (!(type & PCI_NO_IRQ_STEERING)) { io_sethandler(0x04d0, 0x0002,