From d337560baba59e47fabf6e9f40358f2403c959fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Sun, 21 Aug 2022 21:26:48 +0200 Subject: [PATCH] io: use fios2 --- newlib/libc/sys/vita/fios2.h | 162 ++++++++++++++++++++++++++++++++ newlib/libc/sys/vita/io.c | 11 ++- newlib/libc/sys/vita/syscalls.c | 63 +++++++++---- 3 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 newlib/libc/sys/vita/fios2.h diff --git a/newlib/libc/sys/vita/fios2.h b/newlib/libc/sys/vita/fios2.h new file mode 100644 index 000000000..759096058 --- /dev/null +++ b/newlib/libc/sys/vita/fios2.h @@ -0,0 +1,162 @@ +#ifndef __FIOS2_H__ +#define __FIOS2_H__ + +#include + +#define SCE_FIOS_OK 0 + +#define SCE_FIOS_TIME_NULL ((SceFiosTime)0) +#define SCE_FIOS_TIME_EARLIEST ((SceFiosTime)1) +#define SCE_FIOS_TIME_LATEST ((SceFiosTime)0x7FFFFFFFFFFFFFFFLL) + +#define SCE_FIOS_PRIO_MIN ((int8_t)-128) +#define SCE_FIOS_PRIO_DEFAULT ((int8_t)0) +#define SCE_FIOS_PRIO_MAX ((int8_t)127) + +#define SCE_FIOS_FH_SIZE 80 +#define SCE_FIOS_DH_SIZE 80 +#define SCE_FIOS_OP_SIZE 168 +#define SCE_FIOS_CHUNK_SIZE 64 + +#define SCE_FIOS_ALIGN_UP(val, align) (((val) + ((align) - 1)) & ~((align) - 1)) +#define SCE_FIOS_STORAGE_SIZE(num, size) (((num) * (size)) + SCE_FIOS_ALIGN_UP(SCE_FIOS_ALIGN_UP((num), 8) / 8, 8)) + +#define SCE_FIOS_DH_STORAGE_SIZE(numDHs, pathMax) SCE_FIOS_STORAGE_SIZE(numDHs, SCE_FIOS_DH_SIZE + pathMax) +#define SCE_FIOS_FH_STORAGE_SIZE(numFHs, pathMax) SCE_FIOS_STORAGE_SIZE(numFHs, SCE_FIOS_FH_SIZE + pathMax) +#define SCE_FIOS_OP_STORAGE_SIZE(numOps, pathMax) SCE_FIOS_STORAGE_SIZE(numOps, SCE_FIOS_OP_SIZE + pathMax) +#define SCE_FIOS_CHUNK_STORAGE_SIZE(numChunks) SCE_FIOS_STORAGE_SIZE(numChunks, SCE_FIOS_CHUNK_SIZE) + +#define SCE_FIOS_BUFFER_INITIALIZER { 0, 0 } +#define SCE_FIOS_PARAMS_INITIALIZER { 0, sizeof(SceFiosParams), 0, 0, 2, 1, 0, 0, 256 * 1024, 2, 0, 0, 0, 0, 0, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, NULL, NULL, NULL, { 66, 189, 66 }, { 0x40000, 0, 0x40000}, { 8 * 1024, 16 * 1024, 8 * 1024}} +#define SCE_FIOS_OPENPARAMS_INITIALIZER { 0, 0, 0, SCE_FIOS_BUFFER_INITIALIZER } +#define SCE_FIOS_OPATTR_INITIALIZER { 0, 0, 0, 0, 0, 0, 0, 0 } +#define SCE_FIOS_RAM_CACHE_CONTEXT_INITIALIZER { sizeof(SceFiosRamCacheContext), 0, (64 * 1024), NULL, NULL, 0, {0, 0, 0} } + +typedef enum SceFiosWhence { + SCE_FIOS_SEEK_SET = 0, + SCE_FIOS_SEEK_CUR = 1, + SCE_FIOS_SEEK_END = 2 +} SceFiosWhence; + +typedef enum SceFiosOpenFlags { + SCE_FIOS_O_RDONLY = (1 << 0), + SCE_FIOS_O_WRONLY = (1 << 1), + SCE_FIOS_O_RDWR = (SCE_FIOS_O_RDONLY | SCE_FIOS_O_WRONLY), + SCE_FIOS_O_APPEND = (1 << 2), + SCE_FIOS_O_CREAT = (1 << 3), + SCE_FIOS_O_TRUNC = (1 << 4), +} SceFiosOpenFlags; + +typedef int64_t SceFiosTime; + +typedef int32_t SceFiosFH; +typedef int32_t SceFiosDH; +typedef uint64_t SceFiosDate; +typedef int64_t SceFiosOffset; +typedef int64_t SceFiosSize; + +typedef struct SceFiosBuffer { + void *pPtr; + size_t length; +} SceFiosBuffer; + +typedef struct SceFiosOpAttr { + SceFiosTime deadline; + void *pCallback; + void *pCallbackContext; + int32_t priority : 8; + uint32_t opflags : 24; + uint32_t userTag; + void *userPtr; + void *pReserved; +} SceFiosOpAttr; + +typedef struct SceFiosRamCacheContext { + size_t sizeOfContext; + size_t workBufferSize; + size_t blockSize; + void *pWorkBuffer; + const char *pPath; + intptr_t flags; + intptr_t reserved[3]; +} SceFiosRamCacheContext; + +typedef struct SceFiosOpenParams { + uint32_t openFlags : 16; + uint32_t opFlags : 16; + uint32_t reserved; + SceFiosBuffer buffer; +} SceFiosOpenParams; + +typedef struct SceFiosParams { + uint32_t initialized : 1; + uint32_t paramsSize : 15; + uint32_t pathMax : 16; + uint32_t profiling; + uint32_t ioThreadCount; + uint32_t threadsPerScheduler; + uint32_t extraFlag1 : 1; + uint32_t extraFlags : 31; + uint32_t maxChunk; + uint8_t maxDecompressorThreadCount; + uint8_t reserved1; + uint8_t reserved2; + uint8_t reserved3; + intptr_t reserved4; + intptr_t reserved5; + SceFiosBuffer opStorage; + SceFiosBuffer fhStorage; + SceFiosBuffer dhStorage; + SceFiosBuffer chunkStorage; + void *pVprintf; + void *pMemcpy; + void *pProfileCallback; + int threadPriority[3]; + int threadAffinity[3]; + int threadStackSize[3]; +} SceFiosParams; + +typedef struct SceFiosStat { + SceFiosOffset st_size; + SceFiosDate st_atime; + SceFiosDate st_mtime; + SceFiosDate st_ctime; + uint32_t statFlags; + uint32_t reserved; + int64_t uid; + int64_t gid; + int64_t dev; + int64_t ino; + int64_t st_mode; +} SceFiosStat; + +int sceFiosInitialize(const SceFiosParams *params); +void sceFiosTerminate(); + +int sceFiosRenameSync(const SceFiosOpAttr *attr, const char *old_path, const char *new_path); +int sceFiosDeleteSync(const SceFiosOpAttr *attr, const char *path); + +int sceFiosFHOpenSync(const SceFiosOpAttr *attr, SceFiosFH *fh, const char *path, const void *params); +SceFiosSize sceFiosFHReadSync(const SceFiosOpAttr *attr, SceFiosFH fh, void *data, SceFiosSize size); +SceFiosSize sceFiosFHWriteSync(const SceFiosOpAttr *attr, SceFiosFH fh, const void *data, SceFiosSize size); +int sceFiosFHCloseSync(const SceFiosOpAttr *attr, SceFiosFH fh); + +SceFiosOffset sceFiosFHSeek(SceFiosFH fh, SceFiosOffset offset, SceFiosWhence whence); +SceFiosOffset sceFiosFHTell(SceFiosFH fh); +SceFiosSize sceFiosFHGetSize(SceFiosFH fh); + +int sceFiosStatSync(const SceFiosOpAttr *attr, const char *path, SceFiosStat *stat); +int sceFiosFHStatSync(const SceFiosOpAttr *attr, SceFiosFH fh, SceFiosStat *stat); +int sceFiosDHStatSync(const SceFiosOpAttr *attr, SceFiosDH fh, SceFiosStat *stat); + +int sceFiosDirectoryCreateSync(const SceFiosOpAttr *attr, const char *path); +int sceFiosDHOpenSync(const SceFiosOpAttr *attr, SceFiosDH *dh, const char *path, const void *params); +int sceFiosDHCloseSync(const SceFiosOpAttr *attr, SceFiosDH fh); + + +int sceFiosIOFilterAdd(int index, void *pFilterCallback, void *pFilterContext); +void sceFiosIOFilterCache(); + +SceDateTime *sceFiosDateToSceDateTime(SceFiosDate date, SceDateTime *sce_date); + +#endif \ No newline at end of file diff --git a/newlib/libc/sys/vita/io.c b/newlib/libc/sys/vita/io.c index 3b96a2be5..989a2dba0 100644 --- a/newlib/libc/sys/vita/io.c +++ b/newlib/libc/sys/vita/io.c @@ -8,6 +8,7 @@ #include #include #include +#include "fios2.h" #include "vitadescriptor.h" #include "vitaglue.h" @@ -197,7 +198,6 @@ int __vita_fd_drop(DescriptorTranslation *map) switch (map->type) { - case VITA_DESCRIPTOR_FILE: case VITA_DESCRIPTOR_TTY: { ret = sceIoClose(map->sce_uid); @@ -207,6 +207,15 @@ int __vita_fd_drop(DescriptorTranslation *map) } break; } + case VITA_DESCRIPTOR_FILE: + { + ret = sceFiosFHCloseSync(NULL, map->sce_uid); + if (map->filename) + { + free(map->filename); + } + break; + } case VITA_DESCRIPTOR_DIRECTORY: { ret = sceIoDclose(map->sce_uid); diff --git a/newlib/libc/sys/vita/syscalls.c b/newlib/libc/sys/vita/syscalls.c index 7e67ec65f..50eafb2b0 100755 --- a/newlib/libc/sys/vita/syscalls.c +++ b/newlib/libc/sys/vita/syscalls.c @@ -14,6 +14,8 @@ #include #include #include +#include "fios2.h" + #include @@ -39,10 +41,12 @@ _write_r(struct _reent * reent, int fd, const void *buf, size_t nbytes) switch (fdmap->type) { - case VITA_DESCRIPTOR_FILE: case VITA_DESCRIPTOR_TTY: ret = sceIoWrite(fdmap->sce_uid, buf, nbytes); break; + case VITA_DESCRIPTOR_FILE: + ret = sceFiosFHWriteSync(NULL, fdmap->sce_uid, buf, nbytes); + break; case VITA_DESCRIPTOR_SOCKET: type = ERROR_SOCKET; ret = sceNetSend(fdmap->sce_uid, buf, nbytes, 0); @@ -184,7 +188,7 @@ _lseek_r(struct _reent *reent, int fd, _off_t ptr, int dir) switch (fdmap->type) { case VITA_DESCRIPTOR_FILE: - ret = sceIoLseek32(fdmap->sce_uid, ptr, dir); + ret = sceFiosFHSeek(fdmap->sce_uid, ptr, dir); break; case VITA_DESCRIPTOR_TTY: case VITA_DESCRIPTOR_SOCKET: @@ -215,7 +219,7 @@ _mkdir_r (struct _reent * reent, const char * path, int mode) reent->_errno = errno; // set by realpath return -1; } - if ((ret = sceIoMkdir(full_path, 0777)) < 0) + if ((ret = sceFiosDirectoryCreateSync(NULL, full_path)) < 0) { free(full_path); reent->_errno = __vita_sce_errno_to_errno(ret, ERROR_GENERIC); @@ -277,7 +281,20 @@ _open_r(struct _reent *reent, const char *file, int flags, int mode) return -1; } - ret = is_dir ? sceIoDopen(full_path) : sceIoOpen(full_path, sce_flags, 0666); + if (is_dir) { + SceFiosDH handle = 0; + SceFiosOpenParams openParams = SCE_FIOS_OPENPARAMS_INITIALIZER; + openParams.openFlags = sce_flags; + ret = sceFiosDHOpenSync(NULL, &handle, full_path, &openParams); + ret = ret < 0 ? ret : handle; + } else { + SceFiosFH handle = 0; + SceFiosOpenParams openParams = SCE_FIOS_OPENPARAMS_INITIALIZER; + openParams.openFlags = sce_flags; + ret = sceFiosFHOpenSync(NULL, &handle, full_path, &openParams); + ret = ret < 0 ? ret : handle; + } + if (ret < 0) { free(full_path); @@ -291,7 +308,7 @@ _open_r(struct _reent *reent, const char *file, int flags, int mode) if (fd < 0) { free(full_path); - is_dir ? sceIoDclose(ret) : sceIoClose(ret); + is_dir ? sceFiosDHCloseSync(NULL, ret) : sceFiosFHCloseSync(NULL, ret); reent->_errno = EMFILE; return -1; } @@ -322,9 +339,11 @@ _read_r(struct _reent *reent, int fd, void *ptr, size_t len) switch (fdmap->type) { case VITA_DESCRIPTOR_TTY: - case VITA_DESCRIPTOR_FILE: ret = sceIoRead(fdmap->sce_uid, ptr, len); break; + case VITA_DESCRIPTOR_FILE: + ret = sceFiosFHReadSync(NULL, fdmap->sce_uid, ptr, len); + break; case VITA_DESCRIPTOR_SOCKET: type = ERROR_SOCKET; ret = sceNetRecv(fdmap->sce_uid, ptr, len, 0); @@ -372,7 +391,7 @@ _unlink_r(struct _reent *reent, const char * path) reent->_errno = errno; // set by realpath return -1; } - ret = sceIoRemove(full_path); + ret = sceFiosDeleteSync(NULL, full_path); if (ret < 0) { free(full_path); @@ -401,7 +420,7 @@ _rename_r(struct _reent *reent, const char *old, const char *new) reent->_errno = errno; // set by realpath return -1; } - ret = sceIoRename(full_path_old, full_path_new); + ret = sceFiosRenameSync(NULL, full_path_old, full_path_new); if (ret < 0) { free(full_path_old); @@ -427,7 +446,7 @@ _times_r(struct _reent *reent, struct tms *ptms) } static void -scestat_to_stat(struct SceIoStat *in, struct stat *out) +scestat_to_stat(struct SceFiosStat *in, struct stat *out) { memset(out, 0, sizeof(*out)); out->st_size = in->st_size; @@ -435,15 +454,23 @@ scestat_to_stat(struct SceIoStat *in, struct stat *out) out->st_mode |= _IFREG; if (SCE_S_ISDIR(in->st_mode)) out->st_mode |= _IFDIR; - sceRtcGetTime_t(&in->st_atime, &out->st_atime); - sceRtcGetTime_t(&in->st_mtime, &out->st_mtime); - sceRtcGetTime_t(&in->st_ctime, &out->st_ctime); + + SceDateTime aux_date = {0}; + + sceFiosDateToSceDateTime(in->st_atime, &aux_date); + sceRtcGetTime_t(&aux_date, &out->st_atime); + + sceFiosDateToSceDateTime(in->st_mtime, &aux_date); + sceRtcGetTime_t(&aux_date, &out->st_mtime); + + sceFiosDateToSceDateTime(in->st_ctime, &aux_date); + sceRtcGetTime_t(&aux_date, &out->st_ctime); } int _fstat_r(struct _reent *reent, int fd, struct stat *st) { - struct SceIoStat stat = {0}; + struct SceFiosStat stat = {0}; int ret; DescriptorTranslation *fdmap = __vita_fd_grab(fd); @@ -457,9 +484,11 @@ _fstat_r(struct _reent *reent, int fd, struct stat *st) switch (fdmap->type) { case VITA_DESCRIPTOR_TTY: - case VITA_DESCRIPTOR_FILE: case VITA_DESCRIPTOR_DIRECTORY: - ret = sceIoGetstatByFd(fdmap->sce_uid, &stat); + ret = sceFiosDHStatSync(NULL, fdmap->sce_uid, &stat); + break; + case VITA_DESCRIPTOR_FILE: + ret = sceFiosFHStatSync(NULL, fdmap->sce_uid, &stat); break; case VITA_DESCRIPTOR_SOCKET: case VITA_DESCRIPTOR_PIPE: @@ -483,7 +512,7 @@ _fstat_r(struct _reent *reent, int fd, struct stat *st) int _stat_r(struct _reent *reent, const char *path, struct stat *st) { - struct SceIoStat stat = {0}; + struct SceFiosStat stat = {0}; int ret; char* full_path = __realpath(path); if (!full_path) @@ -491,7 +520,7 @@ _stat_r(struct _reent *reent, const char *path, struct stat *st) reent->_errno = errno; // set by realpath return -1; } - if ((ret = sceIoGetstat(full_path, &stat)) < 0) + if ((ret = sceFiosStatSync(NULL, full_path, &stat)) < 0) { free(full_path); reent->_errno = __vita_sce_errno_to_errno(ret, ERROR_GENERIC);