Merge pull request #980 from tambry/Things

Test mode, RSXIO changes reverted and experimental DMA implementation
This commit is contained in:
B1ackDaemon 2015-02-02 09:07:07 +02:00
commit c153215d6d
9 changed files with 241 additions and 15 deletions

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

@ -0,0 +1,125 @@
// Copyright (C) 2015 AlexAltea (https://github.com/AlexAltea/nucleus)
#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");
}

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

@ -0,0 +1,46 @@
// Copyright (C) 2015 AlexAltea (https://github.com/AlexAltea/nucleus)
#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"
@ -329,6 +330,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
if (ARGS(0))
{
LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_REPORT: 0x%x", ARGS(0));
dma_report = ARGS(0);
}
break;
}
@ -887,9 +889,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_SET_ZSTENCIL_CLEAR_VALUE:
{
const u32 a0 = ARGS(0);
m_clear_s = a0 & 0xff;
m_clear_z = a0 >> 8;
const u32 value = ARGS(0);
m_clear_s = value & 0xff;
m_clear_z = value >> 8;
break;
}
@ -1065,7 +1067,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;
@ -1819,7 +1821,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
// Get timestamp, and convert it from microseconds to nanoseconds
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)
// NOTE: DMA broken, implement proper lpar mapping (sys_rsx)
//dma_write64(dma_report, offset + 0x0, timestamp);
//dma_write32(dma_report, offset + 0x8, value);
//dma_write32(dma_report, offset + 0xc, 0);
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);

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

@ -1192,7 +1192,7 @@ s32 cellGcmCallback(vm::ptr<CellGcmContextData> context, u32 count)
//cmd[3] = 0; // some incrementing by module value
//context->current += 0x10;
if (1)
if (0)
{
const u32 address = context->begin;
const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits

View File

@ -166,6 +166,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" />
@ -417,6 +418,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

@ -581,6 +581,9 @@
<ClCompile Include="Emu\RSX\GSRender.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\RSXDMA.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\RSXTexture.cpp">
<Filter>Emu\GPU\RSX</Filter>
</ClCompile>
@ -667,7 +670,7 @@
</ClCompile>
<ClCompile Include="Emu\ARMv7\ARMv7Decoder.cpp">
<Filter>Emu\CPU\ARMv7</Filter>
</ClCompile>
</ClCompile>
<ClCompile Include="Emu\ARMv7\PSVObjectList.cpp">
<Filter>Emu\CPU\ARMv7</Filter>
</ClCompile>
@ -693,7 +696,7 @@
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\ARMv7\Modules\sceGxm.cpp">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\ARMv7\Modules\sceAppMgr.cpp">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
@ -1345,6 +1348,9 @@
<ClInclude Include="Emu\RSX\GSRender.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\RSXDMA.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\RSXFragmentProgram.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
@ -1473,7 +1479,7 @@
</ClInclude>
<ClInclude Include="Emu\ARMv7\Modules\sceLibKernel.h">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClInclude>
</ClInclude>
<ClInclude Include="Emu\ARMv7\PSVObjectList.h">
<Filter>Emu\CPU\ARMv7</Filter>
</ClInclude>
@ -1484,7 +1490,7 @@
<Filter>Emu\CPU\ARMv7\Objects</Filter>
</ClInclude>
<ClInclude Include="Emu\ARMv7\Modules\sceGxm.h">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClInclude>
<ClInclude Include="Emu\ARMv7\Modules\sceAppUtil.h">
<Filter>Emu\CPU\ARMv7\Modules</Filter>

View File

@ -202,6 +202,22 @@ void compile_shader(std::string path)
bool Rpcs3App::OnInit()
{
static const wxCmdLineEntryDesc desc[]
{
{ wxCMD_LINE_SWITCH, "h", "help", "Command line options:\nh (help): Help and commands\nt (test): For directly executing a (S)ELF", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_SWITCH, "t", "test", "Run in test mode on (S)ELF", wxCMD_LINE_VAL_NONE },
{ wxCMD_LINE_PARAM, NULL, NULL, "(S)ELF", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE }
};
parser.SetDesc(desc);
parser.SetCmdLine(argc, argv);
if (parser.Parse())
{
// help was given, terminating
this->Exit();
}
SetSendDbgCommandCallback([](DbgCommand id, CPUThread* t)
{
wxGetApp().SendDbgCommand(id, t);
@ -296,7 +312,7 @@ bool Rpcs3App::OnInit()
m_MainFrame->Show();
m_MainFrame->DoSettings(true);
OnArguments();
OnArguments(parser);
//compile_shader("compile_shader0.spo");
//compile_shader("compile_shader1.spo");
@ -304,14 +320,26 @@ bool Rpcs3App::OnInit()
return true;
}
void Rpcs3App::OnArguments()
void Rpcs3App::OnArguments(const wxCmdLineParser& parser)
{
// Usage:
// rpcs3-*.exe Initializes RPCS3
// rpcs3-*.exe [(S)ELF] Initializes RPCS3, then loads and runs the specified (S)ELF file.
if (Rpcs3App::argc > 1) {
Emu.SetPath(fmt::ToUTF8(argv[1]));
if (parser.FoundSwitch("t"))
{
HLEExitOnStop = Ini.HLEExitOnStop.GetValue();
Ini.HLEExitOnStop.SetValue(true);
if (parser.GetParamCount() != 1)
{
wxLogDebug(wxT("A (S)ELF file needs to be given in test mode, exiting."));
this->Exit();
}
}
if (parser.GetParamCount() > 0)
{
Emu.SetPath(fmt::ToUTF8(parser.GetParam(0)));
Emu.Load();
Emu.Run();
}
@ -319,6 +347,11 @@ void Rpcs3App::OnArguments()
void Rpcs3App::Exit()
{
if (parser.FoundSwitch("t"))
{
Ini.HLEExitOnStop.SetValue(HLEExitOnStop);
}
Emu.Stop();
Ini.Save();

View File

@ -3,6 +3,7 @@
#include "Emu/DbgCommand.h"
#include "Utilities/Thread.h"
#include <wx/app.h>
#include <wx/cmdline.h>
class CPUThread;
@ -11,11 +12,15 @@ wxDECLARE_EVENT(wxEVT_DBG_COMMAND, wxCommandEvent);
class Rpcs3App : public wxApp
{
private:
wxCmdLineParser parser;
// Used to restore the configuration state after a test run
bool HLEExitOnStop;
public:
MainFrame* m_MainFrame;
virtual bool OnInit(); // RPCS3's entry point
virtual void OnArguments(); // Handle arguments: Rpcs3App::argc, Rpcs3App::argv
virtual void OnArguments(const wxCmdLineParser& parser); // Handle arguments: Rpcs3App::argc, Rpcs3App::argv
virtual void Exit();
Rpcs3App();