Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #14 from SysRay/feature
Browse files Browse the repository at this point in the history
Feature branch
  • Loading branch information
SysRay authored Mar 13, 2024
2 parents 8e73ed1 + 847866d commit c8bb397
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 61 deletions.
20 changes: 17 additions & 3 deletions core/fileManager/fileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ struct UniData {
struct FileData: public UniData {
std::unique_ptr<std::fstream> const m_file;

FileData(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path): UniData(UniData::Type::File, path), m_file(std::move(file)) {}
std::ios_base::openmode mode;

FileData(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path, std::ios_base::openmode mode)
: UniData(UniData::Type::File, path), m_file(std::move(file)), mode(mode) {}

virtual ~FileData() { m_file->sync(); }
};
Expand Down Expand Up @@ -150,10 +153,10 @@ class FileManager: public IFileManager {

std::filesystem::path const& getGameFilesDir() const final { return m_dirGameFiles; }

int addFileStream(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path) final {
int addFileStream(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path, std::ios_base::openmode mode) final {
std::unique_lock const lock(m_mutext_int);

return insertItem(m_openFiles, std::make_unique<FileData>(std::move(file), path).release());
return insertItem(m_openFiles, std::make_unique<FileData>(std::move(file), path, mode).release());
}

int addDirIterator(std::unique_ptr<std::filesystem::directory_iterator>&& it, std::filesystem::path const& path) final {
Expand Down Expand Up @@ -181,6 +184,17 @@ class FileManager: public IFileManager {
return nullptr;
}

std::ios_base::openmode getMode(int handle) final {
if (handle < FILE_DESCRIPTOR_MIN) return {};
handle -= FILE_DESCRIPTOR_MIN;

std::unique_lock const lock(m_mutext_int);
if (handle < m_openFiles.size() && m_openFiles[handle] && m_openFiles[handle]->m_type == UniData::Type::File) {
return static_cast<FileData*>(m_openFiles[handle].get())->mode;
}
return {};
}

std::filesystem::path getPath(int handle) final {
if (handle < FILE_DESCRIPTOR_MIN) return {};
handle -= FILE_DESCRIPTOR_MIN;
Expand Down
4 changes: 3 additions & 1 deletion core/fileManager/fileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class IFileManager {
* @param path the mapped path to the file/folder
* @return int handle of the fstream. used by getFile() etc.
*/
virtual int addFileStream(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path) = 0;
virtual int addFileStream(std::unique_ptr<std::fstream>&& file, std::filesystem::path const& path, std::ios_base::openmode mode) = 0;

/**
* @brief Add a directory_iterator
Expand All @@ -107,6 +107,8 @@ class IFileManager {
*/
virtual std::fstream* getFile(int handle) = 0;

virtual std::ios_base::openmode getMode(int handle) = 0;

virtual int getDents(int handle, char* buf, int nbytes, int64_t* basep) = 0;

/**
Expand Down
3 changes: 2 additions & 1 deletion core/initParams/initParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ bool InitParams::init(int argc, char** argv) {

if (vm.count("help")) {
std::cout << desc << '\n';
return 0;
return false;
}
if (!vm.count("file")) {
std::cout << "--file missing\n";
return false;
}

return true;
Expand Down
121 changes: 102 additions & 19 deletions core/kernel/filesystem.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "filesystem.h"

#include "core/fileManager/fileManager.h"
#include "core/memory/memory.h"
#include "logging.h"

#include <assert.h>
#include <unordered_map>
#include <windows.h>

LOG_DEFINE_MODULE(filesystem);
Expand All @@ -23,21 +25,42 @@ std::pair<DWORD, DWORD> convProtection(int prot) {

return {PAGE_NOACCESS, 0};
}

auto getMappings() {
static std::unordered_map<uint64_t, filesystem::SceMap> obj;
return &obj;
}
} // namespace

namespace filesystem {
int mmap(void* addr, size_t len, int prot, SceMap flags, int fd, int64_t offset, void** res) {
LOG_USE_MODULE(filesystem);

if (fd < FILE_DESCRIPTOR_MIN) {
return getErr(ErrCode::_EPERM);
}

// Mapping cases
if (flags.mode == SceMapMode::FIXED) {
LOG_ERR(L"todo: Mmap fixed 0x%08llx len:0x%08llx prot:%d flags:%d fd:%d offset:%lld", addr, len, prot, flags, fd, offset);
return getErr(ErrCode::_EINVAL);
}

if (flags.mode == SceMapMode::VOID_) {
// reserve memory
LOG_ERR(L"todo: Mmap void 0x%08llx len:0x%08llx prot:%d flags:%d fd:%d offset:%lld", addr, len, prot, flags, fd, offset);
return getErr(ErrCode::_EINVAL);
}

if (flags.type == SceMapType::ANON) {
*res = (void*)memory::alloc((uint64_t)addr, len, prot);

getMappings()->emplace(std::make_pair((uint64_t)*res, flags));
return getErr(ErrCode::_EINVAL);
}
// -

// Do file mapping
if (fd < FILE_DESCRIPTOR_MIN) {
return getErr(ErrCode::_EPERM);
}

auto const [fileProt, viewProt] = convProtection(prot);

auto filepath = accessFileManager().getPath(fd);
Expand Down Expand Up @@ -80,8 +103,32 @@ int mmap(void* addr, size_t len, int prot, SceMap flags, int fd, int64_t offset,
return Ok;
}

int munmap(void* address, size_t len) {
return UnmapViewOfFile(address) != 0 ? Ok : -1;
int munmap(void* addr, size_t len) {
LOG_USE_MODULE(filesystem);

auto mappings = getMappings();
if (auto it = mappings->find((uint64_t)addr); it != mappings->end()) {
if (it->second.mode == SceMapMode::FIXED) {
LOG_ERR(L"todo: munmap fixed 0x%08llx len:0x%08llx", addr, len);
return getErr(ErrCode::_EINVAL);
}

if (it->second.mode == SceMapMode::VOID_) {
LOG_ERR(L"todo: munmap void 0x%08llx len:0x%08llx", addr, len);
return getErr(ErrCode::_EINVAL);
}

if (it->second.type == SceMapType::ANON) {
memory::free((uint64_t)addr);
return Ok;
}

// Is file Mapping
return UnmapViewOfFile(addr) != 0 ? Ok : -1;
}

LOG_ERR(L"munmap unknown 0x%08llx 0x%08llx", addr, len);
return -1;
}

size_t read(int handle, void* buf, size_t nbytes) {
Expand Down Expand Up @@ -176,7 +223,7 @@ int open(const char* path, SceOpen flags, SceKernelMode kernelMode) {
}

auto file = std::make_unique<std::fstream>(std::fstream(mappedPath, mode));
int const handle = accessFileManager().addFileStream(std::move(file), mappedPath);
int const handle = accessFileManager().addFileStream(std::move(file), mappedPath, mode);
LOG_INFO(L"OpenFile[%d]: %s mode:0x%lx(0x%lx)", handle, mappedPath.c_str(), mode, kernelMode);

return handle;
Expand Down Expand Up @@ -268,8 +315,40 @@ int fcntl(int fd, int cmd, va_list args) {

size_t readv(int handle, const SceKernelIovec* iov, int iovcnt) {
LOG_USE_MODULE(filesystem);
LOG_ERR(L"todo %S", __FUNCTION__);
return Ok;
if (handle < FILE_DESCRIPTOR_MIN) {
return getErr(ErrCode::_EPERM);
}

auto file = accessFileManager().getFile(handle);
if (file == nullptr) {
return getErr(ErrCode::_EBADF);
}
if (!(*file)) {
LOG_TRACE(L"file end");
return 0;
}

size_t count = 0;

for (int n = 0; n < iovcnt; ++n) {
auto* item = &iov[n];

if (item->iov_base == nullptr || item->iov_len == 0) continue;

file->read((char*)item->iov_base, item->iov_len);

auto const countTemp = file->gcount();

LOG_TRACE(L"KernelRead[%d]: 0x%08llx:%llu read(%lld)", handle, (uint64_t)item->iov_base, item->iov_len, countTemp);

count += countTemp;
if (!(*file)) {
LOG_TRACE(L"file end");
break;
}
}

return count;
}

size_t writev(int handle, const SceKernelIovec* iov, int iovcnt) {
Expand Down Expand Up @@ -466,23 +545,27 @@ size_t pwrite(int handle, const void* buf, size_t nbytes, int64_t offset) {
int64_t lseek(int handle, int64_t offset, int whence) {
LOG_USE_MODULE(filesystem);
LOG_TRACE(L"lseek [%d] 0x%08llx %d", handle, offset, whence);

if (whence > 2) return getErr(ErrCode::_EINVAL);
if (handle < FILE_DESCRIPTOR_MIN) {
return getErr(ErrCode::_EPERM);
}

auto file = accessFileManager().getFile(handle);
file->clear();

if (whence == 0) {
file->seekg(offset, std::ios::beg);
file->seekp(offset, std::ios::beg);
} else if (whence == 1) {
file->seekg(offset, std::ios::cur);
file->seekp(offset, std::ios::cur);
} else if (whence == 2) {
file->seekg(offset, std::ios::end);
file->seekp(offset, std::ios::end);
}
// translate to std
static int _whence[] = {
std::ios::beg,
std::ios::cur,
std::ios::end,
};
// -

auto const mode = accessFileManager().getMode(handle);

if ((mode & std::ios::in) > 0) file->seekg(offset, _whence[whence]);
if ((mode & std::ios::out) > 0) file->seekp(offset, _whence[whence]);

if (!*file) {
LOG_TRACE(L"lseek[%d] einval");
Expand Down
9 changes: 7 additions & 2 deletions core/kernel/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum class SceMapMode : uint16_t {
PRIVATE = 0x0002,
FIXED = 0x0010,
NO_OVERWRITE = 0x0080,
VOID = 0x0100,
VOID_ = 0x0100,
};

enum class SceMapType : uint16_t {
Expand Down Expand Up @@ -76,9 +76,14 @@ struct SceKernelStat {
unsigned int: (8 / 2) * (16 - static_cast<int>(sizeof(SceKernelTimespec)));
};

struct Sce_iovec {
void* iov_base;
size_t iov_len;
};

typedef uint16_t SceKernelMode; // todo needed?

typedef struct iovec SceKernelIovec;
typedef struct Sce_iovec SceKernelIovec;

#if defined(__APICALL_EXTERN)
#define __APICALL __declspec(dllexport)
Expand Down
15 changes: 6 additions & 9 deletions core/kernel/pthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ void init_pThread() {
pimpl->sceSetJmp = (decltype(pimpl->sceSetJmp))accessRuntimeExport()->getSymbol("gNQ1V2vfXDE", "libc", "libc");
pimpl->sceLongJmp = (decltype(pimpl->sceLongJmp))accessRuntimeExport()->getSymbol("lKEN2IebgJ0", "libc", "libc");

assert(pimpl->sceSetJmp != nullptr);
assert(pimpl->sceLongJmp != nullptr);
// assert(pimpl->sceSetJmp != nullptr);
// assert(pimpl->sceLongJmp != nullptr);
}
} // namespace

Expand Down Expand Up @@ -1070,9 +1070,10 @@ void exit(void* value) {
LOG_USE_MODULE(pthread);

auto thread = getPthread(getSelf());
LOG_DEBUG(L"exit| %S id:%d", thread->name.data(), thread->unique_id);
LOG_CRIT(L"Currently not supported, exit| %S id:%d", thread->name.data(), thread->unique_id);

getData()->sceLongJmp(&thread->threadEntryBuf, *(int*)&value);
thread->p.interrupt();
boost::this_thread::interruption_point();
}

void raise(ScePthread_obj obj, void* callback, int signo) {
Expand Down Expand Up @@ -1256,11 +1257,7 @@ void* threadWrapper(void* arg) {

int resJmp = 0;
auto func_setjmp = getData()->sceSetJmp;
if (func_setjmp != nullptr && (resJmp = func_setjmp(&thread->threadEntryBuf)) != 0) {
ret = (void*)(int64_t)resJmp;
} else {
ret = thread->entry(thread->arg);
}
ret = thread->entry(thread->arg);
LOG_DEBUG(L"thread done:%d", thread->unique_id);
return ret;
}
Expand Down
38 changes: 24 additions & 14 deletions core/videoout/videoout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,13 @@ struct VideoOutConfig {
SceVideoOutVblankStatus vblankStatus;
SceVideoOutResolutionStatus resolution;

std::array<vulkan::SwapchainData, 16> bufferSets;
std::array<int32_t, 16> buffers; // index to bufferSets
std::array<vulkan::SwapchainData, 16> bufferSets;

std::array<int32_t, 16> buffers; // index to bufferSets

std::array<std::weak_ptr<IGpuImageObject>, 16> displayBuffers;
uint8_t buffersSetsCount = 0;

uint8_t buffersSetsCount = 0;

double fps = 0.0;

Expand Down Expand Up @@ -377,22 +380,29 @@ void VideoOut::transferDisplay(int handle, int index, VkSemaphore waitSema, size

auto& swapchain = window.config.bufferSets[setIndex];
auto& displayBufferMeta = swapchain.buffers[index];
if (window.config.displayBuffers[index].expired()) {
auto image = getDisplayBuffer(displayBufferMeta.bufferVaddr);
if (image) {
window.config.displayBuffers[index] = image;
vulkan::transfer2Display(displayBufferMeta.transferBuffer, m_vulkanObj, swapchain, image->getImage(), image.get(), index);
vulkan::submitDisplayTransfer(displayBufferMeta.transferBuffer, m_vulkanObj, displayBufferMeta.semPresentReady, displayBufferMeta.semDisplayReady,
waitSema, waitValue);
} else {
auto& displayBuffer = window.config.displayBuffers[index];

// Get the display image
std::shared_ptr<IGpuImageObject> image;
if (displayBuffer.expired()) {
image = getDisplayBuffer(displayBufferMeta.bufferVaddr);
if (!image) {
LOG_ERR(L"No Display for 0x%08llx:%u", displayBufferMeta.bufferVaddr, displayBufferMeta.bufferSize);
return;
}
} else {
auto image = window.config.displayBuffers[index].lock();
image = displayBuffer.lock();
}
// -

// todo check if gpu memory is newer or not (commandprocessor submits)
if (false) {
vulkan::transfer2Display_direct(displayBufferMeta.transferBuffer, m_vulkanObj, swapchain, image.get(), index);
} else {
vulkan::transfer2Display(displayBufferMeta.transferBuffer, m_vulkanObj, swapchain, image->getImage(), image.get(), index);
vulkan::submitDisplayTransfer(displayBufferMeta.transferBuffer, m_vulkanObj, displayBufferMeta.semPresentReady, displayBufferMeta.semDisplayReady, waitSema,
waitValue);
}

vulkan::submitDisplayTransfer(m_vulkanObj, &displayBufferMeta, waitSema, waitValue);
}

void VideoOut::submitFlip(int handle, int index, int64_t flipArg) {
Expand Down
Loading

0 comments on commit c8bb397

Please sign in to comment.