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

View File

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

View File

@ -155,4 +155,6 @@ void sys_fs_init()
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
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(0xa703a51d, cellPadGetInfo2);
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
sys_io.AddFunc(0x0e2dfaad, cellPadInfoPressMode);
sys_io.AddFunc(0x78200559, cellPadInfoSensorMode);
sys_io.AddFunc(0x433f6ec0, cellKbInit);
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 cellFsTruncate(u32 path_addr, u64 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
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 cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
extern int cellPadInfoPressMode(u32 port_no);
extern int cellPadInfoSensorMode(u32 port_no);
//cellKb
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)
{
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 =
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;
}
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()
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;
}
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)
{
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))
{
@ -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("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("a2 = 0x%x", a2);
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());
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));