diff options
Diffstat (limited to 'src/emu/machine/pci.c')
| -rw-r--r-- | src/emu/machine/pci.c | 278 |
1 files changed, 269 insertions, 9 deletions
diff --git a/src/emu/machine/pci.c b/src/emu/machine/pci.c index edeef668b10..c9568935643 100644 --- a/src/emu/machine/pci.c +++ b/src/emu/machine/pci.c @@ -78,16 +78,16 @@ // GLOBAL VARIABLES //************************************************************************** -const device_type PCI_BUS = &device_creator<pci_bus_device>; +const device_type PCI_BUS_LEGACY = &device_creator<pci_bus_legacy_device>; //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- -// pci_bus_device - constructor +// pci_bus_legacy_device - constructor //------------------------------------------------- -pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : +pci_bus_legacy_device::pci_bus_legacy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, PCI_BUS, "PCI Bus", tag, owner, clock), m_father(NULL) { @@ -103,7 +103,7 @@ pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, d INLINE FUNCTIONS ***************************************************************************/ -READ32_MEMBER( pci_bus_device::read ) +READ32_MEMBER( pci_bus_legacy_device::read ) { UINT32 result = 0xffffffff; int function, reg; @@ -138,10 +138,10 @@ READ32_MEMBER( pci_bus_device::read ) -pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus) +pci_bus_legacy_device *pci_bus_legacy_device::pci_search_bustree(int busnum, int devicenum, pci_bus_legacy_device *pcibus) { int a; - pci_bus_device *ret; + pci_bus_legacy_device *ret; if (pcibus->m_busnum == busnum) { @@ -158,7 +158,7 @@ pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pc -WRITE32_MEMBER( pci_bus_device::write ) +WRITE32_MEMBER( pci_bus_legacy_device::write ) { offset %= 2; @@ -207,6 +207,219 @@ WRITE32_MEMBER( pci_bus_device::write ) +READ64_MEMBER(pci_bus_legacy_device::read_64be) +{ + UINT64 result = 0; + mem_mask = FLIPENDIAN_INT64(mem_mask); + if (ACCESSING_BITS_0_31) + result |= (UINT64)read(space, offset * 2 + 0, mem_mask >> 0) << 0; + if (ACCESSING_BITS_32_63) + result |= (UINT64)read(space, offset * 2 + 1, mem_mask >> 32) << 32; + return FLIPENDIAN_INT64(result); +} + +WRITE64_MEMBER(pci_bus_legacy_device::write_64be) +{ + data = FLIPENDIAN_INT64(data); + mem_mask = FLIPENDIAN_INT64(mem_mask); + if (ACCESSING_BITS_0_31) + write(space, offset * 2 + 0, data >> 0, mem_mask >> 0); + if (ACCESSING_BITS_32_63) + write(space, offset * 2 + 1, data >> 32, mem_mask >> 32); +} + + +void pci_bus_legacy_device::add_sibling(pci_bus_legacy_device *sibling, int busnum) +{ + m_siblings[m_siblings_count] = sibling; + m_siblings_busnum[m_siblings_count] = busnum; + m_siblings_count++; +} + + +//------------------------------------------------- +// device_post_load - handle updating after a +// restore +//------------------------------------------------- + +void pci_bus_legacy_device::device_post_load() +{ + if (m_devicenum != -1) + { + m_busnumaddr = pci_search_bustree(m_busnumber, m_devicenum, this); + } +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void pci_bus_legacy_device::device_start() +{ + /* store a pointer back to the device */ + m_devicenum = -1; + + /* find all our devices */ + for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) + if (m_devtag[i] != NULL) + m_device[i] = machine().device(m_devtag[i]); + + if (m_father != NULL) { + pci_bus_legacy_device *father = machine().device<pci_bus_legacy_device>(m_father); + if (father) + father->add_sibling(this, m_busnum); + } + + /* register pci states */ + save_item(NAME(m_address)); + save_item(NAME(m_devicenum)); + save_item(NAME(m_busnum)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void pci_bus_legacy_device::device_reset() +{ + /* reset the drive state */ + m_devicenum = -1; + m_address = 0; +} + + +// NEW IMPLEMENTATION + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type PCI_BUS = &device_creator<pci_bus_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// pci_bus_device - constructor +//------------------------------------------------- +pci_bus_device::pci_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, PCI_BUS, "PCI Bus", tag, owner, clock), + m_father(NULL) +{ + for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) { + m_devtag[i]= NULL; + } + m_siblings_count = 0; +} + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +READ32_MEMBER( pci_bus_device::read ) +{ + UINT32 result = 0xffffffff; + int function, reg; + + offset %= 2; + + switch (offset) + { + case 0: + result = m_address; + break; + + case 1: + if (m_devicenum != -1) + { + if (m_busnumaddr->m_device[m_devicenum] != NULL) + { + function = (m_address >> 8) & 0x07; + reg = (m_address >> 0) & 0xfc; + result = m_busnumaddr->m_device[m_devicenum]->pci_read(m_busnumaddr, function, reg, mem_mask); + } + } + break; + } + + if (LOG_PCI) + logerror("read('%s'): offset=%d result=0x%08X\n", tag(), offset, result); + + return result; +} + + + +pci_bus_device *pci_bus_device::pci_search_bustree(int busnum, int devicenum, pci_bus_device *pcibus) +{ + int a; + pci_bus_device *ret; + + if (pcibus->m_busnum == busnum) + { + return pcibus; + } + for (a = 0; a < pcibus->m_siblings_count; a++) + { + ret = pci_search_bustree(busnum, devicenum, pcibus->m_siblings[a]); + if (ret != NULL) + return ret; + } + return NULL; +} + + + +WRITE32_MEMBER( pci_bus_device::write ) +{ + offset %= 2; + + if (LOG_PCI) + logerror("write('%s'): offset=%d data=0x%08X\n", tag(), offset, data); + + switch (offset) + { + case 0: + m_address = data; + + /* lookup current device */ + if (m_address & 0x80000000) + { + int busnum = (m_address >> 16) & 0xff; + int devicenum = (m_address >> 11) & 0x1f; + m_busnumaddr = pci_search_bustree(busnum, devicenum, this); + if (m_busnumaddr != NULL) + { + m_busnumber = busnum; + m_devicenum = devicenum; + } + else + m_devicenum = -1; + if (LOG_PCI) + logerror(" bus:%d device:%d\n", busnum, devicenum); + } + break; + + case 1: + if (m_devicenum != -1) + { + if (m_busnumaddr->m_device[m_devicenum] != NULL) + { + int function = (m_address >> 8) & 0x07; + int reg = (m_address >> 0) & 0xfc; + m_busnumaddr->m_device[m_devicenum]->pci_write(m_busnumaddr, function, reg, data, mem_mask); + } + if (LOG_PCI) + logerror(" function:%d register:%d\n", (m_address >> 8) & 0x07, (m_address >> 0) & 0xfc); + } + break; + } +} + + + READ64_MEMBER(pci_bus_device::read_64be) { UINT64 result = 0; @@ -259,10 +472,17 @@ void pci_bus_device::device_start() /* store a pointer back to the device */ m_devicenum = -1; + char id[3]; /* find all our devices */ for (int i = 0; i < ARRAY_LENGTH(m_devtag); i++) - if (m_devtag[i] != NULL) - m_device[i] = machine().device(m_devtag[i]); + { + sprintf(id, "%d", i); + pci_connector *conn = downcast<pci_connector *>(subdevice(id)); + if (conn!=NULL) + m_device[i] = conn->get_device(); + else + m_device[i] = NULL; + } if (m_father != NULL) { pci_bus_device *father = machine().device<pci_bus_device>(m_father); @@ -287,3 +507,43 @@ void pci_bus_device::device_reset() m_devicenum = -1; m_address = 0; } + +//------------------------------------------------- +// pci_device_interface - constructor +//------------------------------------------------- + +pci_device_interface::pci_device_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ +} + +//------------------------------------------------- +// ~pci_device_interface - destructor +//------------------------------------------------- + +pci_device_interface::~pci_device_interface() +{ +} + + +const device_type PCI_CONNECTOR = &device_creator<pci_connector>; + + +pci_connector::pci_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, PCI_CONNECTOR, "PCI device connector abstraction", tag, owner, clock), + device_slot_interface(mconfig, *this) +{ +} + +pci_connector::~pci_connector() +{ +} + +void pci_connector::device_start() +{ +} + +pci_device_interface *pci_connector::get_device() +{ + return dynamic_cast<pci_device_interface *>(get_card_device()); +} |
