This commit is contained in:
Nekotekina 2014-08-26 04:52:28 +04:00
commit 9eda0aa245
10 changed files with 126 additions and 85 deletions

View File

@ -255,7 +255,7 @@ struct CellGcmReportData
{
u64 timer;
u32 value;
u32 pad;
u32 padding;
};
struct CellGcmZcullInfo

View File

@ -2,6 +2,7 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "sysPrxForUser.h"
//#include "Emu/RSX/GCM.h"
#include "Emu/RSX/GSManager.h"
@ -60,6 +61,17 @@ u32 gcmGetLocalMemorySize(u32 sdk_version)
return 0x0E000000; // 224MB
}
CellGcmOffsetTable offsetTable;
void InitOffsetTable()
{
offsetTable.ioAddress = Memory.Alloc(3072 * sizeof(u16), 1);
offsetTable.eaAddress = Memory.Alloc(512 * sizeof(u16), 1);
_sys_memset(offsetTable.ioAddress, 0xFF, 3072 * sizeof(u16));
_sys_memset(offsetTable.eaAddress, 0xFF, 512 * sizeof(u16));
}
//----------------------------------------------------------------------------
// Data Retrieval
//----------------------------------------------------------------------------
@ -112,10 +124,29 @@ int cellGcmGetCurrentField()
return CELL_OK;
}
int cellGcmGetNotifyDataAddress()
u32 cellGcmGetNotifyDataAddress(u32 index)
{
UNIMPLEMENTED_FUNC(cellGcmSys);
return CELL_OK;
cellGcmSys->Warning("cellGcmGetNotifyDataAddress(index=%d)", index);
// Get address of 'IO table' and 'EA table'
MemoryAllocator<CellGcmOffsetTable> table;
cellGcmGetOffsetTable(table.GetAddr());
// If entry not in use, return NULL
u16 entry = mem_ptr_t<u16>(table->eaAddress)[241];
if (entry == 0xFFFF) {
return 0;
}
return (entry << 20) + (index * 0x20);
}
/*
* Get base address of local report data area
*/
u32 _cellGcmFunc12()
{
return Memory.RSXFBMem.GetStartAddr(); // TODO
}
u32 cellGcmGetReport(u32 type, u32 index)
@ -124,10 +155,15 @@ u32 cellGcmGetReport(u32 type, u32 index)
if (index >= 2048) {
cellGcmSys->Error("cellGcmGetReport: Wrong local index (%d)", index);
return 0;
return -1;
}
// TODO: What does the argument type do?
return Memory.Read32(Memory.RSXFBMem.GetStartAddr() + index * 0x10 + 0x8);
if (type < 1 || type > 5) {
return -1;
}
mem_ptr_t<CellGcmReportData> local_reports = _cellGcmFunc12();
return local_reports[index].value;
}
u32 cellGcmGetReportDataAddress(u32 index)
@ -145,25 +181,8 @@ u32 cellGcmGetReportDataLocation(u32 index, u32 location)
{
cellGcmSys->Warning("cellGcmGetReportDataLocation(index=%d, location=%d)", index, location);
if (location == CELL_GCM_LOCATION_LOCAL) {
if (index >= 2048) {
cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong local index (%d)", index);
return 0;
}
return Memory.Read32(Memory.RSXFBMem.GetStartAddr() + index * 0x10 + 0x8);
}
if (location == CELL_GCM_LOCATION_MAIN) {
if (index >= 1024*1024) {
cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong main index (%d)", index);
return 0;
}
// TODO: It seems m_report_main_addr is not initialized
return Memory.Read32(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10 + 0x8);
}
cellGcmSys->Error("cellGcmGetReportDataLocation: Wrong location (%d)", location);
return 0;
mem_ptr_t<CellGcmReportData> report = cellGcmGetReportDataAddressLocation(index, location);
return report->value;
}
u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
@ -782,47 +801,30 @@ int cellGcmSortRemapEaIoAddress()
//----------------------------------------------------------------------------
// Memory Mapping
//----------------------------------------------------------------------------
gcm_offset offsetTable = { 0, 0 };
void InitOffsetTable()
{
offsetTable.io = Memory.Alloc(3072 * sizeof(u16), 1);
for (int i = 0; i<3072; i++)
{
Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF);
}
offsetTable.ea = Memory.Alloc(256 * sizeof(u16), 1);//TODO: check flags
for (int i = 0; i<256; i++)
{
Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF);
}
}
s32 cellGcmAddressToOffset(u64 address, mem32_t offset)
{
cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr());
if (address >= 0xD0000000/*not on main memory or local*/)
// Address not on main memory or local memory
if (address >= 0xD0000000) {
return CELL_GCM_ERROR_FAILURE;
}
u32 result;
// If address is in range of local memory
if (Memory.RSXFBMem.IsInMyRange(address))
{
// Address in local memory
if (Memory.RSXFBMem.IsInMyRange(address)) {
result = address - Memory.RSXFBMem.GetStartAddr();
}
// else check if the adress (main memory) is mapped in IO
// Address in main memory else check
else
{
u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20));
u16 upper12Bits = Memory.Read16(offsetTable.ioAddress + sizeof(u16)*(address >> 20));
// If the address is mapped in IO
if (upper12Bits != 0xFFFF) {
result = (((u64)upper12Bits << 20) | (address & (0xFFFFF)));
result = ((u64)upper12Bits << 20) | (address & 0xFFFFF);
}
// address is not mapped in IO
else {
return CELL_GCM_ERROR_FAILURE;
}
@ -839,12 +841,12 @@ u32 cellGcmGetMaxIoMapSize()
return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetReservedAmount();
}
void cellGcmGetOffsetTable(mem_ptr_t<gcm_offset> table)
void cellGcmGetOffsetTable(mem_ptr_t<CellGcmOffsetTable> table)
{
cellGcmSys->Log("cellGcmGetOffsetTable(table_addr=0x%x)", table.GetAddr());
table->io = re(offsetTable.io);
table->ea = re(offsetTable.ea);
table->ioAddress = offsetTable.ioAddress;
table->eaAddress = offsetTable.eaAddress;
}
s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address)
@ -867,14 +869,14 @@ s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size)
if ((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
//check if the mapping was successfull
// Check if the mapping was successfull
if (Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io))
{
//fill the offset table
// Fill the offset table
for (u32 i = 0; i<(size >> 20); i++)
{
Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
Memory.Write16(offsetTable.ioAddress + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
Memory.Write16(offsetTable.eaAddress + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
}
}
else
@ -930,8 +932,8 @@ s32 cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset)
//fill the offset table
for (u32 i = 0; i<(size >> 20); i++)
{
Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
Memory.Write16(offsetTable.ioAddress + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
Memory.Write16(offsetTable.eaAddress + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
}
offset = io;
@ -976,12 +978,12 @@ s32 cellGcmUnmapEaIoAddress(u64 ea)
{
u64 io;
ea = ea >> 20;
io = Memory.Read16(offsetTable.io + (ea*sizeof(u16)));
io = Memory.Read16(offsetTable.ioAddress + (ea*sizeof(u16)));
for (u32 i = 0; i<size; i++)
{
Memory.Write16(offsetTable.io + ((ea + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.ea + ((io + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.ioAddress + ((ea + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.eaAddress + ((io + i)*sizeof(u16)), 0xFFFF);
}
}
else
@ -1002,12 +1004,12 @@ s32 cellGcmUnmapIoAddress(u64 io)
{
u64 ea;
io = io >> 20;
ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16)));
ea = Memory.Read16(offsetTable.eaAddress + (io*sizeof(u16)));
for (u32 i = 0; i<size; i++)
{
Memory.Write16(offsetTable.io + ((ea + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.ea + ((io + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.ioAddress + ((ea + i)*sizeof(u16)), 0xFFFF);
Memory.Write16(offsetTable.eaAddress + ((io + i)*sizeof(u16)), 0xFFFF);
}
}
else
@ -1187,6 +1189,7 @@ void cellGcmSys_init()
cellGcmSys->AddFunc(0xc8f3bd09, cellGcmGetCurrentField);
cellGcmSys->AddFunc(0xf80196c1, cellGcmGetLabelAddress);
cellGcmSys->AddFunc(0x21cee035, cellGcmGetNotifyDataAddress);
cellGcmSys->AddFunc(0x661fe266, _cellGcmFunc12);
cellGcmSys->AddFunc(0x99d397ac, cellGcmGetReport);
cellGcmSys->AddFunc(0x9a0159af, cellGcmGetReportDataAddress);
cellGcmSys->AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation);

View File

@ -10,10 +10,10 @@ enum
CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005,
};
struct gcm_offset
struct CellGcmOffsetTable
{
u64 io;
u64 ea;
be_t<u32> ioAddress; // u16*
be_t<u32> eaAddress; // u16*
};
// Auxiliary functions
@ -26,7 +26,7 @@ s32 cellGcmSetPrepareFlip(mem_ptr_t<CellGcmContextData> ctxt, u32 id);
s32 cellGcmAddressToOffset(u64 address, mem32_t offset);
u32 cellGcmGetMaxIoMapSize();
void cellGcmGetOffsetTable(mem_ptr_t<gcm_offset> table);
void cellGcmGetOffsetTable(mem_ptr_t<CellGcmOffsetTable> table);
s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address);
s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size);
s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags);

View File

@ -13,3 +13,6 @@ struct HeapInfo
{
}
};
// SysCalls
u32 _sys_memset(u32 addr, s32 value, u32 size);

View File

@ -99,7 +99,7 @@ static func_caller* sc_table[kSyscallTableLength] =
null_func,//bind_func(sys_ppu_thread_start), //53 (0x035)
null_func,//bind_func(sys_ppu_...), //54 (0x036) ROOT
null_func,//bind_func(sys_ppu_...), //55 (0x037) ROOT
null_func,//bind_func(sys_ppu_thread_rename), //56 (0x038)
bind_func(sys_ppu_thread_rename), //56 (0x038)
null_func,//bind_func(sys_ppu_thread_recover_page_fault)//57 (0x039)
null_func,//bind_func(sys_ppu_thread_get_page_fault_context),//58 (0x03A)
null_func, //59 (0x03B) UNS

View File

@ -211,10 +211,23 @@ void sys_ppu_thread_once(mem_ptr_t<std::atomic<be_t<u32>>> once_ctrl, u32 entry)
}
}
s32 sys_ppu_thread_get_id(const u32 id_addr)
s32 sys_ppu_thread_get_id(mem64_t thread_id)
{
sys_ppu_thread.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr);
sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.GetAddr());
Memory.Write64(id_addr, GetCurrentPPUThread().GetId());
thread_id = GetCurrentPPUThread().GetId();
return CELL_OK;
}
s32 sys_ppu_thread_rename(u64 thread_id, u32 name_addr)
{
sys_ppu_thread.Log("sys_ppu_thread_rename(thread_id=%d, name_addr=0x%x)", thread_id, name_addr);
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
if (!thr) {
return CELL_ESRCH;
}
thr->SetThreadName(Memory.ReadString(name_addr));
return CELL_OK;
}

View File

@ -26,4 +26,5 @@ s32 sys_ppu_thread_stop(u64 thread_id);
s32 sys_ppu_thread_restart(u64 thread_id);
s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, u32 threadname_addr);
void sys_ppu_thread_once(mem_ptr_t<std::atomic<be_t<u32>>> once_ctrl, u32 entry);
s32 sys_ppu_thread_get_id(const u32 id_addr);
s32 sys_ppu_thread_get_id(mem64_t thread_id);
s32 sys_ppu_thread_rename(u64 thread_id, u32 name_addr);

View File

@ -48,7 +48,7 @@ s32 sys_rsx_memory_free(u32 mem_handle)
/*
* lv2 SysCall 670 (0x29E): sys_rsx_context_allocate
* @param context_id (OUT): RSX_context, E.g. 0x55555555 (in vsh.self)
* @param context_id (OUT): RSX context, E.g. 0x55555555 (in vsh.self)
* @param lpar_dma_control (OUT): Control register area. E.g. 0x60100000 (in vsh.self)
* @param lpar_driver_info (OUT): RSX data like frequencies, sizes, version... E.g. 0x60200000 (in vsh.self)
* @param lpar_reports (OUT): Report data area. E.g. 0x60300000 (in vsh.self)
@ -65,7 +65,7 @@ s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32
/*
* lv2 SysCall 671 (0x29F): sys_rsx_context_free
* @param a1 (IN): RSX_context generated by sys_rsx_context_allocate to free the context.
* @param context_id (IN): RSX context generated by sys_rsx_context_allocate to free the context.
*/
s32 sys_rsx_context_free(u32 context_id)
{
@ -73,15 +73,32 @@ s32 sys_rsx_context_free(u32 context_id)
return CELL_OK;
}
s32 sys_rsx_context_iomap()
/*
* lv2 SysCall 672 (0x2A0): sys_rsx_context_iomap
* @param context_id (IN): RSX context, E.g. 0x55555555 (in vsh.self)
* @param io (IN): IO offset mapping area. E.g. 0x00600000
* @param ea (IN): Start address of mapping area. E.g. 0x20400000
* @param size (IN): Size of mapping area in bytes. E.g. 0x00200000
* @param flags (IN):
*/
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
{
sys_rsx.Todo("sys_rsx_context_iomap()");
sys_rsx.Todo("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)",
context_id, io, ea, size, flags);
return CELL_OK;
}
s32 sys_rsx_context_iounmap()
/*
* lv2 SysCall 673 (0x2A1): sys_rsx_context_iounmap
* @param context_id (IN): RSX context, E.g. 0x55555555 (in vsh.self)
* @param a2 (IN): ?
* @param io_addr (IN): IO address. E.g. 0x00600000 (Start page 6)
* @param size (IN): Size to unmap in byte. E.g. 0x00200000
*/
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size)
{
sys_rsx.Todo("sys_rsx_context_iounmap()");
sys_rsx.Todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)",
context_id, a2, io_addr, size);
return CELL_OK;
}

View File

@ -7,8 +7,8 @@ s32 sys_rsx_memory_allocate(mem32_t mem_handle, mem32_t mem_addr, u32 size, u64
s32 sys_rsx_memory_free(u32 mem_handle);
s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32_t lpar_driver_info, mem32_t lpar_reports, u64 mem_ctx, u64 system_mode);
s32 sys_rsx_context_free(u32 context_id);
s32 sys_rsx_context_iomap();
s32 sys_rsx_context_iounmap();
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags);
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size);
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6);
s32 sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 dev_id);
s32 sys_rsx_device_unmap(u32 dev_id);

View File

@ -21,6 +21,7 @@
#endif
#include "Gui/GLGSFrame.h"
#include <wx/stdpaths.h>
#ifdef _WIN32
#include <wx/msw/wrapwin.h>
@ -117,10 +118,13 @@ bool Rpcs3App::OnInit()
SetAppName(_PRGNAME_);
wxInitAllImageHandlers();
// RPCS3 assumes the current working directory is the folder where it is contained, so we make sure this is true
const wxString executablePath = wxStandardPaths::Get().GetExecutablePath();
wxSetWorkingDirectory(wxPathOnly(executablePath));
main_thread = std::this_thread::get_id();
Ini.Load();
m_MainFrame = new MainFrame();
SetTopWindow(m_MainFrame);
Emu.Init();