summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/machine/pci.c')
-rw-r--r--src/emu/machine/pci.c278
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());
+}