PCI and IRQ rework, pci.c rewritten from ground up, fixes numerous issues such as the bridge being added when the number of normal PCI devices equals the number of normal PCI slots, Windows 95 PCI operation on Intel 430NX, sharing of PCI IRQ's with non-PCI level-triggered devices, having both configuration mechanisms operating at the same time (ALi M1435), etc., and makes the code much more readable.

This commit is contained in:
OBattler
2023-08-07 03:04:52 +02:00
parent cb24ee27cb
commit c30d5d90b7
66 changed files with 1824 additions and 1643 deletions

View File

@@ -128,6 +128,10 @@ typedef struct atkbc_t {
uint8_t channel;
uint8_t stat_hi;
uint8_t pending;
uint8_t irq_state;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t mem[0x100];
@@ -347,15 +351,15 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
dev->status |= STAT_MFULL;
if (dev->mem[0x20] & 0x02)
picint_common(1 << 12, 0, 1);
picint_common(1 << 1, 0, 0);
picint_common(1 << 12, 0, 1, NULL);
picint_common(1 << 1, 0, 0, NULL);
} else {
if (dev->mem[0x20] & 0x01)
picint_common(1 << 1, 0, 1);
picint_common(1 << 12, 0, 0);
picint_common(1 << 1, 0, 1, NULL);
picint_common(1 << 12, 0, 0, NULL);
}
} else if (dev->mem[0x20] & 0x01)
picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
dev->ob = temp;
}
@@ -720,10 +724,10 @@ write_p2(atkbc_t *dev, uint8_t val)
/* PS/2: Handle IRQ's. */
if (dev->misc_flags & FLAG_PS2) {
/* IRQ 12 */
picint_common(1 << 12, 0, val & 0x20);
picint_common(1 << 12, 0, val & 0x20, NULL);
/* IRQ 1 */
picint_common(1 << 1, 0, val & 0x10);
picint_common(1 << 1, 0, val & 0x10, NULL);
}
#endif
@@ -1550,7 +1554,8 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0x4b);
picintc(0x1002);
picintc(0x1000);
picintc(0x0002);
}
dev->status = (dev->status & 0x0f) | 0x60;
@@ -1569,7 +1574,8 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0xcf);
picintc(0x0002);
picintclevel(0x0002, &dev->irq_state);
dev->irq_state = 0;
}
dev->status = (dev->status & 0x0f) | 0x60;
@@ -1852,7 +1858,7 @@ kbc_at_read(uint16_t port, void *priv)
/* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit.
This also means that in AT mode, the IRQ is level-triggered. */
if (!(dev->misc_flags & FLAG_PS2))
picintc(1 << 1);
picintclevel(1 << 1, &dev->irq_state);
break;
case 0x64:
@@ -1901,8 +1907,13 @@ kbc_at_reset(void *priv)
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
dev->misc_flags |= FLAG_PS2;
kbc_at_do_poll = kbc_at_poll_ps2;
} else
picintc(0x1000);
picintc(0x0002);
} else {
kbc_at_do_poll = kbc_at_poll_at;
picintclevel(0x0002, &dev->irq_state);
dev->irq_state = 0;
}
dev->misc_flags |= FLAG_CACHE;
@@ -1924,8 +1935,6 @@ kbc_at_close(void *priv)
atkbc_t *dev = (atkbc_t *) priv;
int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
kbc_at_reset(dev);
/* Stop timers. */
timer_disable(&dev->send_delay_timer);

View File

@@ -54,7 +54,7 @@ typedef struct pci_bridge_t {
uint8_t regs[256];
uint8_t bus_index;
int slot;
uint8_t slot;
} pci_bridge_t;
#ifdef ENABLE_PCI_BRIDGE_LOG
@@ -493,7 +493,10 @@ pci_bridge_init(const device_t *info)
pci_bridge_reset(dev);
dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev);
if (AGP_BRIDGE(dev->local))
pci_add_card(PCI_ADD_AGPBRIDGE, pci_bridge_read, pci_bridge_write, dev, &dev->slot);
else
dev->slot = pci_add_bridge(pci_bridge_read, pci_bridge_write, dev);
interrupt_count = sizeof(interrupts);
interrupt_mask = interrupt_count - 1;

View File

@@ -48,6 +48,8 @@ enum {
SERIAL_INT_TIMEOUT = 16
};
void serial_update_ints(serial_t *dev);
static int next_inst = 0;
static serial_device_t serial_devices[SERIAL_MAX];
@@ -84,6 +86,8 @@ serial_reset_port(serial_t *dev)
dev->out_new = 0xffff;
memset(dev->xmit_fifo, 0, 16);
memset(dev->rcvr_fifo, 0, 16);
serial_update_ints(dev);
dev->irq_state = 0;
}
void
@@ -133,11 +137,15 @@ serial_update_ints(serial_t *dev)
if (stat && (dev->irq != 0xff) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))) {
if (dev->type >= SERIAL_16450)
picintlevel(1 << dev->irq);
else
picintlevel(1 << dev->irq, &dev->irq_state);
else
picint(1 << dev->irq);
} else
picintc(1 << dev->irq);
} else {
if (dev->type >= SERIAL_16450)
picintclevel(1 << dev->irq, &dev->irq_state);
else
picintc(1 << dev->irq);
}
}
static void