Skip to content
Snippets Groups Projects
Commit fd6a543d authored by Mark Cave-Ayland's avatar Mark Cave-Ayland Committed by Kevin Wolf
Browse files

ide/pci: introduce pci_ide_update_mode() function


This function reads the value of the PCI_CLASS_PROG register for PCI IDE
controllers and configures the PCI BARs and/or IDE ioports accordingly.

In the case where we switch to legacy mode, the PCI BARs are set to return zero
(as suggested in the "PCI IDE Controller" specification), the legacy IDE ioports
are enabled, and the PCI interrupt pin cleared to indicate legacy IRQ routing.

Conversely when we switch to native mode, the legacy IDE ioports are disabled
and the PCI interrupt pin set to indicate native IRQ routing. The contents of
the PCI BARs are unspecified, but this is not an issue since if a PCI IDE
controller has been switched to native mode then its BARs will need to be
programmed.

Signed-off-by: default avatarMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-ID: <20231116103355.588580-3-mark.cave-ayland@ilande.co.uk>
Reviewed-by: default avatarKevin Wolf <kwolf@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 75524884
No related branches found
No related tags found
No related merge requests found
......@@ -104,6 +104,90 @@ const MemoryRegionOps pci_ide_data_le_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
void pci_ide_update_mode(PCIIDEState *s)
{
PCIDevice *d = PCI_DEVICE(s);
uint8_t mode = d->config[PCI_CLASS_PROG];
/*
* This function only configures the BARs/ioports for now: PCI IDE
* controllers must manage their own IRQ routing
*/
switch (mode & 0xf) {
case 0xa:
/* Both channels legacy mode */
/*
* TODO: according to the PCI IDE specification the BARs should
* be completely disabled, however Linux for the pegasos2
* machine stil accesses the BAR addresses after switching to legacy
* mode. Hence we leave them active for now.
*/
/* Clear interrupt pin */
pci_config_set_interrupt_pin(d->config, 0);
/* Add legacy IDE ports */
if (!s->bus[0].portio_list.owner) {
portio_list_init(&s->bus[0].portio_list, OBJECT(d),
ide_portio_list, &s->bus[0], "ide");
portio_list_add(&s->bus[0].portio_list,
pci_address_space_io(d), 0x1f0);
}
if (!s->bus[0].portio2_list.owner) {
portio_list_init(&s->bus[0].portio2_list, OBJECT(d),
ide_portio2_list, &s->bus[0], "ide");
portio_list_add(&s->bus[0].portio2_list,
pci_address_space_io(d), 0x3f6);
}
if (!s->bus[1].portio_list.owner) {
portio_list_init(&s->bus[1].portio_list, OBJECT(d),
ide_portio_list, &s->bus[1], "ide");
portio_list_add(&s->bus[1].portio_list,
pci_address_space_io(d), 0x170);
}
if (!s->bus[1].portio2_list.owner) {
portio_list_init(&s->bus[1].portio2_list, OBJECT(d),
ide_portio2_list, &s->bus[1], "ide");
portio_list_add(&s->bus[1].portio2_list,
pci_address_space_io(d), 0x376);
}
break;
case 0xf:
/* Both channels native mode */
/* Set interrupt pin */
pci_config_set_interrupt_pin(d->config, 1);
/* Remove legacy IDE ports */
if (s->bus[0].portio_list.owner) {
portio_list_del(&s->bus[0].portio_list);
portio_list_destroy(&s->bus[0].portio_list);
}
if (s->bus[0].portio2_list.owner) {
portio_list_del(&s->bus[0].portio2_list);
portio_list_destroy(&s->bus[0].portio2_list);
}
if (s->bus[1].portio_list.owner) {
portio_list_del(&s->bus[1].portio_list);
portio_list_destroy(&s->bus[1].portio_list);
}
if (s->bus[1].portio2_list.owner) {
portio_list_del(&s->bus[1].portio2_list);
portio_list_destroy(&s->bus[1].portio2_list);
}
break;
}
}
static IDEState *bmdma_active_if(BMDMAState *bmdma)
{
assert(bmdma->bus->retry_unit != (uint8_t)-1);
......
......@@ -61,6 +61,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
void bmdma_status_writeb(BMDMAState *bm, uint32_t val);
extern MemoryRegionOps bmdma_addr_ioport_ops;
void pci_ide_create_devs(PCIDevice *dev);
void pci_ide_update_mode(PCIIDEState *s);
extern const VMStateDescription vmstate_ide_pci;
extern const MemoryRegionOps pci_ide_cmd_le_ops;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment