Skip to content

Commit

Permalink
Merge branch 'RPCSX:master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
qurious-pixel authored Oct 31, 2023
2 parents cbbb686 + fd14659 commit 44c744d
Show file tree
Hide file tree
Showing 38 changed files with 730 additions and 88 deletions.
1 change: 1 addition & 0 deletions orbis-kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_library(obj.orbis-utils-ipc OBJECT
)
add_library(obj.orbis-kernel OBJECT
src/module.cpp
src/pipe.cpp
src/sysvec.cpp
src/evf.cpp
src/KernelContext.cpp
Expand Down
12 changes: 12 additions & 0 deletions orbis-kernel/include/orbis/KernelContext.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "evf.hpp"
#include "ipmi.hpp"
#include "orbis/utils/IdMap.hpp"
#include "osem.hpp"
#include "utils/LinkedNode.hpp"
#include "utils/SharedCV.hpp"
Expand Down Expand Up @@ -54,6 +55,15 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
void deleteProcess(Process *proc);
Process *findProcessById(pid_t pid) const;

utils::LinkedNode<Process> *getProcessList() {
return m_processes;
}

long allocatePid() {
std::lock_guard lock(m_thread_id_mtx);
return m_thread_id_map.emplace(0).first;
}

long getTscFreq();

void *kalloc(std::size_t size,
Expand Down Expand Up @@ -161,6 +171,8 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {

std::atomic<long> m_tsc_freq{0};

shared_mutex m_thread_id_mtx;
OwningIdMap<char, long, 256, 0> m_thread_id_map;
mutable shared_mutex m_proc_mtx;
utils::LinkedNode<Process> *m_processes = nullptr;

Expand Down
13 changes: 13 additions & 0 deletions orbis-kernel/include/orbis/pipe.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "KernelAllocator.hpp"
#include "file.hpp"
#include "utils/Rc.hpp"

namespace orbis {
struct Pipe final : File {
kvector<std::byte> data;
};

Ref<Pipe> createPipe();
} // namespace orbis
4 changes: 2 additions & 2 deletions orbis-kernel/include/orbis/sys/sysproto.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ SysResult sys_opmc_get_ctr(Thread *thread /* TODO */);
SysResult sys_budget_create(Thread *thread /* TODO */);
SysResult sys_budget_delete(Thread *thread /* TODO */);
SysResult sys_budget_get(Thread *thread /* TODO */);
SysResult sys_budget_set(Thread *thread /* TODO */);
SysResult sys_budget_set(Thread *thread, slong budget);
SysResult sys_virtual_query(Thread *thread, ptr<void> addr, uint64_t unk,
ptr<void> info, size_t infosz);
SysResult sys_mdbg_call(Thread *thread /* TODO */);
Expand Down Expand Up @@ -701,7 +701,7 @@ SysResult sys_sandbox_path(Thread *thread /* TODO */);
SysResult sys_mdbg_service(Thread *thread, uint32_t op, ptr<void> arg0,
ptr<void> arg1);
SysResult sys_randomized_path(Thread *thread /* TODO */);
SysResult sys_rdup(Thread *thread /* TODO */);
SysResult sys_rdup(Thread *thread, sint a, sint b);
SysResult sys_dl_get_metadata(Thread *thread /* TODO */);
SysResult sys_workaround8849(Thread *thread /* TODO */);
SysResult sys_is_development_mode(Thread *thread /* TODO */);
Expand Down
1 change: 1 addition & 0 deletions orbis-kernel/include/orbis/thread/ProcessOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct ProcessOps {
SysResult (*thr_wake)(Thread *thread, slong id);
SysResult (*thr_set_name)(Thread *thread, slong id, ptr<const char> name);

SysResult (*fork)(Thread *thread, slong status);
SysResult (*exit)(Thread *thread, sint status);

SysResult (*processNeeded)(Thread *thread);
Expand Down
2 changes: 2 additions & 0 deletions orbis-kernel/include/orbis/thread/Thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ struct Thread {
void incRef() {}
void decRef() {}
};

extern thread_local Thread *g_currentThread;
} // namespace orbis
56 changes: 55 additions & 1 deletion orbis-kernel/include/orbis/utils/IdMap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class RcIdMap {
}
}

bool insert(std::size_t index, T *object) {
if (mask.test(index)) {
return false;
}

mask.set(index);
objects[index] = object;
return true;
}

std::size_t insert(T *object) {
std::size_t index = mask.countr_one();
mask.set(index);
Expand Down Expand Up @@ -117,6 +127,28 @@ class RcIdMap {
end_iterator end() const { return {}; }

private:
bool insert_impl(IdT id, T *object) {
std::lock_guard lock(mutex);

auto raw = static_cast<std::size_t>(id);
auto page = (raw - MinId) / ChunkSize;
auto index = (raw - MinId) % ChunkSize;

if (page >= ChunkCount) {
return false;
}

if (!m_chunks[page].insert(index, object)) {
return false;
}

if (m_chunks[page].mask.full()) {
m_fullChunks.set(page);
}

return true;
}

IdT insert_impl(T *object) {
std::lock_guard lock(mutex);

Expand Down Expand Up @@ -159,7 +191,29 @@ class RcIdMap {
return result;
}

T *get(IdT id) {
bool insert(IdT id, T *object) {
if (insert_impl(id, object)) {
object->incRef();
return true;
}

return false;
}

bool insert(IdT id, const Ref<T> &ref) { return insert(id, ref.get()); }

bool insert(IdT id, Ref<T> &&ref) {
auto object = ref.release();

if (!insert_impl(id, object)) {
object->decRef();
return false;
}

return true;
}

Ref<T> get(IdT id) {
const auto rawId = static_cast<std::size_t>(id) - MinId;

if (rawId >= MaxId - MinId) {
Expand Down
2 changes: 1 addition & 1 deletion orbis-kernel/include/orbis/utils/SharedCV.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace orbis {
inline namespace utils {
// IPC-ready lightweight condition variable
class shared_cv {
class shared_cv final {
enum : unsigned {
c_waiter_mask = 0xffff,
c_signal_mask = 0x7fff0000,
Expand Down
10 changes: 8 additions & 2 deletions orbis-kernel/src/KernelContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
#include <sys/unistd.h>

namespace orbis {
thread_local Thread *g_currentThread;

KernelContext &g_context = *[]() -> KernelContext * {
// Allocate global shared kernel memory
// TODO: randomize for hardening and reduce size
auto ptr = mmap(reinterpret_cast<void *>(0x200'0000'0000), 0x1'0000'0000,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (!ptr)
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (ptr == MAP_FAILED)
std::abort();

return new (ptr) KernelContext;
Expand Down Expand Up @@ -160,6 +163,9 @@ void KernelContext::kfree(void *ptr, std::size_t size) {
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if ((uintptr_t)ptr == 0x2000001a2b0) {
std::fprintf(stderr, "free %p-%p (%zu)\n", ptr, (char *)ptr + size, size);
}
std::memset(ptr, 0xcc, size);

pthread_mutex_lock(&m_heap_mtx);
Expand Down
61 changes: 61 additions & 0 deletions orbis-kernel/src/pipe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "pipe.hpp"
#include "error/ErrorCode.hpp"
#include "file.hpp"
#include "uio.hpp"
#include <span>
#include <thread>

static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto pipe = static_cast<orbis::Pipe *>(file);
while (true) {
if (pipe->data.empty()) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}

std::lock_guard lock(pipe->mtx);

if (pipe->data.empty()) {
continue;
}

for (auto vec : std::span(uio->iov, uio->iovcnt)) {
auto size = std::min<std::size_t>(pipe->data.size(), vec.len);
uio->offset += size;
std::memcpy(vec.base, pipe->data.data(), size);

if (pipe->data.size() == size) {
break;
}

std::memmove(pipe->data.data(), pipe->data.data() + size,
pipe->data.size() - size);
pipe->data.resize(pipe->data.size() - size);
}

break;
}
return {};
}

static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto pipe = static_cast<orbis::Pipe *>(file);
std::lock_guard lock(pipe->mtx);

for (auto vec : std::span(uio->iov, uio->iovcnt)) {
auto offset = pipe->data.size();
pipe->data.resize(offset + vec.len);
std::memcpy(pipe->data.data(), vec.base, vec.len);
}
uio->resid = 0;
return {};
}

static orbis::FileOps pipe_ops = {.read = pipe_read, .write = pipe_write};

orbis::Ref<orbis::Pipe> orbis::createPipe() {
auto result = knew<Pipe>();
result->ops = &pipe_ops;
return result;
}
21 changes: 19 additions & 2 deletions orbis-kernel/src/sys/sys_descrip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,27 @@ orbis::SysResult orbis::sys_getdtablesize(Thread *thread) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_dup2(Thread *thread, uint from, uint to) {
return ErrorCode::NOSYS;
if (to == 1 || to == 2) { // HACK: ignore setup /dev/console to stdout/stderr
return {};
}

std::lock_guard lock(thread->tproc->fileDescriptors.mutex);

auto file = thread->tproc->fileDescriptors.get(from);
if (file == nullptr) {
return ErrorCode::BADF;
}
thread->tproc->fileDescriptors.close(to);
thread->tproc->fileDescriptors.insert(to, file);
return {};
}
orbis::SysResult orbis::sys_dup(Thread *thread, uint fd) {
return ErrorCode::NOSYS;
auto file = thread->tproc->fileDescriptors.get(fd);
if (file == nullptr) {
return ErrorCode::BADF;
}
thread->retval[0] = thread->tproc->fileDescriptors.insert(std::move(file));
return {};
}
orbis::SysResult orbis::sys_fcntl(Thread *thread, sint fd, sint cmd,
slong arg) {
Expand Down
8 changes: 7 additions & 1 deletion orbis-kernel/src/sys/sys_exit.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <thread>

orbis::SysResult orbis::sys_exit(Thread *thread, sint status) {
if (auto exit = thread->tproc->ops->exit) {
Expand All @@ -13,5 +16,8 @@ orbis::SysResult orbis::sys_abort2(Thread *thread, ptr<const char> why,
}
orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
sint options, ptr<struct rusage> rusage) {
return ErrorCode::NOSYS;
// TODO
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage);
std::this_thread::sleep_for(std::chrono::days(1));
return {};
}
7 changes: 7 additions & 0 deletions orbis-kernel/src/sys/sys_fork.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include <cstdlib>
#include <unistd.h>

orbis::SysResult orbis::sys_fork(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_pdfork(Thread *thread, ptr<sint> fdp, sint flags) {
return ErrorCode::NOSYS;
}

orbis::SysResult orbis::sys_vfork(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_rfork(Thread *thread, sint flags) {
if (auto fork = thread->tproc->ops->fork) {
return fork(thread, flags);
}
return ErrorCode::NOSYS;
}
8 changes: 7 additions & 1 deletion orbis-kernel/src/sys/sys_pipe.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#include "sys/sysproto.hpp"
#include <pipe.hpp>

orbis::SysResult orbis::sys_pipe(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_pipe(Thread *thread) {
auto pipe = createPipe();
thread->retval[0] = thread->tproc->fileDescriptors.insert(pipe);
thread->retval[1] = thread->tproc->fileDescriptors.insert(pipe);
return {};
}
2 changes: 1 addition & 1 deletion orbis-kernel/src/sys/sys_prot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ orbis::SysResult orbis::sys_getpgid(Thread *thread, pid_t pid) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_getsid(Thread *thread, pid_t pid) {
return ErrorCode::NOSYS;
return {};
}
orbis::SysResult orbis::sys_getuid(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_geteuid(Thread *thread) { return ErrorCode::NOSYS; }
Expand Down
Loading

0 comments on commit 44c744d

Please sign in to comment.