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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user