File/dir descriptors numbering experimental impl

This commit is contained in:
Nekotekina 2015-07-29 00:34:22 +03:00
parent badeb29901
commit 06ef95fbea
5 changed files with 121 additions and 63 deletions

View File

@ -407,7 +407,6 @@ namespace vm
#include "vm_ref.h"
#include "vm_ptr.h"
#include "vm_var.h"
class CPUThread;
@ -449,3 +448,5 @@ namespace vm
u32 stack_push(CPUThread& cpu, u32 size, u32 align, u32& old_pos);
void stack_pop(CPUThread& cpu, u32 addr, u32 old_pos);
}
#include "vm_var.h"

View File

@ -14,6 +14,8 @@
extern Module cellFs;
extern u32 _fd_to_id(u32 fd);
s32 cellFsOpen(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> arg, u64 size)
{
cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size);
@ -207,9 +209,9 @@ s32 cellFsGetFreeSize(vm::cptr<char> path, vm::ptr<u32> block_size, vm::ptr<u64>
s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32 entries_size, vm::ptr<u32> data_count)
{
cellFs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count);
cellFs.Warning("cellFsGetDirectoryEntries(fd=%d, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(fd);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(_fd_to_id(fd));
if (!directory)
{
@ -250,11 +252,11 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32
s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<u64> nread)
{
cellFs.Log("cellFsReadWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread);
cellFs.Log("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread);
// TODO: use single sys_fs_fcntl syscall
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file || file->flags & CELL_FS_O_WRONLY)
{
@ -281,11 +283,11 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size,
s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr<void> buf, u64 data_size, vm::ptr<u64> nwrite)
{
cellFs.Log("cellFsWriteWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite);
cellFs.Log("cellFsWriteWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite);
// TODO: use single sys_fs_fcntl syscall
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
{
@ -312,7 +314,7 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr<void> buf, u64 data_size,
s32 cellFsStReadInit(u32 fd, vm::cptr<CellFsRingBuffer> ringbuf)
{
cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf);
cellFs.Warning("cellFsStReadInit(fd=%d, ringbuf=*0x%x)", fd, ringbuf);
if (ringbuf->copy & ~CELL_FS_ST_COPYLESS)
{
@ -329,7 +331,7 @@ s32 cellFsStReadInit(u32 fd, vm::cptr<CellFsRingBuffer> ringbuf)
return CELL_FS_EINVAL;
}
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -365,9 +367,9 @@ s32 cellFsStReadInit(u32 fd, vm::cptr<CellFsRingBuffer> ringbuf)
s32 cellFsStReadFinish(u32 fd)
{
cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd);
cellFs.Warning("cellFsStReadFinish(fd=%d)", fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -388,9 +390,9 @@ s32 cellFsStReadFinish(u32 fd)
s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
{
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf);
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf=*0x%x)", fd, ringbuf);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -412,9 +414,9 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
{
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status);
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, status=*0x%x)", fd, status);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -446,9 +448,9 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
{
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid);
cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, regid=*0x%x)", fd, regid);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -467,9 +469,9 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
{
cellFs.Warning("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size);
cellFs.Warning("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -548,9 +550,9 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
s32 cellFsStReadStop(u32 fd)
{
cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd);
cellFs.Warning("cellFsStReadStop(fd=%d)", fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -579,9 +581,9 @@ s32 cellFsStReadStop(u32 fd)
s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
{
cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize);
cellFs.Warning("cellFsStRead(fd=%d, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -613,9 +615,9 @@ s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
{
cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size);
cellFs.Warning("cellFsStReadGetCurrentAddr(fd=%d, addr=*0x%x, size=*0x%x)", fd, addr, size);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -646,9 +648,9 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
{
cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size);
cellFs.Warning("cellFsStReadPutCurrentAddr(fd=%d, addr=*0x%x, size=0x%llx)", fd, addr, size);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -673,9 +675,9 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
s32 cellFsStReadWait(u32 fd, u64 size)
{
cellFs.Warning("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size);
cellFs.Warning("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -702,9 +704,9 @@ s32 cellFsStReadWait(u32 fd, u64 size)
s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func)
{
cellFs.Warning("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func);
cellFs.Warning("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func=*0x%x)", fd, size, func);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -867,12 +869,12 @@ using fs_aio_cb_t = vm::ptr<void(vm::ptr<CellFsAio> xaio, s32 error, s32 xid, u6
void fsAio(vm::ptr<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
{
cellFs.Notice("FS AIO Request(%d): fd=0x%x, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data);
cellFs.Notice("FS AIO Request(%d): fd=%d, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data);
s32 error = CELL_OK;
u64 result = 0;
const auto file = Emu.GetIdManager().get<lv2_file_t>(aio->fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(aio->fd));
if (!file || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE)))
{
@ -964,9 +966,9 @@ s32 cellFsSetDefaultContainer(u32 id, u32 total_limit)
s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type)
{
cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=0x%x, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type);
cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{

View File

@ -1600,7 +1600,7 @@ Module cellSync("cellSync", []()
cellSync.on_error = [](s64 value, ModuleFunc* func)
{
// get error name for CELL_SYNC errors
auto get_error = [](s32 code) -> const char*
auto get_error = [](u32 code) -> const char*
{
switch (code)
{
@ -1625,7 +1625,7 @@ Module cellSync("cellSync", []()
};
// analyse error code
if (s32 code = (value & 0xffffff00) == 0x80410100 ? static_cast<s32>(value) : 0)
if (u32 code = (value & 0xffffff00) == 0x80410100 ? static_cast<u32>(value) : 0)
{
cellSync.Error("%s() -> %s (0x%x)", func->name, get_error(code), code);
}

View File

@ -13,6 +13,29 @@
SysCallBase sys_fs("sys_fs");
std::array<atomic_t<u32>, 256> g_fds = {}; // file descriptors 0..255 mapped to IDs
u32 _fd_to_id(u32 fd)
{
return fd < g_fds.size() ? g_fds[fd].load() : 0;
}
lv2_file_t::~lv2_file_t()
{
if (Emu.IsStopped())
{
g_fds = {};
}
}
lv2_dir_t::~lv2_dir_t()
{
if (Emu.IsStopped())
{
g_fds = {};
}
}
s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6)
{
sys_fs.Todo("sys_fs_test(arg1=0x%x, arg2=0x%x, arg3=*0x%x, arg4=0x%x, arg5=*0x%x, arg6=0x%x) -> CELL_OK", arg1, arg2, arg3, arg4, arg5, arg6);
@ -113,17 +136,29 @@ s32 sys_fs_open(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, s32 mode, vm::c
return CELL_FS_ENOENT;
}
*fd = Emu.GetIdManager().make<lv2_file_t>(std::move(file), mode, flags);
return CELL_OK;
for (u32 i = 3; i < g_fds.size(); i++)
{
// try to reserve fd
if (g_fds[i].compare_and_swap_test(0, ~0))
{
g_fds[i].store(Emu.GetIdManager().make<lv2_file_t>(std::move(file), mode, flags));
*fd = i;
return CELL_OK;
}
}
// out of file descriptors
return CELL_FS_EMFILE;
}
s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
{
sys_fs.Log("sys_fs_read(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
sys_fs.Log("sys_fs_read(fd=%d, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file || file->flags & CELL_FS_O_WRONLY)
{
@ -139,9 +174,9 @@ s32 sys_fs_read(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<u64> nread)
s32 sys_fs_write(u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
{
sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite);
sys_fs.Log("sys_fs_write(fd=%d, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
{
@ -159,9 +194,9 @@ s32 sys_fs_write(u32 fd, vm::cptr<void> buf, u64 nbytes, vm::ptr<u64> nwrite)
s32 sys_fs_close(u32 fd)
{
sys_fs.Log("sys_fs_close(fd=0x%x)", fd);
sys_fs.Log("sys_fs_close(fd=%d)", fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -170,7 +205,9 @@ s32 sys_fs_close(u32 fd)
// TODO: return CELL_FS_EBUSY if locked
Emu.GetIdManager().remove<lv2_file_t>(fd);
Emu.GetIdManager().remove<lv2_file_t>(_fd_to_id(fd));
g_fds[fd].store(0);
return CELL_OK;
}
@ -188,16 +225,28 @@ s32 sys_fs_opendir(vm::cptr<char> path, vm::ptr<u32> fd)
return CELL_FS_ENOENT;
}
*fd = Emu.GetIdManager().make<lv2_dir_t>(std::move(dir));
for (u32 i = 3; i < g_fds.size(); i++)
{
// try to reserve fd
if (g_fds[i].compare_and_swap_test(0, ~0))
{
g_fds[i].store(Emu.GetIdManager().make<lv2_dir_t>(std::move(dir)));
return CELL_OK;
*fd = i;
return CELL_OK;
}
}
// out of file descriptors
return CELL_FS_EMFILE;
}
s32 sys_fs_readdir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
{
sys_fs.Warning("sys_fs_readdir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread);
sys_fs.Warning("sys_fs_readdir(fd=%d, dir=*0x%x, nread=*0x%x)", fd, dir, nread);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(fd);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(_fd_to_id(fd));
if (!directory)
{
@ -223,16 +272,18 @@ s32 sys_fs_readdir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
s32 sys_fs_closedir(u32 fd)
{
sys_fs.Log("sys_fs_closedir(fd=0x%x)", fd);
sys_fs.Log("sys_fs_closedir(fd=%d)", fd);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(fd);
const auto directory = Emu.GetIdManager().get<lv2_dir_t>(_fd_to_id(fd));
if (!directory)
{
return CELL_FS_EBADF;
}
Emu.GetIdManager().remove<lv2_dir_t>(fd);
Emu.GetIdManager().remove<lv2_dir_t>(_fd_to_id(fd));
g_fds[fd].store(0);
return CELL_OK;
}
@ -272,9 +323,9 @@ s32 sys_fs_stat(vm::cptr<char> path, vm::ptr<CellFsStat> sb)
s32 sys_fs_fstat(u32 fd, vm::ptr<CellFsStat> sb)
{
sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb);
sys_fs.Warning("sys_fs_fstat(fd=%d, sb=*0x%x)", fd, sb);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -415,15 +466,15 @@ s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6)
s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
{
sys_fs.Log("sys_fs_lseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos);
sys_fs.Log("sys_fs_lseek(fd=%d, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos);
if (whence >= 3)
{
sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (%d)", fd, whence);
sys_fs.Error("sys_fs_lseek(): unknown seek whence (%d)", whence);
return CELL_FS_EINVAL;
}
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -439,9 +490,9 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
s32 sys_fs_fget_block_size(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size, vm::ptr<u64> arg4, vm::ptr<u64> arg5)
{
sys_fs.Todo("sys_fs_fget_block_size(fd=0x%x, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5);
sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file)
{
@ -487,9 +538,9 @@ s32 sys_fs_truncate(vm::cptr<char> path, u64 size)
s32 sys_fs_ftruncate(u32 fd, u64 size)
{
sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size);
sys_fs.Warning("sys_fs_ftruncate(fd=%d, size=0x%llx)", fd, size);
const auto file = Emu.GetIdManager().get<lv2_file_t>(fd);
const auto file = Emu.GetIdManager().get<lv2_file_t>(_fd_to_id(fd));
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
{

View File

@ -201,6 +201,8 @@ struct lv2_file_t
, st_callback({})
{
}
~lv2_file_t();
};
REG_ID_TYPE(lv2_file_t, 0x73); // SYS_FS_FD_OBJECT
@ -215,6 +217,8 @@ struct lv2_dir_t
: dir(std::move(dir))
{
}
~lv2_dir_t();
};
REG_ID_TYPE(lv2_dir_t, 0x73); // SYS_FS_FD_OBJECT