Experimental DMA implementation, bug fixes

The experimental DMA implementation is ported from Nucleus.
This commit is contained in:
Raul Tambre 2015-01-27 21:04:40 +02:00
parent 3a51a6ded7
commit e12cfc89de
6 changed files with 195 additions and 10 deletions

124
rpcs3/Emu/RSX/RSXDMA.cpp Normal file
View File

@ -0,0 +1,124 @@
#include "stdafx.h"
#include "RSXDMA.h"
#include "Emu/Memory/Memory.h"
#include "Utilities/Log.h"
DMAObject dma_address(u32 dma_object)
{
// NOTE: RAMIN is not emulated, therefore DMA Objects are hardcoded in this function
switch (dma_object) {
case RSX_CONTEXT_DMA_REPORT_LOCATION_LOCAL:
return DMAObject{ 0x40300000, 0x8000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R starting at 0x1400, test says RW starting at 0x0.
case RSX_CONTEXT_DMA_DEVICE_RW:
return DMAObject{ 0x40000000, 0x1000, DMAObject::READWRITE };
case RSX_CONTEXT_DMA_DEVICE_R:
return DMAObject{ 0x40000000, 0x1000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R, test says RW
case RSX_CONTEXT_DMA_SEMAPHORE_RW:
return DMAObject{ 0x40100000, 0x1000, DMAObject::READWRITE };
case RSX_CONTEXT_DMA_SEMAPHORE_R:
return DMAObject{ 0x40100000, 0x1000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R, test says RW
default:
LOG_WARNING(RSX, "Unknown DMA object (0x%08X)", dma_object);
return DMAObject{};
}
}
u8 dma_read8(u32 dma_object, u8 offset)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::READ)
{
return vm::read8(dma.addr + offset);
}
LOG_WARNING(RSX, "Illegal DMA 8-bit read");
return 0;
}
u16 dma_read16(u32 dma_object, u16 offset)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::READ)
{
return vm::read16(dma.addr + offset);
}
LOG_WARNING(RSX, "Illegal DMA 16-bit read");
return 0;
}
u32 dma_read32(u32 dma_object, u32 offset)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::READ)
{
return vm::read32(dma.addr + offset);
}
LOG_WARNING(RSX, "Illegal DMA 32-bit read");
return 0;
}
u64 dma_read64(u32 dma_object, u64 offset)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::READ)
{
return vm::read64(dma.addr + offset);
}
LOG_WARNING(RSX, "Illegal DMA 64-bit read");
return 0;
}
void dma_write8(u32 dma_object, u32 offset, u8 value)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::WRITE)
{
return vm::write8(dma.addr + offset, value);
}
LOG_WARNING(RSX, "Illegal DMA 32-bit write");
}
void dma_write16(u32 dma_object, u32 offset, u16 value)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::WRITE)
{
return vm::write16(dma.addr + offset, value);
}
LOG_WARNING(RSX, "Illegal DMA 32-bit write");
}
void dma_write32(u32 dma_object, u32 offset, u32 value)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::WRITE)
{
return vm::write32(dma.addr + offset, value);
}
LOG_WARNING(RSX, "Illegal DMA 32-bit write");
}
void dma_write64(u32 dma_object, u32 offset, u64 value)
{
const DMAObject& dma = dma_address(dma_object);
if (dma.addr && dma.flags & DMAObject::WRITE)
{
return vm::write64(dma.addr + offset, value);
}
LOG_WARNING(RSX, "Illegal DMA 64-bit write");
}

45
rpcs3/Emu/RSX/RSXDMA.h Normal file
View File

@ -0,0 +1,45 @@
#pragma once
enum {
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0 = 0x66604200, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY1 = 0x66604201, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY2 = 0x66604202, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY3 = 0x66604203, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY4 = 0x66604204, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY5 = 0x66604205, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY6 = 0x66604206, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY7 = 0x66604207, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY8 = 0x66604208, // Target: lpar_reports[0x1000 : 0x????]
RSX_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F,
RSX_CONTEXT_DMA_SEMAPHORE_RW = 0x66606660, // Target: lpar_reports[0x0000 : 0x1000] (Read/Write)
RSX_CONTEXT_DMA_SEMAPHORE_R = 0x66616661, // Target: lpar_reports[0x0000 : 0x1000] (Read)
RSX_CONTEXT_DMA_REPORT_LOCATION_LOCAL = 0x66626660, // Target: lpar_reports[0x1400 : 0x9400]
RSX_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000,
RSX_CONTEXT_DMA_DEVICE_RW = 0x56616660,
RSX_CONTEXT_DMA_DEVICE_R = 0x56616661,
};
struct DMAObject {
// Flags
enum {
READ = 1 << 0,
WRITE = 1 << 1,
READWRITE = READ | WRITE,
};
u32 addr;
u32 size;
u32 flags;
};
// RSX Direct Memory Access
DMAObject dma_address(u32 dma_object);
u8 dma_read8(u32 dma_object, u32 offset);
u16 dma_read16(u32 dma_object, u32 offset);
u32 dma_read32(u32 dma_object, u32 offset);
u64 dma_read64(u32 dma_object, u32 offset);
void dma_write8(u32 dma_object, u32 offset, u8 value);
void dma_write16(u32 dma_object, u32 offset, u16 value);
void dma_write32(u32 dma_object, u32 offset, u32 value);
void dma_write64(u32 dma_object, u32 offset, u64 value);

View File

@ -4,6 +4,7 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/RSX/GSManager.h"
#include "Emu/RSX/RSXDMA.h"
#include "RSXThread.h"
#include "Emu/SysCalls/Callback.h"
@ -333,6 +334,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_REPORT: 0x%x", ARGS(0));
}
dma_report = ARGS(0);
}
break;
@ -891,9 +894,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_CLEAR_SURFACE:
{
const u32 mask = ARGS(0);
ClearSurface(mask);
ClearSurface(ARGS(0));
}
break;
@ -901,8 +902,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
const u32 value = ARGS(0);
ClearStencil(value & 0xff);
ClearDepth(value >> 8);
ClearStencil(value & 0xff);
}
break;
@ -1076,7 +1077,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
m_cur_fragment_prog = &m_fragment_progs[m_cur_fragment_prog_num];
const u32 a0 = ARGS(0);
const u32 a0 = ARGS(0);
m_cur_fragment_prog->offset = a0 & ~0x3;
m_cur_fragment_prog->addr = GetAddress(m_cur_fragment_prog->offset, (a0 & 0x3) - 1);
m_cur_fragment_prog->ctrl = 0x40;
@ -1091,8 +1092,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_SET_SHADE_MODE:
{
const u32 value = ARGS(0);
ShadeModel(value);
ShadeModel(ARGS(0));
}
break;
@ -1867,9 +1867,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
u64 timestamp = get_system_time() * 1000;
// TODO: Reports can be written to the main memory or the local memory (controlled by NV4097_SET_CONTEXT_DMA_REPORT)
vm::write64(m_local_mem_addr + offset + 0x0, timestamp);
vm::write32(m_local_mem_addr + offset + 0x8, value);
vm::write32(m_local_mem_addr + offset + 0xc, 0);
// NOTE: Uncomment these, if DMA implementation is broken
//vm::write64(m_local_mem_addr + offset + 0x0, timestamp);
//vm::write32(m_local_mem_addr + offset + 0x8, value);
//vm::write32(m_local_mem_addr + offset + 0xc, 0);
dma_write64(dma_report, offset + 0x0, timestamp);
dma_write32(dma_report, offset + 0x8, value);
dma_write32(dma_report, offset + 0xc, 0);
}
break;

View File

@ -136,6 +136,9 @@ public:
u32 m_ctxt_addr;
u32 m_report_main_addr;
// DMA
u32 dma_report;
u32 m_local_mem_addr, m_main_mem_addr;
bool m_strict_ordering[0x1000];

View File

@ -107,6 +107,7 @@
<ClCompile Include="Emu\RSX\GL\OpenGL.cpp" />
<ClCompile Include="Emu\RSX\GSManager.cpp" />
<ClCompile Include="Emu\RSX\GSRender.cpp" />
<ClCompile Include="Emu\RSX\RSXDMA.cpp" />
<ClCompile Include="Emu\RSX\RSXTexture.cpp" />
<ClCompile Include="Emu\RSX\RSXThread.cpp" />
<ClCompile Include="Emu\Memory\vm.cpp" />
@ -348,6 +349,7 @@
<ClInclude Include="Emu\RSX\GSManager.h" />
<ClInclude Include="Emu\RSX\GSRender.h" />
<ClInclude Include="Emu\RSX\Null\NullGSRender.h" />
<ClInclude Include="Emu\RSX\RSXDMA.h" />
<ClInclude Include="Emu\RSX\RSXFragmentProgram.h" />
<ClInclude Include="Emu\RSX\RSXTexture.h" />
<ClInclude Include="Emu\RSX\RSXThread.h" />

View File

@ -665,6 +665,9 @@
<ClCompile Include="Emu\ARMv7\ARMv7Decoder.cpp">
<Filter>Emu\CPU\ARMv7</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\RSXDMA.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1294,5 +1297,8 @@
<ClInclude Include="Emu\ARMv7\Modules\sceLibKernel.h">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\RSXDMA.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
</ItemGroup>
</Project>