Merge pull request #49 from Nekotekina/master

cellSyncMutex+SPU
This commit is contained in:
Ivan 2014-01-12 02:40:53 -08:00
commit e0a70bb0fa
10 changed files with 228 additions and 76 deletions

View file

@ -21,6 +21,15 @@ enum
MFC_MASK_CMD = 0xffff, MFC_MASK_CMD = 0xffff,
}; };
// Atomic Status Update
enum
{
MFC_PUTLLC_SUCCESS = 0,
MFC_PUTLLC_FAILURE = 1, //reservation was lost
MFC_PUTLLUC_SUCCESS = 2,
MFC_GETLLAR_SUCCESS = 4,
};
enum enum
{ {
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF, MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,

View file

@ -470,6 +470,7 @@ public:
Channel<1> QueryType; Channel<1> QueryType;
Channel<1> QueryMask; Channel<1> QueryMask;
Channel<1> TagStatus; Channel<1> TagStatus;
Channel<1> AtomicStat;
} Prxy; } Prxy;
struct struct
@ -519,6 +520,31 @@ public:
} }
break; break;
case MFC_GETLLAR_CMD:
case MFC_PUTLLC_CMD:
case MFC_PUTLLUC_CMD:
{
extern std::mutex g_SyncMutex;
//can provide compatability for CellSyncMutex through SPU<>PPU and SPU<>SPU
if (op == MFC_GETLLAR_CMD)
{
g_SyncMutex.lock();
}
ConLog.Warning("DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x",
op == MFC_GETLLAR_CMD ? "GETLLAR" : op == MFC_PUTLLC_CMD ? "PUTLLC" : "PUTLLUC",
lsa, ea, tag, size, cmd);
dmac.ProcessCmd(op == MFC_GETLLAR_CMD ? MFC_GET_CMD : MFC_PUT_CMD, tag, lsa, ea, 128);
Prxy.AtomicStat.PushUncond(op == MFC_GETLLAR_CMD ? MFC_GETLLAR_SUCCESS : op == MFC_PUTLLC_CMD ? MFC_PUTLLC_SUCCESS : MFC_PUTLLUC_SUCCESS);
if (op == MFC_PUTLLC_CMD || op == MFC_PUTLLUC_CMD)
{
g_SyncMutex.unlock();
}
}
break;
default: default:
ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
op, cmd, lsa, ea, tag, size); op, cmd, lsa, ea, tag, size);
@ -549,6 +575,9 @@ public:
case SPU_RdSigNotify2: case SPU_RdSigNotify2:
return SPU.SNR[1].GetCount(); return SPU.SNR[1].GetCount();
case MFC_RdAtomicStat:
return Prxy.AtomicStat.GetCount();
default: default:
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break; break;
@ -641,6 +670,10 @@ public:
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]); //ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
break; break;
case MFC_RdAtomicStat:
while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
break;
default: default:
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break; break;

View file

@ -425,9 +425,9 @@ public:
return Memory.IsGoodAddr(m_addr, sizeof(T)); return Memory.IsGoodAddr(m_addr, sizeof(T));
} }
__forceinline operator bool() const __forceinline operator u32() const
{ {
return m_addr != 0; return m_addr;
} }
__forceinline bool operator != (nullptr_t) const __forceinline bool operator != (nullptr_t) const
@ -592,6 +592,11 @@ public:
return *this; return *this;
} }
__forceinline T GetValue()
{
return (be_t<T>&)Memory[this->m_addr];
}
operator const T() const operator const T() const
{ {
return (be_t<T>&)Memory[this->m_addr]; return (be_t<T>&)Memory[this->m_addr];

View file

@ -1,9 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/SC_FUNC.h"
#include <mutex>
void cellSync_init(); void cellSync_init();
Module cellSync("cellSync", cellSync_init); void cellSync_unload();
Module cellSync("cellSync", cellSync_init, nullptr, cellSync_unload);
std::mutex g_SyncMutex;
// Return Codes // Return Codes
enum enum
@ -22,78 +25,114 @@ enum
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114, CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114,
}; };
int cellSyncMutexInitialize(mem32_t mutex) struct CellSyncMutex {
be_t<u16> m_freed;
be_t<u16> m_order;
/*
(???) Initialize: set zeros
(???) Lock: increase m_order and wait until m_freed == old m_order
(???) Unlock: increase m_freed
(???) TryLock: ?????
*/
};
int cellSyncMutexInitialize(mem_ptr_t<CellSyncMutex> mutex)
{ {
cellSync.Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr()); cellSync.Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr());
const u32 mutex_addr = mutex.GetAddr();
if (!mutex_addr) if (!mutex.IsGood())
{ {
return CELL_SYNC_ERROR_NULL_POINTER; return CELL_SYNC_ERROR_NULL_POINTER;
} }
if (mutex_addr % 4) if (mutex.GetAddr() % 4)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
mutex = 0;
_mm_sfence(); { /* global mutex */
return CELL_OK; std::lock_guard<std::mutex> lock(g_SyncMutex); //???
mutex->m_freed = 0;
mutex->m_order = 0;
return CELL_OK;
}
} }
int cellSyncMutexLock(mem32_t mutex) int cellSyncMutexLock(mem_ptr_t<CellSyncMutex> mutex)
{ {
cellSync.Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr()); cellSync.Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr());
const u32 mutex_addr = mutex.GetAddr();
if (!mutex_addr) if (!mutex.IsGood())
{ {
return CELL_SYNC_ERROR_NULL_POINTER; return CELL_SYNC_ERROR_NULL_POINTER;
} }
if (mutex_addr % 4) if (mutex.GetAddr() % 4)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
while (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1 << 24));
//need to check how does SPU work with these mutexes, also obtainment order is not guaranteed be_t<u16> old_order;
_mm_lfence(); { /* global mutex */
std::lock_guard<std::mutex> lock(g_SyncMutex);
old_order = mutex->m_order;
mutex->m_order = mutex->m_order + 1;
}
int counter = 0;
while (old_order != mutex->m_freed)
{
Sleep(1);
if (++counter >= 5000)
{
Emu.Pause();
cellSync.Error("cellSyncMutexLock(mutex=0x%x, old_order=%d, order=%d, freed=%d): TIMEOUT",
mutex.GetAddr(), (u16)old_order, (u16)mutex->m_order, (u16)mutex->m_freed);
break;
}
}
return CELL_OK; return CELL_OK;
} }
int cellSyncMutexTryLock(mem32_t mutex) int cellSyncMutexTryLock(mem_ptr_t<CellSyncMutex> mutex)
{ {
cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr()); cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr());
const u32 mutex_addr = mutex.GetAddr();
if (!mutex_addr) if (!mutex.IsGood())
{ {
return CELL_SYNC_ERROR_NULL_POINTER; return CELL_SYNC_ERROR_NULL_POINTER;
} }
if (mutex_addr % 4) if (mutex.GetAddr() % 4)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
//check cellSyncMutexLock { /* global mutex */
if (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1 << 24)) std::lock_guard<std::mutex> lock(g_SyncMutex);
{ if (mutex->m_order != mutex->m_freed)
return CELL_SYNC_ERROR_BUSY; {
return CELL_SYNC_ERROR_BUSY;
}
mutex->m_order = mutex->m_order + 1;
return CELL_OK;
} }
_mm_lfence();
return CELL_OK;
} }
int cellSyncMutexUnlock(mem32_t mutex) int cellSyncMutexUnlock(mem_ptr_t<CellSyncMutex> mutex)
{ {
cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr()); cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr());
const u32 mutex_addr = mutex.GetAddr();
if (!mutex_addr) if (!mutex.IsGood())
{ {
return CELL_SYNC_ERROR_NULL_POINTER; return CELL_SYNC_ERROR_NULL_POINTER;
} }
if (mutex_addr % 4) if (mutex.GetAddr() % 4)
{ {
return CELL_SYNC_ERROR_ALIGN; return CELL_SYNC_ERROR_ALIGN;
} }
//check cellSyncMutexLock
_mm_sfence(); { /* global mutex */
_InterlockedExchange((volatile long*)(Memory + mutex_addr), 0); std::lock_guard<std::mutex> lock(g_SyncMutex);
return CELL_OK; mutex->m_freed = mutex->m_freed + 1;
return CELL_OK;
}
} }
void cellSync_init() void cellSync_init()
@ -102,4 +141,9 @@ void cellSync_init()
cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock); cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock);
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock); cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock); cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
}
void cellSync_unload()
{
g_SyncMutex.unlock();
} }

View file

@ -238,10 +238,12 @@ int cellSysutilGetSystemParamString(s32 id, mem_list_ptr_t<u8> buf, u32 bufsize)
{ {
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME");
memcpy(buf, "Unknown", 8); //for example
break; break;
case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME:
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME");
memcpy(buf, "Unknown", 8);
break; break;
default: default:

View file

@ -3,7 +3,9 @@
#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/SC_FUNC.h"
void sys_fs_init(); void sys_fs_init();
Module sys_fs(0x000e, sys_fs_init); void sys_fs_unload();
Module sys_fs(0x000e, sys_fs_init, nullptr, sys_fs_unload);
Array<vfsStream*> FDs;
bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp)
{ {
@ -137,13 +139,9 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
std::atomic<u32> g_FsAioReadID = 0; std::atomic<u32> g_FsAioReadID = 0;
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, u32 error, int xid, u64 size)> func) void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, u32 error, int xid, u64 size)> func)
{ {
ID id; vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
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)
u64 nbytes = (u64)aio->size; u64 nbytes = (u64)aio->size;
const u32 buf_addr = (u32)aio->buf_addr; const u32 buf_addr = (u32)aio->buf_addr;
@ -153,7 +151,8 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
if(Memory.IsGoodAddr(buf_addr)) if(Memory.IsGoodAddr(buf_addr))
{ {
vfsFile file(orig_file.GetPath().AfterFirst('/'), vfsRead); //open the file again (to prevent access conflicts roughly)
vfsLocalFile file(orig_file.GetPath().AfterFirst('/'), vfsRead);
if(!Memory.IsGoodAddr(buf_addr, nbytes)) if(!Memory.IsGoodAddr(buf_addr, nbytes))
{ {
MemoryBlock& block = Memory.GetMemByAddr(buf_addr); MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
@ -175,11 +174,26 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
const u32 xid = g_FsAioReadID++; const u32 xid = g_FsAioReadID++;
aio_id = xid; aio_id = xid;
sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s], id_addr: 0x%x, func_addr: 0x%x[res=%d, addr=0x%x])", aio.GetAddr(), //start callback thread
orig_file.GetPath().c_str(), aio_id.GetAddr(), func.GetAddr(), res, (u32)aio->buf_addr); if(func)
func.async(aio.GetAddr(), error, xid, res);
}
if(func) int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, u32 error, int xid, u64 size)> func)
func(aio, error, xid, res); {
//ID id;
u32 fd = (u32)aio->fd;
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
std::thread t(fsAioRead, fd, aio, aio_id, func);
t.detach();
sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s, addr=0x%x], id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(),
orig_file.GetPath().c_str(), (u32)aio->buf_addr, aio_id.GetAddr(), func.GetAddr());
return CELL_OK; return CELL_OK;
} }
@ -206,3 +220,16 @@ void sys_fs_init()
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
} }
void sys_fs_unload()
{
for (u32 i = 0; i < FDs.GetCount(); i++)
{
if (FDs[i])
{
FDs[i]->Close();
delete FDs[i];
}
}
FDs.Clear();
}

View file

@ -3,6 +3,7 @@
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
extern Module sys_fs; extern Module sys_fs;
extern Array<vfsStream*> FDs;
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
{ {
@ -94,7 +95,9 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
return CELL_ENOENT; return CELL_ENOENT;
} }
fd = sys_fs.GetNewId(stream, flags); fd = FDs.AddCpy(stream);
//fd = sys_fs.GetNewId(stream, flags);
sys_fs.Warning("cellFsOpen(path: %s): fd == %d", path.mb_str(), fd.GetValue());
return CELL_OK; return CELL_OK;
} }
@ -103,9 +106,12 @@ 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()); fd, buf_addr, nbytes, nread.GetAddr());
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
{ {
@ -125,9 +131,13 @@ 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()); fd, buf_addr, nbytes, nwrite.GetAddr());
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
{ {
MemoryBlock& block = Memory.GetMemByAddr(buf_addr); MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
@ -144,12 +154,17 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
int cellFsClose(u32 fd) int cellFsClose(u32 fd)
{ {
sys_fs.Log("cellFsClose(fd: %d)", fd); sys_fs.Warning("cellFsClose(fd: %d)", fd);
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
file.Close(); file.Close();
Emu.GetIdManager().RemoveID(fd); delete FDs[fd];
//Emu.GetIdManager().RemoveID(fd);
FDs[fd] = nullptr;
return CELL_OK; return CELL_OK;
} }
@ -231,9 +246,12 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
int cellFsFstat(u32 fd, 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());
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
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 |
@ -312,9 +330,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence); sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
return CELL_EINVAL; return CELL_EINVAL;
} }
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
pos = file.Seek(offset, seek_mode); pos = file.Seek(offset, seek_mode);
return CELL_OK; return CELL_OK;
} }
@ -322,9 +343,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
int cellFsFtruncate(u32 fd, u64 size) 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);
ID id; //ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data; if (fd >= FDs.GetCount()) return CELL_ESRCH;
if (FDs[fd] == nullptr) return CELL_ESRCH;
//vfsStream& file = *(vfsStream*)id.m_data;
vfsStream& file = *(vfsStream*)FDs[fd];
u64 initialSize = file.GetSize(); u64 initialSize = file.GetSize();
if (initialSize < size) if (initialSize < size)

View file

@ -6,20 +6,26 @@ SysCallBase sc_mem("memory");
int sys_memory_container_create(u32 cid_addr, u32 yield_size) int sys_memory_container_create(u32 cid_addr, u32 yield_size)
{ {
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size); sc_mem.Warning("(HACK!) sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
if(!Memory.IsGoodAddr(cid_addr, 4)) if(!Memory.IsGoodAddr(cid_addr, 4))
{ {
return CELL_EFAULT; return CELL_EFAULT;
} }
u64 addr = Memory.Alloc(yield_size, 1); yield_size &= ~0xfffff; //round down to 1 MB granularity
//alignment hack (Memory.Alloc does not support alignment yet): alloc size is increased
u64 addr = Memory.Alloc(yield_size + 0x100000, 0x100000); //1 MB alignment (???)
if(!addr) if(!addr)
{ {
return CELL_ENOMEM; return CELL_ENOMEM;
} }
//fix alignment:
addr = (addr + 0x100000) & ~0xfffff;
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size))); Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
return CELL_OK; return CELL_OK;
} }
@ -43,18 +49,20 @@ int sys_memory_container_destroy(u32 cid)
int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
{ {
//0x30000100; //0x30000100;
sc_mem.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags); sc_mem.Warning("(HACK!) sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags);
u32 addr; u32 addr;
switch(flags) switch(flags)
{ {
case SYS_MEMORY_PAGE_SIZE_1M: case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN; if(size & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000); addr = Memory.Alloc(size + 0x100000, 0x100000);
addr = (addr + 0x100000) & ~0xfffff;
break; break;
case SYS_MEMORY_PAGE_SIZE_64K: case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN; if(size & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000); addr = Memory.Alloc(size + 0x10000, 0x10000);
addr = (addr + 0x10000) & ~0xffff;
break; break;
default: return CELL_EINVAL; default: return CELL_EINVAL;

View file

@ -138,7 +138,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
group_info.threads[spu_num] = &new_thread; group_info.threads[spu_num] = &new_thread;
ConLog.Write("New SPU Thread:"); /*ConLog.Write("New SPU Thread:");
ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr); ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr);
ConLog.Write("entry_point = 0x%x", spu_ep); ConLog.Write("entry_point = 0x%x", spu_ep);
ConLog.Write("name = %s", name.c_str()); ConLog.Write("name = %s", name.c_str());
@ -147,7 +147,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
ConLog.Write("a3 = 0x%x", a3); ConLog.Write("a3 = 0x%x", a3);
ConLog.Write("a4 = 0x%x", a4); ConLog.Write("a4 = 0x%x", a4);
ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset); ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset);
ConLog.SkipLn(); ConLog.SkipLn();*/
return CELL_OK; return CELL_OK;
} }

View file

@ -2,7 +2,7 @@
#include "Emu/FS/vfsFileBase.h" #include "Emu/FS/vfsFileBase.h"
#ifdef _DEBUG #ifdef _DEBUG
#define LOADER_DEBUG //#define LOADER_DEBUG
#endif #endif
enum Elf_Machine enum Elf_Machine