Minor improvements

cellFsAioRead partially implemented, cellPadInfoPressMode &
cellPadInfoSensorMode stubs
This commit is contained in:
Nekotekina 2014-01-05 03:58:03 +04:00
parent 64b18b4dc2
commit 5f06f46f32
10 changed files with 106 additions and 42 deletions

View file

@ -293,7 +293,7 @@ public:
}; };
volatile u64 m_indval; volatile u64 m_indval;
}; };
volatile long m_lock; wxCriticalSection m_lock;
public: public:
@ -305,24 +305,19 @@ public:
void Init() void Init()
{ {
m_index = 0; m_index = 0;
m_lock = 0; //simple lock
} }
__forceinline bool Pop(u32& res) __forceinline bool Pop(u32& res)
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (_InterlockedExchange(&m_lock, 1)); wxCriticalSectionLocker lock(m_lock);
_mm_lfence();
if(!m_index) if(!m_index)
{ {
m_lock = 0; //release lock
return false; return false;
} }
res = m_value[--m_index]; res = m_value[--m_index];
m_value[m_index] = 0; m_value[m_index] = 0;
_mm_sfence();
m_lock = 0;
return true; return true;
} }
else else
@ -342,16 +337,12 @@ public:
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (_InterlockedExchange(&m_lock, 1)); wxCriticalSectionLocker lock(m_lock);
_mm_lfence();
if(m_index >= max_count) if(m_index >= max_count)
{ {
m_lock = 0; //release lock
return false; return false;
} }
m_value[m_index++] = value; m_value[m_index++] = value;
_mm_sfence();
m_lock = 0;
return true; return true;
} }
else else
@ -370,14 +361,11 @@ public:
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (_InterlockedExchange(&m_lock, 1)); wxCriticalSectionLocker lock(m_lock);
_mm_lfence();
if(m_index >= max_count) if(m_index >= max_count)
m_value[max_count-1] = value; //last message is overwritten m_value[max_count-1] = value; //last message is overwritten
else else
m_value[m_index++] = value; m_value[m_index++] = value;
_mm_sfence();
m_lock = 0;
} }
else else
{ //lock-free { //lock-free
@ -389,14 +377,11 @@ public:
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (_InterlockedExchange(&m_lock, 1)); wxCriticalSectionLocker lock(m_lock);
_mm_lfence();
if(m_index >= max_count) if(m_index >= max_count)
m_value[max_count-1] |= value; //last message is logically ORed m_value[max_count-1] |= value; //last message is logically ORed
else else
m_value[m_index++] = value; m_value[m_index++] = value;
_mm_sfence();
m_lock = 0;
} }
else else
{ {
@ -412,8 +397,7 @@ public:
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (_InterlockedExchange(&m_lock, 1)); wxCriticalSectionLocker lock(m_lock);
_mm_lfence();
if(!m_index) if(!m_index)
res = 0; //result is undefined res = 0; //result is undefined
else else
@ -421,8 +405,6 @@ public:
res = m_value[--m_index]; res = m_value[--m_index];
m_value[m_index] = 0; m_value[m_index] = 0;
} }
_mm_sfence();
m_lock = 0;
} }
else else
{ //lock-free { //lock-free
@ -436,24 +418,30 @@ public:
} }
} }
u32 GetCount() const __forceinline u32 GetCount()
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (m_lock); wxCriticalSectionLocker lock(m_lock);
_mm_lfence(); return m_index;
}
else
{
return m_index;
} }
return m_index;
} }
u32 GetFreeCount() const __forceinline u32 GetFreeCount()
{ {
if (max_count > 1 || x86) if (max_count > 1 || x86)
{ {
while (m_lock); wxCriticalSectionLocker lock(m_lock);
_mm_lfence(); return max_count - m_index;
}
else
{
return max_count - m_index;
} }
return max_count - m_index;
} }
void SetValue(u32 value) void SetValue(u32 value)

View file

@ -48,8 +48,8 @@ int cellSyncMutexLock(mem32_t mutex)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
//aggressive spin-wait while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24));
while (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)); //need to check how does SPU work with these mutexes, also obtainment order is not guaranteed
_mm_lfence(); _mm_lfence();
return CELL_OK; return CELL_OK;
} }
@ -65,7 +65,8 @@ int cellSyncMutexTryLock(mem32_t mutex)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
if (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)) //check cellSyncMutexLock
if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24))
{ {
return CELL_SYNC_ERROR_BUSY; return CELL_SYNC_ERROR_BUSY;
} }
@ -84,8 +85,9 @@ int cellSyncMutexUnlock(mem32_t mutex)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
//check cellSyncMutexLock
_mm_sfence(); _mm_sfence();
mutex = 0; _InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0);
return CELL_OK; return CELL_OK;
} }

View file

@ -101,12 +101,12 @@ int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry)
{ {
const wxString path = Memory.ReadString(path_addr).mb_str(); const wxString path = Memory.ReadString(path_addr).mb_str();
sysPrxForUser.Warning("sys_raw_spu_load(id=0x%x, path=0x%x [%s], entry_addr=0x%x)", sysPrxForUser.Warning("sys_raw_spu_load(id=0x%x, path=0x%x [%s], entry_addr=0x%x)",
id, path_addr, path, entry.GetAddr()); id, path_addr, path.c_str(), entry.GetAddr());
vfsFile f(path.c_str()); vfsFile f(path.c_str());
if(!f.IsOpened()) if(!f.IsOpened())
{ {
sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path); sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path.c_str());
return CELL_ENOENT; return CELL_ENOENT;
} }

View file

@ -155,4 +155,6 @@ void sys_fs_init()
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate); sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate); sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
} }

View file

@ -16,6 +16,8 @@ void sys_io_init()
sys_io.AddFunc(0x3aaad464, cellPadGetInfo); sys_io.AddFunc(0x3aaad464, cellPadGetInfo);
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2); sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting); sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
sys_io.AddFunc(0x0e2dfaad, cellPadInfoPressMode);
sys_io.AddFunc(0x78200559, cellPadInfoSensorMode);
sys_io.AddFunc(0x433f6ec0, cellKbInit); sys_io.AddFunc(0x433f6ec0, cellKbInit);
sys_io.AddFunc(0xbfce3285, cellKbEnd); sys_io.AddFunc(0xbfce3285, cellKbEnd);

View file

@ -225,6 +225,7 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos);
extern int cellFsFtruncate(u32 fd, u64 size); extern int cellFsFtruncate(u32 fd, u64 size);
extern int cellFsTruncate(u32 path_addr, u64 size); extern int cellFsTruncate(u32 path_addr, u64 size);
extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size); extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size);
extern int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t id, u32 func_addr);
//cellVideo //cellVideo
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr); extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
@ -244,6 +245,8 @@ extern int cellPadSetActDirect(u32 port_no, u32 param_addr);
extern int cellPadGetInfo(u32 info_addr); extern int cellPadGetInfo(u32 info_addr);
extern int cellPadGetInfo2(u32 info_addr); extern int cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting); extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
extern int cellPadInfoPressMode(u32 port_no);
extern int cellPadInfoSensorMode(u32 port_no);
//cellKb //cellKb
extern int cellKbInit(u32 max_connect); extern int cellKbInit(u32 max_connect);

View file

@ -177,7 +177,7 @@ int cellFsClosedir(u32 fd)
int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb) int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
{ {
const wxString& path = Memory.ReadString(path_addr); const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path.mb_str(), sb.GetAddr()); sys_fs.Log("cellFsStat(path: %s, sb_addr: 0x%x)", path.mb_str(), sb.GetAddr());
sb->st_mode = sb->st_mode =
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
@ -373,3 +373,49 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
return CELL_OK; return CELL_OK;
} }
std::atomic<u32> g_FsAioReadID = 0;
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, u32 func_addr)
{
sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x, id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(), aio_id.GetAddr(), func_addr);
ID id;
u32 fd = (u32)aio->fd;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
//open the file again (to prevent access conflicts roughly)
vfsStream file = *Emu.GetVFS().Open(orig_file.GetPath(), vfsRead);
u64 nbytes = (u64)aio->size;
const u32 buf_addr = (u32)aio->buf_addr;
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
{
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
}
//read data immediately (actually it should be read in special thread)
file.Seek((u64)aio->offset);
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
file.Close();
//get a unique id for the callback
const u32 xid = g_FsAioReadID++;
aio_id = xid;
//TODO: init the callback
/*CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
new_thread.SetEntry(func_addr);
new_thread.SetPrio(1001);
new_thread.SetStackSize(0x10000);
new_thread.SetName("FsAioReadCallback");
new_thread.SetArg(0, aio.GetAddr()); //xaio
new_thread.SetArg(1, CELL_OK); //error code
new_thread.SetArg(2, xid); //xid (unique id)
new_thread.SetArg(3, res); //size (bytes read)
new_thread.Run();
new_thread.Exec();*/
return CELL_OK;
}

View file

@ -84,3 +84,12 @@ struct CellFsDirent
}; };
#pragma pack() #pragma pack()
struct CellFsAio
{
be_t<u32> fd;
be_t<u64> offset;
be_t<u32> buf_addr;
be_t<u64> size;
be_t<u64> user_data;
};

View file

@ -221,3 +221,15 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting)
return CELL_OK; return CELL_OK;
} }
int cellPadInfoPressMode(u32 port_no)
{
sys_io.Log("cellPadInfoPressMode(port_no=%d)", port_no);
return CELL_OK;
}
int cellPadInfoSensorMode(u32 port_no)
{
sys_io.Log("cellPadInfoSensorMode(port_no=%d)", port_no);
return CELL_OK;
}

View file

@ -40,7 +40,7 @@ u32 LoadSpuImage(vfsStream& stream)
int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr) int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr)
{ {
const wxString path = Memory.ReadString(path_addr).mb_str(); const wxString path = Memory.ReadString(path_addr).mb_str();
sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path); sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path.c_str());
if(!img.IsGood() || !Memory.IsGoodAddr(path_addr)) if(!img.IsGood() || !Memory.IsGoodAddr(path_addr))
{ {
@ -124,7 +124,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
ConLog.Write("New SPU Thread:"); ConLog.Write("New SPU Thread:");
ConLog.Write("ls_entry = 0x%x", ls_entry); ConLog.Write("ls_entry = 0x%x", ls_entry);
ConLog.Write("name = %s", wxString(name)); ConLog.Write("name = %s", name.c_str());
ConLog.Write("a1 = 0x%x", a1); ConLog.Write("a1 = 0x%x", a1);
ConLog.Write("a2 = 0x%x", a2); ConLog.Write("a2 = 0x%x", a2);
ConLog.Write("a3 = 0x%x", a3); ConLog.Write("a3 = 0x%x", a3);
@ -224,7 +224,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
ConLog.Write("*** attr.option.ct=%d", attr->option.ct.ToLE()); ConLog.Write("*** attr.option.ct=%d", attr->option.ct.ToLE());
const wxString name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str(); const wxString name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str();
ConLog.Write("*** name='%s'", name); ConLog.Write("*** name='%s'", name.c_str());
id = Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(*attr)); id = Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(*attr));