mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-22 12:39:52 +00:00
General improvements:
- Added drafts for event flag emulation; - Implemented memory locking/unlocking; - Refactored common SC_Memory objects; - Implemented VM (virtual memory) syscalls; - Improved cellGameBootCheck; - Added more dummy values to cellVideoOutGetDeviceInfo; - Mapped functions sys_mmapper_allocate_memory and sys_mmapper_map_memory to sysPrxForUser; - Mapped syscalls 341 and 342 (duplicates of 324 and 325) to sys_memory_container_create and sys_memory_container_destroy; Improved PKG installation routine: - Allow immediate game booting; - Fixed and improved game folder path handling.
This commit is contained in:
parent
ff4fcdd5fd
commit
a9a246a866
@ -133,6 +133,7 @@ bool DynamicMemoryBlockBase<PT>::Free(u64 addr)
|
|||||||
{
|
{
|
||||||
if(addr == m_used_mem[i].addr)
|
if(addr == m_used_mem[i].addr)
|
||||||
{
|
{
|
||||||
|
if(IsLocked(m_used_mem[i].addr)) return false;
|
||||||
m_used_mem.RemoveAt(i);
|
m_used_mem.RemoveAt(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -158,3 +159,68 @@ u8* DynamicMemoryBlockBase<PT>::GetMem(u64 addr) const
|
|||||||
assert(0);
|
assert(0);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename PT>
|
||||||
|
bool DynamicMemoryBlockBase<PT>::IsLocked(const u64 addr)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_locked_mem.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(addr == m_locked_mem[i].addr)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PT>
|
||||||
|
void DynamicMemoryBlockBase<PT>::AppendLockedMem(u64 addr, u32 size)
|
||||||
|
{
|
||||||
|
m_locked_mem.Move(new MemBlockInfo(addr, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PT>
|
||||||
|
bool DynamicMemoryBlockBase<PT>::Lock(u64 addr, u32 size)
|
||||||
|
{
|
||||||
|
if(!IsInMyRange(addr, size))
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsMyAddress(addr) || IsMyAddress(addr + size - 1))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppendLockedMem(addr, size);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PT>
|
||||||
|
bool DynamicMemoryBlockBase<PT>::Unlock(u64 addr , u32 size)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_locked_mem.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(addr == m_locked_mem[i].addr)
|
||||||
|
{
|
||||||
|
if(m_locked_mem.Get(i).size > size)
|
||||||
|
{
|
||||||
|
m_locked_mem.Get(i).size -= size;
|
||||||
|
}
|
||||||
|
else if(m_locked_mem.Get(i).size == size)
|
||||||
|
{
|
||||||
|
m_locked_mem.RemoveAt(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -210,7 +210,7 @@ __forceinline void MemoryBlock::FastWrite128(const u64 addr, const u128 value)
|
|||||||
|
|
||||||
bool MemoryBlock::Write8(const u64 addr, const u8 value)
|
bool MemoryBlock::Write8(const u64 addr, const u8 value)
|
||||||
{
|
{
|
||||||
if(!IsMyAddress(addr)) return false;
|
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||||
|
|
||||||
FastWrite8(FixAddr(addr), value);
|
FastWrite8(FixAddr(addr), value);
|
||||||
return true;
|
return true;
|
||||||
@ -218,7 +218,7 @@ bool MemoryBlock::Write8(const u64 addr, const u8 value)
|
|||||||
|
|
||||||
bool MemoryBlock::Write16(const u64 addr, const u16 value)
|
bool MemoryBlock::Write16(const u64 addr, const u16 value)
|
||||||
{
|
{
|
||||||
if(!IsMyAddress(addr)) return false;
|
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||||
|
|
||||||
FastWrite16(FixAddr(addr), value);
|
FastWrite16(FixAddr(addr), value);
|
||||||
return true;
|
return true;
|
||||||
@ -226,7 +226,7 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value)
|
|||||||
|
|
||||||
bool MemoryBlock::Write32(const u64 addr, const u32 value)
|
bool MemoryBlock::Write32(const u64 addr, const u32 value)
|
||||||
{
|
{
|
||||||
if(!IsMyAddress(addr)) return false;
|
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||||
|
|
||||||
FastWrite32(FixAddr(addr), value);
|
FastWrite32(FixAddr(addr), value);
|
||||||
return true;
|
return true;
|
||||||
@ -234,7 +234,7 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value)
|
|||||||
|
|
||||||
bool MemoryBlock::Write64(const u64 addr, const u64 value)
|
bool MemoryBlock::Write64(const u64 addr, const u64 value)
|
||||||
{
|
{
|
||||||
if(!IsMyAddress(addr)) return false;
|
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||||
|
|
||||||
FastWrite64(FixAddr(addr), value);
|
FastWrite64(FixAddr(addr), value);
|
||||||
return true;
|
return true;
|
||||||
@ -242,7 +242,7 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value)
|
|||||||
|
|
||||||
bool MemoryBlock::Write128(const u64 addr, const u128 value)
|
bool MemoryBlock::Write128(const u64 addr, const u128 value)
|
||||||
{
|
{
|
||||||
if(!IsMyAddress(addr)) return false;
|
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||||
|
|
||||||
FastWrite128(FixAddr(addr), value);
|
FastWrite128(FixAddr(addr), value);
|
||||||
return true;
|
return true;
|
||||||
|
@ -356,6 +356,16 @@ public:
|
|||||||
return UserMemory->Free(addr);
|
return UserMemory->Free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lock(const u64 addr, const u32 size)
|
||||||
|
{
|
||||||
|
return UserMemory->Lock(addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Unlock(const u64 addr, const u32 size)
|
||||||
|
{
|
||||||
|
return UserMemory->Unlock(addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
|
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
|
||||||
{
|
{
|
||||||
if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr))
|
if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr))
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
|
|
||||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
||||||
virtual bool IsMyAddress(const u64 addr);
|
virtual bool IsMyAddress(const u64 addr);
|
||||||
|
virtual bool IsLocked(const u64 addr) { return false; }
|
||||||
|
|
||||||
__forceinline const u8 FastRead8(const u64 addr) const;
|
__forceinline const u8 FastRead8(const u64 addr) const;
|
||||||
__forceinline const u16 FastRead16(const u64 addr) const;
|
__forceinline const u16 FastRead16(const u64 addr) const;
|
||||||
@ -106,6 +107,8 @@ public:
|
|||||||
virtual u64 Alloc(u32 size) { return 0; }
|
virtual u64 Alloc(u32 size) { return 0; }
|
||||||
virtual bool Alloc() { return false; }
|
virtual bool Alloc() { return false; }
|
||||||
virtual bool Free(u64 addr) { return false; }
|
virtual bool Free(u64 addr) { return false; }
|
||||||
|
virtual bool Lock(u64 addr, u32 size) { return false; }
|
||||||
|
virtual bool Unlock(u64 addr, u32 size) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemoryBlockLE : public MemoryBlock
|
class MemoryBlockLE : public MemoryBlock
|
||||||
@ -171,6 +174,7 @@ template<typename PT>
|
|||||||
class DynamicMemoryBlockBase : public PT
|
class DynamicMemoryBlockBase : public PT
|
||||||
{
|
{
|
||||||
Array<MemBlockInfo> m_used_mem;
|
Array<MemBlockInfo> m_used_mem;
|
||||||
|
Array<MemBlockInfo> m_locked_mem;
|
||||||
u32 m_max_size;
|
u32 m_max_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -182,6 +186,7 @@ public:
|
|||||||
virtual bool IsInMyRange(const u64 addr);
|
virtual bool IsInMyRange(const u64 addr);
|
||||||
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
||||||
virtual bool IsMyAddress(const u64 addr);
|
virtual bool IsMyAddress(const u64 addr);
|
||||||
|
virtual bool IsLocked(const u64 addr);
|
||||||
|
|
||||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
||||||
|
|
||||||
@ -191,11 +196,14 @@ public:
|
|||||||
virtual u64 Alloc(u32 size);
|
virtual u64 Alloc(u32 size);
|
||||||
virtual bool Alloc();
|
virtual bool Alloc();
|
||||||
virtual bool Free(u64 addr);
|
virtual bool Free(u64 addr);
|
||||||
|
virtual bool Lock(u64 addr, u32 size);
|
||||||
|
virtual bool Unlock(u64 addr, u32 size);
|
||||||
|
|
||||||
virtual u8* GetMem(u64 addr) const;
|
virtual u8* GetMem(u64 addr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AppendUsedMem(u64 addr, u32 size);
|
void AppendUsedMem(u64 addr, u32 size);
|
||||||
|
void AppendLockedMem(u64 addr, u32 size);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "DynamicMemoryBlockBase.inl"
|
#include "DynamicMemoryBlockBase.inl"
|
||||||
|
@ -107,12 +107,14 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameConten
|
|||||||
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood())
|
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood())
|
||||||
return CELL_GAME_ERROR_PARAM;
|
return CELL_GAME_ERROR_PARAM;
|
||||||
|
|
||||||
|
wxString dir ("/dev_hdd0/game/" + Emu.m_title_id + "/USRDIR");
|
||||||
|
|
||||||
type = CELL_GAME_GAMETYPE_DISC;
|
type = CELL_GAME_GAMETYPE_DISC;
|
||||||
attributes = 0;
|
attributes = 0;
|
||||||
size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
|
||||||
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||||
size->sysSizeKB = 0;
|
size->sysSizeKB = 0;
|
||||||
//TODO: dirName
|
Memory.WriteString(dirName.GetAddr(), dir);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -129,9 +131,14 @@ int cellGameDataCheck()
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGameContentPermit()
|
int cellGameContentPermit(mem_list_ptr_t<u8> contentInfoPath, mem_list_ptr_t<u8> usrdirPath)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED_FUNC(cellGame);
|
cellGame.Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)",
|
||||||
|
contentInfoPath.GetAddr(), usrdirPath.GetAddr());
|
||||||
|
|
||||||
|
if (!contentInfoPath.IsGood() || !usrdirPath.IsGood())
|
||||||
|
return CELL_GAME_ERROR_PARAM;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,17 +386,32 @@ int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 option_addr)
|
|||||||
|
|
||||||
int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, mem_ptr_t<CellVideoOutDeviceInfo> info)
|
int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, mem_ptr_t<CellVideoOutDeviceInfo> info)
|
||||||
{
|
{
|
||||||
cellSysutil.Error("Unimplemented function: cellVideoOutGetDeviceInfo(videoOut=%u, deviceIndex=%u, info_addr=0x%x)",
|
cellSysutil.Warning("cellVideoOutGetDeviceInfo(videoOut=%u, deviceIndex=%u, info_addr=0x%x)",
|
||||||
videoOut, deviceIndex, info.GetAddr());
|
videoOut, deviceIndex, info.GetAddr());
|
||||||
|
|
||||||
if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND;
|
if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
// Use standard dummy values for now.
|
||||||
info->portType = CELL_VIDEO_OUT_PORT_HDMI;
|
info->portType = CELL_VIDEO_OUT_PORT_HDMI;
|
||||||
info->colorSpace = Emu.GetGSManager().GetColorSpace();
|
info->colorSpace = Emu.GetGSManager().GetColorSpace();
|
||||||
//info->latency = ;
|
info->latency = 1000;
|
||||||
//info->availableModeCount = ;
|
info->availableModeCount = 1;
|
||||||
info->state = CELL_VIDEO_OUT_DEVICE_STATE_AVAILABLE;
|
info->state = CELL_VIDEO_OUT_DEVICE_STATE_AVAILABLE;
|
||||||
//info->rgbOutputRange = ;
|
info->rgbOutputRange = 1;
|
||||||
|
info->colorInfo.blueX = 0xFFFF;
|
||||||
|
info->colorInfo.blueY = 0xFFFF;
|
||||||
|
info->colorInfo.greenX = 0xFFFF;
|
||||||
|
info->colorInfo.greenY = 0xFFFF;
|
||||||
|
info->colorInfo.redX = 0xFFFF;
|
||||||
|
info->colorInfo.redY = 0xFFFF;
|
||||||
|
info->colorInfo.whiteX = 0xFFFF;
|
||||||
|
info->colorInfo.whiteY = 0xFFFF;
|
||||||
|
info->colorInfo.gamma = 100;
|
||||||
|
info->availableModes[0].aspect = 0;
|
||||||
|
info->availableModes[0].conversion = 0;
|
||||||
|
info->availableModes[0].refreshRates = 0xF;
|
||||||
|
info->availableModes[0].resolutionId = 1;
|
||||||
|
info->availableModes[0].scanMode = 0;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 sys_prx_register_library()
|
s64 sys_prx_register_library(u32 lib_addr)
|
||||||
{
|
{
|
||||||
sysPrxForUser.Error("sys_prx_register_library()");
|
sysPrxForUser.Error("sys_prx_register_library(lib_addr=0x%x)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,4 +79,7 @@ void sysPrxForUser_init()
|
|||||||
//sysPrxForUser.AddFunc(0xaede4b03, sys_heap_free);
|
//sysPrxForUser.AddFunc(0xaede4b03, sys_heap_free);
|
||||||
//sysPrxForUser.AddFunc(0x8a561d92, sys_heap_delete_heap);
|
//sysPrxForUser.AddFunc(0x8a561d92, sys_heap_delete_heap);
|
||||||
sysPrxForUser.AddFunc(0xb2fcf2c8, sys_heap_create_heap);
|
sysPrxForUser.AddFunc(0xb2fcf2c8, sys_heap_create_heap);
|
||||||
|
|
||||||
|
sysPrxForUser.AddFunc(0xb257540b, sys_mmapper_allocate_memory);
|
||||||
|
sysPrxForUser.AddFunc(0xdc578057, sys_mmapper_map_memory);
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,8 @@ static func_caller* sc_table[1024] =
|
|||||||
null_func, //77 (0x04D)
|
null_func, //77 (0x04D)
|
||||||
null_func, //78 (0x04E)
|
null_func, //78 (0x04E)
|
||||||
null_func, //79 (0x04F)
|
null_func, //79 (0x04F)
|
||||||
null_func, null_func, null_func, null_func, null_func, //84
|
null_func, null_func, bind_func(sys_event_flag_create), bind_func(sys_event_flag_destroy), null_func, //84
|
||||||
null_func, null_func, null_func, null_func, null_func, //89
|
bind_func(sys_event_flag_wait), bind_func(sys_event_flag_trywait), bind_func(sys_event_flag_set), null_func, null_func, //89
|
||||||
bind_func(sys_semaphore_create), //90 (0x05A)
|
bind_func(sys_semaphore_create), //90 (0x05A)
|
||||||
bind_func(sys_semaphore_destroy), //91 (0x05B)
|
bind_func(sys_semaphore_destroy), //91 (0x05B)
|
||||||
bind_func(sys_semaphore_wait), //92 (0x05C)
|
bind_func(sys_semaphore_wait), //92 (0x05C)
|
||||||
@ -76,7 +76,7 @@ static func_caller* sc_table[1024] =
|
|||||||
bind_func(sys_cond_signal_all), //109 (0x06D)
|
bind_func(sys_cond_signal_all), //109 (0x06D)
|
||||||
null_func, null_func, null_func, null_func, //113 (0x071)
|
null_func, null_func, null_func, null_func, //113 (0x071)
|
||||||
bind_func(sys_semaphore_get_value), //114 (0x072)
|
bind_func(sys_semaphore_get_value), //114 (0x072)
|
||||||
null_func, null_func, null_func, null_func, null_func, //119 (0x077)
|
null_func, null_func, null_func, bind_func(sys_event_flag_clear), null_func, //119 (0x077)
|
||||||
bind_func(sys_rwlock_create), //120 (0x078)
|
bind_func(sys_rwlock_create), //120 (0x078)
|
||||||
bind_func(sys_rwlock_destroy), //121 (0x079)
|
bind_func(sys_rwlock_destroy), //121 (0x079)
|
||||||
bind_func(sys_rwlock_rlock), //122 (0x07A)
|
bind_func(sys_rwlock_rlock), //122 (0x07A)
|
||||||
@ -87,8 +87,8 @@ static func_caller* sc_table[1024] =
|
|||||||
bind_func(sys_rwlock_wunlock), //127 (0x07F)
|
bind_func(sys_rwlock_wunlock), //127 (0x07F)
|
||||||
bind_func(sys_event_queue_create), //128 (0x080)
|
bind_func(sys_event_queue_create), //128 (0x080)
|
||||||
null_func, //129 (0x081)
|
null_func, //129 (0x081)
|
||||||
bind_func(sys_event_queue_receive), null_func, null_func, null_func, bind_func(sys_event_port_create), //134
|
bind_func(sys_event_queue_receive), null_func, bind_func(sys_event_flag_cancel), null_func, bind_func(sys_event_port_create), //134
|
||||||
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), null_func, //139
|
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), bind_func(sys_event_flag_get), //139
|
||||||
null_func, bind_func(sys_timer_usleep), bind_func(sys_timer_sleep), null_func, bind_func(sys_time_get_timezone), //144
|
null_func, bind_func(sys_timer_usleep), bind_func(sys_timer_sleep), null_func, bind_func(sys_time_get_timezone), //144
|
||||||
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
|
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
|
||||||
null_func, null_func, null_func, null_func, null_func, //154
|
null_func, null_func, null_func, null_func, null_func, //154
|
||||||
@ -121,15 +121,15 @@ static func_caller* sc_table[1024] =
|
|||||||
null_func, null_func, null_func, null_func, null_func, //289
|
null_func, null_func, null_func, null_func, null_func, //289
|
||||||
null_func, null_func, null_func, null_func, null_func, //294
|
null_func, null_func, null_func, null_func, null_func, //294
|
||||||
null_func, null_func, null_func, null_func, null_func, //299
|
null_func, null_func, null_func, null_func, null_func, //299
|
||||||
null_func, null_func, null_func, null_func, null_func, //304
|
bind_func(sys_vm_memory_map), bind_func(sys_vm_unmap), bind_func(sys_vm_append_memory), bind_func(sys_vm_return_memory), bind_func(sys_vm_lock), //304
|
||||||
null_func, null_func, null_func, null_func, null_func, //309
|
bind_func(sys_vm_unlock), bind_func(sys_vm_touch), bind_func(sys_vm_flush), bind_func(sys_vm_invalidate), bind_func(sys_vm_store), //309
|
||||||
null_func, null_func, null_func, null_func, null_func, //314
|
bind_func(sys_vm_sync), bind_func(sys_vm_test), bind_func(sys_vm_get_statistics), null_func, null_func, //314
|
||||||
null_func, null_func, null_func, null_func, null_func, //319
|
null_func, null_func, null_func, null_func, null_func, //319
|
||||||
null_func, null_func, null_func, null_func, bind_func(sys_memory_container_create), //324
|
null_func, null_func, null_func, null_func, bind_func(sys_memory_container_create), //324
|
||||||
bind_func(sys_memory_container_destroy), null_func, null_func, null_func, null_func, //329
|
bind_func(sys_memory_container_destroy), null_func, null_func, null_func, null_func, //329
|
||||||
bind_func(sys_mmapper_allocate_address), null_func, null_func, null_func, null_func, //334
|
bind_func(sys_mmapper_allocate_address), null_func, null_func, null_func, null_func, //334
|
||||||
null_func, null_func, null_func, null_func, null_func, //339
|
null_func, null_func, null_func, null_func, null_func, //339
|
||||||
null_func, null_func, null_func, null_func, null_func, //344
|
null_func, bind_func(sys_memory_container_create), bind_func(sys_memory_container_destroy), null_func, null_func, //344
|
||||||
null_func, null_func, null_func, bind_func(sys_memory_allocate), bind_func(sys_memory_free), //349
|
null_func, null_func, null_func, bind_func(sys_memory_allocate), bind_func(sys_memory_free), //349
|
||||||
null_func, null_func, bind_func(sys_memory_get_user_memory_size), null_func, null_func, //354
|
null_func, null_func, bind_func(sys_memory_get_user_memory_size), null_func, null_func, //354
|
||||||
null_func, null_func, null_func, null_func, null_func, //359
|
null_func, null_func, null_func, null_func, null_func, //359
|
||||||
|
@ -122,6 +122,14 @@ extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_add
|
|||||||
u32 data, u32 data_size, int prio, u64 flags );
|
u32 data, u32 data_size, int prio, u64 flags );
|
||||||
|
|
||||||
//sys_event
|
//sys_event
|
||||||
|
extern int sys_event_flag_create(u32 eflag_id_addr, u32 attr_addr, u64 init);
|
||||||
|
extern int sys_event_flag_destroy(u32 eflag_id);
|
||||||
|
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr, u32 timeout);
|
||||||
|
extern int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr);
|
||||||
|
extern int sys_event_flag_set(u32 eflag_id, u64 bitptn);
|
||||||
|
extern int sys_event_flag_clear(u32 eflag_id, u64 bitptn);
|
||||||
|
extern int sys_event_flag_cancel(u32 eflag_id, u32 num_addr);
|
||||||
|
extern int sys_event_flag_get(u32 eflag_id, u32 flag_addr);
|
||||||
extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size);
|
extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size);
|
||||||
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
|
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
|
||||||
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
|
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
|
||||||
@ -183,6 +191,21 @@ extern int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32
|
|||||||
extern int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr);
|
extern int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr);
|
||||||
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
|
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
|
||||||
|
|
||||||
|
//vm
|
||||||
|
extern int sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr);
|
||||||
|
extern int sys_vm_unmap(u32 addr);
|
||||||
|
extern int sys_vm_append_memory(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_return_memory(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_lock(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_unlock(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_touch(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_flush(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_invalidate(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_store(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_sync(u32 addr, u32 size);
|
||||||
|
extern int sys_vm_test(u32 addr, u32 size, u32 result_addr);
|
||||||
|
extern int sys_vm_get_statistics(u32 addr, u32 stat_addr);
|
||||||
|
|
||||||
//cellFs
|
//cellFs
|
||||||
extern int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size);
|
extern int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size);
|
||||||
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread);
|
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread);
|
||||||
|
@ -5,6 +5,103 @@
|
|||||||
|
|
||||||
SysCallBase sys_event("sys_event");
|
SysCallBase sys_event("sys_event");
|
||||||
|
|
||||||
|
int sys_event_flag_create(u32 eflag_id_addr, u32 attr_addr, u64 init)
|
||||||
|
{
|
||||||
|
sys_event.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)", eflag_id_addr, attr_addr, init);
|
||||||
|
|
||||||
|
if(!Memory.IsGoodAddr(eflag_id_addr, 4) || !Memory.IsGoodAddr(attr_addr, sizeof(sys_event_flag_attr)))
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_event_flag_attr attr = (sys_event_flag_attr&)Memory[attr_addr];
|
||||||
|
attr.protocol = re(attr.protocol);
|
||||||
|
attr.pshared = re(attr.pshared);
|
||||||
|
attr.ipc_key = re(attr.ipc_key);
|
||||||
|
attr.flags = re(attr.flags);
|
||||||
|
attr.type = re(attr.type);
|
||||||
|
|
||||||
|
sys_event.Warning("name = %s", attr.name);
|
||||||
|
sys_event.Warning("type = %d", attr.type);
|
||||||
|
|
||||||
|
Memory.Write32(eflag_id_addr, sys_event.GetNewId(new event_flag(init, attr)));
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_destroy(u32 eflag_id)
|
||||||
|
{
|
||||||
|
sys_event.Warning("sys_event_flag_destroy(eflag_id=0x%x)", eflag_id);
|
||||||
|
|
||||||
|
if(!sys_event.CheckId(eflag_id)) return CELL_ESRCH;
|
||||||
|
|
||||||
|
Emu.GetIdManager().RemoveID(eflag_id);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr, u32 timeout)
|
||||||
|
{
|
||||||
|
sys_event.Warning("Unimplemented function: sys_event_flag_wait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=0x%x)"
|
||||||
|
, eflag_id, bitptn, mode, result_addr, timeout);
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr)
|
||||||
|
{
|
||||||
|
sys_event.Warning("Unimplemented function: sys_event_flag_trywait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)"
|
||||||
|
, eflag_id, bitptn, mode, result_addr);
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||||
|
{
|
||||||
|
sys_event.Warning("sys_event_flag_set(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
|
||||||
|
|
||||||
|
event_flag* event_flag_data = nullptr;
|
||||||
|
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
|
||||||
|
|
||||||
|
event_flag_data->pattern |= bitptn;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||||
|
{
|
||||||
|
sys_event.Warning("sys_event_flag_clear(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
|
||||||
|
|
||||||
|
event_flag* event_flag_data = nullptr;
|
||||||
|
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
|
||||||
|
|
||||||
|
event_flag_data->pattern &= bitptn;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_cancel(u32 eflag_id, u32 num_addr)
|
||||||
|
{
|
||||||
|
sys_event.Warning("Unimplemented function: sys_event_flag_cancel(eflag_id=0x%x, num_addr=0x%x)"
|
||||||
|
, eflag_id, num_addr);
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_event_flag_get(u32 eflag_id, u32 flag_addr)
|
||||||
|
{
|
||||||
|
sys_event.Warning("sys_event_flag_get(eflag_id=0x%x, flag_addr=0x%x)", eflag_id, flag_addr);
|
||||||
|
|
||||||
|
if(!Memory.IsGoodAddr(flag_addr, 4))
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_flag* event_flag_data = nullptr;
|
||||||
|
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
|
||||||
|
|
||||||
|
Memory.Write64(flag_addr, event_flag_data->pattern);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//128
|
//128
|
||||||
int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size)
|
int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size)
|
||||||
{
|
{
|
||||||
|
@ -1,26 +1,9 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
#include "SC_Memory.h"
|
||||||
|
|
||||||
SysCallBase sc_mem("memory");
|
SysCallBase sc_mem("memory");
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SYS_MEMORY_PAGE_SIZE_1M = 0x400,
|
|
||||||
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MemoryContainerInfo
|
|
||||||
{
|
|
||||||
u64 addr;
|
|
||||||
u32 size;
|
|
||||||
|
|
||||||
MemoryContainerInfo(u64 addr, u32 size)
|
|
||||||
: addr(addr)
|
|
||||||
, size(size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
||||||
{
|
{
|
||||||
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
|
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
|
||||||
@ -93,29 +76,11 @@ int sys_memory_free(u32 start_addr)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mmapper_info
|
|
||||||
{
|
|
||||||
u64 addr;
|
|
||||||
u32 size;
|
|
||||||
u32 flags;
|
|
||||||
|
|
||||||
mmapper_info(u64 _addr, u32 _size, u32 _flags)
|
|
||||||
: addr(_addr)
|
|
||||||
, size(_size)
|
|
||||||
, flags(_flags)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
mmapper_info()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
|
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
|
||||||
{
|
{
|
||||||
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
|
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
|
||||||
|
|
||||||
Memory.Write32(alloc_addr, Memory.Alloc(size, 4));
|
Memory.Write32(alloc_addr, Memory.Alloc(size, alignment));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -126,7 +91,7 @@ int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr)
|
|||||||
|
|
||||||
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
|
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
|
||||||
|
|
||||||
u64 addr = Memory.Alloc(size, 1);
|
u64 addr = Memory.Alloc(size, 4);
|
||||||
|
|
||||||
if(!addr)
|
if(!addr)
|
||||||
return CELL_ENOMEM;
|
return CELL_ENOMEM;
|
||||||
@ -147,17 +112,10 @@ int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
|
|||||||
{
|
{
|
||||||
sc_mem.Error("sys_mmapper_map_memory failed!");
|
sc_mem.Error("sys_mmapper_map_memory failed!");
|
||||||
}
|
}
|
||||||
//Memory.MemoryBlocks.Add((new MemoryBlock())->SetRange(start_addr, info->size));
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sys_memory_info
|
|
||||||
{
|
|
||||||
u32 total_user_memory;
|
|
||||||
u32 available_user_memory;
|
|
||||||
};
|
|
||||||
|
|
||||||
int sys_memory_get_user_memory_size(u32 mem_info_addr)
|
int sys_memory_get_user_memory_size(u32 mem_info_addr)
|
||||||
{
|
{
|
||||||
sys_memory_info info;
|
sys_memory_info info;
|
||||||
|
59
rpcs3/Emu/SysCalls/lv2/SC_Memory.h
Normal file
59
rpcs3/Emu/SysCalls/lv2/SC_Memory.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SYS_MEMORY_CONTAINER_ID_INVALID 0xFFFFFFFF
|
||||||
|
#define SYS_VM_TEST_INVALID 0x0000ULL
|
||||||
|
#define SYS_VM_TEST_UNUSED 0x0001ULL
|
||||||
|
#define SYS_VM_TEST_ALLOCATED 0x0002ULL
|
||||||
|
#define SYS_VM_TEST_STORED 0x0004ULL
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SYS_MEMORY_PAGE_SIZE_1M = 0x400,
|
||||||
|
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemoryContainerInfo
|
||||||
|
{
|
||||||
|
u64 addr;
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
MemoryContainerInfo(u64 addr, u32 size)
|
||||||
|
: addr(addr)
|
||||||
|
, size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mmapper_info
|
||||||
|
{
|
||||||
|
u64 addr;
|
||||||
|
u32 size;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
|
mmapper_info(u64 _addr, u32 _size, u32 _flags)
|
||||||
|
: addr(_addr)
|
||||||
|
, size(_size)
|
||||||
|
, flags(_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
mmapper_info()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sys_memory_info
|
||||||
|
{
|
||||||
|
u32 total_user_memory;
|
||||||
|
u32 available_user_memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sys_vm_statistics {
|
||||||
|
u64 vm_crash_ppu;
|
||||||
|
u64 vm_crash_spu;
|
||||||
|
u64 vm_read;
|
||||||
|
u64 vm_write;
|
||||||
|
u32 physical_mem_size;
|
||||||
|
u32 physical_mem_used;
|
||||||
|
u64 timestamp;
|
||||||
|
};
|
286
rpcs3/Emu/SysCalls/lv2/SC_VM.cpp
Normal file
286
rpcs3/Emu/SysCalls/lv2/SC_VM.cpp
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
#include "SC_Memory.h"
|
||||||
|
|
||||||
|
SysCallBase sc_vm("vm");
|
||||||
|
MemoryContainerInfo* current_ct;
|
||||||
|
|
||||||
|
int sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_memory_map(vsize=0x%x,psize=0x%x,cidr=0x%x,flags=0x%llx,policy=0x%llx,addr=0x%x)",
|
||||||
|
vsize, psize, cid, flag, policy, addr);
|
||||||
|
|
||||||
|
// Check output address.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4))
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check virtual size.
|
||||||
|
if((vsize < (0x100000 * 32)) || (vsize > (0x100000 * 256)))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check physical size.
|
||||||
|
if(psize > (0x100000 * 256))
|
||||||
|
{
|
||||||
|
return CELL_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If container ID is SYS_MEMORY_CONTAINER_ID_INVALID, allocate directly.
|
||||||
|
if(cid == SYS_MEMORY_CONTAINER_ID_INVALID)
|
||||||
|
{
|
||||||
|
u32 new_addr;
|
||||||
|
switch(flag)
|
||||||
|
{
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_1M:
|
||||||
|
new_addr = Memory.Alloc(psize, 0x100000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS_MEMORY_PAGE_SIZE_64K:
|
||||||
|
new_addr = Memory.Alloc(psize, 0x10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!new_addr) return CELL_ENOMEM;
|
||||||
|
|
||||||
|
// Create a new MemoryContainerInfo to act as default container with vsize.
|
||||||
|
current_ct = new MemoryContainerInfo(new_addr, vsize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check memory container.
|
||||||
|
MemoryContainerInfo* ct;
|
||||||
|
if(!sc_vm.CheckId(cid, ct)) return CELL_ESRCH;
|
||||||
|
|
||||||
|
current_ct = ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a pointer for the allocated memory.
|
||||||
|
Memory.Write32(addr, current_ct->addr);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_unmap(u32 addr)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_unmap(addr=0x%x)", addr);
|
||||||
|
|
||||||
|
// Simply free the memory to unmap.
|
||||||
|
if(!Memory.Free(addr)) return CELL_EINVAL;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_append_memory(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_append_memory(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total memory size must not be superior to 256MB.
|
||||||
|
if((current_ct->size + size) > (0x100000 * 256))
|
||||||
|
{
|
||||||
|
return CELL_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The size is added to the virtual size, which should be inferior to the physical size allocated.
|
||||||
|
current_ct->size += size;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_return_memory(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_return_memory(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The memory size to return should not be superior to the virtual size in use minus 1MB.
|
||||||
|
if((current_ct->size - size - 0x100000) < 0)
|
||||||
|
{
|
||||||
|
return CELL_EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The size is returned to physical memory and is subtracted to the virtual size.
|
||||||
|
current_ct->size -= size;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_lock(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_lock(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The memory size to return should not be superior to the virtual size to lock minus 1MB.
|
||||||
|
if((current_ct->size - size - 0x100000) < 0)
|
||||||
|
{
|
||||||
|
return CELL_EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The locked memory area keeps allocated and unchanged until sys_vm_unlocked is called.
|
||||||
|
Memory.Lock(addr, size);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_unlock(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("sys_vm_unlock(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Memory.Unlock(addr, size);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_touch(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_touch(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_touch allocates physical memory for a virtual memory address.
|
||||||
|
// This function is asynchronous, so it may not complete immediately.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_flush(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_flush(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_flush frees physical memory for a virtual memory address and creates a backup if the memory area is dirty.
|
||||||
|
// This function is asynchronous, so it may not complete immediately.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_invalidate(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_invalidate(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_invalidate frees physical memory for a virtual memory address.
|
||||||
|
// This function is asynchronous, so it may not complete immediately.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_store(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_store(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_store creates a backup for a dirty virtual memory area and marks it as clean.
|
||||||
|
// This function is asynchronous, so it may not complete immediately.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_sync(u32 addr, u32 size)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_sync(addr=0x%x,size=0x%x)", addr, size);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_sync stalls execution until all asynchronous vm calls finish.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_test(u32 addr, u32 size, u32 result_addr)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_test(addr=0x%x,size=0x%x,result_addr=0x%x)", addr, size, result_addr);
|
||||||
|
|
||||||
|
// Check address and size.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_test checks the state of a portion of the virtual memory area.
|
||||||
|
|
||||||
|
// Faking.
|
||||||
|
Memory.Write64(result_addr, SYS_VM_TEST_ALLOCATED);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_vm_get_statistics(u32 addr, u32 stat_addr)
|
||||||
|
{
|
||||||
|
sc_vm.Warning("Unimplemented function: sys_vm_get_statistics(addr=0x%x,stat_addr=0x%x)", addr, stat_addr);
|
||||||
|
|
||||||
|
// Check address.
|
||||||
|
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr))
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// sys_vm_get_statistics collects virtual memory management stats.
|
||||||
|
|
||||||
|
sys_vm_statistics stats;
|
||||||
|
stats.physical_mem_size = current_ct->size; // Total physical memory allocated for the virtual memory area.
|
||||||
|
stats.physical_mem_used = 0; // Physical memory in use by the virtual memory area.
|
||||||
|
stats.timestamp = 0; // Current time.
|
||||||
|
stats.vm_crash_ppu = 0; // Number of bad virtual memory accesses from a PPU thread.
|
||||||
|
stats.vm_crash_spu = 0; // Number of bad virtual memory accesses from a SPU thread.
|
||||||
|
stats.vm_read = 0; // Number of virtual memory backup reading operations.
|
||||||
|
stats.vm_write = 0; // Number of virtual memory backup writing operations.
|
||||||
|
Memory.WriteData(stat_addr, stats); // Faking.
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
@ -43,6 +43,11 @@ void Emulator::SetPath(const wxString& path, const wxString& elf_path)
|
|||||||
m_elf_path = elf_path;
|
m_elf_path = elf_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Emulator::SetTitleID(const wxString& id)
|
||||||
|
{
|
||||||
|
m_title_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
void Emulator::CheckStatus()
|
void Emulator::CheckStatus()
|
||||||
{
|
{
|
||||||
ArrayF<CPUThread>& threads = GetCPU().GetThreads();
|
ArrayF<CPUThread>& threads = GetCPU().GetThreads();
|
||||||
|
@ -93,11 +93,13 @@ class Emulator
|
|||||||
public:
|
public:
|
||||||
wxString m_path;
|
wxString m_path;
|
||||||
wxString m_elf_path;
|
wxString m_elf_path;
|
||||||
|
wxString m_title_id;
|
||||||
|
|
||||||
Emulator();
|
Emulator();
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void SetPath(const wxString& path, const wxString& elf_path = wxEmptyString);
|
void SetPath(const wxString& path, const wxString& elf_path = wxEmptyString);
|
||||||
|
void SetTitleID(const wxString& id);
|
||||||
|
|
||||||
std::shared_ptr<vfsFileBase> OpenFile(const wxString& path, vfsOpenMode mode = vfsRead)
|
std::shared_ptr<vfsFileBase> OpenFile(const wxString& path, vfsOpenMode mode = vfsRead)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
struct sys_event_flag_attr
|
||||||
|
{
|
||||||
|
u32 protocol;
|
||||||
|
u32 pshared;
|
||||||
|
u64 ipc_key;
|
||||||
|
int flags;
|
||||||
|
int type;
|
||||||
|
char name[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct event_flag
|
||||||
|
{
|
||||||
|
sys_event_flag_attr attr;
|
||||||
|
u64 pattern;
|
||||||
|
|
||||||
|
event_flag(u64 pattern, sys_event_flag_attr attr)
|
||||||
|
: pattern(pattern)
|
||||||
|
, attr(attr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct sys_event_queue_attr
|
struct sys_event_queue_attr
|
||||||
{
|
{
|
||||||
u32 attr_protocol;
|
u32 attr_protocol;
|
||||||
|
@ -45,6 +45,47 @@ wxString GetPaneName()
|
|||||||
return wxString::Format("Pane_%d", pane_num++);
|
return wxString::Format("Pane_%d", pane_num++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxMoveDir(wxString sFrom, wxString sTo)
|
||||||
|
{
|
||||||
|
if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH;
|
||||||
|
if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH;
|
||||||
|
|
||||||
|
if (!::wxDirExists(sFrom)) {
|
||||||
|
::wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!wxDirExists(sTo)) {
|
||||||
|
if (!wxFileName::Mkdir(sTo, 0777, wxPATH_MKDIR_FULL)) {
|
||||||
|
::wxLogError(wxT("%s could not be created!"), sTo.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDir fDir(sFrom);
|
||||||
|
wxString sNext = wxEmptyString;
|
||||||
|
bool bIsFile = fDir.GetFirst(&sNext);
|
||||||
|
while (bIsFile) {
|
||||||
|
const wxString sFileFrom = sFrom + sNext;
|
||||||
|
const wxString sFileTo = sTo + sNext;
|
||||||
|
if (::wxDirExists(sFileFrom)) {
|
||||||
|
wxMoveDir(sFileFrom, sFileTo);
|
||||||
|
::wxRmdir(sFileFrom);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!::wxFileExists(sFileTo)) {
|
||||||
|
if (!::wxCopyFile(sFileFrom, sFileTo)) {
|
||||||
|
::wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::wxRemoveFile(sFileFrom);
|
||||||
|
}
|
||||||
|
bIsFile = fDir.GetNext(&sNext);
|
||||||
|
}
|
||||||
|
::wxRmdir(sFrom);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
MainFrame::MainFrame()
|
MainFrame::MainFrame()
|
||||||
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600))
|
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600))
|
||||||
, m_aui_mgr(this)
|
, m_aui_mgr(this)
|
||||||
@ -276,7 +317,109 @@ void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event))
|
|||||||
if (!wxRemoveFile(ctrl.GetPath()+".dec"))
|
if (!wxRemoveFile(ctrl.GetPath()+".dec"))
|
||||||
ConLog.Warning("Could not delete the decoded DEC file");
|
ConLog.Warning("Could not delete the decoded DEC file");
|
||||||
|
|
||||||
|
// Copy the PKG to dev_hdd0 and format the path to be identical to the PS3.
|
||||||
|
wxString gamePath = "\\dev_hdd0\\game\\";
|
||||||
|
pkg_header *header;
|
||||||
|
pkg_info((const char *)fileName.mb_str(), &header);
|
||||||
|
|
||||||
|
// Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO).
|
||||||
|
wxString titleID_full (header->title_id);
|
||||||
|
wxString titleID = titleID_full.SubString(7, 15);
|
||||||
|
|
||||||
|
// Travel to bin folder.
|
||||||
|
wxSetWorkingDirectory(wxGetCwd() + "\\..\\");
|
||||||
|
|
||||||
|
// Save the main dir.
|
||||||
|
wxString mainDir = wxGetCwd();
|
||||||
|
|
||||||
|
// Set PKG dir.
|
||||||
|
wxString oldPkgDir = wxT(wxGetCwd() + "\\" + titleID_full);
|
||||||
|
wxString newPkgDir = wxT(wxGetCwd() + gamePath + titleID);
|
||||||
|
|
||||||
|
// Move the final folder.
|
||||||
|
wxMoveDir(oldPkgDir, newPkgDir);
|
||||||
|
|
||||||
|
// Save the title ID.
|
||||||
|
Emu.SetTitleID(titleID);
|
||||||
|
|
||||||
ConLog.Write("PKG: extract done.");
|
ConLog.Write("PKG: extract done.");
|
||||||
|
|
||||||
|
// Travel to the installed PKG.
|
||||||
|
wxSetWorkingDirectory(newPkgDir);
|
||||||
|
|
||||||
|
wxString elf[6] = {
|
||||||
|
"\\PS3_GAME\\USRDIR\\BOOT.BIN",
|
||||||
|
"\\USRDIR\\BOOT.BIN",
|
||||||
|
"\\BOOT.BIN",
|
||||||
|
"\\PS3_GAME\\USRDIR\\EBOOT.BIN",
|
||||||
|
"\\USRDIR\\EBOOT.BIN",
|
||||||
|
"\\EBOOT.BIN"
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int i=0;i<6;i++)
|
||||||
|
{
|
||||||
|
if(wxFile::Access(wxGetCwd() + elf[i], wxFile::read))
|
||||||
|
{
|
||||||
|
ConLog.Write("SELF: booting...");
|
||||||
|
|
||||||
|
wxString fileIn = wxGetCwd()+elf[i];
|
||||||
|
wxString fileOut = (wxGetCwd()+elf[i])+".elf";
|
||||||
|
|
||||||
|
// Check if the data really needs to be decrypted.
|
||||||
|
if(!wxFileExists(fileIn))
|
||||||
|
{
|
||||||
|
ConLog.Error("Could not open game boot file!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFile f(fileIn);
|
||||||
|
// Get the key version.
|
||||||
|
f.Seek(0x08);
|
||||||
|
be_t<u16> key_version;
|
||||||
|
f.Read(&key_version, sizeof(key_version));
|
||||||
|
|
||||||
|
if(key_version.ToBE() == const_se_t<u16, 0x8000>::value)
|
||||||
|
{
|
||||||
|
ConLog.Warning("Debug SELF detected! Removing fake header...");
|
||||||
|
|
||||||
|
// Get the real elf offset.
|
||||||
|
f.Seek(0x10);
|
||||||
|
be_t<u64> elf_offset;
|
||||||
|
f.Read(&elf_offset, sizeof(elf_offset));
|
||||||
|
|
||||||
|
// Start at the real elf offset.
|
||||||
|
f.Seek(elf_offset);
|
||||||
|
|
||||||
|
wxFile out(fileOut, wxFile::write);
|
||||||
|
|
||||||
|
// Copy the data.
|
||||||
|
char buf[2048];
|
||||||
|
while (ssize_t size = f.Read(buf, 2048))
|
||||||
|
out.Write(buf, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!scetool_decrypt((scetool::s8 *)fileIn.mb_str(), (scetool::s8 *)fileOut.mb_str()))
|
||||||
|
{
|
||||||
|
ConLog.Write("Could not decrypt game boot file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Close();
|
||||||
|
|
||||||
|
// Set the working directory back.
|
||||||
|
wxSetWorkingDirectory(mainDir);
|
||||||
|
|
||||||
|
Emu.SetPath(fileOut);
|
||||||
|
Emu.Load();
|
||||||
|
if (!wxRemoveFile(fileOut))
|
||||||
|
ConLog.Warning("Could not delete the decrypted ELF file");
|
||||||
|
|
||||||
|
ConLog.Write("Game: boot done.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
|
void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
|
||||||
|
@ -257,6 +257,7 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Timer.cpp" />
|
<ClCompile Include="Emu\SysCalls\lv2\SC_Timer.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Trace.cpp" />
|
<ClCompile Include="Emu\SysCalls\lv2\SC_Trace.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
|
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
|
||||||
|
<ClCompile Include="Emu\SysCalls\lv2\SC_VM.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\cellAudio.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\cellAudio.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\cellFont.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\cellFont.cpp" />
|
||||||
|
@ -340,6 +340,9 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\Modules\cellGame.cpp">
|
<ClCompile Include="Emu\SysCalls\Modules\cellGame.cpp">
|
||||||
<Filter>Emu\SysCalls\Modules</Filter>
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\SysCalls\lv2\SC_VM.cpp">
|
||||||
|
<Filter>Emu\SysCalls\lv2</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user