mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
parent
5953781c13
commit
373d189edb
@ -131,11 +131,13 @@ public:
|
||||
}
|
||||
|
||||
bool HasID(const s64 id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
if(id == wxID_ANY)
|
||||
return m_id_map.begin() != m_id_map.end();
|
||||
}
|
||||
|
||||
return CheckID(id);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
|
||||
extern void SM_Sleep();
|
||||
extern DWORD SM_GetCurrentThreadId();
|
||||
@ -49,6 +48,10 @@ public:
|
||||
|
||||
SMutexResult trylock(T tid)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return SMR_ABORT;
|
||||
}
|
||||
T old = (T)free_value;
|
||||
|
||||
if (!owner.compare_exchange_strong(old, tid))
|
||||
@ -57,15 +60,10 @@ public:
|
||||
{
|
||||
return SMR_DEADLOCK;
|
||||
}
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return SMR_ABORT;
|
||||
}
|
||||
if (old == (T)dead_value)
|
||||
{
|
||||
return SMR_DESTROYED;
|
||||
}
|
||||
|
||||
return SMR_FAILED;
|
||||
}
|
||||
|
||||
@ -74,6 +72,10 @@ public:
|
||||
|
||||
SMutexResult unlock(T tid, T to = (T)free_value)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return SMR_ABORT;
|
||||
}
|
||||
T old = tid;
|
||||
|
||||
if (!owner.compare_exchange_strong(old, to))
|
||||
|
@ -111,7 +111,7 @@ thread::thread()
|
||||
}
|
||||
|
||||
void thread::start(std::function<void()> func)
|
||||
{
|
||||
{ // got a crash related with strings
|
||||
m_thr = std::thread([this, func]() { NamedThreadBase info(m_name); g_tls_this_thread = &info; func(); });
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,8 @@ CPUThread* CPUThreadManager::GetThread(u32 id)
|
||||
{
|
||||
CPUThread* res;
|
||||
|
||||
if (!id) return nullptr;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(id, res)) return nullptr;
|
||||
|
||||
return res;
|
||||
|
@ -601,13 +601,16 @@ public:
|
||||
|
||||
u32 GetChannelCount(u32 ch)
|
||||
{
|
||||
u32 count;
|
||||
switch(ch)
|
||||
{
|
||||
case SPU_WrOutMbox:
|
||||
return SPU.Out_MBox.GetFreeCount();
|
||||
|
||||
case SPU_RdInMbox:
|
||||
return SPU.In_MBox.GetCount();
|
||||
count = SPU.In_MBox.GetCount();
|
||||
ConLog.Warning("GetChannelCount(%s) -> %d", spu_ch_name[ch], count);
|
||||
return count;
|
||||
|
||||
case SPU_WrOutIntrMbox:
|
||||
ConLog.Warning("GetChannelCount(%s) = 0", spu_ch_name[ch]);
|
||||
@ -688,6 +691,8 @@ public:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Emu.IsStopped()) ConLog.Warning("%s: %s writing aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||
}
|
||||
|
||||
void ReadChannel(SPU_GPR_hdr& r, u32 ch)
|
||||
@ -725,6 +730,8 @@ public:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Emu.IsStopped()) ConLog.Warning("%s: %s aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||
}
|
||||
|
||||
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa + m_offset) && lsa < 0x40000; }
|
||||
|
61
rpcs3/Emu/Event.cpp
Normal file
61
rpcs3/Emu/Event.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "stdafx.h"
|
||||
#include "event.h"
|
||||
|
||||
void EventManager::Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EventManager::Clear()
|
||||
{
|
||||
key_map.clear();
|
||||
}
|
||||
|
||||
bool EventManager::CheckKey(u64 key)
|
||||
{
|
||||
if (!key) return true;
|
||||
SMutexLocker lock(m_lock);
|
||||
|
||||
return key_map.find(key) != key_map.end();
|
||||
}
|
||||
|
||||
bool EventManager::RegisterKey(EventQueue* data, u64 key)
|
||||
{
|
||||
if (!key) return true;
|
||||
SMutexLocker lock(m_lock);
|
||||
|
||||
if (key_map.find(key) != key_map.end()) return false;
|
||||
|
||||
key_map[key] = data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventManager::GetEventQueue(u64 key, EventQueue*& data)
|
||||
{
|
||||
data = nullptr;
|
||||
if (!key) return false;
|
||||
SMutexLocker lock(m_lock);
|
||||
|
||||
auto f = key_map.find(key);
|
||||
if (f != key_map.end())
|
||||
{
|
||||
data = f->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventManager::UnregisterKey(u64 key)
|
||||
{
|
||||
if (!key) return false;
|
||||
SMutexLocker lock(m_lock);
|
||||
|
||||
auto f = key_map.find(key);
|
||||
if (f != key_map.end())
|
||||
{
|
||||
key_map.erase(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -4,8 +4,9 @@
|
||||
#include "Emu/Audio/cellAudio.h"
|
||||
|
||||
void cellAudio_init();
|
||||
void cellAudio_load();
|
||||
void cellAudio_unload();
|
||||
Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload);
|
||||
Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload);
|
||||
|
||||
enum
|
||||
{
|
||||
@ -80,16 +81,66 @@ struct CellAudioPortConfig
|
||||
be_t<u32> portAddr;
|
||||
};
|
||||
|
||||
struct CellAudioConfig //custom structure
|
||||
struct AudioPortConfig
|
||||
{
|
||||
bool m_is_audio_initialized;
|
||||
bool m_is_audio_port_opened;
|
||||
bool m_is_audio_port_started;
|
||||
CellAudioPortParam m_param;
|
||||
|
||||
const u32 m_buffer; // 64 KB or 128 KB with 8x16 config
|
||||
const u32 m_index;
|
||||
|
||||
AudioPortConfig();
|
||||
|
||||
~AudioPortConfig();
|
||||
};
|
||||
|
||||
CellAudioPortParam* m_param = new CellAudioPortParam;
|
||||
struct AudioConfig //custom structure
|
||||
{
|
||||
Array<AudioPortConfig*> m_ports;
|
||||
bool m_is_audio_initialized;
|
||||
u32 m_port_in_use;
|
||||
u64 event_key;
|
||||
|
||||
CellAudioConfig* m_config = new CellAudioConfig;
|
||||
AudioConfig()
|
||||
: m_is_audio_initialized(false)
|
||||
, m_port_in_use(0)
|
||||
, event_key(0)
|
||||
{
|
||||
m_ports.SetCount(8);
|
||||
for (u32 i = 0; i < m_ports.GetCount(); i++)
|
||||
m_ports[i] = nullptr;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (u32 i = 0; i < m_ports.GetCount(); i++)
|
||||
{
|
||||
if (m_ports[i])
|
||||
{
|
||||
delete m_ports[i];
|
||||
m_ports[i] = nullptr;
|
||||
}
|
||||
}
|
||||
m_port_in_use = 0;
|
||||
}
|
||||
} m_config;
|
||||
|
||||
AudioPortConfig::AudioPortConfig()
|
||||
: m_is_audio_port_started(false)
|
||||
, m_buffer(Memory.Alloc(1024 * 128, 1024))
|
||||
, m_index(Memory.Alloc(16, 16))
|
||||
{
|
||||
m_config.m_port_in_use++;
|
||||
mem64_t index(m_index);
|
||||
index = 0;
|
||||
}
|
||||
|
||||
AudioPortConfig::~AudioPortConfig()
|
||||
{
|
||||
m_config.m_port_in_use--;
|
||||
Memory.Free(m_buffer);
|
||||
Memory.Free(m_index);
|
||||
}
|
||||
|
||||
//libmixer datatypes
|
||||
typedef void * CellAANHandle;
|
||||
@ -197,68 +248,94 @@ struct CellSoundSynth2EffectAttr
|
||||
int cellAudioInit()
|
||||
{
|
||||
cellAudio.Warning("cellAudioInit()");
|
||||
if(m_config->m_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
|
||||
m_config->m_is_audio_initialized = true;
|
||||
if (m_config.m_is_audio_initialized)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_ALREADY_INIT;
|
||||
}
|
||||
|
||||
m_config.m_is_audio_initialized = true;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioQuit()
|
||||
{
|
||||
cellAudio.Warning("cellAudioQuit()");
|
||||
if (m_config->m_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
m_config->m_is_audio_initialized = false;
|
||||
|
||||
if (!m_config.m_is_audio_initialized)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
m_config.m_is_audio_initialized = false;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
|
||||
{
|
||||
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x,portNum_addr=0x%x)",audioParam.GetAddr(),portNum.GetAddr());
|
||||
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x, portNum_addr=0x%x)", audioParam.GetAddr(), portNum.GetAddr());
|
||||
|
||||
if(!audioParam.IsGood() || !portNum.IsGood()) return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||
m_config->m_is_audio_port_opened = true;
|
||||
|
||||
m_param->nChannel = audioParam->nChannel;
|
||||
m_param->nBlock = audioParam->nBlock;
|
||||
m_param->attr = audioParam->attr;
|
||||
m_param->level = audioParam->level;
|
||||
|
||||
//TODO: implementation of ring buffer
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
|
||||
{
|
||||
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x,portConfig_addr=0x%x)",portNum,portConfig.GetAddr());
|
||||
|
||||
if(!portConfig.IsGood())
|
||||
if(!audioParam.IsGood() || !portNum.IsGood())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
//if(portNum > 7) return CELL_AUDIO_ERROR_PORT_FULL;
|
||||
|
||||
if(!m_config->m_is_audio_port_opened)
|
||||
if (m_config.m_port_in_use >= m_config.m_ports.GetCount())
|
||||
{
|
||||
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
||||
return CELL_OK;
|
||||
return CELL_AUDIO_ERROR_PORT_FULL;
|
||||
}
|
||||
|
||||
if(m_config->m_is_audio_port_started)
|
||||
for (u32 i = 0; i < m_config.m_ports.GetCount(); i++)
|
||||
{
|
||||
if (m_config.m_ports[i] == nullptr)
|
||||
{
|
||||
CellAudioPortParam& ref = (m_config.m_ports[i] = new AudioPortConfig)->m_param;
|
||||
|
||||
ref.nChannel = audioParam->nChannel;
|
||||
ref.nBlock = audioParam->nBlock;
|
||||
ref.attr = audioParam->attr;
|
||||
ref.level = audioParam->level;
|
||||
|
||||
portNum = i;
|
||||
cellAudio.Warning("*** audio port opened(nChannel=%lld, nBlock=0x%llx, attr=0x%llx, level=%f): port = %d",
|
||||
(u64)ref.nChannel, (u64)ref.nBlock, (u64)ref.attr, (float)ref.level, portNum.GetValue());
|
||||
//TODO: implementation of ring buffer
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_AUDIO_ERROR_PORT_FULL;
|
||||
}
|
||||
|
||||
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
|
||||
{
|
||||
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig_addr=0x%x)", portNum, portConfig.GetAddr());
|
||||
|
||||
if (!portConfig.IsGood() || portNum >= m_config.m_ports.GetCount())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (!m_config.m_ports[portNum])
|
||||
{
|
||||
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
||||
}
|
||||
else if (m_config.m_ports[portNum]->m_is_audio_port_started)
|
||||
{
|
||||
portConfig->status = CELL_AUDIO_STATUS_RUN;
|
||||
}
|
||||
else
|
||||
{
|
||||
CellAudioPortParam& ref = m_config.m_ports[portNum]->m_param;
|
||||
|
||||
portConfig->status = CELL_AUDIO_STATUS_READY;
|
||||
portConfig->nChannel = m_param->nChannel;
|
||||
portConfig->nBlock = m_param->nBlock;
|
||||
portConfig->portSize = sizeof(float)*256*(m_param->nChannel)*(m_param->nBlock);
|
||||
portConfig->portAddr = Memory.Alloc(portConfig->portSize, 4); // 0x20020000 WARNING: Memory leak.
|
||||
portConfig->readIndexAddr = Memory.Alloc(m_param->nBlock, 4); // 0x20010010 on ps3 WARNING: Memory leak.
|
||||
portConfig->nChannel = ref.nChannel;
|
||||
portConfig->nBlock = ref.nBlock;
|
||||
portConfig->portSize = ref.nChannel * ref.nBlock * 256;
|
||||
portConfig->portAddr = m_config.m_ports[portNum]->m_buffer; // 0x20020000
|
||||
portConfig->readIndexAddr = m_config.m_ports[portNum]->m_index; // 0x20010010 on ps3
|
||||
|
||||
// portAddr - readIndexAddr == 0xFFF0 on ps3
|
||||
Memory.Write64(portConfig->readIndexAddr, 1);
|
||||
// Memory.Write64(portConfig->readIndexAddr, 1);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -266,23 +343,43 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
|
||||
|
||||
int cellAudioPortStart(u32 portNum)
|
||||
{
|
||||
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)",portNum);
|
||||
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum);
|
||||
|
||||
if (!m_config->m_is_audio_port_opened)
|
||||
if (portNum >= m_config.m_ports.GetCount())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (!m_config.m_ports[portNum])
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||
}
|
||||
|
||||
m_config->m_is_audio_port_started = true;
|
||||
if (m_config.m_ports[portNum]->m_is_audio_port_started)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
|
||||
}
|
||||
|
||||
m_config.m_ports[portNum]->m_is_audio_port_started = true;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioPortClose(u32 portNum)
|
||||
{
|
||||
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)",portNum);
|
||||
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum);
|
||||
|
||||
if (!m_config->m_is_audio_port_opened)
|
||||
if (portNum >= m_config.m_ports.GetCount())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (!m_config.m_ports[portNum])
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
}
|
||||
|
||||
m_config->m_is_audio_port_opened = false;
|
||||
delete m_config.m_ports[portNum];
|
||||
m_config.m_ports[portNum] = nullptr;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -290,123 +387,131 @@ int cellAudioPortStop(u32 portNum)
|
||||
{
|
||||
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)",portNum);
|
||||
|
||||
if (m_config->m_is_audio_port_started == false)
|
||||
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
if (portNum >= m_config.m_ports.GetCount())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
m_config->m_is_audio_port_started = false;
|
||||
if (!m_config.m_ports[portNum])
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
}
|
||||
|
||||
if (!m_config.m_ports[portNum]->m_is_audio_port_started)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||
}
|
||||
|
||||
m_config.m_ports[portNum]->m_is_audio_port_started = false;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp)
|
||||
{
|
||||
cellAudio.Warning("cellAudioGetPortTimestamp(portNum=0x%x,tag=0x%x,stamp=0x%x)",portNum,tag,stamp.GetAddr());
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp_addr=0x%x)", portNum, tag, stamp.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag)
|
||||
{
|
||||
cellAudio.Warning("cellAudioGetPortBlockTag(portNum=0x%x,blockNo=0x%x,tag=0x%x)",portNum,blockNo,tag.GetAddr());
|
||||
UNIMPLEMENTED_FUNC (cellAudio);
|
||||
cellAudio.Error("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag_addr=0x%x)", portNum, blockNo, tag.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioSetPortLevel(u32 portNum, float level)
|
||||
{
|
||||
cellAudio.Warning("cellAudioSetPortLevel(portNum=0x%x,level=0x%x)",portNum,level);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Utility Functions
|
||||
int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key)
|
||||
{
|
||||
cellAudio.Warning("cellAudioCreateNotifyEventQueue(id=0x%x,key=0x%x)",id.GetAddr(),key.GetAddr());
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioCreateNotifyEventQueueEx(mem32_t id, mem64_t key, u32 iFlags)
|
||||
{
|
||||
cellAudio.Warning("cellAudioCreateNotifyEventQueueEx(id=0x%x,key=0x%x,iFlags=0x%x)",id.GetAddr(),key.GetAddr(),iFlags);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.GetAddr(), key.GetAddr(), iFlags);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioSetNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%x)",key);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
m_config.event_key = key;
|
||||
|
||||
EventQueue* eq;
|
||||
if (!Emu.GetEventManager().GetEventQueue(key, eq))
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
eq->events.push(0, 0, 0, 0);
|
||||
eq->events.push(0, 0, 0, 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.Warning("cellAudioSetNotifyEventQueueEx(key=0x%x,iFlags=0x%x)",key,iFlags);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%x)",key);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.Warning("cellAudioRemoveNotifyEventQueueEx(key=0x%x,iFlags=0x%x)",key,iFlags);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioAddData(u32 portNum, mem32_t src, uint samples, float volume)
|
||||
int cellAudioAddData(u32 portNum, mem32_t src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.Warning("cellAudioAddData(portNum=0x%x,src=0x%x,samples=0x%x,volume=0x%x)",portNum,src.GetAddr(),samples,volume);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioAddData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.GetAddr(), samples, volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioAdd2chData(u32 portNum, mem32_t src, uint samples, float volume)
|
||||
int cellAudioAdd2chData(u32 portNum, mem32_t src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.Warning("cellAudioAdd2chData(portNum=0x%x,src=0x%x,samples=0x%x,volume=0x%x)",portNum,src.GetAddr(),samples,volume);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioAdd2chData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.GetAddr(), samples, volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioAdd6chData(u32 portNum, mem32_t src, float volume)
|
||||
{
|
||||
cellAudio.Warning("cellAudioAdd6chData(portNum=0x%x,src=0x%x,volume=0x%x)",portNum,src.GetAddr(),volume);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioAdd6chData(portNum=0x%x, src_addr=0x%x, volume=%f)", portNum, src.GetAddr(), volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
{
|
||||
cellAudio.Warning("cellAudioMiscSetAccessoryVolume(devNum=0x%x,volume=0x%x)",devNum,volume);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioSendAck(u64 data3)
|
||||
{
|
||||
cellAudio.Warning("cellAudioSendAck(data3=0x%x)",data3);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioSendAck(data3=0x%llx)", data3);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice)
|
||||
{
|
||||
cellAudio.Warning("cellAudioSetPersonalDevice(iPersonalStream=0x%x,iDevice=0x%x)",iPersonalStream,iDevice);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioUnsetPersonalDevice(int iPersonalStream)
|
||||
{
|
||||
cellAudio.Warning("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)",iPersonalStream);
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
cellAudio.Error("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -1013,9 +1118,14 @@ void cellAudio_init()
|
||||
//TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions
|
||||
}
|
||||
|
||||
void cellAudio_load()
|
||||
{
|
||||
m_config.m_is_audio_initialized = false;
|
||||
m_config.Clear();
|
||||
}
|
||||
|
||||
void cellAudio_unload()
|
||||
{
|
||||
m_config->m_is_audio_initialized = false;
|
||||
m_config->m_is_audio_port_opened = false;
|
||||
m_config->m_is_audio_port_started = false;
|
||||
m_config.m_is_audio_initialized = false;
|
||||
m_config.Clear();
|
||||
}
|
@ -115,7 +115,7 @@ int sdata_unpack(wxString packed_file, wxString unpacked_file)
|
||||
int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Warning("cellFsSdataOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
|
||||
sys_fs.Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
|
||||
path.wx_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
|
||||
|
||||
if (!fd.IsGood() || (!arg.IsGood() && size))
|
||||
@ -179,7 +179,7 @@ void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*
|
||||
if(func)
|
||||
func.async(aio, error, xid, res);
|
||||
|
||||
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=%d, res=%d, xid=%d [%s])",
|
||||
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, res=0x%x, xid=0x%x [%s])",
|
||||
fd, (u64)aio->offset, buf_addr, (u64)aio->size, res, xid, path.wx_str());
|
||||
}
|
||||
|
||||
|
@ -86,9 +86,11 @@ static func_caller* sc_table[1024] =
|
||||
bind_func(sys_rwlock_trywlock), //126 (0x07E)
|
||||
bind_func(sys_rwlock_wunlock), //127 (0x07F)
|
||||
bind_func(sys_event_queue_create), //128 (0x080)
|
||||
null_func, //129 (0x081)
|
||||
bind_func(sys_event_queue_receive), null_func, bind_func(sys_event_flag_cancel), bind_func(sys_event_queue_drain), bind_func(sys_event_port_create), //134
|
||||
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), bind_func(sys_event_flag_get), //139
|
||||
bind_func(sys_event_queue_destroy), //129 (0x081)
|
||||
bind_func(sys_event_queue_receive), bind_func(sys_event_queue_tryreceive), // 131
|
||||
bind_func(sys_event_flag_cancel), bind_func(sys_event_queue_drain), bind_func(sys_event_port_create), //134
|
||||
bind_func(sys_event_port_destroy), bind_func(sys_event_port_connect_local), //136
|
||||
bind_func(sys_event_port_disconnect), 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
|
||||
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
|
||||
@ -99,8 +101,10 @@ static func_caller* sc_table[1024] =
|
||||
bind_func(sys_spu_thread_group_start), bind_func(sys_spu_thread_group_suspend), //174
|
||||
null_func, null_func, null_func, bind_func(sys_spu_thread_group_join), null_func, //179
|
||||
null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, bind_func(sys_spu_thread_write_snr), //184
|
||||
null_func, null_func, bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189
|
||||
bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), null_func, bind_func(sys_spu_thread_bind_queue), null_func, //194
|
||||
bind_func(sys_spu_thread_group_connect_event), bind_func(sys_spu_thread_group_disconnect_event), //186
|
||||
bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189
|
||||
bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), bind_func(sys_spu_thread_disconnect_event), //192
|
||||
bind_func(sys_spu_thread_bind_queue), bind_func(sys_spu_thread_unbind_queue), //194
|
||||
null_func, null_func, null_func, null_func, null_func, //199
|
||||
null_func, null_func, null_func, null_func, null_func, //204
|
||||
null_func, null_func, null_func, null_func, null_func, //209
|
||||
@ -112,7 +116,7 @@ static func_caller* sc_table[1024] =
|
||||
null_func, null_func, null_func, null_func, null_func, //239
|
||||
null_func, null_func, null_func, null_func, null_func, //244
|
||||
null_func, null_func, null_func, null_func, null_func, //249
|
||||
null_func, bind_func(sys_spu_thread_group_connect_event_all_threads), null_func, null_func, null_func, //254
|
||||
null_func, bind_func(sys_spu_thread_group_connect_event_all_threads), bind_func(sys_spu_thread_group_disconnect_event_all_threads), null_func, null_func, //254
|
||||
null_func, null_func, null_func, null_func, null_func, //259
|
||||
null_func, null_func, null_func, null_func, null_func, //264
|
||||
null_func, null_func, null_func, null_func, null_func, //269
|
||||
|
@ -128,16 +128,20 @@ extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_add
|
||||
|
||||
//sys_event
|
||||
extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> attr, u64 event_queue_key, int size);
|
||||
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_connect_local(u32 event_port_id, u32 event_queue_id);
|
||||
extern int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
|
||||
extern int sys_event_queue_destroy(u32 equeue_id, int mode);
|
||||
extern int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> _event, u64 timeout);
|
||||
extern int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t<sys_event_data> event_array, int size, mem32_t number);
|
||||
extern int sys_event_queue_drain(u32 event_queue_id);
|
||||
extern int sys_event_port_create(mem32_t eport_id, int port_type, u64 name);
|
||||
extern int sys_event_port_destroy(u32 eport_id);
|
||||
extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
|
||||
extern int sys_event_port_disconnect(u32 eport_id);
|
||||
extern int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
|
||||
|
||||
//sys_event_flag
|
||||
extern int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init);
|
||||
extern int sys_event_flag_destroy(u32 eflag_id);
|
||||
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u32 timeout);
|
||||
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout);
|
||||
extern int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result);
|
||||
extern int sys_event_flag_set(u32 eflag_id, u64 bitptn);
|
||||
extern int sys_event_flag_clear(u32 eflag_id, u64 bitptn);
|
||||
@ -181,6 +185,16 @@ extern int sys_mutex_lock(u32 mutex_id, u64 timeout);
|
||||
extern int sys_mutex_trylock(u32 mutex_id);
|
||||
extern int sys_mutex_unlock(u32 mutex_id);
|
||||
|
||||
//sys_rwlock
|
||||
extern int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr);
|
||||
extern int sys_rwlock_destroy(u32 rw_lock_id);
|
||||
extern int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout);
|
||||
extern int sys_rwlock_tryrlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_runlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout);
|
||||
extern int sys_rwlock_trywlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_wunlock(u32 rw_lock_id);
|
||||
|
||||
//ppu_thread
|
||||
extern void sys_ppu_thread_exit(int errorcode);
|
||||
extern int sys_ppu_thread_yield();
|
||||
@ -197,7 +211,7 @@ extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
|
||||
extern int sys_ppu_thread_get_id(const u32 id_addr);
|
||||
|
||||
//memory
|
||||
extern int sys_memory_container_create(u32 cid_addr, u32 yield_size);
|
||||
extern int sys_memory_container_create(mem32_t cid, u32 yield_size);
|
||||
extern int sys_memory_container_destroy(u32 cid);
|
||||
extern int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr);
|
||||
extern int sys_memory_free(u32 start_addr);
|
||||
@ -290,13 +304,13 @@ extern int cellMouseGetRawData(u32 port_no, mem_class_t data);
|
||||
extern int cellGcmCallback(u32 context_addr, u32 count);
|
||||
|
||||
//sys_tty
|
||||
extern int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);
|
||||
extern int sys_tty_write(u32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr);
|
||||
extern int sys_tty_read(s32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);
|
||||
extern int sys_tty_write(s32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr);
|
||||
|
||||
//sys_heap
|
||||
extern int sys_heap_create_heap(const u32 heap_addr, const u32 start_addr, const u32 size);
|
||||
extern int sys_heap_malloc(const u32 heap_addr, const u32 size);
|
||||
extern int _sys_heap_memalign(u32 heap_id, u32 align, u32 size, u64 p4);
|
||||
extern int _sys_heap_memalign(u32 heap_id, u32 align, u32 size);
|
||||
|
||||
//sys_spu
|
||||
extern int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr);
|
||||
@ -307,9 +321,11 @@ extern int sys_spu_thread_group_start(u32 id);
|
||||
extern int sys_spu_thread_group_suspend(u32 id);
|
||||
extern int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr);
|
||||
extern int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
||||
extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
|
||||
extern int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
|
||||
extern int sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et);
|
||||
extern int sys_spu_thread_group_disconnect_event(u32 id, u32 et);
|
||||
extern int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr);
|
||||
extern int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup);
|
||||
extern int sys_raw_spu_create(mem32_t id, u32 attr_addr);
|
||||
extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
||||
extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
|
||||
@ -318,7 +334,10 @@ extern int sys_spu_thread_write_spu_mb(u32 id, u32 value);
|
||||
extern int sys_spu_thread_set_spu_cfg(u32 id, u64 value);
|
||||
extern int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value);
|
||||
extern int sys_spu_thread_write_snr(u32 id, u32 number, u32 value);
|
||||
extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
|
||||
extern int sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup);
|
||||
extern int sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num);
|
||||
extern int sys_spu_thread_unbind_queue(u32 id, u32 spuq_num);
|
||||
extern int sys_spu_thread_get_exit_status(u32 id, mem32_t status);
|
||||
|
||||
//sys_time
|
||||
@ -350,16 +369,6 @@ extern int sys_trace_allocate_buffer();
|
||||
extern int sys_trace_free_buffer();
|
||||
extern int sys_trace_create2();
|
||||
|
||||
//sys_rwlock
|
||||
extern int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr);
|
||||
extern int sys_rwlock_destroy(u32 rw_lock_id);
|
||||
extern int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout);
|
||||
extern int sys_rwlock_tryrlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_runlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout);
|
||||
extern int sys_rwlock_trywlock(u32 rw_lock_id);
|
||||
extern int sys_rwlock_wunlock(u32 rw_lock_id);
|
||||
|
||||
//sys_rsx
|
||||
extern int sys_rsx_device_open();
|
||||
extern int sys_rsx_device_close();
|
||||
|
@ -72,7 +72,11 @@ int sys_cond_wait(u32 cond_id, u64 timeout)
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
|
||||
do
|
||||
{
|
||||
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_cond_wait(cond_id=%d, ...) aborted", cond_id);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
switch (cond_data->cond.WaitTimeout(1))
|
||||
{
|
||||
@ -85,7 +89,6 @@ int sys_cond_wait(u32 cond_id, u64 timeout)
|
||||
{
|
||||
if (!timeout)
|
||||
{
|
||||
sys_cond.Warning("sys_cond_wait(cond_id=0x%x, timeout=0x%llx): TIMEOUT", cond_id, timeout);
|
||||
counter = 0;
|
||||
}
|
||||
else
|
||||
|
@ -21,25 +21,201 @@ int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> at
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
equeue_id = sys_event.GetNewId(new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size));
|
||||
sys_event.Warning("*** event_queue created[%s] (protocol=0x%x, type=0x%x): id = %d",
|
||||
switch (attr->protocol.ToBE())
|
||||
{
|
||||
case se32(SYS_SYNC_PRIORITY): break;
|
||||
case se32(SYS_SYNC_RETRY): sys_event.Error("Invalid SYS_SYNC_RETRY protocol attr"); return CELL_EINVAL;
|
||||
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL;
|
||||
case se32(SYS_SYNC_FIFO): break;
|
||||
default: sys_event.Error("Unknown 0x%x protocol attr", (u32)attr->protocol); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
switch (attr->type.ToBE())
|
||||
{
|
||||
case se32(SYS_PPU_QUEUE): break;
|
||||
case se32(SYS_SPU_QUEUE): break;
|
||||
default: sys_event.Error("Unknown 0x%x type attr", (u32)attr->type); return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (event_queue_key && Emu.GetEventManager().CheckKey(event_queue_key))
|
||||
{
|
||||
return CELL_EEXIST;
|
||||
}
|
||||
|
||||
EventQueue* eq = new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size);
|
||||
|
||||
if (event_queue_key && !Emu.GetEventManager().RegisterKey(eq, event_queue_key))
|
||||
{
|
||||
delete eq;
|
||||
return CELL_EAGAIN;
|
||||
}
|
||||
|
||||
equeue_id = sys_event.GetNewId(eq);
|
||||
sys_event.Warning("*** event_queue created [%s] (protocol=0x%x, type=0x%x): id = %d",
|
||||
attr->name, (u32)attr->protocol, (int)attr->type, equeue_id.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
int sys_event_queue_destroy(u32 equeue_id, int mode)
|
||||
{
|
||||
sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x, event_addr=0x%x, timeout=0x%x)",
|
||||
equeue_id, event_addr, timeout);
|
||||
sys_event.Warning("sys_event_queue_destroy(equeue_id=%d, mode=0x%x)", equeue_id, mode);
|
||||
|
||||
if(!sys_event.CheckId(equeue_id))
|
||||
EventQueue* eq;
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
int result;
|
||||
auto queue_receive = [&](int status) -> bool
|
||||
if (mode && mode != SYS_EVENT_QUEUE_DESTROY_FORCE)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
eq->m_mutex.lock(tid);
|
||||
eq->owner.lock(tid);
|
||||
// check if some threads are waiting for an event
|
||||
if (!mode && eq->list.GetCount())
|
||||
{
|
||||
eq->owner.unlock(tid);
|
||||
eq->m_mutex.unlock(tid);
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
eq->owner.unlock(tid, ~0);
|
||||
eq->m_mutex.unlock(tid);
|
||||
while (eq->list.GetCount())
|
||||
{
|
||||
Sleep(1);
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_event_queue_destroy(equeue=%d, ...) aborted", equeue_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Emu.GetEventManager().UnregisterKey(eq->key);
|
||||
eq->ports.clear();
|
||||
Emu.GetIdManager().RemoveID(equeue_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t<sys_event_data> event_array, int size, mem32_t number)
|
||||
{
|
||||
sys_event.Error("sys_event_queue_tryreceive(equeue_id=%d, event_array_addr=0x%x, size=%d, number_addr=0x%x)",
|
||||
equeue_id, event_array.GetAddr(), size, number.GetAddr());
|
||||
|
||||
if (size < 0 || !number.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (size && !Memory.IsGoodAddr(event_array.GetAddr(), sizeof(sys_event_data) * size))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
EventQueue* eq;
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (eq->type != SYS_PPU_QUEUE)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
number = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
eq->m_mutex.lock(tid);
|
||||
eq->owner.lock(tid);
|
||||
if (eq->list.GetCount())
|
||||
{
|
||||
number = 0;
|
||||
eq->owner.unlock(tid);
|
||||
eq->m_mutex.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
number = eq->events.pop_all((sys_event_data*)(Memory + event_array.GetAddr()), size);
|
||||
eq->owner.unlock(tid);
|
||||
eq->m_mutex.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> event, u64 timeout)
|
||||
{
|
||||
sys_event.Warning("sys_event_queue_receive(equeue_id=%d, event_addr=0x%x, timeout=%lld)",
|
||||
equeue_id, event.GetAddr(), timeout);
|
||||
|
||||
if (!event.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
EventQueue* eq;
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (eq->type != SYS_PPU_QUEUE)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
eq->push(tid); // add thread to sleep queue
|
||||
|
||||
timeout = timeout ? (timeout / 1000) : ~0;
|
||||
u64 counter = 0;
|
||||
while (true)
|
||||
{
|
||||
switch (eq->owner.trylock(tid))
|
||||
{
|
||||
case SMR_OK:
|
||||
if (!eq->events.count())
|
||||
{
|
||||
eq->owner.unlock(tid);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 next = (eq->protocol == SYS_SYNC_FIFO) ? eq->pop() : eq->pop_prio();
|
||||
if (next != tid)
|
||||
{
|
||||
eq->owner.unlock(tid, next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SMR_SIGNAL:
|
||||
{
|
||||
eq->events.pop(*(sys_event_data*)(Memory + event));
|
||||
eq->owner.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
case SMR_FAILED: break;
|
||||
default: eq->invalidate(tid); return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
if (counter++ > timeout || Emu.IsStopped())
|
||||
{
|
||||
if (Emu.IsStopped()) ConLog.Warning("sys_event_queue_receive(equeue=%d, ...) aborted", equeue_id);
|
||||
eq->invalidate(tid);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
/* auto queue_receive = [&](int status) -> bool
|
||||
{
|
||||
if(status == CPUThread_Stopped)
|
||||
{
|
||||
@ -48,7 +224,12 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
}
|
||||
|
||||
EventQueue* equeue;
|
||||
Emu.GetIdManager().GetIDData(equeue_id, equeue);
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, equeue))
|
||||
{
|
||||
result = CELL_ESRCH;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i=0; i<equeue->pos; ++i)
|
||||
{
|
||||
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
|
||||
@ -71,12 +252,10 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
{
|
||||
if(equeue->ports[i]->has_data)
|
||||
{
|
||||
auto dst = (sys_event_data&)Memory[event_addr];
|
||||
|
||||
dst.source = equeue->ports[i]->name;
|
||||
dst.data1 = equeue->ports[i]->data1;
|
||||
dst.data2 = equeue->ports[i]->data2;
|
||||
dst.data3 = equeue->ports[i]->data3;
|
||||
event->source = equeue->ports[i]->name;
|
||||
event->data1 = equeue->ports[i]->data1;
|
||||
event->data2 = equeue->ports[i]->data2;
|
||||
event->data3 = equeue->ports[i]->data3;
|
||||
|
||||
equeue->ports[i]->has_data = false;
|
||||
|
||||
@ -88,85 +267,167 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
return true;
|
||||
};
|
||||
|
||||
GetCurrentPPUThread().WaitFor(queue_receive);
|
||||
|
||||
return result;
|
||||
GetCurrentPPUThread().WaitFor(queue_receive);*/
|
||||
}
|
||||
|
||||
int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name)
|
||||
int sys_event_queue_drain(u32 equeue_id)
|
||||
{
|
||||
sys_event.Warning("sys_event_queue_drain(equeue_id=%d)", equeue_id);
|
||||
|
||||
EventQueue* eq;
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
eq->events.clear();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_create(mem32_t eport_id, int port_type, u64 name)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_create(eport_id_addr=0x%x, port_type=0x%x, name=0x%llx)",
|
||||
eport_id_addr, port_type, name);
|
||||
eport_id.GetAddr(), port_type, name);
|
||||
|
||||
if(!Memory.IsGoodAddr(eport_id_addr, 4))
|
||||
if (!eport_id.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (port_type != SYS_EVENT_PORT_LOCAL)
|
||||
{
|
||||
sys_event.Error("sys_event_port_create: invalid port_type(0x%x)", port_type);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
EventPort* eport = new EventPort();
|
||||
u32 id = sys_event.GetNewId(eport);
|
||||
eport->pos = 0;
|
||||
eport->has_data = false;
|
||||
eport->name = name ? name : id;
|
||||
Memory.Write32(eport_id_addr, id);
|
||||
eport->name = name ? name : ((u64)sys_process_getpid() << 32) | (u64)id;
|
||||
eport_id = id;
|
||||
sys_event.Warning("*** sys_event_port created: id = %d", id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id)
|
||||
int sys_event_port_destroy(u32 eport_id)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_connect_local(event_port_id=0x%x, event_queue_id=0x%x)",
|
||||
event_port_id, event_queue_id);
|
||||
sys_event.Warning("sys_event_port_destroy(eport_id=%d)", eport_id);
|
||||
|
||||
if(!sys_event.CheckId(event_port_id) || !sys_event.CheckId(event_queue_id))
|
||||
EventPort* eport;
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
if (eport->mutex.trylock(tid) != SMR_OK)
|
||||
{
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
if (eport->eq)
|
||||
{
|
||||
eport->mutex.unlock(tid);
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
eport->mutex.unlock(tid, ~0);
|
||||
Emu.GetIdManager().RemoveID(eport_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_connect_local(u32 eport_id, u32 equeue_id)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_connect_local(eport_id=%d, equeue_id=%d)", eport_id, equeue_id);
|
||||
|
||||
EventPort* eport;
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
if (eport->mutex.trylock(tid) != SMR_OK)
|
||||
{
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
if (eport->eq)
|
||||
{
|
||||
eport->mutex.unlock(tid);
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
EventQueue* equeue;
|
||||
Emu.GetIdManager().GetIDData(event_port_id, eport);
|
||||
Emu.GetIdManager().GetIDData(event_queue_id, equeue);
|
||||
equeue->ports[equeue->pos++] = eport;
|
||||
eport->queue[eport->pos++] = equeue;
|
||||
if (!Emu.GetIdManager().GetIDData(equeue_id, equeue))
|
||||
{
|
||||
sys_event.Error("sys_event_port_connect_local: event_queue(%d) not found!", equeue_id);
|
||||
eport->mutex.unlock(tid);
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
equeue->ports.add(eport);
|
||||
}
|
||||
|
||||
eport->eq = equeue;
|
||||
eport->mutex.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3)
|
||||
int sys_event_port_disconnect(u32 eport_id)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_send(event_port_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)",
|
||||
event_port_id, data1, data2, data3);
|
||||
sys_event.Warning("sys_event_port_disconnect(eport_id=%d)", eport_id);
|
||||
|
||||
if(!sys_event.CheckId(event_port_id))
|
||||
EventPort* eport;
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
EventPort* eport;
|
||||
Emu.GetIdManager().GetIDData(event_port_id, eport);
|
||||
|
||||
if(!eport->pos)
|
||||
if (!eport->eq)
|
||||
{
|
||||
return CELL_ENOTCONN;
|
||||
}
|
||||
|
||||
if(eport->has_data)
|
||||
u32 tid = GetCurrentPPUThread().GetId();
|
||||
|
||||
if (eport->mutex.trylock(tid) != SMR_OK)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
eport->has_data = true;
|
||||
eport->data1 = data1;
|
||||
eport->data2 = data2;
|
||||
eport->data3 = data3;
|
||||
|
||||
eport->eq->ports.remove(eport);
|
||||
eport->eq = 0;
|
||||
eport->mutex.unlock(tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_queue_drain(u32 event_queue_id)
|
||||
int sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
|
||||
{
|
||||
sys_event.Error("sys_event_queue_drain(event_queue_id=0x%x)", event_queue_id);
|
||||
sys_event.Warning("sys_event_port_send(eport_id=%d, data1=0x%llx, data2=0x%llx, data3=0x%llx)",
|
||||
eport_id, data1, data2, data3);
|
||||
|
||||
EventPort* eport;
|
||||
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
SMutexLocker lock(eport->mutex);
|
||||
|
||||
if (!eport->eq)
|
||||
{
|
||||
return CELL_ENOTCONN;
|
||||
}
|
||||
|
||||
if (!eport->eq->events.push(eport->name, data1, data2, data3))
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
@ -6,7 +6,8 @@ SysCallBase sys_event_flag("sys_event_flag");
|
||||
|
||||
int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)", eflag_id.GetAddr(), attr.GetAddr(), init);
|
||||
sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
|
||||
eflag_id.GetAddr(), attr.GetAddr(), init);
|
||||
|
||||
if(!eflag_id.IsGood() || !attr.IsGood())
|
||||
{
|
||||
@ -16,7 +17,7 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
|
||||
switch (attr->protocol.ToBE())
|
||||
{
|
||||
case se32(SYS_SYNC_PRIORITY): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY attr"); break;
|
||||
case se32(SYS_SYNC_RETRY): break;
|
||||
case se32(SYS_SYNC_RETRY): sys_event_flag.Warning("TODO: SYS_SYNC_RETRY attr"); break;
|
||||
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT attr"); break;
|
||||
case se32(SYS_SYNC_FIFO): sys_event_flag.Warning("TODO: SYS_SYNC_FIFO attr"); break;
|
||||
default: return CELL_EINVAL;
|
||||
@ -36,14 +37,15 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
|
||||
|
||||
eflag_id = sys_event_flag.GetNewId(new event_flag(init, (u32)attr->protocol, (int)attr->type));
|
||||
|
||||
sys_event_flag.Warning("*** event_flag created[%s] (protocol=%d, type=%d): id = %d", attr->name, (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());
|
||||
sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d",
|
||||
attr->name, (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_flag_destroy(u32 eflag_id)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_destroy(eflag_id=0x%x)", eflag_id);
|
||||
sys_event_flag.Warning("sys_event_flag_destroy(eflag_id=%d)", eflag_id);
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
@ -53,23 +55,23 @@ int sys_event_flag_destroy(u32 eflag_id)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u32 timeout)
|
||||
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_wait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=0x%x)",
|
||||
sys_event_flag.Error("sys_event_flag_wait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=%lld)",
|
||||
eflag_id, bitptn, mode, result.GetAddr(), timeout);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_trywait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
|
||||
sys_event_flag.Error("sys_event_flag_trywait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
|
||||
eflag_id, bitptn, mode, result.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_set(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
sys_event_flag.Warning("sys_event_flag_set(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
@ -81,7 +83,7 @@ int sys_event_flag_set(u32 eflag_id, u64 bitptn)
|
||||
|
||||
int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_clear(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
sys_event_flag.Warning("sys_event_flag_clear(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
|
||||
|
||||
event_flag* ef;
|
||||
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
|
||||
@ -93,13 +95,13 @@ int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
|
||||
|
||||
int sys_event_flag_cancel(u32 eflag_id, mem32_t num)
|
||||
{
|
||||
sys_event_flag.Error("sys_event_flag_cancel(eflag_id=0x%x, num_addr=0x%x)", eflag_id, num.GetAddr());
|
||||
sys_event_flag.Error("sys_event_flag_cancel(eflag_id=%d, num_addr=0x%x)", eflag_id, num.GetAddr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_flag_get(u32 eflag_id, mem64_t flags)
|
||||
{
|
||||
sys_event_flag.Warning("sys_event_flag_get(eflag_id=0x%x, flags_addr=0x%x)", eflag_id, flags.GetAddr());
|
||||
sys_event_flag.Warning("sys_event_flag_get(eflag_id=%d, flags_addr=0x%x)", eflag_id, flags.GetAddr());
|
||||
|
||||
if (!flags.IsGood())
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ extern Module sys_fs;
|
||||
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
|
||||
sys_fs.Log("cellFsOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
|
||||
path.wx_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
|
||||
|
||||
const wxString& ppath = path;
|
||||
@ -57,7 +57,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
|
||||
if(_oflags != 0)
|
||||
{
|
||||
sys_fs.Error("'%s' has unknown flags! flags: 0x%08x", ppath.wx_str(), flags);
|
||||
sys_fs.Error("\"%s\" has unknown flags! flags: 0x%08x", ppath.wx_str(), flags);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
@ -65,21 +65,21 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
|
||||
if(!stream || !stream->IsOpened())
|
||||
{
|
||||
sys_fs.Error("'%s' not found! flags: 0x%08x", ppath.wx_str(), flags);
|
||||
sys_fs.Error("\"%s\" not found! flags: 0x%08x", ppath.wx_str(), flags);
|
||||
delete stream;
|
||||
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
fd = sys_fs.GetNewId(stream, flags);
|
||||
ConLog.Warning("*** cellFsOpen(path: %s): fd=%d", path.wx_str(), fd.GetValue());
|
||||
ConLog.Warning("*** cellFsOpen(path=\"%s\"): fd = %d", path.wx_str(), fd.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||
{
|
||||
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
|
||||
sys_fs.Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)",
|
||||
fd, buf_addr, nbytes, nread.GetAddr());
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
@ -100,7 +100,7 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||
|
||||
int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||
{
|
||||
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
|
||||
sys_fs.Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)",
|
||||
fd, buf_addr, nbytes, nwrite.GetAddr());
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
@ -121,7 +121,7 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||
|
||||
int cellFsClose(u32 fd)
|
||||
{
|
||||
sys_fs.Warning("cellFsClose(fd: %d)", fd);
|
||||
sys_fs.Warning("cellFsClose(fd=%d)", fd);
|
||||
|
||||
if(!Emu.GetIdManager().RemoveID(fd))
|
||||
return CELL_ESRCH;
|
||||
@ -186,7 +186,7 @@ int cellFsClosedir(u32 fd)
|
||||
int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsStat(path: %s, sb_addr: 0x%x)", path.wx_str(), sb.GetAddr());
|
||||
sys_fs.Log("cellFsStat(path=\"%s\", sb_addr: 0x%x)", path.wx_str(), sb.GetAddr());
|
||||
|
||||
sb->st_mode =
|
||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
||||
@ -205,7 +205,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||
{
|
||||
if(path.CmpNoCase(Emu.GetVFS().m_devices[i].GetPs3Path().RemoveLast(1)) == 0)
|
||||
{
|
||||
sys_fs.Log("cellFsStat: '%s' is a mount point.", path.wx_str());
|
||||
sys_fs.Log("cellFsStat: \"%s\" is a mount point.", path.wx_str());
|
||||
sb->st_mode |= CELL_FS_S_IFDIR;
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -230,7 +230,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_fs.Warning("cellFsStat: '%s' not found.", path.wx_str());
|
||||
sys_fs.Warning("cellFsStat: \"%s\" not found.", path.wx_str());
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||
|
||||
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
|
||||
{
|
||||
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||
sys_fs.Log("cellFsFstat(fd=%d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
@ -315,14 +315,14 @@ int cellFsUnlink(u32 path_addr)
|
||||
int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||
{
|
||||
vfsSeekMode seek_mode;
|
||||
sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos.GetAddr());
|
||||
sys_fs.Log("cellFsLseek(fd=%d, offset=0x%llx, whence=0x%x, pos_addr=0x%x)", fd, offset, whence, pos.GetAddr());
|
||||
switch(whence)
|
||||
{
|
||||
case CELL_SEEK_SET: seek_mode = vfsSeekSet; break;
|
||||
case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break;
|
||||
case CELL_SEEK_END: seek_mode = vfsSeekEnd; break;
|
||||
default:
|
||||
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
||||
sys_fs.Error(fd, "Unknown seek whence! (0x%x)", whence);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
@ -334,7 +334,7 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||
|
||||
int cellFsFtruncate(u32 fd, u64 size)
|
||||
{
|
||||
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
||||
sys_fs.Log("cellFsFtruncate(fd=%d, size=%lld)", fd, size);
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
u64 initialSize = file->GetSize();
|
||||
@ -360,12 +360,12 @@ int cellFsFtruncate(u32 fd, u64 size)
|
||||
int cellFsTruncate(u32 path_addr, u64 size)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsTruncate(path: %s, size: %lld)", path.wx_str(), size);
|
||||
sys_fs.Log("cellFsTruncate(path=\"%s\", size=%lld)", path.wx_str(), size);
|
||||
|
||||
vfsFile f(path, vfsReadWrite);
|
||||
if(!f.IsOpened())
|
||||
{
|
||||
sys_fs.Warning("cellFsTruncate: '%s' not found.", path.wx_str());
|
||||
sys_fs.Warning("cellFsTruncate: \"%s\" not found.", path.wx_str());
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
u64 initialSize = f.GetSize();
|
||||
@ -390,7 +390,7 @@ int cellFsTruncate(u32 path_addr, u64 size)
|
||||
|
||||
int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
|
||||
{
|
||||
sys_fs.Log("cellFsFGetBlockSize(fd: %d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr());
|
||||
sys_fs.Log("cellFsFGetBlockSize(fd=%d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr());
|
||||
|
||||
sector_size = 4096; // ?
|
||||
block_size = 4096; // ?
|
||||
|
@ -22,13 +22,13 @@ int sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size)
|
||||
sc_heap.Warning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size);
|
||||
|
||||
u32 heap_id = sc_heap.GetNewId(new HeapInfo(heap_addr, align, size));
|
||||
sc_heap.Warning("*** sys_heap created(): id=0x%x", heap_id);
|
||||
sc_heap.Warning("*** sys_heap created: id = %d", heap_id);
|
||||
return heap_id;
|
||||
}
|
||||
|
||||
int sys_heap_malloc(const u32 heap_id, const u32 size)
|
||||
{
|
||||
sc_heap.Warning("sys_heap_malloc(heap_id=0x%x, size=0x%x)", heap_id, size);
|
||||
sc_heap.Warning("sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size);
|
||||
|
||||
HeapInfo* heap;
|
||||
if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH;
|
||||
@ -36,9 +36,9 @@ int sys_heap_malloc(const u32 heap_id, const u32 size)
|
||||
return Memory.Alloc(size, 1);
|
||||
}
|
||||
|
||||
int _sys_heap_memalign(u32 heap_id, u32 align, u32 size, u64 p4)
|
||||
int _sys_heap_memalign(u32 heap_id, u32 align, u32 size)
|
||||
{
|
||||
sc_heap.Warning("_sys_heap_memalign(heap_id=0x%x, align=0x%x, size=0x%x, p4=0x%llx, ... ???)", heap_id, align, size, p4);
|
||||
sc_heap.Warning("_sys_heap_memalign(heap_id=%d, align=0x%x, size=0x%x)", heap_id, align, size);
|
||||
|
||||
HeapInfo* heap;
|
||||
if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH;
|
||||
|
@ -7,7 +7,7 @@ SysCallBase sys_lwcond("sys_lwcond");
|
||||
|
||||
int sys_lwcond_create(mem_ptr_t<sys_lwcond_t> lwcond, mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwcond_attribute_t> attr)
|
||||
{
|
||||
sys_lwcond.Log("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)",
|
||||
sys_lwcond.Warning("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)",
|
||||
lwcond.GetAddr(), lwmutex.GetAddr(), attr.GetAddr());
|
||||
|
||||
if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT;
|
||||
@ -15,7 +15,7 @@ int sys_lwcond_create(mem_ptr_t<sys_lwcond_t> lwcond, mem_ptr_t<sys_lwmutex_t> l
|
||||
lwcond->lwmutex = lwmutex.GetAddr();
|
||||
lwcond->lwcond_queue = sys_lwcond.GetNewId(new LWCond(attr->name_u64));
|
||||
|
||||
sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id=0x%x",
|
||||
sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id = %d",
|
||||
attr->name, (u32)lwmutex->attribute, (u32)lwmutex->sleep_queue, (u32)lwcond->lwcond_queue);
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -77,7 +77,7 @@ int sys_lwcond_signal_to(mem_ptr_t<sys_lwcond_t> lwcond, u32 ppu_thread_id)
|
||||
|
||||
int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
|
||||
{
|
||||
sys_lwcond.Log("sys_lwcond_wait(lwcond_addr=0x%x, timeout=%llu)", lwcond.GetAddr(), timeout);
|
||||
sys_lwcond.Log("sys_lwcond_wait(lwcond_addr=0x%x, timeout=%lld)", lwcond.GetAddr(), timeout);
|
||||
|
||||
if (!lwcond.IsGood()) return CELL_EFAULT;
|
||||
LWCond* lwc;
|
||||
@ -95,7 +95,11 @@ int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
|
||||
bool was_locked = true;
|
||||
do
|
||||
{
|
||||
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_lwcond_wait(sq id=%d, ...) aborted", id);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
if (was_locked) lwmutex->unlock(tid);
|
||||
Sleep(1);
|
||||
if (was_locked = (lwmutex->trylock(tid) == CELL_OK))
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/lv2/SC_Lwmutex.h"
|
||||
#include <mutex>
|
||||
|
||||
SysCallBase sc_lwmutex("sys_lwmutex");
|
||||
|
||||
@ -36,7 +35,7 @@ int sys_lwmutex_create(mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwmutex_a
|
||||
u32 sq_id = sc_lwmutex.GetNewId(new SleepQueue(attr->name_u64));
|
||||
lwmutex->sleep_queue = sq_id;
|
||||
|
||||
sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sleep_queue=0x%x",
|
||||
sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d",
|
||||
attr->name, (u32)lwmutex->attribute, sq_id);
|
||||
|
||||
return CELL_OK;
|
||||
@ -89,3 +88,174 @@ int sys_lwmutex_unlock(mem_ptr_t<sys_lwmutex_t> lwmutex)
|
||||
return lwmutex->unlock(GetCurrentPPUThread().GetId());
|
||||
}
|
||||
|
||||
void SleepQueue::push(u32 tid)
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
list.AddCpy(tid);
|
||||
}
|
||||
|
||||
u32 SleepQueue::pop() // SYS_SYNC_FIFO
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (list.GetCount())
|
||||
{
|
||||
u32 res = list[0];
|
||||
list.RemoveAt(0);
|
||||
if (res && Emu.GetIdManager().CheckID(res))
|
||||
// check thread
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
u32 SleepQueue::pop_prio() // SYS_SYNC_PRIORITY
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (list.GetCount())
|
||||
{
|
||||
u64 max_prio = 0;
|
||||
u32 sel = 0;
|
||||
for (u32 i = 0; i < list.GetCount(); i++)
|
||||
{
|
||||
CPUThread* t = Emu.GetCPU().GetThread(list[i]);
|
||||
if (!t)
|
||||
{
|
||||
list[i] = 0;
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
u64 prio = t->GetPrio();
|
||||
if (prio > max_prio)
|
||||
{
|
||||
max_prio = prio;
|
||||
sel = i;
|
||||
}
|
||||
}
|
||||
u32 res = list[sel];
|
||||
list.RemoveAt(sel);
|
||||
/* if (Emu.GetIdManager().CheckID(res)) */
|
||||
if (res)
|
||||
// check thread
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 SleepQueue::pop_prio_inherit() // (TODO)
|
||||
{
|
||||
ConLog.Error("TODO: SleepQueue::pop_prio_inherit()");
|
||||
Emu.Pause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SleepQueue::invalidate(u32 tid)
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
|
||||
for (u32 i = 0; i < list.GetCount(); i++)
|
||||
{
|
||||
if (list[i] = tid)
|
||||
{
|
||||
list[i] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sys_lwmutex_t::trylock(be_t<u32> tid)
|
||||
{
|
||||
if (!attribute.ToBE()) return CELL_EINVAL;
|
||||
|
||||
if (tid == owner.GetOwner())
|
||||
{
|
||||
if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE))
|
||||
{
|
||||
recursive_count += 1;
|
||||
if (!recursive_count.ToBE()) return CELL_EKRESOURCE;
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_EDEADLK;
|
||||
}
|
||||
}
|
||||
|
||||
switch (owner.trylock(tid))
|
||||
{
|
||||
case SMR_OK: recursive_count = 1; return CELL_OK;
|
||||
case SMR_FAILED: return CELL_EBUSY;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int sys_lwmutex_t::unlock(be_t<u32> tid)
|
||||
{
|
||||
if (tid != owner.GetOwner())
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
else
|
||||
{
|
||||
recursive_count -= 1;
|
||||
if (!recursive_count.ToBE())
|
||||
{
|
||||
be_t<u32> target = 0;
|
||||
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
|
||||
{
|
||||
case se32(SYS_SYNC_FIFO):
|
||||
case se32(SYS_SYNC_PRIORITY):
|
||||
SleepQueue* sq;
|
||||
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
|
||||
target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio();
|
||||
case se32(SYS_SYNC_RETRY): default: owner.unlock(tid, target); break;
|
||||
}
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int sys_lwmutex_t::lock(be_t<u32> tid, u64 timeout)
|
||||
{
|
||||
switch (int res = trylock(tid))
|
||||
{
|
||||
case CELL_EBUSY: break;
|
||||
default: return res;
|
||||
}
|
||||
|
||||
SleepQueue* sq;
|
||||
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
|
||||
|
||||
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
|
||||
{
|
||||
case se32(SYS_SYNC_PRIORITY):
|
||||
case se32(SYS_SYNC_FIFO):
|
||||
sq->push(tid);
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (owner.lock(tid, timeout))
|
||||
{
|
||||
case SMR_OK:
|
||||
sq->invalidate(tid);
|
||||
case SMR_SIGNAL:
|
||||
recursive_count = 1; return CELL_OK;
|
||||
case SMR_TIMEOUT:
|
||||
sq->invalidate(tid); return CELL_ETIMEDOUT;
|
||||
case SMR_ABORT:
|
||||
if (Emu.IsStopped()) ConLog.Warning("sys_lwmutex_t::lock(sq=%d, ...) aborted", (u32)sleep_queue);
|
||||
default:
|
||||
sq->invalidate(tid); return CELL_EINVAL;
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ struct sys_lwmutex_attribute_t
|
||||
};
|
||||
};
|
||||
|
||||
class SleepQueue
|
||||
struct SleepQueue
|
||||
{
|
||||
/* struct q_rec
|
||||
{
|
||||
@ -46,88 +46,20 @@ class SleepQueue
|
||||
u64 prio;
|
||||
q_rec(u32 tid, u64 prio): tid(tid), prio(prio) {}
|
||||
}; */
|
||||
|
||||
SMutex m_mutex;
|
||||
Array<u32> list;
|
||||
SMutex m_mutex;
|
||||
u64 m_name;
|
||||
|
||||
public:
|
||||
SleepQueue(u64 name)
|
||||
SleepQueue(u64 name = 0)
|
||||
: m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void push(u32 tid)
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
list.AddCpy(tid);
|
||||
}
|
||||
|
||||
u32 pop() // SYS_SYNC_FIFO
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (list.GetCount())
|
||||
{
|
||||
u32 res = list[0];
|
||||
list.RemoveAt(0);
|
||||
if (Emu.GetIdManager().CheckID(res))
|
||||
// check thread
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
u32 pop_prio() // SYS_SYNC_PRIORITY
|
||||
{
|
||||
SMutexLocker lock(m_mutex);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (list.GetCount())
|
||||
{
|
||||
u64 max_prio = 0;
|
||||
u32 sel = 0;
|
||||
for (u32 i = 0; i < list.GetCount(); i++)
|
||||
{
|
||||
CPUThread* t = Emu.GetCPU().GetThread(list[i]);
|
||||
if (!t)
|
||||
{
|
||||
list[i] = 0;
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
|
||||
u64 prio = t->GetPrio();
|
||||
if (prio > max_prio)
|
||||
{
|
||||
max_prio = prio;
|
||||
sel = i;
|
||||
}
|
||||
}
|
||||
u32 res = list[sel];
|
||||
list.RemoveAt(sel);
|
||||
/* if (Emu.GetIdManager().CheckID(res)) */
|
||||
if (res)
|
||||
// check thread
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 pop_prio_inherit() // (TODO)
|
||||
{
|
||||
ConLog.Error("TODO: SleepQueue::pop_prio_inherit()");
|
||||
Emu.Pause();
|
||||
}
|
||||
void push(u32 tid);
|
||||
u32 pop(); // SYS_SYNC_FIFO
|
||||
u32 pop_prio(); // SYS_SYNC_PRIORITY
|
||||
u32 pop_prio_inherit(); // (TODO)
|
||||
void invalidate(u32 tid);
|
||||
};
|
||||
|
||||
struct sys_lwmutex_t
|
||||
@ -149,85 +81,11 @@ struct sys_lwmutex_t
|
||||
be_t<u32> sleep_queue;
|
||||
be_t<u32> pad;
|
||||
|
||||
int trylock(be_t<u32> tid)
|
||||
{
|
||||
if (!attribute.ToBE()) return CELL_EINVAL;
|
||||
|
||||
if (tid == owner.GetOwner())
|
||||
{
|
||||
if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE))
|
||||
{
|
||||
recursive_count += 1;
|
||||
if (!recursive_count.ToBE()) return CELL_EKRESOURCE;
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_EDEADLK;
|
||||
}
|
||||
}
|
||||
|
||||
switch (owner.trylock(tid))
|
||||
{
|
||||
case SMR_OK: recursive_count = 1; return CELL_OK;
|
||||
case SMR_FAILED: return CELL_EBUSY;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int unlock(be_t<u32> tid)
|
||||
{
|
||||
if (tid != owner.GetOwner())
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
else
|
||||
{
|
||||
recursive_count -= 1;
|
||||
if (!recursive_count.ToBE())
|
||||
{
|
||||
be_t<u32> target = 0;
|
||||
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
|
||||
{
|
||||
case se32(SYS_SYNC_FIFO):
|
||||
case se32(SYS_SYNC_PRIORITY):
|
||||
SleepQueue* sq;
|
||||
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
|
||||
target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio();
|
||||
case se32(SYS_SYNC_RETRY): default: owner.unlock(tid, target); break;
|
||||
}
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int lock(be_t<u32> tid, u64 timeout)
|
||||
{
|
||||
switch (int res = trylock(tid))
|
||||
{
|
||||
case CELL_EBUSY: break;
|
||||
default: return res;
|
||||
}
|
||||
|
||||
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
|
||||
{
|
||||
case se32(SYS_SYNC_PRIORITY):
|
||||
case se32(SYS_SYNC_FIFO):
|
||||
SleepQueue* sq;
|
||||
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
|
||||
sq->push(tid);
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (owner.lock(tid, timeout))
|
||||
{
|
||||
case SMR_OK: case SMR_SIGNAL: recursive_count = 1; return CELL_OK;
|
||||
case SMR_TIMEOUT: return CELL_ETIMEDOUT;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
int trylock(be_t<u32> tid);
|
||||
int unlock(be_t<u32> tid);
|
||||
int lock(be_t<u32> tid, u64 timeout);
|
||||
};
|
||||
|
||||
/*
|
||||
class lwmutex_locker
|
||||
{
|
||||
mem_ptr_t<sys_lwmutex_t> m_mutex;
|
||||
@ -248,4 +106,4 @@ class lwmutex_locker
|
||||
{
|
||||
m_mutex->unlock(m_id);
|
||||
}
|
||||
};
|
||||
};*/
|
@ -4,11 +4,11 @@
|
||||
|
||||
SysCallBase sc_mem("memory");
|
||||
|
||||
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
||||
int sys_memory_container_create(mem32_t cid, 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.GetAddr(), yield_size);
|
||||
|
||||
if(!Memory.IsGoodAddr(cid_addr, 4))
|
||||
if (!cid.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
@ -22,13 +22,14 @@ int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
|
||||
cid = sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size));
|
||||
sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_memory_container_destroy(u32 cid)
|
||||
{
|
||||
sc_mem.Warning("sys_memory_container_destroy(cid=0x%x)", cid);
|
||||
sc_mem.Warning("sys_memory_container_destroy(cid=%d)", cid);
|
||||
|
||||
MemoryContainerInfo* ct;
|
||||
|
||||
|
@ -53,7 +53,11 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout)
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
|
||||
do
|
||||
{
|
||||
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_mutex_lock(mutex_id=%d, ...) aborted", mutex_id);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (mtx_data->mtx.TryLock() == wxMUTEX_NO_ERROR) return CELL_OK;
|
||||
Sleep(1);
|
||||
@ -62,7 +66,6 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout)
|
||||
{
|
||||
if (!timeout)
|
||||
{
|
||||
sys_mtx.Warning("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx): TIMEOUT", mutex_id, timeout);
|
||||
counter = 0;
|
||||
}
|
||||
else
|
||||
|
@ -27,7 +27,7 @@ int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr
|
||||
|
||||
rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, attr->name_u64));
|
||||
|
||||
sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id=%d",
|
||||
sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d",
|
||||
attr->name, (u32)attr->attr_protocol, rw_lock_id.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
@ -51,7 +51,7 @@ int sys_rwlock_destroy(u32 rw_lock_id)
|
||||
|
||||
int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
|
||||
{
|
||||
sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=%llu)", rw_lock_id, timeout);
|
||||
sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout);
|
||||
|
||||
RWLock* rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw)) return CELL_ESRCH;
|
||||
@ -63,7 +63,11 @@ int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
|
||||
do
|
||||
{
|
||||
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_rwlock_rlock(rw_lock_id=%d, ...) aborted", rw_lock_id);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
Sleep(1);
|
||||
|
||||
if (rw->rlock_trylock(tid)) return CELL_OK;
|
||||
@ -72,7 +76,6 @@ int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
|
||||
{
|
||||
if (!timeout)
|
||||
{
|
||||
sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=%d): TIMEOUT", rw_lock_id);
|
||||
counter = 0;
|
||||
}
|
||||
else
|
||||
@ -109,7 +112,7 @@ int sys_rwlock_runlock(u32 rw_lock_id)
|
||||
|
||||
int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
|
||||
{
|
||||
sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=%llu)", rw_lock_id, timeout);
|
||||
sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout);
|
||||
|
||||
RWLock* rw;
|
||||
if (!sys_rwlock.CheckId(rw_lock_id, rw)) return CELL_ESRCH;
|
||||
@ -123,7 +126,11 @@ int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
|
||||
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
|
||||
do
|
||||
{
|
||||
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_rwlock_wlock(rw_lock_id=%d, ...) aborted", rw_lock_id);
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
Sleep(1);
|
||||
|
||||
if (rw->wlock_trylock(tid, true)) return CELL_OK;
|
||||
@ -132,7 +139,6 @@ int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
|
||||
{
|
||||
if (!timeout)
|
||||
{
|
||||
sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=%d): TIMEOUT", rw_lock_id);
|
||||
counter = 0;
|
||||
}
|
||||
else
|
||||
|
@ -156,7 +156,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
//166
|
||||
int sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg.GetAddr());
|
||||
sc_spu.Warning("sys_spu_thread_set_argument(id=%d, arg_addr=0x%x)", id, arg.GetAddr());
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
|
||||
@ -180,7 +180,7 @@ int sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg)
|
||||
//165
|
||||
int sys_spu_thread_get_exit_status(u32 id, mem32_t status)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_get_exit_status(id=0x%x, status_addr=0x%x)", id, status.GetAddr());
|
||||
sc_spu.Warning("sys_spu_thread_get_exit_status(id=%d, status_addr=0x%x)", id, status.GetAddr());
|
||||
|
||||
if (!status.IsGood())
|
||||
{
|
||||
@ -207,7 +207,7 @@ int sys_spu_thread_get_exit_status(u32 id, mem32_t status)
|
||||
//171
|
||||
int sys_spu_thread_group_destroy(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_destroy(id=0x%x)", id);
|
||||
sc_spu.Warning("sys_spu_thread_group_destroy(id=%d)", id);
|
||||
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
@ -232,7 +232,7 @@ int sys_spu_thread_group_destroy(u32 id)
|
||||
//173
|
||||
int sys_spu_thread_group_start(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id);
|
||||
sc_spu.Warning("sys_spu_thread_group_start(id=%d)", id);
|
||||
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
@ -255,7 +255,7 @@ int sys_spu_thread_group_start(u32 id)
|
||||
//174
|
||||
int sys_spu_thread_group_suspend(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id);
|
||||
sc_spu.Warning("sys_spu_thread_group_suspend(id=%d)", id);
|
||||
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
@ -293,7 +293,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
|
||||
|
||||
id = sc_spu.GetNewId(new SpuGroupInfo(name, num, prio, attr->type, attr->ct));
|
||||
|
||||
sc_spu.Warning("*** SPU Thread Group created [%s] (type=%d, option.ct=%d): id=%d",
|
||||
sc_spu.Warning("*** SPU Thread Group created [%s] (type=0x%x, option.ct=0x%x): id=%d",
|
||||
name.wx_str(), (int)attr->type, (u32)attr->ct, id.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
@ -302,7 +302,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
|
||||
//178
|
||||
int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
|
||||
sc_spu.Warning("sys_spu_thread_group_join(id=%d, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
|
||||
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
@ -326,7 +326,11 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (Emu.IsStopped()) return CELL_OK;
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("sys_spu_thread_group_join(id=%d, ...) aborted", id);
|
||||
return CELL_OK;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
@ -342,40 +346,6 @@ int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_connect_event(id=0x%x,eq=0x%x,et=0x%x,spup=0x%x)", id, eq, et, spup);
|
||||
|
||||
EventQueue* equeue;
|
||||
if(!sys_event.CheckId(eq, equeue))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(spup > 63)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
for(int j=0; j<equeue->pos; ++j)
|
||||
{
|
||||
if(!equeue->ports[j]->thread)
|
||||
{
|
||||
equeue->ports[j]->thread = thr;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
//160
|
||||
int sys_raw_spu_create(mem32_t id, u32 attr_addr)
|
||||
{
|
||||
@ -414,7 +384,7 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
|
||||
//181
|
||||
int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=0x%x)",
|
||||
sc_spu.Warning("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)",
|
||||
id, address, value, type);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
@ -424,15 +394,30 @@ int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
(*(SPUThread*)thr).WriteLS64(address, value);
|
||||
if (!thr->IsRunning())
|
||||
{
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 1: (*(SPUThread*)thr).WriteLS8(address, value); return CELL_OK;
|
||||
case 2: (*(SPUThread*)thr).WriteLS16(address, value); return CELL_OK;
|
||||
case 4: (*(SPUThread*)thr).WriteLS32(address, value); return CELL_OK;
|
||||
case 8: (*(SPUThread*)thr).WriteLS64(address, value); return CELL_OK;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//182
|
||||
int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value_addr=0x%x, type=0x%x)",
|
||||
sc_spu.Warning("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)",
|
||||
id, address, value.GetAddr(), type);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
@ -442,20 +427,35 @@ int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(!value.IsGood() || !(*(SPUThread*)thr).IsGoodLSA(address))
|
||||
if (!thr->IsRunning())
|
||||
{
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
if(!value.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
value = (*(SPUThread*)thr).ReadLS64(address);
|
||||
if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
switch (type)
|
||||
{
|
||||
case 1: value = (*(SPUThread*)thr).ReadLS8(address); return CELL_OK;
|
||||
case 2: value = (*(SPUThread*)thr).ReadLS16(address); return CELL_OK;
|
||||
case 4: value = (*(SPUThread*)thr).ReadLS32(address); return CELL_OK;
|
||||
case 8: value = (*(SPUThread*)thr).ReadLS64(address); return CELL_OK;
|
||||
default: return CELL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//190
|
||||
int sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value);
|
||||
sc_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
@ -464,11 +464,7 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(!(*(SPUThread*)thr).SPU.In_MBox.Push(value))
|
||||
{
|
||||
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
|
||||
return CELL_EBUSY; //?
|
||||
}
|
||||
(*(SPUThread*)thr).SPU.In_MBox.PushUncond(value);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -476,7 +472,7 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||
//187
|
||||
int sys_spu_thread_set_spu_cfg(u32 id, u64 value)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=0x%x, value=0x%x)", id, value);
|
||||
sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
@ -498,7 +494,7 @@ int sys_spu_thread_set_spu_cfg(u32 id, u64 value)
|
||||
//188
|
||||
int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=0x%x, value_addr=0x%x)", id, value.GetAddr());
|
||||
sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value_addr=0x%x)", id, value.GetAddr());
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
@ -515,7 +511,7 @@ int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
|
||||
//184
|
||||
int sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
|
||||
{
|
||||
sc_spu.Log("sys_spu_thread_write_snr(id=0x%x, number=%d, value=0x%x)", id, number, value);
|
||||
sc_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value);
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
|
||||
@ -540,9 +536,23 @@ int sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_group_connect_event(id=%d, eq=%d, et=0x%x)", id, eq, et);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_group_disconnect_event(u32 id, u32 et)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_group_disconnect_event(id=%d, et=0x%x)", id, et);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=0x%x, eq=0x%x, req=0x%llx, spup_addr=0x%x)",
|
||||
sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(id=%d, eq=%d, req=0x%llx, spup_addr=0x%x)",
|
||||
id, eq, req, spup_addr);
|
||||
|
||||
EventQueue* equeue;
|
||||
@ -562,6 +572,7 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
/*
|
||||
for(u32 i=0; i<group->list.GetCount(); ++i)
|
||||
{
|
||||
CPUThread* t;
|
||||
@ -582,13 +593,79 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num)
|
||||
int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_bind_queue(id=0x%x, spuq=0x%x, spuq_num=0x%x)", id, spuq, spuq_num);
|
||||
sc_spu.Error("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_connect_event(id=%d, eq=%d, et=0x%x, spup=%d)", id, eq, et, spup);
|
||||
|
||||
EventQueue* equeue;
|
||||
if(!sys_event.CheckId(eq, equeue))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(spup > 63)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
/*
|
||||
for(int j=0; j<equeue->pos; ++j)
|
||||
{
|
||||
if(!equeue->ports[j]->thread)
|
||||
{
|
||||
equeue->ports[j]->thread = thr;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
//
|
||||
int sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_disconnect_event(id=%d, event_type=0x%x, spup=%d", id, event_type, spup);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
SPU-Side functions:
|
||||
int sys_spu_thread_receive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_t d3);
|
||||
int sys_spu_thread_send_event(u8 spup, u24 data0, u32 data1);
|
||||
int sys_spu_thread_throw_event(u8 spup, u24 data0, u32 data1);
|
||||
int sys_spu_thread_tryreceive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_t d3);
|
||||
*/
|
||||
|
||||
int sys_spu_thread_bind_queue(u32 id, u32 equeue_id, u32 spuq_num)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=%d)", id, equeue_id, spuq_num);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
|
||||
{
|
||||
sc_spu.Error("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=%d)", id, spuq_num);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_count, int max
|
||||
|
||||
int sys_semaphore_destroy(u32 sem)
|
||||
{
|
||||
sys_sem.Log("sys_semaphore_destroy(sem=0x%x)", sem);
|
||||
sys_sem.Log("sys_semaphore_destroy(sem=%d)", sem);
|
||||
|
||||
if(!sys_sem.CheckId(sem)) return CELL_ESRCH;
|
||||
|
||||
@ -75,7 +75,7 @@ int sys_semaphore_wait(u32 sem, u64 timeout)
|
||||
|
||||
int sys_semaphore_trywait(u32 sem)
|
||||
{
|
||||
sys_sem.Log("sys_semaphore_trywait(sem=0x%x)", sem);
|
||||
sys_sem.Log("sys_semaphore_trywait(sem=%d)", sem);
|
||||
|
||||
semaphore* sem_data = nullptr;
|
||||
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
|
||||
@ -88,7 +88,7 @@ int sys_semaphore_trywait(u32 sem)
|
||||
|
||||
int sys_semaphore_post(u32 sem, int count)
|
||||
{
|
||||
sys_sem.Log("sys_semaphore_post(sem=0x%x, count=%d)", sem, count);
|
||||
sys_sem.Log("sys_semaphore_post(sem=%d, count=%d)", sem, count);
|
||||
|
||||
semaphore* sem_data = nullptr;
|
||||
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
|
||||
@ -104,7 +104,7 @@ int sys_semaphore_post(u32 sem, int count)
|
||||
|
||||
int sys_semaphore_get_value(u32 sem, u32 count_addr)
|
||||
{
|
||||
sys_sem.Log("sys_semaphore_get_value(sem=0x%x, count_addr=0x%x)", sem, count_addr);
|
||||
sys_sem.Log("sys_semaphore_get_value(sem=%d, count_addr=0x%x)", sem, count_addr);
|
||||
|
||||
semaphore* sem_data = nullptr;
|
||||
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
|
||||
int sys_tty_read(s32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
|
||||
{
|
||||
ConLog.Warning("sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
|
||||
Memory.Write32NN(preadlen_addr, len);
|
||||
|
@ -355,6 +355,7 @@ void Emulator::Load()
|
||||
GetGSManager().Init();
|
||||
GetCallbackManager().Init();
|
||||
GetAudioManager().Init();
|
||||
GetEventManager().Init();
|
||||
|
||||
thread.Run();
|
||||
|
||||
@ -448,6 +449,7 @@ void Emulator::Stop()
|
||||
|
||||
GetGSManager().Close();
|
||||
GetAudioManager().Close();
|
||||
GetEventManager().Clear();
|
||||
GetCPU().Close();
|
||||
//SysCallsManager.Close();
|
||||
GetIdManager().Clear();
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "Loader/Loader.h"
|
||||
#include "SysCalls/Callback.h"
|
||||
#include "SysCalls/Modules.h"
|
||||
#include "event.h"
|
||||
|
||||
struct EmuInfo
|
||||
{
|
||||
@ -89,6 +90,7 @@ class Emulator
|
||||
AudioManager m_audio_manager;
|
||||
CallbackManager m_callback_manager;
|
||||
CPUThread* m_ppu_callback_thr;
|
||||
EventManager m_event_manager;
|
||||
|
||||
VFS m_vfs;
|
||||
|
||||
@ -128,6 +130,7 @@ public:
|
||||
Array<u64>& GetBreakPoints() { return m_break_points; }
|
||||
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
||||
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
|
||||
EventManager& GetEventManager() { return m_event_manager; }
|
||||
|
||||
void AddModuleInit(ModuleInitializer* m)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "Emu/SysCalls/lv2/SC_Lwmutex.h"
|
||||
|
||||
enum EventQueueType
|
||||
{
|
||||
@ -6,10 +7,33 @@ enum EventQueueType
|
||||
SYS_SPU_QUEUE = 2,
|
||||
};
|
||||
|
||||
enum EventQueueDestroyMode
|
||||
{
|
||||
// DEFAULT = 0,
|
||||
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
|
||||
};
|
||||
|
||||
enum EventPortType
|
||||
{
|
||||
SYS_EVENT_PORT_LOCAL = 1,
|
||||
};
|
||||
|
||||
enum EventSourceType
|
||||
{
|
||||
SYS_SPU_THREAD_EVENT_USER = 1,
|
||||
/* SYS_SPU_THREAD_EVENT_DMA = 2, */ // not supported
|
||||
};
|
||||
|
||||
enum EventSourceKey : u64
|
||||
{
|
||||
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501,
|
||||
/* SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502, */
|
||||
};
|
||||
|
||||
struct sys_event_queue_attr
|
||||
{
|
||||
be_t<u32> protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO
|
||||
be_t<int> type;
|
||||
be_t<int> type; // SYS_PPU_QUEUE or SYS_SPU_QUEUE
|
||||
union
|
||||
{
|
||||
char name[8];
|
||||
@ -29,34 +53,171 @@ struct EventQueue;
|
||||
|
||||
struct EventPort
|
||||
{
|
||||
u64 name;
|
||||
u64 data1;
|
||||
u64 data2;
|
||||
u64 data3;
|
||||
bool has_data;
|
||||
CPUThread* thread;
|
||||
EventQueue* queue[127];
|
||||
int pos;
|
||||
};
|
||||
u64 name; // generated or user-specified code that is passed to sys_event_data struct
|
||||
EventQueue* eq; // event queue this port has been connected to
|
||||
SMutex mutex; // may be locked until the event sending is finished
|
||||
|
||||
struct EventQueue
|
||||
{
|
||||
EventPort* ports[127];
|
||||
int size;
|
||||
int pos;
|
||||
|
||||
u32 m_protocol;
|
||||
int m_type;
|
||||
u64 m_name;
|
||||
u64 m_key;
|
||||
|
||||
EventQueue(u32 protocol, int type, u64 name, u64 key, int size)
|
||||
: m_type(type)
|
||||
, m_protocol(protocol)
|
||||
, m_name(name)
|
||||
, m_key(key)
|
||||
, size(size)
|
||||
, pos(0)
|
||||
EventPort(u64 name = 0)
|
||||
: eq(nullptr)
|
||||
, name(name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class EventRingBuffer
|
||||
{
|
||||
Array<sys_event_data> data;
|
||||
SMutex m_lock;
|
||||
u32 buf_pos;
|
||||
u32 buf_count;
|
||||
|
||||
public:
|
||||
const u32 size;
|
||||
|
||||
EventRingBuffer(u32 size)
|
||||
: size(size)
|
||||
, buf_pos(0)
|
||||
, buf_count(0)
|
||||
{
|
||||
data.SetCount(size);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
buf_count = 0;
|
||||
buf_pos = 0;
|
||||
}
|
||||
|
||||
bool push(u64 name, u64 d1, u64 d2, u64 d3)
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
if (buf_count >= size) return false;
|
||||
|
||||
sys_event_data& ref = data[(buf_pos + buf_count++) % size];
|
||||
ref.source = name;
|
||||
ref.data1 = d1;
|
||||
ref.data2 = d2;
|
||||
ref.data3 = d3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pop(sys_event_data& ref)
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
if (!buf_count) return false;
|
||||
|
||||
sys_event_data& from = data[buf_pos];
|
||||
buf_pos = (buf_pos + 1) % size;
|
||||
buf_count--;
|
||||
ref.source = from.source;
|
||||
ref.data1 = from.data1;
|
||||
ref.data2 = from.data2;
|
||||
ref.data3 = from.data3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 pop_all(sys_event_data* ptr, u32 max)
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
|
||||
u32 res = 0;
|
||||
while (buf_count && max)
|
||||
{
|
||||
sys_event_data& from = data[buf_pos];
|
||||
ptr->source = from.source;
|
||||
ptr->data1 = from.data1;
|
||||
ptr->data2 = from.data2;
|
||||
ptr->data3 = from.data3;
|
||||
buf_pos = (buf_pos + 1) % size;
|
||||
buf_count--;
|
||||
max--;
|
||||
ptr++;
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 count()
|
||||
{
|
||||
return buf_count;
|
||||
}
|
||||
};
|
||||
|
||||
class EventPortList
|
||||
{
|
||||
Array<EventPort*> data;
|
||||
SMutex m_lock;
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
for (u32 i = 0; i < data.GetCount(); i++)
|
||||
{
|
||||
data[i]->eq = nullptr; // force all ports to disconnect
|
||||
}
|
||||
data.Clear();
|
||||
}
|
||||
|
||||
void add(EventPort* port)
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
data.AddCpy(port);
|
||||
}
|
||||
|
||||
void remove(EventPort* port)
|
||||
{
|
||||
SMutexLocker lock(m_lock);
|
||||
for (u32 i = 0; i < data.GetCount(); i++)
|
||||
{
|
||||
if (data[i] == port)
|
||||
{
|
||||
data.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct EventQueue : SleepQueue
|
||||
{
|
||||
EventPortList ports;
|
||||
EventRingBuffer events;
|
||||
SMutex owner;
|
||||
|
||||
const union
|
||||
{
|
||||
u64 name_u64;
|
||||
char name[8];
|
||||
};
|
||||
const u32 protocol;
|
||||
const int type;
|
||||
const u64 key;
|
||||
|
||||
EventQueue(u32 protocol, int type, u64 name, u64 key, int size)
|
||||
: type(type)
|
||||
, protocol(protocol)
|
||||
, name_u64(name)
|
||||
, key(key)
|
||||
, events(size) // size: max event count this queue can hold
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class EventManager
|
||||
{
|
||||
SMutex m_lock;
|
||||
std::unordered_map<u64, EventQueue*> key_map;
|
||||
|
||||
public:
|
||||
void Init();
|
||||
void Clear();
|
||||
bool CheckKey(u64 key);
|
||||
bool RegisterKey(EventQueue* data, u64 key);
|
||||
bool GetEventQueue(u64 key, EventQueue*& data);
|
||||
bool UnregisterKey(u64 key);
|
||||
};
|
@ -224,6 +224,7 @@
|
||||
<ClCompile Include="Emu\CPU\CPUThread.cpp" />
|
||||
<ClCompile Include="Emu\CPU\CPUThreadManager.cpp" />
|
||||
<ClCompile Include="Emu\DbgConsole.cpp" />
|
||||
<ClCompile Include="Emu\Event.cpp" />
|
||||
<ClCompile Include="Emu\FS\VFS.cpp" />
|
||||
<ClCompile Include="Emu\FS\vfsDevice.cpp" />
|
||||
<ClCompile Include="Emu\FS\vfsDirBase.cpp" />
|
||||
|
@ -388,6 +388,9 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysutilAp.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Event.cpp">
|
||||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
Loading…
Reference in New Issue
Block a user