mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
(nw) Merge branch 'seattle_pci'
This commit is contained in:
commit
a8b214c9aa
@ -1737,6 +1737,8 @@ if (MACHINES["PCI"]~=null) then
|
||||
MAME_DIR .. "src/devices/machine/pci-usb.h",
|
||||
MAME_DIR .. "src/devices/machine/pci-sata.cpp",
|
||||
MAME_DIR .. "src/devices/machine/pci-sata.h",
|
||||
MAME_DIR .. "src/devices/machine/pci-ide.cpp",
|
||||
MAME_DIR .. "src/devices/machine/pci-ide.h",
|
||||
MAME_DIR .. "src/devices/machine/pci-apic.cpp",
|
||||
MAME_DIR .. "src/devices/machine/pci-apic.h",
|
||||
MAME_DIR .. "src/devices/machine/pci-smbus.cpp",
|
||||
|
@ -8,9 +8,9 @@
|
||||
*
|
||||
*************************************/
|
||||
#define LOG_GALILEO (0)
|
||||
#define LOG_REG (0)
|
||||
#define LOG_TIMERS (0)
|
||||
#define LOG_DMA (0)
|
||||
#define LOG_PCI (0)
|
||||
|
||||
const device_type GT64XXX = &device_creator<gt64xxx_device>;
|
||||
|
||||
@ -28,10 +28,19 @@ gt64xxx_device::gt64xxx_device(const machine_config &mconfig, const char *tag, d
|
||||
m_be(0), m_autoconfig(0), m_irq_num(-1),
|
||||
m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32),
|
||||
m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32),
|
||||
m_region(*this, DEVICE_SELF)
|
||||
m_romRegion(*this, "rom"),
|
||||
m_updateRegion(*this, "update"), m_cs_map(4)
|
||||
{
|
||||
}
|
||||
|
||||
void gt64xxx_device::set_cs_map(int id, address_map_constructor map, const char *name, device_t *device)
|
||||
{
|
||||
m_cs_map[id].enable = true;
|
||||
m_cs_map[id].name = name;
|
||||
m_cs_map[id].device = device;
|
||||
m_cs_map[id].map = map;
|
||||
}
|
||||
|
||||
const address_space_config *gt64xxx_device::memory_space_config(address_spacenum spacenum) const
|
||||
{
|
||||
return (spacenum == AS_PROGRAM) ? pci_bridge_device::memory_space_config(spacenum) : (spacenum == AS_DATA) ? &m_mem_config : (spacenum == AS_IO) ? &m_io_config : nullptr;
|
||||
@ -53,11 +62,35 @@ void gt64xxx_device::device_start()
|
||||
io_offset = 0x00000000;
|
||||
status = 0x0;
|
||||
|
||||
// ROM size = 4 MB
|
||||
m_cpu_space->install_rom (0x1fc00000, 0x1fffffff, m_region->base());
|
||||
//dma_addr_map.reserve(static_cast<size_t>(proc_addr_bank::ADDR_NUM));
|
||||
dma_addr_map.resize(static_cast<size_t>(proc_addr_bank::ADDR_NUM));
|
||||
|
||||
// MIPS drc
|
||||
m_cpu->add_fastram(0x1fc00000, 0x1fffffff, TRUE, m_region->base());
|
||||
// DMA timer
|
||||
m_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::perform_dma), this));
|
||||
// Leave the timer disabled.
|
||||
m_dma_timer->adjust(attotime::never, 0, DMA_TIMER_PERIOD);
|
||||
|
||||
// ROM
|
||||
UINT32 romSize = m_romRegion->bytes();
|
||||
m_cpu_space->install_rom (0x1fc00000, 0x1fc00000 + romSize - 1, m_romRegion->base());
|
||||
// ROM MIPS DRC
|
||||
m_cpu->add_fastram(0x1fc00000, 0x1fc00000 + romSize - 1, TRUE, m_romRegion->base());
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: gt64xxx_device::device_start ROM Mapped size: 0x%08X start: 0x1fc00000 end: %08X\n", tag(), romSize, 0x1fc00000 + romSize - 1);
|
||||
|
||||
// Update region address is based on seattle driver
|
||||
if (m_updateRegion) {
|
||||
romSize = m_updateRegion->bytes();
|
||||
m_cpu_space->install_rom(0x1fd00000, 0x1fd00000 + romSize - 1, m_updateRegion->base());
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: gt64xxx_device::device_start UPDATE Mapped size: 0x%08X start: 0x1fd00000 end: %08X\n", tag(), romSize, 0x1fd00000 + romSize - 1);
|
||||
}
|
||||
|
||||
/* allocate timers for the galileo */
|
||||
m_timer[0].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this));
|
||||
m_timer[1].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this));
|
||||
m_timer[2].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this));
|
||||
m_timer[3].timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gt64xxx_device::timer_callback), this));
|
||||
}
|
||||
|
||||
void gt64xxx_device::device_reset()
|
||||
@ -105,6 +138,12 @@ void gt64xxx_device::device_reset()
|
||||
|
||||
map_cpu_space();
|
||||
regenerate_config_mapping();
|
||||
|
||||
m_dma_active = 0;
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
m_last_dma = 0;
|
||||
|
||||
m_prev_addr = 0;
|
||||
}
|
||||
|
||||
void gt64xxx_device::map_cpu_space()
|
||||
@ -125,14 +164,40 @@ void gt64xxx_device::map_cpu_space()
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_cpu_space cpu_reg start: %08X end: %08X\n", tag(), winStart, winEnd);
|
||||
|
||||
// Ras0
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_LO]<<20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_HI]<<20) | 0xfffff;
|
||||
m_ram[0].resize((winEnd+1-winStart)/4);
|
||||
m_cpu_space->install_ram(winStart, winEnd, &m_ram[0][0]);
|
||||
m_cpu->add_fastram(winStart, m_ram[0].size()*sizeof(m_ram[0][0]), FALSE, &m_ram[0][0]);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_cpu_space ras0 start: %08X end: %08X\n", tag(), winStart, winEnd);
|
||||
// RAS[0:3]
|
||||
for (int ramIndex = 0; ramIndex < 4; ++ramIndex)
|
||||
{
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex/2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
m_ram[ramIndex].resize((winEnd + 1 - winStart) / 4);
|
||||
m_cpu_space->install_ram(winStart, winEnd, m_ram[ramIndex].data());
|
||||
//m_cpu->add_fastram(winStart, m_ram[ramIndex].size() * sizeof(m_ram[ramIndex][0]), FALSE, &m_ram[ramIndex][0]);
|
||||
//m_cpu->add_fastram(winStart, m_ram[ramIndex].size() * sizeof(UINT32), FALSE, m_ram[ramIndex].data());
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_cpu_space ras[%i] start: %08X end: %08X\n", tag(), ramIndex, winStart, winEnd);
|
||||
}
|
||||
|
||||
// CS[0:3]
|
||||
//m_cpu_space->install_device_delegate(0x16000000, 0x17ffffff, machine().root_device(), m_cs_map[3].map);
|
||||
typedef void (gt64xxx_device::*tramp_t)(::address_map &, device_t &);
|
||||
static const tramp_t trampolines[4] = {
|
||||
>64xxx_device::map_trampoline<0>,
|
||||
>64xxx_device::map_trampoline<1>,
|
||||
>64xxx_device::map_trampoline<2>,
|
||||
>64xxx_device::map_trampoline<3>
|
||||
};
|
||||
for (int ramIndex = 0; ramIndex < 4; ++ramIndex)
|
||||
{
|
||||
if (m_cs_map[ramIndex].enable)
|
||||
{
|
||||
winStart = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (ramIndex / 3)] << 21) | (m_reg[GREG_CS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_CS_2_0_LO + 0x10 / 4 * (ramIndex / 3)] << 21) | (m_reg[GREG_CS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
install_cs_map(winStart, winEnd, trampolines[ramIndex], m_cs_map[ramIndex].name);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_cpu_space cs[%i] start: %08X end: %08X\n", tag(), ramIndex, winStart, winEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PCI IO Window
|
||||
winStart = m_reg[GREG_PCI_IO_LO]<<21;
|
||||
@ -158,25 +223,79 @@ void gt64xxx_device::map_cpu_space()
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_cpu_space pci_mem1 start: %08X end: %08X\n", tag(), winStart, winEnd);
|
||||
|
||||
// Setup the address mapping table for DMA lookups
|
||||
for (size_t index = 0; index < proc_addr_bank::ADDR_NUM; ++index)
|
||||
{
|
||||
if (index < proc_addr_bank::ADDR_PCI_MEM1) {
|
||||
dma_addr_map[index].low_addr = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * index] << 21);
|
||||
dma_addr_map[index].high_addr = (dma_addr_map[index].low_addr & 0xf0000000) | (m_reg[GREG_RAS_1_0_HI + 0x10 / 4 * index] << 21) | 0x1fffff;
|
||||
}
|
||||
else {
|
||||
dma_addr_map[index].low_addr = (m_reg[GREG_PCI_MEM1_LO] << 21);
|
||||
dma_addr_map[index].high_addr = (dma_addr_map[index].low_addr & 0xf0000000) | (m_reg[GREG_PCI_MEM1_HI] << 21) | 0x1fffff;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case proc_addr_bank::ADDR_PCI_IO:
|
||||
dma_addr_map[index].space = &this->space(AS_IO);
|
||||
break;
|
||||
case proc_addr_bank::ADDR_PCI_MEM0:
|
||||
case proc_addr_bank::ADDR_PCI_MEM1:
|
||||
dma_addr_map[index].space = &this->space(AS_DATA);
|
||||
break;
|
||||
default:
|
||||
dma_addr_map[index].space = m_cpu_space;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gt64xxx_device::map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space,
|
||||
UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space)
|
||||
{
|
||||
/*
|
||||
int ramIndex;
|
||||
UINT32 winStart, winEnd, winSize;
|
||||
|
||||
// PCI Target Window 1
|
||||
if (m_cpu_regs[NREG_PCITW1]&0x1000) {
|
||||
winStart = m_cpu_regs[NREG_PCITW1]&0xffe00000;
|
||||
winEnd = winStart | (~(0xf0000000 | (((m_cpu_regs[NREG_PCITW1]>>13)&0x7f)<<21)));
|
||||
winSize = winEnd - winStart + 1;
|
||||
memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::target1_r), this));
|
||||
memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::target1_w), this));
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_extra Target Window 1 start=%08X end=%08X size=%08X laddr=%08X\n", tag(), winStart, winEnd, winSize, m_target1_laddr);
|
||||
}
|
||||
*/
|
||||
|
||||
// Not sure if GREG_RAS_1_0_LO should be added on PCI address map side.
|
||||
// RAS0
|
||||
ramIndex = 0;
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
winSize = winEnd - winStart + 1;
|
||||
memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_0_r), this));
|
||||
memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_0_w), this));
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_extra RAS0 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize);
|
||||
|
||||
// RAS1
|
||||
ramIndex = 1;
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
winSize = winEnd - winStart + 1;
|
||||
memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_1_r), this));
|
||||
memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_1_w), this));
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_extra RAS1 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize);
|
||||
|
||||
// RAS2
|
||||
ramIndex = 2;
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
winSize = winEnd - winStart + 1;
|
||||
memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_2_r), this));
|
||||
memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_2_w), this));
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_extra RAS2 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize);
|
||||
|
||||
// RAS3
|
||||
ramIndex = 3;
|
||||
winStart = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_LO + 0x8 / 4 * ramIndex] << 20);
|
||||
winEnd = (m_reg[GREG_RAS_1_0_LO + 0x10 / 4 * (ramIndex / 2)] << 21) | (m_reg[GREG_RAS0_HI + 0x8 / 4 * ramIndex] << 20) | 0xfffff;
|
||||
winSize = winEnd - winStart + 1;
|
||||
memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::ras_3_r), this));
|
||||
memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::ras_3_w), this));
|
||||
if (LOG_GALILEO)
|
||||
logerror("%s: map_extra RAS3 start=%08X end=%08X size=%08X\n", tag(), winStart, winEnd, winSize);
|
||||
}
|
||||
|
||||
void gt64xxx_device::reset_all_mappings()
|
||||
@ -201,14 +320,14 @@ WRITE32_MEMBER (gt64xxx_device::pci_config_w)
|
||||
READ32_MEMBER (gt64xxx_device::master_mem0_r)
|
||||
{
|
||||
UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo pci mem0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
WRITE32_MEMBER (gt64xxx_device::master_mem0_w)
|
||||
{
|
||||
this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -216,14 +335,14 @@ WRITE32_MEMBER (gt64xxx_device::master_mem0_w)
|
||||
READ32_MEMBER (gt64xxx_device::master_mem1_r)
|
||||
{
|
||||
UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo pci mem1 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
WRITE32_MEMBER (gt64xxx_device::master_mem1_w)
|
||||
{
|
||||
this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo pci mem1 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask);
|
||||
}
|
||||
|
||||
@ -231,15 +350,79 @@ WRITE32_MEMBER (gt64xxx_device::master_mem1_w)
|
||||
READ32_MEMBER (gt64xxx_device::master_io_r)
|
||||
{
|
||||
UINT32 result = this->space(AS_IO).read_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%06X:galileo pci io read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), result, mem_mask);
|
||||
if (LOG_PCI && m_prev_addr != offset) {
|
||||
m_prev_addr = offset;
|
||||
logerror("%06X:galileo pci io read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), result, mem_mask);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
WRITE32_MEMBER (gt64xxx_device::master_io_w)
|
||||
{
|
||||
this->space(AS_IO).write_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%06X:galileo pciio write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask);
|
||||
if (LOG_PCI && m_prev_addr != offset) {
|
||||
m_prev_addr = offset;
|
||||
logerror("%06X:galileo pciio write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO] << 21) | (offset * 4), data, mem_mask);
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(gt64xxx_device::ras_0_r)
|
||||
{
|
||||
UINT32 result = m_ram[0][offset];
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(gt64xxx_device::ras_0_w)
|
||||
{
|
||||
COMBINE_DATA(&m_ram[0][offset]);
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(gt64xxx_device::ras_1_r)
|
||||
{
|
||||
UINT32 result = m_ram[1][offset];
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(gt64xxx_device::ras_1_w)
|
||||
{
|
||||
COMBINE_DATA(&m_ram[1][offset]);
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(gt64xxx_device::ras_2_r)
|
||||
{
|
||||
UINT32 result = m_ram[2][offset];
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(gt64xxx_device::ras_2_w)
|
||||
{
|
||||
COMBINE_DATA(&m_ram[2][offset]);
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(gt64xxx_device::ras_3_r)
|
||||
{
|
||||
UINT32 result = m_ram[3][offset];
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, result, mem_mask);
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(gt64xxx_device::ras_3_w)
|
||||
{
|
||||
COMBINE_DATA(&m_ram[3][offset]);
|
||||
if (LOG_PCI)
|
||||
logerror("%06X:galileo ras_0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask);
|
||||
}
|
||||
|
||||
|
||||
@ -267,7 +450,7 @@ READ32_MEMBER (gt64xxx_device::cpu_if_r)
|
||||
}
|
||||
|
||||
/* eat some time for those which poll this register */
|
||||
space.device().execute().eat_cycles(100);
|
||||
//space.device().execute().eat_cycles(100);
|
||||
|
||||
if (LOG_TIMERS)
|
||||
logerror("%08X:hires_timer_r = %08X\n", space.device().safe_pc(), result);
|
||||
@ -277,10 +460,15 @@ READ32_MEMBER (gt64xxx_device::cpu_if_r)
|
||||
case GREG_PCI_COMMAND:
|
||||
// code at 40188 loops until this returns non-zero in bit 0
|
||||
//result = 0x0001;
|
||||
// bit 0 => byte swap
|
||||
// bit 2:1 => SyncMode, 00 = PCLK=[0,33], 01 = PCLK>=TClk/2, 10 = PCLK = TCLK/2
|
||||
result = (result & ~0x1) | (m_be ^ 0x1);
|
||||
break;
|
||||
|
||||
case GREG_CONFIG_DATA:
|
||||
result = config_data_r(space, offset);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%08X:Galileo GREG_CONFIG_DATA read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result);
|
||||
break;
|
||||
|
||||
case GREG_CONFIG_ADDRESS:
|
||||
@ -317,22 +505,24 @@ 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();
|
||||
if (LOG_GALILEO)
|
||||
logerror("%08X:Galileo Memory Map data write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
|
||||
break;
|
||||
@ -344,9 +534,6 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w)
|
||||
{
|
||||
int which = offset % 4;
|
||||
|
||||
if (LOG_DMA)
|
||||
logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
|
||||
|
||||
/* keep the read only activity bit */
|
||||
m_reg[offset] &= ~0x4000;
|
||||
m_reg[offset] |= (oldata & 0x4000);
|
||||
@ -357,8 +544,18 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w)
|
||||
m_reg[offset] &= ~0x2000;
|
||||
|
||||
/* if enabling, start the DMA */
|
||||
if (!(oldata & 0x1000) && (data & 0x1000))
|
||||
perform_dma(space, which);
|
||||
if (!(oldata & 0x1000) && (data & 0x1000) && !(m_dma_active & (1<<which)))
|
||||
{
|
||||
// Trigger the timer if there are no dma's active
|
||||
if (m_dma_active==0)
|
||||
m_dma_timer->adjust(attotime::zero, 0, DMA_TIMER_PERIOD);
|
||||
m_dma_active |= (1<< which);
|
||||
//perform_dma(space, which);
|
||||
if (LOG_DMA)
|
||||
logerror("%08X:Galileo starting DMA Chan %i\n", space.device().safe_pc(), which);
|
||||
}
|
||||
if (LOG_GALILEO)
|
||||
logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset * 4, data, mem_mask);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -428,9 +625,30 @@ WRITE32_MEMBER(gt64xxx_device::cpu_if_w)
|
||||
break;
|
||||
|
||||
case GREG_CONFIG_ADDRESS:
|
||||
pci_host_device::config_address_w(space, offset, data);
|
||||
// Type 0 config transactions signalled by Bus Num = 0 and Device Num != 0
|
||||
// Bits 15:11 get mapped into device number for configuration
|
||||
UINT32 modData;
|
||||
if (0 && (data & 0xff0000) == 0x0 && (data & 0xf800)) {
|
||||
// Type 0 transaction
|
||||
modData = 0;
|
||||
// Select the device based on one hot bit
|
||||
for (int i = 11; i<16; i++) {
|
||||
if ((data >> i) & 0x1) {
|
||||
// One hot encoding, bit 11 will mean device 1
|
||||
modData = i - 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Re-organize into Type 1 transaction for bus 0 (local bus)
|
||||
modData = (modData << 11) | (data & 0x7ff) | (0x80000000);
|
||||
}
|
||||
else {
|
||||
// Type 1 transaction, no modification needed
|
||||
modData = data;
|
||||
}
|
||||
pci_host_device::config_address_w(space, offset, modData);
|
||||
if (LOG_GALILEO)
|
||||
logerror("%08X:Galileo PCI config address write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
|
||||
logerror("%08X:Galileo PCI config address write to offset %03X = %08X & %08X origData = %08X\n", space.device().safe_pc(), offset*4, modData, mem_mask, data);
|
||||
break;
|
||||
|
||||
case GREG_DMA0_COUNT: case GREG_DMA1_COUNT: case GREG_DMA2_COUNT: case GREG_DMA3_COUNT:
|
||||
@ -464,8 +682,8 @@ void gt64xxx_device::update_irqs()
|
||||
if (m_irq_num != -1)
|
||||
m_cpu->set_input_line(m_irq_num, state);
|
||||
|
||||
if (LOG_GALILEO)
|
||||
logerror("Galileo IRQ %s\n", (state == ASSERT_LINE) ? "asserted" : "cleared");
|
||||
if (1 && LOG_GALILEO)
|
||||
logerror("Galileo IRQ %s irqNum: %i state = %08X mask = %08X\n", (state == ASSERT_LINE) ? "asserted" : "cleared", m_irq_num, m_reg[GREG_INT_STATE], m_reg[GREG_INT_MASK]);
|
||||
}
|
||||
|
||||
|
||||
@ -498,6 +716,15 @@ TIMER_CALLBACK_MEMBER(gt64xxx_device::timer_callback)
|
||||
* Galileo DMA handler
|
||||
*
|
||||
*************************************/
|
||||
address_space* gt64xxx_device::dma_decode_address(UINT32 &addr)
|
||||
{
|
||||
for (size_t index = 0; index < proc_addr_bank::ADDR_NUM; ++index)
|
||||
{
|
||||
if (addr >= dma_addr_map[index].low_addr && addr <= dma_addr_map[index].high_addr)
|
||||
return dma_addr_map[index].space;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int gt64xxx_device::dma_fetch_next(address_space &space, int which)
|
||||
{
|
||||
@ -539,16 +766,33 @@ int gt64xxx_device::dma_fetch_next(address_space &space, int which)
|
||||
}
|
||||
|
||||
|
||||
void gt64xxx_device::perform_dma(address_space &space, int which)
|
||||
TIMER_CALLBACK_MEMBER (gt64xxx_device::perform_dma)
|
||||
{
|
||||
do
|
||||
// Cycle through the channels
|
||||
int which = -1;
|
||||
for (int i = 1; i <= 4; i++)
|
||||
{
|
||||
which = (m_last_dma + i) % 4;
|
||||
if ((m_dma_active & (1 << which)) && (m_reg[GREG_DMA0_CONTROL + which] & 0x1000))
|
||||
break;
|
||||
|
||||
}
|
||||
// Save which dma is processed for arbitration next time
|
||||
m_last_dma = which;
|
||||
|
||||
if (which==-1)
|
||||
{
|
||||
logerror("gt64xxx_device::perform_dma Warning! DMA Timer called with no pending DMA. m_dma_active = %08X\n", m_dma_active);
|
||||
} else
|
||||
{
|
||||
offs_t srcaddr = m_reg[GREG_DMA0_SOURCE + which];
|
||||
offs_t dstaddr = m_reg[GREG_DMA0_DEST + which];
|
||||
UINT32 bytesleft = m_reg[GREG_DMA0_COUNT + which] & 0xffff;
|
||||
address_space* srcSpace = dma_decode_address(srcaddr);
|
||||
address_space* dstSpace = dma_decode_address(dstaddr);
|
||||
|
||||
int srcinc, dstinc;
|
||||
|
||||
m_dma_active = which;
|
||||
m_reg[GREG_DMA0_CONTROL + which] |= 0x5000;
|
||||
|
||||
/* determine src/dst inc */
|
||||
@ -570,32 +814,50 @@ void gt64xxx_device::perform_dma(address_space &space, int which)
|
||||
if (LOG_DMA)
|
||||
logerror("Performing DMA%d: src=%08X dst=%08X bytes=%04X sinc=%d dinc=%d\n", which, srcaddr, dstaddr, bytesleft, srcinc, dstinc);
|
||||
|
||||
int burstCount = 0;
|
||||
/* standard transfer */
|
||||
while (bytesleft > 0)
|
||||
while (bytesleft > 0 && burstCount < DMA_BURST_SIZE)
|
||||
{
|
||||
if (bytesleft < 4)
|
||||
{
|
||||
space.write_byte(dstaddr, space.read_byte(srcaddr));
|
||||
//space.write_byte(dstaddr, space.read_byte(srcaddr));
|
||||
dstSpace->write_byte(dstaddr, srcSpace->read_byte(srcaddr));
|
||||
srcaddr += srcinc;
|
||||
dstaddr += dstinc;
|
||||
bytesleft--;
|
||||
}
|
||||
|
||||
else {
|
||||
//space.write_byte(dstaddr, space.read_byte(srcaddr));
|
||||
dstSpace->write_dword(dstaddr, srcSpace->read_dword(srcaddr));
|
||||
srcaddr += srcinc * 4;
|
||||
dstaddr += dstinc * 4;
|
||||
bytesleft -= 4;
|
||||
}
|
||||
burstCount++;
|
||||
}
|
||||
/* not verified, but seems logical these should be updated byte the end */
|
||||
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_dma_active = -1;
|
||||
|
||||
/* if we did not hit zero, punt and return later */
|
||||
if (bytesleft != 0)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
/* interrupt? */
|
||||
if (!(m_reg[GREG_DMA0_CONTROL + which] & 0x400))
|
||||
{
|
||||
m_reg[GREG_INT_STATE] |= 1 << (GINT_DMA0COMP_SHIFT + which);
|
||||
update_irqs();
|
||||
}
|
||||
} while (dma_fetch_next(space, which));
|
||||
|
||||
m_reg[GREG_DMA0_CONTROL + which] &= ~0x5000;
|
||||
// Fetch the next dma for this channel (to be performed next scheduled burst)
|
||||
if (dma_fetch_next(*m_cpu_space, which) == 0)
|
||||
{
|
||||
m_dma_active &= ~(1 << which);
|
||||
// Turn off the timer
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,7 @@
|
||||
// Galileo GT-64xxx System Controller
|
||||
// Skeleton code based off seattle machine driver.
|
||||
// TODO:
|
||||
// Testing
|
||||
// Need PCI to be able to have a target delay a dma transfer
|
||||
// Add PCI target maps
|
||||
// Add PCI Func 1 calls
|
||||
// Need PCI to be able to have a target delay (pci bus stall) a dma transfer
|
||||
// Configurable byte swapping on cpu and pci busses.
|
||||
|
||||
#ifndef GT64XXX_H
|
||||
@ -16,34 +13,42 @@
|
||||
#include "cpu/mips/mips3.h"
|
||||
|
||||
// Supports R4600/4650/4700/R5000 CPUs
|
||||
#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock) \
|
||||
#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock, _irq_num) \
|
||||
MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x014611ab, 0x03, 0x00000000) \
|
||||
downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
|
||||
downcast<gt64xxx_device *>(device)->set_clock(_clock);
|
||||
downcast<gt64xxx_device *>(device)->set_clock(_clock); \
|
||||
downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);
|
||||
|
||||
// Supports the following 32-bit bus CPUs:
|
||||
// IDT RC4640 and RC4650 (in 32-bit mode)
|
||||
// QED RM523X
|
||||
// NEC/Toshiba VR4300
|
||||
#define MCFG_GT64111_ADD(_tag, _cpu_tag, _clock) \
|
||||
#define MCFG_GT64111_ADD(_tag, _cpu_tag, _clock, _irq_num) \
|
||||
MCFG_PCI_DEVICE_ADD(_tag, GT64XXX, 0x414611ab, 0x10, 0x058000, 0x00000000) \
|
||||
downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
|
||||
downcast<gt64xxx_device *>(device)->set_clock(_clock);
|
||||
downcast<gt64xxx_device *>(device)->set_clock(_clock); \
|
||||
downcast<gt64xxx_device *>(device)->set_irq_num(_irq_num);
|
||||
|
||||
#define MCFG_GT64XXX_SET_BE_CPU(_be) \
|
||||
downcast<gt64xxx_device *>(device)->set_be(_be);
|
||||
|
||||
#define MCFG_GT64XXX__IRQ_ADD(_irq_num) \
|
||||
#define MCFG_GT64XXX_IRQ_ADD(_irq_num) \
|
||||
downcast<gt64xxx_device *>(device)->set_irq_info(_irq_num);
|
||||
|
||||
#define MCFG_GT64XXX_SET_CS(_cs_num, _map) \
|
||||
downcast<gt64xxx_device *>(device)->set_cs_map(_cs_num, ADDRESS_MAP_NAME(_map), #_map, owner);
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Galileo constants
|
||||
*
|
||||
*************************************/
|
||||
|
||||
//#define SYSTEM_CLOCK 50000000
|
||||
#define TIMER_PERIOD attotime::from_hz(m_clock)
|
||||
#define PCI_BUS_CLOCK 33000000
|
||||
// Number of dma words to transfer at a time, real hardware configurable between 8-32
|
||||
#define DMA_BURST_SIZE 32
|
||||
#define DMA_TIMER_PERIOD attotime::from_hz(PCI_BUS_CLOCK / 48)
|
||||
|
||||
/* Galileo registers - 0x000-0x3ff */
|
||||
#define GREG_CPU_CONFIG (0x000/4)
|
||||
@ -161,6 +166,7 @@
|
||||
#define GINT_TARABORT_SHIFT (19)
|
||||
#define GINT_RETRYCTR_SHIFT (20)
|
||||
|
||||
|
||||
/*************************************
|
||||
* Structures
|
||||
*************************************/
|
||||
@ -171,6 +177,22 @@ struct galileo_timer
|
||||
UINT8 active;
|
||||
};
|
||||
|
||||
struct galileo_addr_map
|
||||
{
|
||||
UINT32 low_addr;
|
||||
UINT32 high_addr;
|
||||
address_space* space;
|
||||
galileo_addr_map() : low_addr(0xffffffff), high_addr(0x0) {}
|
||||
};
|
||||
|
||||
struct galileo_device_map
|
||||
{
|
||||
bool enable;
|
||||
const char *name;
|
||||
device_t *device;
|
||||
address_map_constructor map;
|
||||
galileo_device_map() : enable(false), device(nullptr) {}
|
||||
};
|
||||
|
||||
class gt64xxx_device : public pci_host_device {
|
||||
public:
|
||||
@ -181,12 +203,10 @@ public:
|
||||
UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) override;
|
||||
|
||||
void set_cpu_tag(const char *tag) { cpu_tag = tag;}
|
||||
void set_cpu_tag(const UINT32 clock) { m_clock = clock;}
|
||||
void set_clock(const UINT32 clock) {m_clock = clock;}
|
||||
void set_be(const int be) {m_be = be;}
|
||||
void set_autoconfig(const int autoconfig) {m_autoconfig = autoconfig;}
|
||||
void set_irq_info(const int irq_num) {m_irq_num = irq_num;}
|
||||
|
||||
void set_irq_num(const int irq_num) {m_irq_num = irq_num;}
|
||||
virtual DECLARE_ADDRESS_MAP(config_map, 32) override;
|
||||
|
||||
// pci bus
|
||||
@ -207,14 +227,21 @@ public:
|
||||
DECLARE_WRITE32_MEMBER(master_io_w);
|
||||
|
||||
// devices
|
||||
DECLARE_READ32_MEMBER (ras_1_0_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_1_0_w);
|
||||
DECLARE_READ32_MEMBER (ras_3_2_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_3_2_w);
|
||||
DECLARE_READ32_MEMBER (cs_2_0_r);
|
||||
DECLARE_WRITE32_MEMBER(cs_2_0_w);
|
||||
DECLARE_READ32_MEMBER (cs_boot_3_r);
|
||||
DECLARE_WRITE32_MEMBER(cs_boot_3_w);
|
||||
DECLARE_READ32_MEMBER (ras_0_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_0_w);
|
||||
DECLARE_READ32_MEMBER(ras_1_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_1_w);
|
||||
DECLARE_READ32_MEMBER(ras_2_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_2_w);
|
||||
DECLARE_READ32_MEMBER(ras_3_r);
|
||||
DECLARE_WRITE32_MEMBER(ras_3_w);
|
||||
DECLARE_READ32_MEMBER (cs_0_r);
|
||||
DECLARE_WRITE32_MEMBER(cs_0_w);
|
||||
|
||||
// Enums
|
||||
enum proc_addr_bank {ADDR_RAS1_0, ADDR_RAS3_2, ADDR_CS2_0, ADDR_CS3_BCS, ADDR_PCI_IO, ADDR_PCI_MEM0, ADDR_PCI_MEM1, ADDR_NUM};
|
||||
|
||||
void set_cs_map(int id, address_map_constructor map, const char *name, device_t *device);
|
||||
|
||||
protected:
|
||||
address_space *m_cpu_space;
|
||||
@ -222,6 +249,7 @@ protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
|
||||
private:
|
||||
mips3_device *m_cpu;
|
||||
const char *cpu_tag;
|
||||
@ -231,17 +259,20 @@ private:
|
||||
|
||||
address_space_config m_mem_config, m_io_config;
|
||||
|
||||
required_memory_region m_region;
|
||||
required_memory_region m_romRegion;
|
||||
optional_memory_region m_updateRegion;
|
||||
|
||||
DECLARE_ADDRESS_MAP(cpu_map, 32);
|
||||
|
||||
void map_cpu_space();
|
||||
|
||||
UINT32 m_prev_addr;
|
||||
/* raw register data */
|
||||
UINT32 m_reg[0xd00/4];
|
||||
|
||||
/* timer info */
|
||||
galileo_timer m_timer[4];
|
||||
TIMER_CALLBACK_MEMBER(timer_callback);
|
||||
|
||||
/* DMA info */
|
||||
INT8 m_dma_active;
|
||||
@ -249,10 +280,26 @@ private:
|
||||
// Ram
|
||||
std::vector<UINT32> m_ram[4];
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_callback);
|
||||
// Chip Select
|
||||
std::vector<galileo_device_map> m_cs_map;
|
||||
|
||||
template<int id> void map_trampoline(::address_map &map, device_t &device) {
|
||||
m_cs_map[id].map(map, *m_cs_map[id].device);
|
||||
}
|
||||
template <typename T> void install_cs_map(offs_t addrstart, offs_t addrend, void (T::*map)(::address_map &map, device_t &device), const char *name) {
|
||||
//address_map_delegate delegate(map, name, static_cast<T *>(this));
|
||||
address_map_delegate delegate(map, name, static_cast<T *>(this));
|
||||
m_cpu_space->install_device_delegate(addrstart, addrend, *this, delegate);
|
||||
}
|
||||
|
||||
void update_irqs();
|
||||
|
||||
int m_last_dma;
|
||||
emu_timer* m_dma_timer;
|
||||
std::vector<galileo_addr_map> dma_addr_map;
|
||||
int dma_fetch_next(address_space &space, int which);
|
||||
void perform_dma(address_space &space, int which);
|
||||
TIMER_CALLBACK_MEMBER(perform_dma);
|
||||
address_space* dma_decode_address(UINT32 &addr);
|
||||
|
||||
};
|
||||
|
||||
|
157
src/devices/machine/pci-ide.cpp
Normal file
157
src/devices/machine/pci-ide.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ted Green
|
||||
#include "pci-ide.h"
|
||||
|
||||
const device_type IDE_PCI = &device_creator<ide_pci_device>;
|
||||
|
||||
ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: pci_device(mconfig, IDE_PCI, "IDE PCI interface", tag, owner, clock, "ide_pci", __FILE__),
|
||||
m_ide(*this, "ide"),
|
||||
m_ide2(*this, "ide2"),
|
||||
m_irq_num(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(config_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x10, 0x17) AM_WRITE(address_base_w)
|
||||
AM_RANGE(0x40, 0x5f) AM_READWRITE(pcictrl_r, pcictrl_w)
|
||||
AM_INHERIT_FROM(pci_device::config_map)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(chan1_data_command_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, read_cs0, write_cs0)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(chan1_control_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x0, 0x3) AM_READWRITE(ide_read_cs1, ide_write_cs1)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(chan2_data_command_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, read_cs0, write_cs0)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(chan2_control_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x0, 0x3) AM_READWRITE(ide2_read_cs1, ide2_write_cs1)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
DEVICE_ADDRESS_MAP_START(bus_master_map, 32, ide_pci_device)
|
||||
AM_RANGE(0x0, 0x7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w)
|
||||
AM_RANGE(0x8, 0xf) AM_DEVREADWRITE("ide2", bus_master_ide_controller_device, bmdma_r, bmdma_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT(pci_ide)
|
||||
MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", nullptr, true)
|
||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(ide_pci_device, ide_interrupt))
|
||||
//MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
|
||||
MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":pci:00.0", AS_DATA)
|
||||
MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, nullptr, "cdrom", true)
|
||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(ide_pci_device, ide_interrupt))
|
||||
//MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM)
|
||||
MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":pci:00.0", AS_DATA)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor ide_pci_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME(pci_ide);
|
||||
}
|
||||
|
||||
void ide_pci_device::set_irq_info(const char *tag, const int irq_num)
|
||||
{
|
||||
m_cpu_tag = tag;
|
||||
m_irq_num = irq_num;
|
||||
}
|
||||
|
||||
void ide_pci_device::device_start()
|
||||
{
|
||||
m_cpu = machine().device<cpu_device>(m_cpu_tag);
|
||||
|
||||
pci_device::device_start();
|
||||
|
||||
add_map(8, M_IO, FUNC(ide_pci_device::chan1_data_command_map));
|
||||
bank_infos[0].adr = 0x1f0;
|
||||
add_map(4, M_IO, FUNC(ide_pci_device::chan1_control_map));
|
||||
bank_infos[1].adr = 0x3f4;
|
||||
add_map(8, M_IO, FUNC(ide_pci_device::chan2_data_command_map));
|
||||
bank_infos[2].adr = 0x170;
|
||||
add_map(4, M_IO, FUNC(ide_pci_device::chan2_control_map));
|
||||
bank_infos[3].adr = 0x374;
|
||||
add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map));
|
||||
bank_infos[4].adr = 0xf00;
|
||||
}
|
||||
|
||||
void ide_pci_device::device_reset()
|
||||
{
|
||||
pci_device::device_reset();
|
||||
}
|
||||
|
||||
READ32_MEMBER(ide_pci_device::ide_read_cs1)
|
||||
{
|
||||
// PCI offset starts at 0x3f4, idectrl expects 0x3f0
|
||||
UINT32 data = 0;
|
||||
data = m_ide->read_cs1(space, ++offset, mem_mask);
|
||||
return data;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
READ32_MEMBER(ide_pci_device::ide2_read_cs1)
|
||||
{
|
||||
// PCI offset starts at 0x374, idectrl expects 0x370
|
||||
UINT32 data = 0;
|
||||
data = m_ide2->read_cs1(space, ++offset, 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);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt)
|
||||
{
|
||||
if (m_irq_num != -1) {
|
||||
m_cpu->set_input_line(m_irq_num, state);
|
||||
}
|
||||
if (0)
|
||||
logerror("%s:ide_interrupt %i set to %i\n", machine().describe_context(), m_irq_num, state);
|
||||
}
|
||||
|
||||
READ32_MEMBER(ide_pci_device::pcictrl_r)
|
||||
{
|
||||
return m_config_data[offset];
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(ide_pci_device::pcictrl_w)
|
||||
{
|
||||
COMBINE_DATA(&m_config_data[offset]);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(ide_pci_device::address_base_w)
|
||||
{
|
||||
if (1) {
|
||||
// Bits 0 (ide) and 2 (ide2) control if the mapping is legacy or BAR
|
||||
switch (offset) {
|
||||
case 0:
|
||||
if ((pclass & 0x1) == 0)
|
||||
data = (data & 0xfffff000) | 0x1f0;
|
||||
break;
|
||||
case 1:
|
||||
if ((pclass & 0x1) == 0)
|
||||
data = (data & 0xfffff000) | 0x3f4;
|
||||
break;
|
||||
case 2:
|
||||
if ((pclass & 0x4) == 0)
|
||||
data = (data & 0xfffff000) | 0x170;
|
||||
break;
|
||||
default:
|
||||
if ((pclass & 0x4) == 0)
|
||||
data = (data & 0xfffff000) | 0x374;
|
||||
}
|
||||
}
|
||||
pci_device::address_base_w(space, offset, data);
|
||||
}
|
65
src/devices/machine/pci-ide.h
Normal file
65
src/devices/machine/pci-ide.h
Normal file
@ -0,0 +1,65 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ted Green
|
||||
/***************************************************************************
|
||||
|
||||
pci-ide.h
|
||||
|
||||
Generic PCI IDE controller implementation.
|
||||
Based on datasheet for National Semiconductor PC87415
|
||||
|
||||
TODO:
|
||||
Add pci configuration write to PIF byte
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PCI_IDE_H
|
||||
#define PCI_IDE_H
|
||||
|
||||
#include "pci.h"
|
||||
#include "idectrl.h"
|
||||
|
||||
#define MCFG_IDE_PCI_ADD(_tag, _main_id, _revision, _subdevice_id) \
|
||||
MCFG_PCI_DEVICE_ADD(_tag, IDE_PCI, _main_id, _revision, 0x01018a, _subdevice_id)
|
||||
|
||||
#define MCFG_IDE_PCI_IRQ_ADD(_cpu_tag, _irq_num) \
|
||||
downcast<ide_pci_device *>(device)->set_irq_info(_cpu_tag, _irq_num);
|
||||
|
||||
class ide_pci_device : public pci_device {
|
||||
public:
|
||||
ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
required_device<bus_master_ide_controller_device> m_ide;
|
||||
required_device<bus_master_ide_controller_device> m_ide2;
|
||||
virtual DECLARE_ADDRESS_MAP(config_map, 32) override;
|
||||
DECLARE_WRITE_LINE_MEMBER(ide_interrupt);
|
||||
DECLARE_READ32_MEMBER(ide_read_cs1);
|
||||
DECLARE_WRITE32_MEMBER(ide_write_cs1);
|
||||
DECLARE_READ32_MEMBER(ide2_read_cs1);
|
||||
DECLARE_WRITE32_MEMBER(ide2_write_cs1);
|
||||
void set_irq_info(const char *tag, const int irq_num);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const override;
|
||||
|
||||
private:
|
||||
const char *m_cpu_tag;
|
||||
cpu_device *m_cpu;
|
||||
int m_irq_num;
|
||||
int m_irq_status;
|
||||
|
||||
UINT32 m_config_data[0x10];
|
||||
DECLARE_ADDRESS_MAP(chan1_data_command_map, 32);
|
||||
DECLARE_ADDRESS_MAP(chan1_control_map, 32);
|
||||
DECLARE_ADDRESS_MAP(chan2_data_command_map, 32);
|
||||
DECLARE_ADDRESS_MAP(chan2_control_map, 32);
|
||||
DECLARE_ADDRESS_MAP(bus_master_map, 32);
|
||||
DECLARE_READ32_MEMBER(pcictrl_r);
|
||||
DECLARE_WRITE32_MEMBER(pcictrl_w);
|
||||
DECLARE_WRITE32_MEMBER(address_base_w);
|
||||
};
|
||||
|
||||
extern const device_type IDE_PCI;
|
||||
|
||||
#endif
|
@ -106,11 +106,17 @@ void voodoo_pci_device::device_start()
|
||||
pci_device::device_start();
|
||||
if (m_type<=TYPE_VOODOO_2) {
|
||||
add_map(16*1024*1024, M_MEM | M_PREF, FUNC(voodoo_pci_device::voodoo_reg_map));
|
||||
bank_infos[0].adr = 0xff000000;
|
||||
} else {
|
||||
add_map(32*1024*1024, M_MEM, FUNC(voodoo_pci_device::banshee_reg_map));
|
||||
add_map(32*1024*1024, M_MEM, FUNC(voodoo_pci_device::lfb_map));
|
||||
add_map(256, M_IO, FUNC(voodoo_pci_device::io_map));
|
||||
bank_infos[0].adr = 0xf8000000;
|
||||
bank_infos[1].adr = 0xf8000008;
|
||||
bank_infos[2].adr = 0xfffffff0;
|
||||
}
|
||||
|
||||
save_item(NAME(m_pcictrl_reg));
|
||||
}
|
||||
|
||||
void voodoo_pci_device::device_reset()
|
||||
|
Loading…
Reference in New Issue
Block a user