From 1c64de15ef94fe09ffa0a8820501f430ded23b6b Mon Sep 17 00:00:00 2001 From: Ted Green Date: Tue, 17 May 2016 19:03:52 -0600 Subject: [PATCH] voodoo: Stopped blocking of non-fifo'd register writes (nw) gt64xxx: Added PCI stall functions (nw) --- src/devices/machine/gt64xxx.cpp | 98 +++++++++++++++++++++++++++------ src/devices/machine/gt64xxx.h | 9 +++ src/devices/video/voodoo.cpp | 9 ++- 3 files changed, 96 insertions(+), 20 deletions(-) diff --git a/src/devices/machine/gt64xxx.cpp b/src/devices/machine/gt64xxx.cpp index c7a4af83633..a92326f3c4a 100644 --- a/src/devices/machine/gt64xxx.cpp +++ b/src/devices/machine/gt64xxx.cpp @@ -139,6 +139,13 @@ void gt64xxx_device::device_reset() map_cpu_space(); regenerate_config_mapping(); + m_pci_stall_state = 0; + m_retry_count = 0; + m_pci_cpu_stalled = 0; + m_cpu_stalled_offset = 0; + m_cpu_stalled_data = 0; + m_cpu_stalled_mem_mask = 0; + m_dma_active = 0; m_dma_timer->adjust(attotime::never); m_last_dma = 0; @@ -303,6 +310,28 @@ void gt64xxx_device::reset_all_mappings() pci_device::reset_all_mappings(); } +// PCI Stalling +WRITE_LINE_MEMBER(gt64xxx_device::pci_stall) +{ + // Reset the retry count once unstalled + if (state==0 && m_pci_stall_state==1) { + m_retry_count = 0; + // Check if it is a stalled cpu access and re-issue + if (m_pci_cpu_stalled) { + m_pci_cpu_stalled = 0; + // master_mem0_w -- Should actually be checking for master_mem1_w as well + this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM0_LO] << 21) | (m_cpu_stalled_offset * 4), m_cpu_stalled_data, m_cpu_stalled_mem_mask); + /* resume CPU execution */ + machine().scheduler().trigger(45678); + if (LOG_GALILEO) + logerror("Resuming CPU on PCI Stall offset=0x%08X data=0x%08X\n", m_cpu_stalled_offset * 4, m_cpu_stalled_data); + } + } + + /* set the new state */ + m_pci_stall_state = state; +} + // PCI bus control READ32_MEMBER (gt64xxx_device::pci_config_r) { @@ -326,6 +355,18 @@ READ32_MEMBER (gt64xxx_device::master_mem0_r) } WRITE32_MEMBER (gt64xxx_device::master_mem0_w) { + if (m_pci_stall_state) { + // Save the write data and stall the cpu + m_pci_cpu_stalled = 1; + m_cpu_stalled_offset = offset; + m_cpu_stalled_data = data; + m_cpu_stalled_mem_mask = mem_mask; + // Stall cpu until trigger + m_cpu_space->device().execute().spin_until_trigger(45678); + if (LOG_GALILEO || LOG_PCI) + logerror("%08X:Stalling CPU on PCI Stall\n", m_cpu_space->device().safe_pc()); + return; + } this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask); if (LOG_PCI) logerror("%06X:galileo pci mem0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask); @@ -483,7 +524,8 @@ READ32_MEMBER (gt64xxx_device::cpu_if_r) break; default: - logerror("%08X:Galileo read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result); + if (LOG_GALILEO) + logerror("%08X:Galileo read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result); break; } @@ -505,21 +547,21 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) /* switch off the offset for special cases */ switch (offset) { - //case GREG_RAS_1_0_LO: - //case GREG_RAS_1_0_HI: - //case GREG_RAS_3_2_LO: - //case GREG_RAS_3_2_HI: - //case GREG_CS_2_0_LO: - //case GREG_CS_2_0_HI: - //case GREG_CS_3_BOOT_LO: - //case GREG_CS_3_BOOT_HI: - //case GREG_PCI_IO_LO: - //case GREG_PCI_IO_HI: - //case GREG_PCI_MEM0_LO: - //case GREG_PCI_MEM0_HI: + case GREG_RAS_1_0_LO: + case GREG_RAS_1_0_HI: + case GREG_RAS_3_2_LO: + case GREG_RAS_3_2_HI: + case GREG_CS_2_0_LO: + case GREG_CS_2_0_HI: + case GREG_CS_3_BOOT_LO: + case GREG_CS_3_BOOT_HI: + case GREG_PCI_IO_LO: + case GREG_PCI_IO_HI: + case GREG_PCI_MEM0_LO: + case GREG_PCI_MEM0_HI: case GREG_INTERNAL_SPACE: - //case GREG_PCI_MEM1_LO: - //case GREG_PCI_MEM1_HI: + case GREG_PCI_MEM1_LO: + case GREG_PCI_MEM1_HI: case GREG_CS3_HI: map_cpu_space(); remap_cb(); @@ -661,7 +703,8 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w) break; default: - logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); + if (LOG_GALILEO) + logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask); break; } } @@ -818,9 +861,30 @@ TIMER_CALLBACK_MEMBER (gt64xxx_device::perform_dma) /* standard transfer */ while (bytesleft > 0 && burstCount < DMA_BURST_SIZE) { + if (m_pci_stall_state) { + if (LOG_DMA && m_retry_count<4) + logerror("%08X:Stalling DMA on voodoo retry_count: %i\n", m_cpu_space->device().safe_pc(), m_retry_count); + // Save info + m_reg[GREG_DMA0_SOURCE + which] = srcaddr; + m_reg[GREG_DMA0_DEST + which] = dstaddr; + m_reg[GREG_DMA0_COUNT + which] = (m_reg[GREG_DMA0_COUNT + which] & ~0xffff) | bytesleft; + + m_retry_count++; + UINT32 configRetryCount = (m_reg[GREG_PCI_TIMEOUT] >> 16) & 0xff; + if (m_retry_count >= configRetryCount && configRetryCount > 0) { + logerror("gt64xxx_device::perform_dma Error! Too many PCI retries. DMA%d: src=%08X dst=%08X bytes=%04X sinc=%d dinc=%d\n", which, srcaddr, dstaddr, bytesleft, srcinc, dstinc); + // Signal error and abort DMA + m_dma_active &= ~(1 << which); + m_retry_count = 0; + return; + } + else { + // Come back later + return; + } + } if (bytesleft < 4) { - //space.write_byte(dstaddr, space.read_byte(srcaddr)); dstSpace->write_byte(dstaddr, srcSpace->read_byte(srcaddr)); srcaddr += srcinc; dstaddr += dstinc; diff --git a/src/devices/machine/gt64xxx.h b/src/devices/machine/gt64xxx.h index 91846a8fab7..69cde74d34b 100644 --- a/src/devices/machine/gt64xxx.h +++ b/src/devices/machine/gt64xxx.h @@ -209,6 +209,8 @@ public: void set_irq_num(const int irq_num) {m_irq_num = irq_num;} virtual DECLARE_ADDRESS_MAP(config_map, 32) override; + DECLARE_WRITE_LINE_MEMBER(pci_stall); + // pci bus DECLARE_READ32_MEMBER( pci_config_r); DECLARE_WRITE32_MEMBER( pci_config_w); @@ -257,6 +259,13 @@ private: int m_be, m_autoconfig; int m_irq_num; + int m_pci_stall_state; + int m_retry_count; + int m_pci_cpu_stalled; + UINT32 m_cpu_stalled_offset; + UINT32 m_cpu_stalled_data; + UINT32 m_cpu_stalled_mem_mask; + address_space_config m_mem_config, m_io_config; required_memory_region m_romRegion; diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index 3c77de769d7..f257dfc6d8e 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -3671,9 +3671,12 @@ WRITE32_MEMBER( voodoo_device::voodoo_w ) return; } - /* if this is a non-FIFO command, let it go to the FIFO, but stall until it completes */ - if (!(access & REGISTER_FIFO)) - stall = TRUE; + // if this is non-FIFO command, execute immediately + if (!(access & REGISTER_FIFO)) { + register_w(this, offset, data); + g_profiler.stop(); + return; + } /* track swap buffers */ if ((offset & 0xff) == swapbufferCMD)