pci: Move interrupt line and pin functions into PCI device and add variables (nw)

pci-ide: Add legacy mapping based on prog i/f register (nw)
This commit is contained in:
Ted Green 2017-01-08 08:39:31 -07:00
parent 57ac19beee
commit 58ff1eb0e1
4 changed files with 105 additions and 47 deletions

View file

@ -14,8 +14,11 @@ ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, d
}
DEVICE_ADDRESS_MAP_START(config_map, 32, ide_pci_device)
AM_RANGE(0x08, 0x0b) AM_WRITE8(prog_if_w, 0x0000ff00)
AM_RANGE(0x10, 0x1f) AM_WRITE(address_base_w)
AM_RANGE(0x40, 0x5f) AM_READWRITE(pcictrl_r, pcictrl_w)
AM_RANGE(0x70, 0x77) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w) // PCI646
AM_RANGE(0x78, 0x7f) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, bmdma_r, bmdma_w) // PCI646
AM_INHERIT_FROM(pci_device::config_map)
ADDRESS_MAP_END
@ -80,7 +83,17 @@ void ide_pci_device::device_start()
add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map));
bank_infos[4].adr = 0xf00;
// Setup stored BARs
pci_bar[0] = 0x1f0;
pci_bar[1] = 0x3f4;
pci_bar[2] = 0x170;
pci_bar[3] = 0x374;
pci_bar[4] = 0xf00;
m_irq_handler.resolve_safe();
intr_pin = 0x1;
intr_line = 0xe;
}
void ide_pci_device::device_reset()
@ -94,8 +107,8 @@ void ide_pci_device::device_reset()
READ32_MEMBER(ide_pci_device::ide_read_cs1)
{
// PCI offset starts at 0x3f4, idectrl expects 0x3f0
uint32_t data = 0;
data = m_ide->read_cs1(space, ++offset, mem_mask);
uint32_t data;
data = m_ide->read_cs1(space, 1, mem_mask);
if (0)
logerror("%s:ide_read_cs1 offset=%08X data=%08X mask=%08X\n", machine().describe_context(), offset, data, mem_mask);
return data;
@ -104,21 +117,21 @@ READ32_MEMBER(ide_pci_device::ide_read_cs1)
WRITE32_MEMBER(ide_pci_device::ide_write_cs1)
{
// PCI offset starts at 0x3f4, idectrl expects 0x3f0
m_ide->write_cs1(space, ++offset, data, mem_mask);
m_ide->write_cs1(space, 1, data, mem_mask);
}
READ32_MEMBER(ide_pci_device::ide2_read_cs1)
{
// PCI offset starts at 0x374, idectrl expects 0x370
uint32_t data = 0;
data = m_ide2->read_cs1(space, ++offset, mem_mask);
uint32_t data;
data = m_ide2->read_cs1(space, 1, mem_mask);
return data;
}
WRITE32_MEMBER(ide_pci_device::ide2_write_cs1)
{
// PCI offset starts at 0x374, idectrl expects 0x370
m_ide2->write_cs1(space, ++offset, data, mem_mask);
m_ide2->write_cs1(space, 1, data, mem_mask);
}
WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt)
@ -141,6 +154,42 @@ WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt)
logerror("%s:ide_interrupt %i set to %i\n", machine().describe_context(), m_irq_num, state);
}
WRITE8_MEMBER(ide_pci_device::prog_if_w)
{
uint32_t oldVal = pclass;
pclass = (pclass & ~(0xff)) | (data & 0xff);
// Check for switch to/from compatibility (legacy) mode from/to pci mode
if ((oldVal ^ pclass) & 0x5) {
// Map Primary IDE Channel
if (pclass & 0x1) {
// PCI Mode
// Enabling BAR 4 in legacy mode
bank_infos[4].flags &= ~M_DISABLED;
pci_device::address_base_w(space, 0, pci_bar[0]);
pci_device::address_base_w(space, 1, pci_bar[1]);
} else {
// Legacy Mode
// Disabling BAR 4 in legacy mode
bank_infos[4].flags |= M_DISABLED;
pci_device::address_base_w(space, 0, 0x1f0);
pci_device::address_base_w(space, 1, 0x3f4);
}
// Map Primary IDE Channel
if (pclass & 0x4) {
// PCI Mode
pci_device::address_base_w(space, 2, pci_bar[2]);
pci_device::address_base_w(space, 3, pci_bar[3]);
}
else {
// Legacy Mode
pci_device::address_base_w(space, 2, 0x170);
pci_device::address_base_w(space, 3, 0x374);
}
}
if (1)
logerror("%s:prog_if_w pclass = %06X\n", machine().describe_context(), pclass);
}
READ32_MEMBER(ide_pci_device::pcictrl_r)
{
return m_config_data[offset];
@ -150,7 +199,7 @@ WRITE32_MEMBER(ide_pci_device::pcictrl_w)
{
COMBINE_DATA(&m_config_data[offset]);
// PCI646U2 Offset 0x50 is interrupt status
if (main_id == 0x10950646 && offset == 0x10 / 4 && (data & 0x4)) {
if (main_id == 0x10950646 && offset == (0x10 / 4) && (data & 0x4)) {
m_config_data[0x10 / 4] &= ~0x4;
if (0)
logerror("%s:ide_pci_device::pcictrl_w Clearing interrupt status\n", machine().describe_context());
@ -161,24 +210,24 @@ WRITE32_MEMBER(ide_pci_device::address_base_w)
{
// data==0xffffffff is used to identify required memory space
if (data != 0xffffffff) {
// Bits 0 (ide) and 2 (ide2) control if the mapping is legacy or BAR
// Save local copy of BAR
pci_bar[offset] = data;
// Bits 0 (primary) and 2 (secondary) control if the mapping is legacy or BAR
switch (offset) {
case 0:
if ((pclass & 0x1) == 0)
data = (data & 0xfffff000) | 0x1f0;
case 0: case 1:
if ((pclass & 0x1) == 1)
pci_device::address_base_w(space, offset, data);
break;
case 1:
if ((pclass & 0x1) == 0)
data = (data & 0xfffff000) | 0x3f4;
break;
case 2:
if ((pclass & 0x4) == 0)
data = (data & 0xfffff000) | 0x170;
case 2: case 3:
if ((pclass & 0x4) == 1)
pci_device::address_base_w(space, offset, data);
break;
default:
if ((pclass & 0x4) == 0)
data = (data & 0xfffff000) | 0x374;
pci_device::address_base_w(space, offset, data);
// Not sure what to do for the bus master ide BAR in legacy mode
// prog_if_w will disable register in legacy mode
if ((pclass & 0x5) == 0)
logerror("Mapping bar[%i] in legacy mode\n", offset);
}
}
pci_device::address_base_w(space, offset, data);
}

View file

@ -53,6 +53,7 @@ private:
cpu_device *m_cpu;
int m_irq_num;
devcb_write_line m_irq_handler;
uint32_t pci_bar[6];
uint32_t m_config_data[0x10];
DECLARE_ADDRESS_MAP(chan1_data_command_map, 32);
@ -60,6 +61,7 @@ private:
DECLARE_ADDRESS_MAP(chan2_data_command_map, 32);
DECLARE_ADDRESS_MAP(chan2_control_map, 32);
DECLARE_ADDRESS_MAP(bus_master_map, 32);
DECLARE_WRITE8_MEMBER(prog_if_w);
DECLARE_READ32_MEMBER(pcictrl_r);
DECLARE_WRITE32_MEMBER(pcictrl_w);
DECLARE_WRITE32_MEMBER(address_base_w);

View file

@ -23,6 +23,8 @@ DEVICE_ADDRESS_MAP_START(config_map, 32, pci_device)
AM_RANGE(0x2c, 0x2f) AM_WRITENOP
AM_RANGE(0x30, 0x33) AM_READWRITE (expansion_base_r, expansion_base_w)
AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff)
AM_RANGE(0x3c, 0x3f) AM_READWRITE8(interrupt_line_r, interrupt_line_w, 0x000000ff)
AM_RANGE(0x3c, 0x3f) AM_READWRITE8(interrupt_pin_r, interrupt_pin_w, 0x0000ff00)
ADDRESS_MAP_END
DEVICE_ADDRESS_MAP_START(config_map, 32, pci_bridge_device)
@ -67,6 +69,8 @@ pci_device::pci_device(const machine_config &mconfig, device_type type, const ch
pclass = 0xffffff;
subsystem_id = 0xffffffff;
is_multifunction_device = false;
intr_pin = 0x0;
intr_line = 0xff;
}
void pci_device::set_ids(uint32_t _main_id, uint8_t _revision, uint32_t _pclass, uint32_t _subsystem_id)
@ -245,6 +249,30 @@ READ8_MEMBER(pci_device::capptr_r)
return 0x00;
}
READ8_MEMBER(pci_device::interrupt_line_r)
{
logerror("interrupt_line_r = %02x\n", intr_line);
return intr_line;
}
WRITE8_MEMBER(pci_device::interrupt_line_w)
{
COMBINE_DATA(&intr_line);
logerror("interrupt_line_w %02x\n", data);
}
READ8_MEMBER(pci_device::interrupt_pin_r)
{
logerror("interrupt_pin_r = %02x\n", intr_pin);
return intr_pin;
}
WRITE8_MEMBER(pci_device::interrupt_pin_w)
{
COMBINE_DATA(&intr_pin);
logerror("interrupt_pin_w = %02x\n", data);
}
void pci_device::set_remap_cb(mapper_cb _remap_cb)
{
remap_cb = _remap_cb;
@ -749,28 +777,6 @@ WRITE16_MEMBER(pci_bridge_device::iolimitu_w)
logerror("iolimitu_w %04x\n", iolimitu);
}
READ8_MEMBER (pci_bridge_device::interrupt_line_r)
{
logerror("interrupt_line_r\n");
return 0xff;
}
WRITE8_MEMBER (pci_bridge_device::interrupt_line_w)
{
logerror("interrupt_line_w %02x\n", data);
}
READ8_MEMBER (pci_bridge_device::interrupt_pin_r)
{
logerror("interrupt_pin_r\n");
return 0xff;
}
WRITE8_MEMBER (pci_bridge_device::interrupt_pin_w)
{
logerror("interrupt_pin_w %02x\n", data);
}
READ16_MEMBER (pci_bridge_device::bridge_control_r)
{
return bridge_control;

View file

@ -80,6 +80,10 @@ public:
DECLARE_READ32_MEMBER (expansion_base_r);
DECLARE_WRITE32_MEMBER(expansion_base_w);
virtual DECLARE_READ8_MEMBER(capptr_r);
DECLARE_READ8_MEMBER(interrupt_line_r);
DECLARE_WRITE8_MEMBER(interrupt_line_w);
DECLARE_READ8_MEMBER(interrupt_pin_r);
DECLARE_WRITE8_MEMBER(interrupt_pin_w);
protected:
optional_memory_region m_region;
@ -118,6 +122,7 @@ protected:
uint32_t expansion_rom_size;
uint32_t expansion_rom_base;
bool is_multifunction_device;
uint8_t intr_line, intr_pin;
virtual void device_start() override;
virtual void device_reset() override;
@ -192,10 +197,6 @@ public:
DECLARE_WRITE16_MEMBER(iobaseu_w);
DECLARE_READ16_MEMBER (iolimitu_r);
DECLARE_WRITE16_MEMBER(iolimitu_w);
DECLARE_READ8_MEMBER (interrupt_line_r);
DECLARE_WRITE8_MEMBER (interrupt_line_w);
DECLARE_READ8_MEMBER (interrupt_pin_r);
DECLARE_WRITE8_MEMBER (interrupt_pin_w);
DECLARE_READ16_MEMBER (bridge_control_r);
DECLARE_WRITE16_MEMBER(bridge_control_w);