kernel: split context and allocator & initial implementation of process/thread local objects
Some checks are pending
Formatting check / formatting-check (push) Waiting to run
Build RPCSX / build-linux (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.1-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.2-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.4-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv8.5-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9-a) (push) Waiting to run
Build RPCSX / build-android (arm64-v8a, armv9.1-a) (push) Waiting to run
Build RPCSX / build-android (x86_64, x86-64) (push) Waiting to run

This commit is contained in:
DH 2025-10-10 19:56:11 +03:00
parent b358d6b2c9
commit 2589143798
34 changed files with 774 additions and 597 deletions

View file

@ -1,139 +0,0 @@
#pragma once
#include "rx/LinkedNode.hpp"
#include "rx/Serializer.hpp"
#include <cassert>
namespace kernel {
namespace detail {
struct GlobalObjectCtl {
void (*construct)();
void (*destruct)();
void (*serialize)(rx::Serializer &);
void (*deserialize)(rx::Deserializer &);
};
template <typename NamespaceT, typename T> struct GlobalKernelObjectInstance {
static inline T *instance = nullptr;
static inline rx::LinkedNode<GlobalObjectCtl> ctl = {
.object = {
.construct = +[] { instance->construct(); },
.destruct = +[] { instance->destruct(); },
.serialize = +[](rx::Serializer &s) { instance->serialize(s); },
.deserialize = +[](rx::Deserializer &s) { instance->deserialize(s); },
},
};
};
} // namespace detail
template <typename NamespaceT> struct GlobalKernelObjectStorage {
template <typename T> static void AddObject() {
auto node = &detail::GlobalKernelObjectInstance<NamespaceT, T>::ctl;
auto head = GetHead();
if (head) {
head->prev = node;
node->next = head;
}
*GetHeadPtr() = node;
}
static void ConstructAll() {
for (auto it = GetHead(); it != nullptr; it = it->next) {
it->object.construct();
}
}
static void DestructAll() {
for (auto it = GetHead(); it != nullptr; it = it->next) {
it->object.destruct();
}
}
static void SerializeAll(rx::Serializer &s) {
for (auto it = GetHead(); it != nullptr; it = it->next) {
it->object.serialize(s);
}
}
static void DeserializeAll(rx::Deserializer &s) {
for (auto it = GetHead(); it != nullptr; it = it->next) {
it->object.deserialize(s);
}
}
private:
static rx::LinkedNode<detail::GlobalObjectCtl> *GetHead() {
return *GetHeadPtr();
}
static rx::LinkedNode<detail::GlobalObjectCtl> **GetHeadPtr() {
static rx::LinkedNode<detail::GlobalObjectCtl> *registry;
return &registry;
}
};
template <rx::Serializable T, typename NamespaceT>
requires std::is_default_constructible_v<T>
class GlobalKernelObject {
union U {
T object;
U() {}
~U() {}
};
U mHolder;
public:
template <typename = void> GlobalKernelObject() {
auto &instance =
detail::GlobalKernelObjectInstance<NamespaceT,
GlobalKernelObject>::instance;
assert(instance == nullptr);
instance = this;
GlobalKernelObjectStorage<NamespaceT>::template AddObject<
GlobalKernelObject>();
}
T *operator->() { return &mHolder.object; }
const T *operator->() const { return &mHolder.object; }
T &operator*() { return mHolder.object; }
const T &operator*() const { return mHolder.object; }
operator T &() { return mHolder.object; }
operator const T &() const { return mHolder.object; }
void serialize(rx::Serializer &s)
requires rx::Serializable<T>
{
s.serialize(mHolder.object);
}
void deserialize(rx::Deserializer &s)
requires rx::Serializable<T>
{
std::construct_at(&mHolder.object);
s.deserialize(mHolder.object);
}
T &get() { return mHolder.object; }
const T &get() const { return mHolder.object; }
private:
template <typename... Args>
requires(std::is_constructible_v<T, Args && ...>)
void construct(Args &&...args) noexcept(
std::is_nothrow_constructible_v<T, Args &&...>) {
std::construct_at(&mHolder.object, std::forward<Args>(args)...);
}
template <typename... Args>
void destruct() noexcept(std::is_nothrow_destructible_v<T>) {
mHolder.object.~T();
}
friend detail::GlobalKernelObjectInstance<NamespaceT, GlobalKernelObject>;
};
} // namespace kernel

View file

@ -0,0 +1,180 @@
#pragma once
#include "rx/Rc.hpp"
#include "rx/Serializer.hpp"
#include "rx/TypeId.hpp"
#include <memory>
#include <mutex>
namespace kernel {
class KernelObjectBase : public rx::RcBase {
rx::TypeId mType;
public:
KernelObjectBase(rx::TypeId type) : mType(type) {}
[[nodiscard]] rx::TypeId getType() const { return mType; }
template <typename T> [[nodiscard]] bool isa() const {
return mType == rx::TypeId::get<T>();
}
};
template <rx::Serializable StateT>
struct KernelObject : KernelObjectBase, StateT {
template <typename... Args>
KernelObject(Args &&...args)
: KernelObjectBase(rx::TypeId::get<StateT>()),
StateT(std::forward<Args>(args)...) {}
virtual void serialize(rx::Serializer &s) const {
if constexpr (requires(const KernelObject &instance) {
instance.lock();
instance.unlock();
}) {
std::lock_guard lock(*this);
s.serialize(static_cast<const StateT &>(*this));
} else {
s.serialize(static_cast<const StateT &>(*this));
}
}
virtual void deserialize(rx::Deserializer &s) {
s.deserialize(static_cast<StateT &>(*this));
}
};
namespace detail {
struct StaticObjectCtl {
std::size_t offset = -1ull;
void (*construct)(void *object);
void (*destruct)(void *object);
void (*serialize)(void *object, rx::Serializer &);
void (*deserialize)(void *object, rx::Deserializer &);
template <typename T> constexpr static StaticObjectCtl Create() {
return {
.construct =
+[](void *object) {
std::construct_at(reinterpret_cast<T *>(object));
},
.destruct = +[](void *object) { reinterpret_cast<T *>(object)->~T(); },
.serialize =
+[](void *object, rx::Serializer &serializer) {
serializer.serialize(*reinterpret_cast<T *>(object));
},
.deserialize =
+[](void *object, rx::Deserializer &deserializer) {
deserializer.deserialize(*reinterpret_cast<T *>(object));
},
};
}
};
struct GlobalScope;
struct ProcessScope;
struct ThreadScope;
} // namespace detail
template <typename NamespaceT, typename ScopeT> std::byte *getScopeStorage();
template <typename NamespaceT, typename ScopeT>
struct StaticKernelObjectStorage {
template <typename T> static std::uint32_t Allocate() {
auto &instance = GetInstance();
auto object = detail::StaticObjectCtl::Create<T>();
instance.m_registry.push_back(object);
auto offset = instance.m_size;
offset = rx::alignUp(offset, alignof(T));
instance.m_registry.back().offset = offset;
instance.m_size = offset + sizeof(T);
instance.m_alignment =
std::max<std::size_t>(alignof(T), instance.m_alignment);
// std::printf(
// "%s::Allocate(%s, %zu, %zu) -> %zu\n",
// rx::TypeId::get<StaticKernelObjectStorage<NamespaceT,
// ScopeT>>().getName().data(), rx::TypeId::get<T>().getName().data(),
// sizeof(T), alignof(T), offset);
return offset;
}
static std::size_t GetSize() { return GetInstance().m_size; }
static std::size_t GetAlignment() { return GetInstance().m_alignment; }
static std::byte *getScopeStorage() {
return kernel::getScopeStorage<NamespaceT, ScopeT>();
}
static void ConstructAll() {
auto &instance = GetInstance();
auto storage = getScopeStorage();
for (auto objectCtl : instance.m_registry) {
objectCtl.construct(storage + objectCtl.offset);
}
}
static void DestructAll() {
auto &instance = GetInstance();
auto storage = getScopeStorage();
for (auto objectCtl : instance.m_registry) {
objectCtl.destruct(storage + objectCtl.offset);
}
}
static void SerializeAll(rx::Serializer &s) {
auto &instance = GetInstance();
auto storage = getScopeStorage();
s.serialize(instance.m_size);
s.serialize(instance.m_registry.size());
for (auto objectCtl : instance.m_registry) {
objectCtl.serialize(storage + objectCtl.offset, s);
}
}
static void DeserializeAll(rx::Deserializer &s) {
auto &instance = GetInstance();
auto storage = getScopeStorage();
auto size = s.deserialize<std::size_t>();
auto registrySize = s.deserialize<std::size_t>();
if (size != instance.m_size || registrySize != instance.m_registry.size()) {
s.setFailure();
return;
}
for (auto objectCtl : instance.m_registry) {
objectCtl.deserialize(storage + objectCtl.offset, s);
}
}
private:
static StaticKernelObjectStorage &GetInstance() {
static StaticKernelObjectStorage instance;
return instance;
}
std::vector<detail::StaticObjectCtl> m_registry;
std::size_t m_size = 0;
std::size_t m_alignment = 1;
};
template <typename NamespaceT, typename ScopeT, rx::Serializable T>
class StaticObjectRef {
std::uint32_t mOffset;
public:
explicit StaticObjectRef(std::uint32_t offset) : mOffset(offset) {}
T *get() {
return reinterpret_cast<T *>(getScopeStorage<NamespaceT, ScopeT>() +
mOffset);
}
T *operator->() { return get(); }
};
} // namespace kernel

View file

@ -7,6 +7,7 @@ add_library(obj.orbis-kernel OBJECT
src/event.cpp
src/evf.cpp
src/ipmi.cpp
src/KernelAllocator.cpp
src/KernelContext.cpp
src/umtx.cpp
src/sys/sys_acct.cpp

View file

@ -1,26 +0,0 @@
#pragma once
#include <kernel/GlobalKernelObject.hpp>
namespace orbis {
struct OrbisNamespace;
template <rx::Serializable T>
using GlobalKernelObject = kernel::GlobalKernelObject<T, OrbisNamespace>;
template <rx::Serializable T> GlobalKernelObject<T> createGlobalObject() {
return {};
}
inline void constructAllGlobals() {
kernel::GlobalKernelObjectStorage<OrbisNamespace>::ConstructAll();
}
inline void destructAllGlobals() {
kernel::GlobalKernelObjectStorage<OrbisNamespace>::DestructAll();
}
template <typename T> T &getGlobalObject() {
assert(detail::GlobalKernelObjectInstance<GlobalKernelObject<T>>::instance);
return kernel::detail::GlobalKernelObjectInstance<
OrbisNamespace, GlobalKernelObject<T>>::instance->get();
}
} // namespace orbis

View file

@ -10,7 +10,6 @@
#include <vector>
namespace orbis {
inline namespace utils {
void *kalloc(std::size_t size, std::size_t align);
void kfree(void *ptr, std::size_t size);
template <typename T> struct kallocator {
@ -51,7 +50,6 @@ template <typename K, typename T, typename Hash = std::hash<K>,
typename Pred = std::equal_to<K>>
using kunmap =
std::unordered_map<K, T, Hash, Pred, kallocator<std::pair<const K, T>>>;
} // namespace utils
template <typename T, typename... Args>
requires(std::is_constructible_v<T, Args...>)
@ -61,17 +59,17 @@ T *knew(Args &&...args) {
struct DynamicObject final : T {
using T::T;
void operator delete(void *pointer) { utils::kfree(pointer, sizeof(T)); }
void operator delete(void *pointer) { kfree(pointer, sizeof(T)); }
};
auto loc = static_cast<DynamicObject *>(
utils::kalloc(sizeof(DynamicObject), alignof(DynamicObject)));
kalloc(sizeof(DynamicObject), alignof(DynamicObject)));
return std::construct_at(loc, std::forward<Args>(args)...);
} else {
static_assert(!std::is_polymorphic_v<T>,
"Polymorphic type should be derived from rx::RcBase");
auto loc = static_cast<T *>(utils::kalloc(sizeof(T), alignof(T)));
auto loc = static_cast<T *>(kalloc(sizeof(T), alignof(T)));
return std::construct_at(loc, std::forward<Args>(args)...);
}
}
@ -80,8 +78,10 @@ T *knew(Args &&...args) {
template <typename T> void kdelete(T *ptr) {
static_assert(std::is_final_v<T>, "Uncertain type size");
ptr->~T();
utils::kfree(ptr, sizeof(T));
kfree(ptr, sizeof(T));
}
// clang-format on
void initializeAllocator();
void deinitializeAllocator();
} // namespace orbis

View file

@ -1,7 +1,7 @@
#pragma once
#include "AppInfo.hpp"
#include "Budget.hpp"
#include "KernelAllocator.hpp"
#include "KernelObject.hpp"
#include "evf.hpp"
#include "ipmi.hpp"
#include "orbis/note.hpp"
@ -50,12 +50,7 @@ public:
long getTscFreq();
void *kalloc(std::size_t size,
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
void kfree(void *ptr, std::size_t size);
std::pair<EventFlag *, bool> createEventFlag(utils::kstring name,
std::int32_t flags,
std::pair<EventFlag *, bool> createEventFlag(kstring name, std::int32_t flags,
std::uint64_t initPattern) {
std::lock_guard lock(m_evf_mtx);
@ -78,7 +73,7 @@ public:
return {};
}
std::pair<Semaphore *, bool> createSemaphore(utils::kstring name,
std::pair<Semaphore *, bool> createSemaphore(kstring name,
std::uint32_t attrs,
std::int32_t initCount,
std::int32_t maxCount) {
@ -100,8 +95,7 @@ public:
return {};
}
std::pair<rx::Ref<IpmiServer>, ErrorCode>
createIpmiServer(utils::kstring name) {
std::pair<rx::Ref<IpmiServer>, ErrorCode> createIpmiServer(kstring name) {
std::lock_guard lock(m_sem_mtx);
auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr);
@ -128,15 +122,14 @@ public:
return {};
}
std::tuple<utils::kmap<utils::kstring, char[128]> &,
std::unique_lock<rx::shared_mutex>>
std::tuple<kmap<kstring, char[128]> &, std::unique_lock<rx::shared_mutex>>
getKernelEnv() {
std::unique_lock lock(m_kenv_mtx);
return {m_kenv, std::move(lock)};
}
void setKernelEnv(std::string_view key, std::string_view value) {
auto &kenvValue = m_kenv[utils::kstring(key)];
auto &kenvValue = m_kenv[kstring(key)];
auto len = std::min(sizeof(kenvValue) - 1, value.size());
std::memcpy(kenvValue, value.data(), len);
kenvValue[len] = '0';
@ -177,14 +170,10 @@ public:
return processTypeBudgets[static_cast<int>(processType)];
}
void serialize(rx::Serializer &) const {}
void deserialize(rx::Deserializer &) {}
private:
rx::shared_mutex m_heap_mtx;
rx::shared_mutex m_heap_map_mtx;
void *m_heap_next = this + 1;
utils::kmultimap<std::size_t, void *> m_free_heap;
utils::kmultimap<std::size_t, void *> m_used_node;
std::atomic<long> m_tsc_freq{0};
rx::shared_mutex m_thread_id_mtx;
@ -193,17 +182,17 @@ private:
rx::LinkedNode<Process> *m_processes = nullptr;
rx::shared_mutex m_evf_mtx;
utils::kmap<utils::kstring, rx::Ref<EventFlag>> m_event_flags;
kmap<kstring, rx::Ref<EventFlag>> m_event_flags;
rx::shared_mutex m_sem_mtx;
utils::kmap<utils::kstring, rx::Ref<Semaphore>> m_semaphores;
kmap<kstring, rx::Ref<Semaphore>> m_semaphores;
rx::shared_mutex mIpmiServerMtx;
utils::kmap<utils::kstring, rx::Ref<IpmiServer>> mIpmiServers;
kmap<kstring, rx::Ref<IpmiServer>> mIpmiServers;
rx::shared_mutex m_kenv_mtx;
utils::kmap<utils::kstring, char[128]> m_kenv; // max size: 127 + '\0'
kmap<kstring, char[128]> m_kenv; // max size: 127 + '\0'
};
extern KernelContext &g_context;
extern GlobalObjectRef<KernelContext> g_context;
} // namespace orbis

View file

@ -0,0 +1,108 @@
#pragma once
#include <kernel/KernelObject.hpp>
namespace orbis {
struct OrbisNamespace;
template <rx::Serializable StateT>
using GlobalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::GlobalScope,
StateT>;
template <rx::Serializable StateT>
using ProcessLocalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope,
StateT>;
template <rx::Serializable StateT>
using ThreadLocalObjectRef =
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope,
StateT>;
template <rx::Serializable StateT>
GlobalObjectRef<StateT> createGlobalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::template Allocate<StateT>();
return GlobalObjectRef<StateT>(layoutOffset);
}
template <rx::Serializable StateT>
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope, StateT>
createProcessLocalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace,
kernel::detail::ProcessScope>::template Allocate<StateT>();
return kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ProcessScope,
StateT>(layoutOffset);
}
template <rx::Serializable StateT>
kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope, StateT>
createThreadLocalObject() {
auto layoutOffset = kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::template Allocate<StateT>();
return kernel::StaticObjectRef<OrbisNamespace, kernel::detail::ThreadScope,
StateT>(layoutOffset);
}
inline void constructAllGlobals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::ConstructAll();
}
inline void constructAllProcessLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::ConstructAll();
}
inline void constructAllThreadLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::ConstructAll();
}
inline void destructAllGlobals() {
kernel::StaticKernelObjectStorage<OrbisNamespace,
kernel::detail::GlobalScope>::DestructAll();
}
inline void destructAllProcessLocals() {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::DestructAll();
}
inline void destructAllThreadLocals() {
kernel::StaticKernelObjectStorage<OrbisNamespace,
kernel::detail::ThreadScope>::DestructAll();
}
inline void serializeAllGlobals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::SerializeAll(s);
}
inline void serializeAllProcessLocals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::SerializeAll(s);
}
inline void serializeAllThreadLocals(rx::Serializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::SerializeAll(s);
}
inline void deserializeAllGlobals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::GlobalScope>::DeserializeAll(s);
}
inline void deserializeAllProcessLocals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ProcessScope>::DeserializeAll(s);
}
inline void deserializeAllThreadLocals(rx::Deserializer &s) {
kernel::StaticKernelObjectStorage<
OrbisNamespace, kernel::detail::ThreadScope>::DeserializeAll(s);
}
} // namespace orbis

View file

@ -57,7 +57,7 @@ struct EventFlag final {
};
rx::shared_mutex queueMtx;
utils::kvector<WaitingThread> waitingThreads;
kvector<WaitingThread> waitingThreads;
enum class NotifyType { Set, Cancel, Destroy };

View file

@ -82,7 +82,7 @@ struct File : rx::RcBase {
int flags = 0;
int mode = 0;
int hostFd = -1;
utils::kvector<Dirent> dirEntries;
kvector<Dirent> dirEntries;
bool noBlock() const { return (flags & 4) != 0; }
};

View file

@ -21,7 +21,7 @@ enum class DynType : std::uint8_t {
};
struct ModuleNeeded {
utils::kstring name;
kstring name;
std::uint16_t version;
std::uint64_t attr;
bool isExport;
@ -67,7 +67,7 @@ struct Relocation {
struct Module final {
Process *proc{};
utils::kstring vfsPath;
kstring vfsPath;
char moduleName[256]{};
char soName[256]{};
ModuleHandle id{};
@ -110,15 +110,15 @@ struct Module final {
bool isTlsDone = false;
utils::kstring interp;
utils::kvector<Symbol> symbols;
utils::kvector<Relocation> pltRelocations;
utils::kvector<Relocation> nonPltRelocations;
utils::kvector<ModuleNeeded> neededModules;
utils::kvector<ModuleNeeded> neededLibraries;
utils::kvector<rx::Ref<Module>> importedModules;
utils::kvector<rx::Ref<Module>> namespaceModules;
utils::kvector<utils::kstring> needed;
kstring interp;
kvector<Symbol> symbols;
kvector<Relocation> pltRelocations;
kvector<Relocation> nonPltRelocations;
kvector<ModuleNeeded> neededModules;
kvector<ModuleNeeded> neededLibraries;
kvector<rx::Ref<Module>> importedModules;
kvector<rx::Ref<Module>> namespaceModules;
kvector<kstring> needed;
std::atomic<unsigned> references{0};

View file

@ -93,13 +93,13 @@ struct Process final {
// Named objects for debugging
rx::shared_mutex namedObjMutex;
utils::kmap<void *, utils::kstring> namedObjNames;
kmap<void *, kstring> namedObjNames;
rx::OwningIdMap<NamedObjInfo, uint, 65535, 1> namedObjIds;
utils::kmap<std::int32_t, SigAction> sigActions;
kmap<std::int32_t, SigAction> sigActions;
// Named memory ranges for debugging
rx::shared_mutex namedMemMutex;
utils::kmap<NamedMemoryRange, utils::kstring> namedMem;
kmap<NamedMemoryRange, kstring> namedMem;
};
} // namespace orbis

View file

@ -0,0 +1,221 @@
#include "KernelAllocator.hpp"
#include "KernelObject.hpp"
#include "rx/Serializer.hpp"
#include "rx/SharedMutex.hpp"
#include "rx/print.hpp"
#include <sys/mman.h>
static const std::uint64_t g_allocProtWord = 0xDEADBEAFBADCAFE1;
static constexpr std::uintptr_t kHeapBaseAddress = 0x00000600'0000'0000;
static constexpr auto kHeapSize = 0x1'0000'0000;
static constexpr int kDebugHeap = 0;
namespace orbis {
struct KernelMemoryResource {
mutable rx::shared_mutex m_heap_mtx;
rx::shared_mutex m_heap_map_mtx;
void *m_heap_next = nullptr;
kmultimap<std::size_t, void *> m_free_heap;
kmultimap<std::size_t, void *> m_used_node;
~KernelMemoryResource() {
::munmap(std::bit_cast<void *>(kHeapBaseAddress), kHeapSize);
}
void *kalloc(std::size_t size,
std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__);
void kfree(void *ptr, std::size_t size);
void serialize(rx::Serializer &) const {
// FIXME: implement
}
void deserialize(rx::Deserializer &) {
// FIXME: implement
}
void lock() const { m_heap_mtx.lock(); }
void unlock() const { m_heap_mtx.unlock(); }
};
static KernelMemoryResource *sMemoryResource;
static std::byte *sGlobalStorage;
using GlobalStorage =
kernel::StaticKernelObjectStorage<OrbisNamespace,
kernel::detail::GlobalScope>;
void initializeAllocator() {
auto ptr = (std::byte *)::mmap(std::bit_cast<void *>(kHeapBaseAddress),
kHeapSize, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (ptr == MAP_FAILED) {
perror("mmap failed");
FILE *maps = std::fopen("/proc/self/maps", "r");
char *line = nullptr;
std::size_t size = 0;
while (getline(&line, &size, maps) > 0) {
std::puts(line);
}
std::free(line);
std::fclose(maps);
std::abort();
}
sMemoryResource = new (ptr) KernelMemoryResource();
sMemoryResource->m_heap_next = ptr + sizeof(KernelMemoryResource);
rx::print(stderr, "global: size {}, alignment {}\n", GlobalStorage::GetSize(),
GlobalStorage::GetAlignment());
// allocate whole global storage
sGlobalStorage = (std::byte *)sMemoryResource->kalloc(
GlobalStorage::GetSize(), GlobalStorage::GetAlignment());
}
void deinitializeAllocator() {
sMemoryResource->kfree(sGlobalStorage, GlobalStorage::GetSize());
delete sMemoryResource;
sMemoryResource = nullptr;
sGlobalStorage = nullptr;
}
void *KernelMemoryResource::kalloc(std::size_t size, std::size_t align) {
size = (size + (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1)) &
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if (m_heap_map_mtx.try_lock()) {
std::lock_guard lock(m_heap_map_mtx, std::adopt_lock);
// Try to reuse previously freed block
for (auto [it, end] = m_free_heap.equal_range(size); it != end; ++it) {
auto result = it->second;
if (!(std::bit_cast<std::uintptr_t>(result) & (align - 1))) {
auto node = m_free_heap.extract(it);
node.key() = 0;
node.mapped() = nullptr;
m_used_node.insert(m_used_node.begin(), std::move(node));
// std::fprintf(stderr, "kalloc: reuse %p-%p, size = %lx\n", result,
// (char *)result + size, size);
if (kDebugHeap > 0) {
std::memcpy(std::bit_cast<std::byte *>(result) + size,
&g_allocProtWord, sizeof(g_allocProtWord));
}
return result;
}
}
}
std::lock_guard lock(m_heap_mtx);
align = std::max<std::size_t>(align, __STDCPP_DEFAULT_NEW_ALIGNMENT__);
auto heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
heap = (heap + (align - 1)) & ~(align - 1);
if (kDebugHeap > 1) {
if (auto diff = (heap + size + sizeof(g_allocProtWord)) % 4096; diff != 0) {
heap += 4096 - diff;
heap &= ~(align - 1);
}
}
if (heap + size > kHeapBaseAddress + kHeapSize) {
std::fprintf(stderr, "out of kernel memory");
std::abort();
}
// Check overflow
if (heap + size < heap) {
std::fprintf(stderr, "too big allocation");
std::abort();
}
// std::fprintf(stderr, "kalloc: allocate %lx-%lx, size = %lx, align=%lx\n",
// heap, heap + size, size, align);
auto result = reinterpret_cast<void *>(heap);
if (kDebugHeap > 0) {
std::memcpy(std::bit_cast<std::byte *>(result) + size, &g_allocProtWord,
sizeof(g_allocProtWord));
}
if (kDebugHeap > 0) {
m_heap_next =
reinterpret_cast<void *>(heap + size + sizeof(g_allocProtWord));
} else {
m_heap_next = reinterpret_cast<void *>(heap + size);
}
if (kDebugHeap > 1) {
heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
align = std::min<std::size_t>(align, 4096);
heap = (heap + (align - 1)) & ~(align - 1);
size = 4096;
// std::fprintf(stderr, "kalloc: protect %lx-%lx, size = %lx, align=%lx\n",
// heap, heap + size, size, align);
auto result = ::mmap(reinterpret_cast<void *>(heap), size, PROT_NONE,
MAP_FIXED | MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (result == MAP_FAILED) {
std::fprintf(stderr, "failed to protect memory");
std::abort();
}
m_heap_next = reinterpret_cast<void *>(heap + size);
}
return result;
}
void KernelMemoryResource::kfree(void *ptr, std::size_t size) {
size = (size + (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1)) &
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if (std::bit_cast<std::uintptr_t>(ptr) < kHeapBaseAddress ||
std::bit_cast<std::uintptr_t>(ptr) + size >
kHeapBaseAddress + kHeapSize) {
std::fprintf(stderr, "kfree: invalid address");
std::abort();
}
if (kDebugHeap > 0) {
if (std::memcmp(std::bit_cast<std::byte *>(ptr) + size, &g_allocProtWord,
sizeof(g_allocProtWord)) != 0) {
std::fprintf(stderr, "kernel heap corruption\n");
std::abort();
}
std::memset(ptr, 0xcc, size + sizeof(g_allocProtWord));
}
// std::fprintf(stderr, "kfree: release %p-%p, size = %lx\n", ptr,
// (char *)ptr + size, size);
std::lock_guard lock(m_heap_map_mtx);
if (!m_used_node.empty()) {
auto node = m_used_node.extract(m_used_node.begin());
node.key() = size;
node.mapped() = ptr;
m_free_heap.insert(std::move(node));
} else {
m_free_heap.emplace(size, ptr);
}
}
void kfree(void *ptr, std::size_t size) {
return sMemoryResource->kfree(ptr, size);
}
void *kalloc(std::size_t size, std::size_t align) {
return sMemoryResource->kalloc(size, align);
}
} // namespace orbis
template <>
std::byte *
kernel::getScopeStorage<orbis::OrbisNamespace, kernel::detail::GlobalScope>() {
return orbis::sGlobalStorage;
}

View file

@ -1,4 +1,5 @@
#include "orbis/KernelContext.hpp"
#include "KernelObject.hpp"
#include "orbis/thread/Process.hpp"
#include "orbis/thread/ProcessOps.hpp"
#include "orbis/utils/Logs.hpp"
@ -13,37 +14,10 @@
#include <unistd.h>
#include <utility>
static const std::uint64_t g_allocProtWord = 0xDEADBEAFBADCAFE1;
static constexpr std::uintptr_t kHeapBaseAddress = 0x00000600'0000'0000;
static constexpr auto kHeapSize = 0x1'0000'0000;
static constexpr int kDebugHeap = 0;
namespace orbis {
GlobalObjectRef<KernelContext> g_context = createGlobalObject<KernelContext>();
thread_local Thread *g_currentThread;
KernelContext &g_context = *[]() -> KernelContext * {
// Allocate global shared kernel memory
// TODO: randomize for hardening and reduce size
auto ptr = mmap(std::bit_cast<void *>(kHeapBaseAddress), kHeapSize,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (ptr == MAP_FAILED) {
perror("mmap failed");
FILE *maps = fopen("/proc/self/maps", "r");
char *line = nullptr;
std::size_t size = 0;
while (getline(&line, &size, maps) > 0) {
std::printf("%s", line);
}
free(line);
fclose(maps);
std::abort();
}
return new (ptr) KernelContext;
}();
KernelContext::KernelContext() {
// std::printf("orbis::KernelContext initialized, addr=%p\n", this);
// std::printf("TSC frequency: %lu\n", getTscFreq());
@ -158,138 +132,6 @@ long KernelContext::getTscFreq() {
return m_tsc_freq.load();
}
void *KernelContext::kalloc(std::size_t size, std::size_t align) {
size = (size + (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1)) &
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if (m_heap_map_mtx.try_lock()) {
std::lock_guard lock(m_heap_map_mtx, std::adopt_lock);
// Try to reuse previously freed block
for (auto [it, end] = m_free_heap.equal_range(size); it != end; ++it) {
auto result = it->second;
if (!(std::bit_cast<std::uintptr_t>(result) & (align - 1))) {
auto node = m_free_heap.extract(it);
node.key() = 0;
node.mapped() = nullptr;
m_used_node.insert(m_used_node.begin(), std::move(node));
// std::fprintf(stderr, "kalloc: reuse %p-%p, size = %lx\n", result,
// (char *)result + size, size);
if (kDebugHeap > 0) {
std::memcpy(std::bit_cast<std::byte *>(result) + size,
&g_allocProtWord, sizeof(g_allocProtWord));
}
return result;
}
}
}
std::lock_guard lock(m_heap_mtx);
align = std::max<std::size_t>(align, __STDCPP_DEFAULT_NEW_ALIGNMENT__);
auto heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
heap = (heap + (align - 1)) & ~(align - 1);
if (kDebugHeap > 1) {
if (auto diff = (heap + size + sizeof(g_allocProtWord)) % 4096; diff != 0) {
heap += 4096 - diff;
heap &= ~(align - 1);
}
}
if (heap + size > kHeapBaseAddress + kHeapSize) {
std::fprintf(stderr, "out of kernel memory");
std::abort();
}
// Check overflow
if (heap + size < heap) {
std::fprintf(stderr, "too big allocation");
std::abort();
}
// std::fprintf(stderr, "kalloc: allocate %lx-%lx, size = %lx, align=%lx\n",
// heap, heap + size, size, align);
auto result = reinterpret_cast<void *>(heap);
if (kDebugHeap > 0) {
std::memcpy(std::bit_cast<std::byte *>(result) + size, &g_allocProtWord,
sizeof(g_allocProtWord));
}
if (kDebugHeap > 0) {
m_heap_next =
reinterpret_cast<void *>(heap + size + sizeof(g_allocProtWord));
} else {
m_heap_next = reinterpret_cast<void *>(heap + size);
}
if (kDebugHeap > 1) {
heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
align = std::min<std::size_t>(align, 4096);
heap = (heap + (align - 1)) & ~(align - 1);
size = 4096;
// std::fprintf(stderr, "kalloc: protect %lx-%lx, size = %lx, align=%lx\n",
// heap, heap + size, size, align);
auto result = ::mmap(reinterpret_cast<void *>(heap), size, PROT_NONE,
MAP_FIXED | MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (result == MAP_FAILED) {
std::fprintf(stderr, "failed to protect memory");
std::abort();
}
m_heap_next = reinterpret_cast<void *>(heap + size);
}
return result;
}
void KernelContext::kfree(void *ptr, std::size_t size) {
size = (size + (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1)) &
~(__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1);
if (!size)
std::abort();
if (std::bit_cast<std::uintptr_t>(ptr) < kHeapBaseAddress ||
std::bit_cast<std::uintptr_t>(ptr) + size >
kHeapBaseAddress + kHeapSize) {
std::fprintf(stderr, "kfree: invalid address");
std::abort();
}
if (kDebugHeap > 0) {
if (std::memcmp(std::bit_cast<std::byte *>(ptr) + size, &g_allocProtWord,
sizeof(g_allocProtWord)) != 0) {
std::fprintf(stderr, "kernel heap corruption\n");
std::abort();
}
std::memset(ptr, 0xcc, size + sizeof(g_allocProtWord));
}
// std::fprintf(stderr, "kfree: release %p-%p, size = %lx\n", ptr,
// (char *)ptr + size, size);
std::lock_guard lock(m_heap_map_mtx);
if (!m_used_node.empty()) {
auto node = m_used_node.extract(m_used_node.begin());
node.key() = size;
node.mapped() = ptr;
m_free_heap.insert(std::move(node));
} else {
m_free_heap.emplace(size, ptr);
}
}
inline namespace utils {
void kfree(void *ptr, std::size_t size) { return g_context.kfree(ptr, size); }
void *kalloc(std::size_t size, std::size_t align) {
return g_context.kalloc(size, align);
}
} // namespace utils
inline namespace logs {
template <>
void log_class_string<kstring>::format(std::string &out, const void *arg) {

View file

@ -30,7 +30,7 @@ orbis::ErrorCode orbis::ipmiCreateServer(Process *proc, void *serverImpl,
const char *name,
const IpmiCreateServerConfig &config,
rx::Ref<IpmiServer> &result) {
auto [server, errorCode] = g_context.createIpmiServer(name);
auto [server, errorCode] = g_context->createIpmiServer(name);
ORBIS_RET_ON_ERROR(errorCode);
server->serverImpl = serverImpl;
@ -44,9 +44,9 @@ orbis::ErrorCode orbis::ipmiCreateServer(Process *proc, void *serverImpl,
orbis::ErrorCode orbis::ipmiCreateSession(Thread *thread, void *sessionImpl,
ptr<void> userData,
rx::Ref<IpmiSession> &result) {
std::unique_lock ipmiMapLock(g_context.ipmiMap.mutex);
std::unique_lock ipmiMapLock(g_context->ipmiMap.mutex);
for (auto [kid, obj] : g_context.ipmiMap) {
for (auto [kid, obj] : g_context->ipmiMap) {
auto server = dynamic_cast<IpmiServer *>(obj);
if (server == nullptr) {
continue;
@ -104,7 +104,7 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr<uint> result,
ORBIS_RET_ON_ERROR(ipmiCreateClient(thread->tproc, _params.clientImpl, _name,
_config, client));
auto kid = g_context.ipmiMap.insert(std::move(client));
auto kid = g_context->ipmiMap.insert(std::move(client));
if (kid == -1) {
return ErrorCode::MFILE;
@ -139,7 +139,7 @@ orbis::SysResult orbis::sysIpmiCreateServer(Thread *thread, ptr<uint> result,
ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), _params.name));
ORBIS_RET_ON_ERROR(ipmiCreateServer(thread->tproc, _params.serverImpl, _name,
_config, server));
auto kid = g_context.ipmiMap.insert(std::move(server));
auto kid = g_context->ipmiMap.insert(std::move(server));
if (kid == -1) {
return ErrorCode::MFILE;
@ -184,7 +184,7 @@ orbis::SysResult orbis::sysIpmiCreateSession(Thread *thread, ptr<uint> result,
ORBIS_RET_ON_ERROR(
ipmiCreateSession(thread, _params.sessionImpl, _userData.data, session));
auto kid = g_context.ipmiMap.insert(std::move(session));
auto kid = g_context->ipmiMap.insert(std::move(session));
if (kid == -1) {
return ErrorCode::MFILE;
@ -233,7 +233,7 @@ orbis::SysResult orbis::sysIpmiServerReceivePacket(Thread *thread,
ORBIS_RET_ON_ERROR(
uread(_params, ptr<IpmiServerReceivePacketParams>(params)));
auto server = g_context.ipmiMap.get(kid).cast<IpmiServer>();
auto server = g_context->ipmiMap.get(kid).cast<IpmiServer>();
if (server == nullptr) {
return ErrorCode::INVAL;
@ -301,7 +301,7 @@ orbis::SysResult orbis::sysIpmiSendConnectResult(Thread *thread,
ORBIS_LOG_NOTICE(__FUNCTION__, kid);
auto ipmiObject = g_context.ipmiMap.get(kid);
auto ipmiObject = g_context->ipmiMap.get(kid);
if (ipmiObject == nullptr) {
return ErrorCode::INVAL;
}
@ -352,7 +352,7 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -422,7 +422,7 @@ orbis::SysResult orbis::sysIpmiClientInvokeAsyncMethod(Thread *thread,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -513,7 +513,7 @@ orbis::SysResult orbis::sysImpiSessionRespondAsync(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -572,7 +572,7 @@ orbis::SysResult orbis::sysIpmiClientTryGetResult(Thread *thread,
IpmiTryGetResultParams _params;
ORBIS_RET_ON_ERROR(uread(_params, (ptr<IpmiTryGetResultParams>)params));
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -649,7 +649,7 @@ orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -750,7 +750,7 @@ orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -804,7 +804,7 @@ orbis::SysResult orbis::sysIpmiSessionTrySendMessage(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -847,7 +847,7 @@ orbis::SysResult orbis::sysIpmiClientDisconnect(Thread *thread,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -873,7 +873,7 @@ orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -900,7 +900,7 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -1040,7 +1040,7 @@ orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr<uint> result,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -1053,7 +1053,7 @@ orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr<uint> result,
IpmiClientConnectParams _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiClientConnectParams>(params)));
auto server = g_context.findIpmiServer(client->name);
auto server = g_context->findIpmiServer(client->name);
if (server == nullptr) {
return SysResult::notAnError(ErrorCode::NOENT);
@ -1173,7 +1173,7 @@ orbis::SysResult orbis::sysIpmiSessionGetClientAppId(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -1198,7 +1198,7 @@ orbis::SysResult orbis::sysIpmiSessionGetUserData(Thread *thread,
return ErrorCode::INVAL;
}
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;
@ -1221,7 +1221,7 @@ orbis::SysResult orbis::sysIpmiServerGetName(Thread *thread, ptr<uint> result,
return ErrorCode::INVAL;
}
auto server = g_context.ipmiMap.get(kid).cast<IpmiServer>();
auto server = g_context->ipmiMap.get(kid).cast<IpmiServer>();
if (server == nullptr) {
return ErrorCode::INVAL;
@ -1246,7 +1246,7 @@ orbis::SysResult orbis::sysIpmiClientGetName(Thread *thread, ptr<uint> result,
return ErrorCode::INVAL;
}
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -1283,7 +1283,7 @@ orbis::SysResult orbis::sysIpmiClientWaitEventFlag(Thread *thread,
IpmiWaitEventFlagParam _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiWaitEventFlagParam>(params)));
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -1344,7 +1344,7 @@ orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread,
IpmiPollEventFlagParam _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiPollEventFlagParam>(params)));
auto client = g_context.ipmiMap.get(kid).cast<IpmiClient>();
auto client = g_context->ipmiMap.get(kid).cast<IpmiClient>();
if (client == nullptr) {
return ErrorCode::INVAL;
@ -1384,7 +1384,7 @@ orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread,
IpmiSetEventFlagParam _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiSetEventFlagParam>(params)));
auto session = g_context.ipmiMap.get(kid).cast<IpmiSession>();
auto session = g_context->ipmiMap.get(kid).cast<IpmiSession>();
if (session == nullptr) {
return ErrorCode::INVAL;

View file

@ -97,7 +97,7 @@ orbis::SysResult orbis::sys_cpuset_getaffinity(Thread *thread, cpulevel_t level,
if (id == ~id_t(0) || id == thread->tproc->pid) {
whichProcess = thread->tproc;
} else {
whichProcess = g_context.findProcessById(id);
whichProcess = g_context->findProcessById(id);
if (whichProcess == nullptr) {
return ErrorCode::SRCH;
@ -163,7 +163,7 @@ orbis::SysResult orbis::sys_cpuset_setaffinity(Thread *thread, cpulevel_t level,
} else {
ORBIS_LOG_ERROR(__FUNCTION__, "process not found", level, which, id,
cpusetsize);
whichProcess = g_context.findProcessById(id);
whichProcess = g_context->findProcessById(id);
if (whichProcess == nullptr) {
return ErrorCode::SRCH;

View file

@ -89,7 +89,7 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
nodeIt = kq->notes.begin();
if (change.filter == kEvFiltProc) {
auto process = g_context.findProcessById(change.ident);
auto process = g_context->findProcessById(change.ident);
if (process == nullptr) {
return ErrorCode::SRCH;
}
@ -124,7 +124,7 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
}
} else if (change.filter == kEvFiltGraphicsCore ||
change.filter == kEvFiltDisplay) {
g_context.deviceEventEmitter->subscribe(&*nodeIt);
g_context->deviceEventEmitter->subscribe(&*nodeIt);
}
}
}
@ -185,7 +185,7 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
nodeIt->event.data |= 1000ull << 16; // clock
kq->cv.notify_all(kq->mtx);
} else if (g_context.fwType == FwType::Ps5 &&
} else if (g_context->fwType == FwType::Ps5 &&
change.filter == kEvFiltGraphicsCore && change.ident == 0) {
nodeIt->triggered = true;
kq->cv.notify_all(kq->mtx);

View file

@ -25,7 +25,7 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
int hostPid = pid;
if (pid > 0) {
auto process = g_context.findProcessById(pid);
auto process = g_context->findProcessById(pid);
if (process == nullptr) {
return ErrorCode::SRCH;
}
@ -42,7 +42,7 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
auto process = g_context.findProcessByHostId(result);
auto process = g_context->findProcessByHostId(result);
if (process == nullptr) {
ORBIS_LOG_ERROR("host process not found", result);
continue;

View file

@ -80,7 +80,7 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
// ORBIS_LOG_ERROR(__FUNCTION__, op, id, len);
// thread->where();
std::lock_guard lock(orbis::g_context.regMgrMtx);
std::lock_guard lock(orbis::g_context->regMgrMtx);
if (op == 1) {
// set int
@ -89,7 +89,7 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
}
ORBIS_LOG_ERROR(__FUNCTION__, op, id, *(std::uint32_t *)value);
g_context.regMgrInt[id] = *(std::uint32_t *)value;
g_context->regMgrInt[id] = *(std::uint32_t *)value;
return {};
}
if (op == 2) {
@ -98,8 +98,8 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
return ErrorCode::INVAL;
}
auto intValIt = g_context.regMgrInt.find(id);
if (intValIt == g_context.regMgrInt.end()) {
auto intValIt = g_context->regMgrInt.find(id);
if (intValIt == g_context->regMgrInt.end()) {
ORBIS_LOG_ERROR("registry int entry not exists", op, id, len);
thread->where();
// return ErrorCode::NOENT;
@ -774,7 +774,7 @@ orbis::SysResult orbis::sys_budget_create(Thread *thread, ptr<char> name,
BudgetInfo _resources[kMaxBudgets];
ORBIS_RET_ON_ERROR(uread(_resources, resources, count));
auto processTypeBudget = g_context.getProcessTypeBudget(processType);
auto processTypeBudget = g_context->getProcessTypeBudget(processType);
int invalidResourceCount = 0;
for (auto &resource : std::span(_resources, count)) {
@ -804,7 +804,7 @@ orbis::SysResult orbis::sys_budget_create(Thread *thread, ptr<char> name,
rx::Ref budget =
orbis::knew<Budget>(_name, processType, std::span(_resources, count));
auto id = g_context.budgets.insert(budget);
auto id = g_context->budgets.insert(budget);
thread->retval[0] = id;
return {};
}
@ -845,9 +845,9 @@ orbis::SysResult orbis::sys_budget_get(Thread *thread, sint id,
}
budget =
g_context.getProcessTypeBudget(static_cast<Budget::ProcessType>(id));
g_context->getProcessTypeBudget(static_cast<Budget::ProcessType>(id));
} else {
budget = g_context.budgets.get(id);
budget = g_context->budgets.get(id);
if (!budget) {
return ErrorCode::SRCH;
@ -873,7 +873,7 @@ orbis::SysResult orbis::sys_budget_set(Thread *thread, sint budgetId) {
return ErrorCode::NOSYS;
}
auto budget = g_context.budgets.get(budgetId);
auto budget = g_context->budgets.get(budgetId);
if (!budget) {
return ErrorCode::SRCH;
}
@ -940,7 +940,7 @@ orbis::SysResult orbis::sys_dmem_container(Thread *thread, uint id) {
orbis::SysResult orbis::sys_get_authinfo(Thread *thread, pid_t pid,
ptr<AuthInfo> info) {
auto process = pid > 0 ? g_context.findProcessById(pid) : thread->tproc;
auto process = pid > 0 ? g_context->findProcessById(pid) : thread->tproc;
if (process == nullptr) {
return ErrorCode::SRCH;
}
@ -1188,7 +1188,7 @@ orbis::SysResult orbis::sys_randomized_path(Thread *thread, sint type,
}
orbis::SysResult orbis::sys_rdup(Thread *thread, sint pid, sint fd) {
ORBIS_LOG_TODO(__FUNCTION__, pid, fd);
for (auto it = g_context.getProcessList(); it != nullptr; it = it->next) {
for (auto it = g_context->getProcessList(); it != nullptr; it = it->next) {
auto &p = it->object;
if (p.pid != pid) {
continue;
@ -1297,7 +1297,7 @@ orbis::SysResult orbis::sys_budget_get_ptype(Thread *thread, sint pid) {
if (pid < 0 || pid == thread->tproc->pid) {
process = thread->tproc;
} else {
process = g_context.findProcessById(pid);
process = g_context->findProcessById(pid);
if (!process) {
return ErrorCode::SRCH;
@ -1344,7 +1344,7 @@ orbis::SysResult orbis::sys_thr_get_name(Thread *thread, lwpid_t lwpid,
searchThread = thread->tproc->threadsMap.get(lwpid - thread->tproc->pid);
if (searchThread == nullptr) {
if (auto process = g_context.findProcessById(lwpid)) {
if (auto process = g_context->findProcessById(lwpid)) {
searchThread = process->threadsMap.get(lwpid - process->pid);
}
}
@ -1446,7 +1446,7 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
return sysIpmiSessionSetEventFlag(thread, result, kid, params, paramsSz);
}
if (auto ipmi = g_context.ipmiMap.get(kid)) {
if (auto ipmi = g_context->ipmiMap.get(kid)) {
if (auto client = ipmi.cast<IpmiClient>()) {
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, client->name, result,
params, paramsSz);
@ -1652,7 +1652,7 @@ orbis::sys_get_kernel_mem_statistics(Thread *thread /* TODO */) {
orbis::SysResult orbis::sys_get_sdk_compiled_version(Thread *thread,
ptr<const char> path) {
ORBIS_LOG_ERROR(__FUNCTION__, path);
thread->retval[0] = g_context.sdkVersion;
thread->retval[0] = g_context->sdkVersion;
return {};
}
orbis::SysResult orbis::sys_app_state_change(Thread *thread, sint state) {
@ -1680,7 +1680,7 @@ orbis::SysResult orbis::sys_budget_get_ptype_of_budget(Thread *thread,
return ErrorCode::NOSYS;
}
rx::Ref<Budget> budget = g_context.budgets.get(budgetId);
rx::Ref<Budget> budget = g_context->budgets.get(budgetId);
if (!budget) {
return ErrorCode::SRCH;
@ -1877,10 +1877,10 @@ orbis::SysResult orbis::sys_begin_app_mount(Thread *thread,
rx::Ref appInfo = orbis::knew<RcAppInfo>();
AppInfoEx *appInfoData = appInfo.get();
auto handle = g_context.appInfos.insert(appInfo);
auto handle = g_context->appInfos.insert(appInfo);
ORBIS_LOG_TODO(__FUNCTION__, handle);
thread->where();
if (handle == decltype(g_context.appInfos)::npos) {
if (handle == decltype(g_context->appInfos)::npos) {
return ErrorCode::DOOFUS;
}

View file

@ -114,7 +114,7 @@ orbis::SysResult orbis::sys_kill(Thread *thread, sint pid, sint signum) {
int hostPid = pid;
if (pid > 0) {
auto process = g_context.findProcessById(pid);
auto process = g_context->findProcessById(pid);
if (process == nullptr) {
return ErrorCode::SRCH;
}

View file

@ -92,7 +92,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
// 4.17.0.0.3.0
if (name[0] == net && name[1] == 17 && name[2] == 0 && name[3] == 0 &&
name[4] == 3 && name[5] == 0) {
if (g_context.fwSdkVersion == 0) {
if (g_context->fwSdkVersion == 0) {
// proto fw
return {};
}
@ -197,7 +197,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
return ErrorCode::INVAL;
}
auto budget = g_context.budgets.get(thread->tproc->budgetId);
auto budget = g_context->budgets.get(thread->tproc->budgetId);
auto fmem = budget->get(BudgetResource::Fmem);
*(uint64_t *)old = fmem.total;
return {};
@ -208,7 +208,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
return ErrorCode::INVAL;
}
auto budget = g_context.budgets.get(thread->tproc->budgetId);
auto budget = g_context->budgets.get(thread->tproc->budgetId);
auto fmem = budget->get(BudgetResource::Fmem);
auto result = (uint64_t *)old;
@ -225,7 +225,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
ORBIS_LOG_ERROR("KERN_PROC_PROC 2");
if (namelen >= 4) {
auto process = g_context.findProcessById(name[3]);
auto process = g_context->findProcessById(name[3]);
if (process == nullptr || process->exitStatus.has_value()) {
return ErrorCode::SRCH;
}
@ -245,7 +245,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
}
if (name[0] == kern && name[1] == proc && name[2] == 55) {
if (g_context.fwType != FwType::Ps5) {
if (g_context->fwType != FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -259,7 +259,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
if (name[0] == kern && name[1] == proc && name[2] == 36) {
Process *process = thread->tproc;
if (process->pid != name[3]) {
process = g_context.findProcessById(name[3]);
process = g_context->findProcessById(name[3]);
if (process == nullptr) {
ORBIS_LOG_ERROR("get sdk version by pid: process not found", name[3],
thread->tproc->pid);
@ -276,7 +276,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
auto sdkVersion = process->sdkVersion;
if (sdkVersion == 0) {
sdkVersion = g_context.fwSdkVersion;
sdkVersion = g_context->fwSdkVersion;
}
ORBIS_RET_ON_ERROR(uwrite(ptr<uint32_t>(old), sdkVersion));
@ -290,7 +290,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
// 1 - 14 - 35 - pid
Process *process = thread->tproc;
if (process->pid != name[3] && name[3] != -1) {
process = g_context.findProcessById(name[3]);
process = g_context->findProcessById(name[3]);
if (process == nullptr) {
ORBIS_LOG_ERROR("appinfo process not found", name[3],
thread->tproc->pid);
@ -384,7 +384,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
}
if (name[0] == kern && name[1] == proc && name[2] == 64) {
auto appInfo = g_context.appInfos.get(name[3]);
auto appInfo = g_context->appInfos.get(name[3]);
if (appInfo == nullptr) {
return ErrorCode::SRCH; // ?
}
@ -418,7 +418,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
if (name[0] == 1 && name[1] == proc && name[2] == 65) {
// AppInfo by appId get/set
// 1 - 14 - 65 - appId
auto appInfo = g_context.appInfos.get(name[3]);
auto appInfo = g_context->appInfos.get(name[3]);
if (appInfo == nullptr) {
ORBIS_LOG_ERROR("appinfo appId not found", name[3], thread->tproc->pid);
return ErrorCode::SRCH;
@ -461,7 +461,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
if (name[0] == kern && name[1] == proc && name[2] == 68) {
Process *process = thread->tproc;
if (process->pid != name[3]) {
process = g_context.findProcessById(name[3]);
process = g_context->findProcessById(name[3]);
if (process == nullptr) {
ORBIS_LOG_ERROR("get ps5 sdk version by pid: process not found",
name[3], thread->tproc->pid);
@ -478,7 +478,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
auto sdkVersion = process->sdkVersion;
if (sdkVersion == 0) {
sdkVersion = g_context.fwSdkVersion;
sdkVersion = g_context->fwSdkVersion;
}
ORBIS_RET_ON_ERROR(uwrite(ptr<uint32_t>(old), sdkVersion));
@ -699,7 +699,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
dest[count++] = budgets;
dest[count++] = mlock_avail;
} else if (searchName == "hw.sce_main_socid") {
if (g_context.fwType != FwType::Ps5) {
if (g_context->fwType != FwType::Ps5) {
return ErrorCode::INVAL;
}
@ -844,7 +844,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
return ErrorCode::INVAL;
}
*(std::uint32_t *)old = g_context.safeMode;
*(std::uint32_t *)old = g_context->safeMode;
}
if (new_ != nullptr && newlen == 4) {
ORBIS_LOG_ERROR("sysctl: set kern.init_safe_mode",
@ -902,7 +902,7 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
return {};
case sysctl_hw::sce_main_socid:
if (g_context.fwType != FwType::Ps5) {
if (g_context->fwType != FwType::Ps5) {
return ErrorCode::INVAL;
}
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
@ -933,13 +933,13 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
return ErrorCode::INVAL;
}
if (g_context.fwType != FwType::Ps5 &&
if (g_context->fwType != FwType::Ps5 &&
std::string_view((char *)thread->tproc->appInfo.titleId) ==
"NPXS20973") {
ORBIS_LOG_ERROR("get tsc freq: returning patched value");
*(uint64_t *)old = 1000000;
} else {
*(uint64_t *)old = g_context.getTscFreq();
*(uint64_t *)old = g_context->getTscFreq();
}
return {};
}

View file

@ -1,5 +1,5 @@
#include "orbis/umtx.hpp"
#include "GlobalKernelObject.hpp"
#include "KernelObject.hpp"
#include "error.hpp"
#include "orbis-config.hpp"
#include "orbis/thread.hpp"
@ -25,7 +25,7 @@ struct UmtxCond {
struct UmtxChain {
rx::shared_mutex mtx;
using queue_type = utils::kmultimap<UmtxKey, UmtxCond>;
using queue_type = kmultimap<UmtxKey, UmtxCond>;
queue_type sleep_queue;
queue_type spare_queue;

View file

@ -32,7 +32,7 @@ enum class MessageId {
};
static void runGPU() {
if (g_gpuPid != 0 || orbis::g_context.gpuDevice != nullptr) {
if (g_gpuPid != 0 || orbis::g_context->gpuDevice != nullptr) {
return;
}
@ -54,8 +54,8 @@ static void runGPU() {
amdgpu::DeviceCtl gpu;
{
pthread_setname_np(pthread_self(), "rpcsx-gpu");
std::lock_guard lock(orbis::g_context.gpuDeviceMtx);
if (orbis::g_context.gpuDevice != nullptr) {
std::lock_guard lock(orbis::g_context->gpuDeviceMtx);
if (orbis::g_context->gpuDevice != nullptr) {
std::exit(0);
}
@ -66,7 +66,7 @@ static void runGPU() {
::close(logFd);
gpu = amdgpu::DeviceCtl::createDevice();
orbis::g_context.gpuDevice = gpu.getOpaque();
orbis::g_context->gpuDevice = gpu.getOpaque();
}
gpu.start();

View file

@ -344,7 +344,7 @@ void Device::start() {
}
std::jthread vblankThread([](const std::stop_token &stopToken) {
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltDisplay,
[=](orbis::KNote *note) -> std::optional<orbis::intptr_t> {
if (DisplayEvent(note->event.ident >> 48) ==
@ -362,7 +362,7 @@ void Device::start() {
std::chrono::duration_cast<std::chrono::nanoseconds>(period);
std::this_thread::sleep_until(prevVBlank);
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltDisplay,
[=](orbis::KNote *note) -> std::optional<orbis::intptr_t> {
if (DisplayEvent(note->event.ident >> 48) == DisplayEvent::VBlank) {
@ -941,7 +941,7 @@ void Device::flip(std::uint32_t pid, int bufferIndex, std::uint64_t arg) {
flip(pid, bufferIndex, arg, vk::context->swapchainImages[imageIndex],
vk::context->swapchainImageViews[imageIndex]);
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltDisplay,
[=](orbis::KNote *note) -> std::optional<orbis::intptr_t> {
if (DisplayEvent(note->event.ident >> 48) == DisplayEvent::Flip) {

View file

@ -345,7 +345,7 @@ bool ComputePipe::releaseMem(Ring &ring) {
}
if (intSel) {
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltGraphicsCore,
[=, this](orbis::KNote *note) -> std::optional<std::int64_t> {
if (note->event.ident == kGcEventCompute0RelMem + index) {
@ -1375,7 +1375,7 @@ bool GraphicsPipe::eventWriteEop(Ring &ring) {
}
if (intSel != 0) {
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltGraphicsCore,
[=](orbis::KNote *note) -> std::optional<std::int64_t> {
if (note->event.ident == kGcEventGfxEop) {

View file

@ -40,7 +40,7 @@ struct HostFile : orbis::File {
};
struct SocketFile : orbis::File {
orbis::utils::kstring name;
orbis::kstring name;
int dom = -1;
int type = -1;
int prot = -1;
@ -846,7 +846,7 @@ orbis::ErrorCode HostFsDevice::open(rx::Ref<orbis::File> *file,
}
// Assume the file is a directory and try to read direntries
orbis::utils::kvector<orbis::Dirent> dirEntries;
orbis::kvector<orbis::Dirent> dirEntries;
char hostEntryBuffer[sizeof(dirent64) * 4];
while (true) {
auto r = getdents64(hostFd, hostEntryBuffer, sizeof(hostEntryBuffer));

View file

@ -31,7 +31,7 @@ static orbis::ErrorCode blockpool_ioctl(orbis::File *file,
ORBIS_LOG_TODO("blockpool expand", args->len, args->searchStart,
args->searchEnd, args->flags);
auto dmem = orbis::g_context.dmemDevice.rawStaticCast<DmemDevice>();
auto dmem = orbis::g_context->dmemDevice.rawStaticCast<DmemDevice>();
std::lock_guard lock(dmem->mtx);
std::uint64_t start = args->searchStart;
ORBIS_RET_ON_ERROR(
@ -64,7 +64,7 @@ static orbis::ErrorCode blockpool_mmap(orbis::File *file, void **address,
return orbis::ErrorCode::NOMEM;
}
auto dmem = orbis::g_context.dmemDevice.rawStaticCast<DmemDevice>();
auto dmem = orbis::g_context->dmemDevice.rawStaticCast<DmemDevice>();
auto mapped = reinterpret_cast<std::byte *>(vm::map(
*address, size, prot, flags, vm::kMapInternalReserveOnly, blockPool));

View file

@ -148,7 +148,7 @@ static void runBridge(int vmId) {
std::thread{[=] {
pthread_setname_np(pthread_self(), "Bridge");
auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice};
auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice};
auto &gpuCtx = gpu.getContext();
std::vector<std::uint64_t> fetchedCommands;
fetchedCommands.reserve(std::size(gpuCtx.cpuCacheCommands));
@ -247,7 +247,7 @@ static void initDceMemory(DceDevice *device) {
return;
}
auto dmem = orbis::g_context.dmemDevice.cast<DmemDevice>();
auto dmem = orbis::g_context->dmemDevice.cast<DmemDevice>();
std::uint64_t start = 0;
if (dmem->allocate(&start, ~0ull, kDceControlMemorySize, 0x100000, 1) !=
orbis::ErrorCode{}) {
@ -278,12 +278,12 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request,
void *argp, orbis::Thread *thread) {
auto device = static_cast<DceDevice *>(file->device.get());
auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice};
auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice};
auto &gpuCtx = gpu.getContext();
// std::this_thread::sleep_for(std::chrono::seconds(5));
if (orbis::g_context.fwType == orbis::FwType::Ps5) {
if (orbis::g_context->fwType == orbis::FwType::Ps5) {
if (request == 0x80308217) {
auto args = reinterpret_cast<FlipControlArgs *>(argp);
@ -489,7 +489,7 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request,
} else if (args->id == 1) {
// Mode set
orbis::g_context.deviceEventEmitter->emit(
orbis::g_context->deviceEventEmitter->emit(
orbis::kEvFiltDisplay,
[](orbis::KNote *note) -> std::optional<orbis::intptr_t> {
if ((note->event.ident >> 48) == 0x64) {
@ -603,7 +603,7 @@ static orbis::ErrorCode dce_mmap(orbis::File *file, void **address,
ORBIS_LOG_FATAL("dce mmap", address, size, offset);
auto dce = file->device.cast<DceDevice>();
initDceMemory(dce.get());
auto dmem = orbis::g_context.dmemDevice.cast<DmemDevice>();
auto dmem = orbis::g_context->dmemDevice.cast<DmemDevice>();
return dmem->mmap(address, size, prot, flags, dce->dmemOffset + offset);
}
@ -614,15 +614,15 @@ static const orbis::FileOps ops = {
static void createGpu() {
{
std::lock_guard lock(orbis::g_context.gpuDeviceMtx);
if (orbis::g_context.gpuDevice != nullptr) {
std::lock_guard lock(orbis::g_context->gpuDeviceMtx);
if (orbis::g_context->gpuDevice != nullptr) {
return;
}
rx::createGpuDevice();
}
while (orbis::g_context.gpuDevice == nullptr) {
while (orbis::g_context->gpuDevice == nullptr) {
}
}
@ -642,9 +642,9 @@ void DceDevice::initializeProcess(orbis::Process *process) {
createGpu();
auto vmId = allocateVmId();
std::lock_guard lock(orbis::g_context.gpuDeviceMtx);
std::lock_guard lock(orbis::g_context->gpuDeviceMtx);
{
auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice};
auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice};
gpu.submitMapProcess(process->pid, vmId);
process->vmId = vmId;
}

View file

@ -73,7 +73,7 @@ orbis::ErrorCode DmemDevice::mmap(void **address, std::uint64_t len,
return orbis::ErrorCode::INVAL;
}
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.submitMapMemory(orbis::g_currentThread->tproc->pid,
reinterpret_cast<std::uint64_t>(result), len,
memoryType, index, prot, directMemoryStart);

View file

@ -56,7 +56,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
switch (request) {
case 0xc008811b: // get submit done flag ptr?
if (device->submitArea == nullptr) {
auto dmem = orbis::g_context.dmemDevice.staticCast<DmemDevice>();
auto dmem = orbis::g_context->dmemDevice.staticCast<DmemDevice>();
std::uint64_t start = 0;
auto err = dmem->allocate(&start, ~0, vm::kPageSize, 0, 0);
if (err != orbis::ErrorCode{}) {
@ -78,7 +78,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
break;
case 0xc004812e: {
if (orbis::g_context.fwType != orbis::FwType::Ps5) {
if (orbis::g_context->fwType != orbis::FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -94,7 +94,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
}
case 0xc0488131: {
if (orbis::g_context.fwType != orbis::FwType::Ps5) {
if (orbis::g_context->fwType != orbis::FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -123,7 +123,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
// thread->where();
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
if (args->contextControl[0]) {
gpu.submitGfxCommand(gcFile->gfxPipe,
orbis::g_currentThread->tproc->vmId,
@ -155,7 +155,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
}
case 0xc0188132: {
if (orbis::g_context.fwType != orbis::FwType::Ps5) {
if (orbis::g_context->fwType != orbis::FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -186,7 +186,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
// args->submits[i].unk1);
// }
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
for (unsigned i = 0; i < args->count / 2; ++i) {
auto addressLo = static_cast<std::uint32_t>(args->submits[i].address);
auto addressHi =
@ -215,7 +215,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
};
auto args = reinterpret_cast<Args *>(argp);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
for (unsigned i = 0; i < args->count; ++i) {
gpu.submitGfxCommand(gcFile->gfxPipe,
orbis::g_currentThread->tproc->vmId,
@ -236,7 +236,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
};
auto args = reinterpret_cast<Args *>(argp);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.waitForIdle();
gpu.submitSwitchBuffer(orbis::g_currentThread->tproc->gfxRing);
} else {
@ -258,7 +258,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
auto args = reinterpret_cast<Args *>(argp);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
for (unsigned i = 0; i < args->count; ++i) {
gpu.submitGfxCommand(gcFile->gfxPipe,
orbis::g_currentThread->tproc->vmId,
@ -277,7 +277,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
}
case 0xc0048116: { // submit done?
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
// gpu.waitForIdle();
} else {
return orbis::ErrorCode::BUSY;
@ -285,7 +285,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
}
case 0xc0048117:
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.waitForIdle();
} else {
return orbis::ErrorCode::BUSY;
@ -354,7 +354,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
args->queueId, args->vqueueId, args->ringBaseAddress,
args->readPtrAddress, args->doorbell, args->ringSize);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.mapComputeQueue(thread->tproc->vmId, args->meId, args->pipeId,
args->queueId, args->vqueueId, args->ringBaseAddress,
args->readPtrAddress, args->doorbell,
@ -379,7 +379,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
ORBIS_LOG_ERROR("gc ioctl ding dong for workload", args->meId, args->pipeId,
args->queueId, args->nextStartOffsetInDw);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.submitComputeQueue(args->meId, args->pipeId, args->queueId,
args->nextStartOffsetInDw);
gpu.waitForIdle();
@ -471,7 +471,7 @@ orbis::ErrorCode GcDevice::open(rx::Ref<orbis::File> *file, const char *path,
}
void GcDevice::addClient(orbis::Process *process) {
auto dce = orbis::g_context.dceDevice.rawStaticCast<DceDevice>();
auto dce = orbis::g_context->dceDevice.rawStaticCast<DceDevice>();
dce->initializeProcess(process);
std::lock_guard lock(mtx);

View file

@ -35,7 +35,7 @@ static orbis::ErrorCode hid_ioctl(orbis::File *file, std::uint64_t request,
return {};
case 0x8004486e:
if (orbis::g_context.fwType != orbis::FwType::Ps5) {
if (orbis::g_context->fwType != orbis::FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -48,7 +48,7 @@ static orbis::ErrorCode hid_ioctl(orbis::File *file, std::uint64_t request,
return {};
case 0xc0484851: {
if (orbis::g_context.fwType != orbis::FwType::Ps5) {
if (orbis::g_context->fwType != orbis::FwType::Ps5) {
return orbis::ErrorCode::INVAL;
}
@ -78,7 +78,7 @@ static orbis::ErrorCode hid_ioctl(orbis::File *file, std::uint64_t request,
thread->where();
if (args->op == 6) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
*args->result = 1;
*args->status = 1;
@ -106,7 +106,7 @@ static orbis::ErrorCode hid_ioctl(orbis::File *file, std::uint64_t request,
// ORBIS_LOG_ERROR("hid read state", args.hidId, args.unk0, args.state,
// args.unk2, args.connected, args.unk4, args.unk5);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
*args.state = gpu.getContext().kbPadState;
*args.connected = 1;
*args.unk4 = 1; // is wireless?
@ -130,7 +130,7 @@ static orbis::ErrorCode hid_ioctl(orbis::File *file, std::uint64_t request,
orbis::uint padding;
orbis::ptr<orbis::uint> unk5;
};
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
auto args = *reinterpret_cast<MiniReadStateArgs *>(argp);
*args.state = gpu.getContext().kbPadState;
thread->retval[0] = 1;

View file

@ -162,7 +162,7 @@ orbis::Semaphore *ipmi::createSemaphore(std::string_view name, uint32_t attrs,
uint64_t initCount, uint64_t maxCount) {
auto result =
orbis::g_context
.createSemaphore(orbis::kstring(name), attrs, initCount, maxCount)
->createSemaphore(orbis::kstring(name), attrs, initCount, maxCount)
.first;
std::memcpy(result->name, name.data(), name.size());
result->name[name.size()] = 0;
@ -172,14 +172,14 @@ orbis::Semaphore *ipmi::createSemaphore(std::string_view name, uint32_t attrs,
orbis::EventFlag *ipmi::createEventFlag(std::string_view name, uint32_t attrs,
uint64_t initPattern) {
return orbis::g_context
.createEventFlag(orbis::kstring(name), attrs, initPattern)
->createEventFlag(orbis::kstring(name), attrs, initPattern)
.first;
}
void ipmi::createShm(const char *name, uint32_t flags, uint32_t mode,
uint64_t size) {
rx::Ref<orbis::File> shm;
auto shmDevice = orbis::g_context.shmDevice.staticCast<IoDevice>();
auto shmDevice = orbis::g_context->shmDevice.staticCast<IoDevice>();
shmDevice->open(&shm, name, flags, mode, nullptr);
shm->ops->truncate(shm.get(), size, nullptr);
}
@ -357,11 +357,11 @@ ipmi::IpmiServer &ipmi::createIpmiServer(orbis::Process *process,
if ((packet.info.type & ~0x8010) == 0x41) {
auto msgHeader = std::bit_cast<orbis::IpmiSyncMessageHeader *>(
packet.message.data());
auto process = orbis::g_context.findProcessById(msgHeader->pid);
auto process = orbis::g_context->findProcessById(msgHeader->pid);
if (process == nullptr) {
continue;
}
auto client = orbis::g_context.ipmiMap.get(packet.info.clientKid)
auto client = orbis::g_context->ipmiMap.get(packet.info.clientKid)
.cast<orbis::IpmiClient>();
if (client == nullptr) {
continue;
@ -378,11 +378,11 @@ ipmi::IpmiServer &ipmi::createIpmiServer(orbis::Process *process,
if ((packet.info.type & ~0x10) == 0x43) {
auto msgHeader = (orbis::IpmiAsyncMessageHeader *)packet.message.data();
auto process = orbis::g_context.findProcessById(msgHeader->pid);
auto process = orbis::g_context->findProcessById(msgHeader->pid);
if (process == nullptr) {
continue;
}
auto client = orbis::g_context.ipmiMap.get(packet.info.clientKid)
auto client = orbis::g_context->ipmiMap.get(packet.info.clientKid)
.cast<orbis::IpmiClient>();
if (client == nullptr) {
continue;
@ -448,7 +448,7 @@ void ipmi::createAudioSystemObjects(orbis::Process *process) {
std::snprintf(buffer, sizeof(buffer), "sceAudioOutMix%x",
args.threadId);
auto [eventFlag, inserted] =
orbis::g_context.createEventFlag(buffer, 0x100, 0);
orbis::g_context->createEventFlag(buffer, 0x100, 0);
if (!inserted) {
return 17; // FIXME: verify
@ -571,10 +571,10 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
createIpmiServer(process, "SceLoginMgrServer");
int lnsStatusServer;
if (orbis::g_context.fwType == orbis::FwType::Ps5) {
if (orbis::g_context->fwType == orbis::FwType::Ps5) {
lnsStatusServer = 0x30010;
} else {
if (orbis::g_context.fwSdkVersion > 0x6000000) {
if (orbis::g_context->fwSdkVersion > 0x6000000) {
lnsStatusServer = 0x30013;
} else {
lnsStatusServer = 0x30010;
@ -603,12 +603,12 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
return 0;
})
.addSyncMethodStub(
orbis::g_context.fwSdkVersion > 0x6000000 ? 0x30033 : 0x3002e,
orbis::g_context->fwSdkVersion > 0x6000000 ? 0x30033 : 0x3002e,
[]() -> std::int32_t {
auto commonDialog = std::get<0>(orbis::g_context.dialogs.front());
auto commonDialog = std::get<0>(orbis::g_context->dialogs.front());
auto currentDialogId =
*reinterpret_cast<std::int16_t *>(commonDialog + 4);
auto currentDialog = std::get<0>(orbis::g_context.dialogs.back());
auto currentDialog = std::get<0>(orbis::g_context->dialogs.back());
if (currentDialogId == 5) {
std::int32_t titleSize = 8192;
std::int32_t buttonNameSize = 64;
@ -640,7 +640,7 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
return 0;
})
.addSyncMethod(
orbis::g_context.fwSdkVersion > 0x6000000 ? 0x30044 : 0x3003f,
orbis::g_context->fwSdkVersion > 0x6000000 ? 0x30044 : 0x3003f,
[=](std::vector<std::vector<std::byte>>,
const std::vector<std::span<std::byte>> &inData) -> std::int32_t {
struct InitDialogArgs {
@ -673,23 +673,23 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
perror("mmap");
std::abort();
}
orbis::g_context.dialogs.emplace_back(shmAddress,
controlStat.st_size);
orbis::g_context->dialogs.emplace_back(shmAddress,
controlStat.st_size);
return 0;
})
.addSyncMethod(
orbis::g_context.fwSdkVersion > 0x6000000 ? 0x30045 : 0x30040,
orbis::g_context->fwSdkVersion > 0x6000000 ? 0x30045 : 0x30040,
[=](std::vector<std::vector<std::byte>>,
const std::vector<std::span<std::byte>> &inData) -> std::int32_t {
if (!orbis::g_context.dialogs.empty()) {
if (!orbis::g_context->dialogs.empty()) {
auto currentDialogAddr =
std::get<0>(orbis::g_context.dialogs.back());
std::get<0>(orbis::g_context->dialogs.back());
auto currentDialogSize =
std::get<1>(orbis::g_context.dialogs.back());
std::get<1>(orbis::g_context->dialogs.back());
ORBIS_LOG_TODO("Unmap shm after unlinking", currentDialogAddr,
currentDialogSize);
rx::mem::unmap(currentDialogAddr, currentDialogSize);
orbis::g_context.dialogs.pop_back();
orbis::g_context->dialogs.pop_back();
}
return 0;
});
@ -706,7 +706,7 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
}
std::strncpy((char *)out, result.data(), result.size() + 1);
size = result.size() + 1;
orbis::g_context.createEventFlag(orbis::kstring(result), 0x200, 0);
orbis::g_context->createEventFlag(orbis::kstring(result), 0x200, 0);
return 0;
})
.addSyncMethodStub(0xd);
@ -977,8 +977,8 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
std::strncpy((char *)outData[0].data(), result.data(),
result.size() + 1);
outData[0].resize(result.size() + 1);
orbis::g_context.createEventFlag(orbis::kstring(result), 0x200,
0);
orbis::g_context->createEventFlag(orbis::kstring(result), 0x200,
0);
outData[1] = toBytes<orbis::uint64_t>(0);
return 0;

View file

@ -26,8 +26,10 @@
#include <elf.h>
#include <linux/prctl.h>
#include <orbis/GlobalKernelObject.hpp>
#include <orbis/KernelAllocator.hpp>
#include <orbis/KernelContext.hpp>
#include <orbis/KernelObject.hpp>
#include <orbis/module.hpp>
#include <orbis/module/Module.hpp>
#include <orbis/sys/sysentry.hpp>
@ -80,7 +82,7 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
prot |= PROT_EXEC;
}
auto gpuDevice = amdgpu::DeviceCtl{orbis::g_context.gpuDevice};
auto gpuDevice = amdgpu::DeviceCtl{orbis::g_context->gpuDevice};
if (gpuDevice && (prot & (isWrite ? PROT_WRITE : PROT_READ)) != 0) {
auto &gpuContext = gpuDevice.getContext();
@ -357,10 +359,10 @@ static void onSysExit(orbis::Thread *thread, int id, uint64_t *args,
static void guestInitDev() {
auto dmem1 = createDmemCharacterDevice(1);
orbis::g_context.dmemDevice = dmem1;
orbis::g_context->dmemDevice = dmem1;
auto dce = createDceCharacterDevice();
orbis::g_context.dceDevice = dce;
orbis::g_context->dceDevice = dce;
auto ttyFd = ::open("tty.txt", O_CREAT | O_TRUNC | O_WRONLY, 0666);
auto consoleDev = createConsoleCharacterDevice(STDIN_FILENO, ttyFd);
@ -464,7 +466,7 @@ static void guestInitDev() {
vfs::addDevice("cayman/reg", createCaymanRegCharacterDevice());
vfs::addDevice("hctrl", createHidCharacterDevice());
if (orbis::g_context.fwType == orbis::FwType::Ps5) {
if (orbis::g_context->fwType == orbis::FwType::Ps5) {
vfs::addDevice("iccnvs4", createIccPowerCharacterDevice());
vfs::addDevice("ajmi", createAjmCharacterDevice());
vfs::addDevice("ssd0", createHddCharacterDevice(0x100000000));
@ -515,8 +517,8 @@ static void guestInitDev() {
});
auto shm = createShmDevice();
orbis::g_context.shmDevice = shm;
orbis::g_context.blockpoolDevice = createBlockPoolDevice();
orbis::g_context->shmDevice = shm;
orbis::g_context->blockpoolDevice = createBlockPoolDevice();
}
static void guestInitFd(orbis::Thread *mainThread) {
@ -533,8 +535,8 @@ static void guestInitFd(orbis::Thread *mainThread) {
}
static orbis::Process *createGuestProcess() {
auto pid = orbis::g_context.allocatePid() * 10000 + 1;
return orbis::g_context.createProcess(pid);
auto pid = orbis::g_context->allocatePid() * 10000 + 1;
return orbis::g_context->createProcess(pid);
}
static orbis::Thread *createGuestThread() {
@ -590,7 +592,7 @@ int guestExec(orbis::Thread *mainThread, ExecEnv execEnv,
mainThread->tproc->type = orbis::ProcessType::Ps5;
mainThread->tproc->sysent = &orbis::ps5_sysvec;
} else {
if (orbis::g_context.fwType == orbis::FwType::Ps4) {
if (orbis::g_context->fwType == orbis::FwType::Ps4) {
mainThread->tproc->sysent = &orbis::ps4_sysvec;
} else {
mainThread->tproc->sysent = &orbis::ps5_sysvec;
@ -670,11 +672,11 @@ ExecEnv guestCreateExecEnv(orbis::Thread *mainThread,
mainThread->tproc->sdkVersion = processParam->sdkVersion;
}
if (orbis::g_context.sdkVersion == 0 && mainThread->tproc->sdkVersion != 0) {
orbis::g_context.sdkVersion = mainThread->tproc->sdkVersion;
if (orbis::g_context->sdkVersion == 0 && mainThread->tproc->sdkVersion != 0) {
orbis::g_context->sdkVersion = mainThread->tproc->sdkVersion;
}
if (mainThread->tproc->sdkVersion == 0) {
mainThread->tproc->sdkVersion = orbis::g_context.sdkVersion;
mainThread->tproc->sdkVersion = orbis::g_context->sdkVersion;
}
if (executableModule->dynType == orbis::DynType::None) {
@ -713,7 +715,7 @@ ExecEnv guestCreateExecEnv(orbis::Thread *mainThread,
std::abort();
}
if (orbis::g_context.fwType == orbis::FwType::Ps4) {
if (orbis::g_context->fwType == orbis::FwType::Ps4) {
for (auto sym : libkernel->symbols) {
if (sym.id == 0xd2f4e7e480cc53d0) {
auto address = (uint64_t)libkernel->base + sym.address;
@ -736,20 +738,20 @@ ExecEnv guestCreateExecEnv(orbis::Thread *mainThread,
}
}
if (orbis::g_context.fwSdkVersion == 0) {
if (orbis::g_context->fwSdkVersion == 0) {
auto moduleParam = reinterpret_cast<std::byte *>(libkernel->moduleParam);
auto fwSdkVersion = moduleParam //
+ sizeof(uint64_t) // size
+ sizeof(uint64_t); // magic
orbis::g_context.fwSdkVersion = *(uint32_t *)fwSdkVersion;
std::printf("fw sdk version: %x\n", orbis::g_context.fwSdkVersion);
orbis::g_context->fwSdkVersion = *(uint32_t *)fwSdkVersion;
std::printf("fw sdk version: %x\n", orbis::g_context->fwSdkVersion);
}
if (orbis::g_context.fwType == orbis::FwType::Unknown) {
if (orbis::g_context->fwType == orbis::FwType::Unknown) {
if (libkernel->dynType == orbis::DynType::Ps4) {
orbis::g_context.fwType = orbis::FwType::Ps4;
orbis::g_context->fwType = orbis::FwType::Ps4;
} else {
orbis::g_context.fwType = orbis::FwType::Ps5;
orbis::g_context->fwType = orbis::FwType::Ps5;
}
}
@ -787,7 +789,7 @@ static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path,
std::vector<std::string> argv,
std::vector<std::string> envv,
orbis::AppInfoEx appInfo) {
auto childPid = orbis::g_context.allocatePid() * 10000 + 1;
auto childPid = orbis::g_context->allocatePid() * 10000 + 1;
auto flag = orbis::knew<std::atomic<bool>>();
*flag = false;
@ -803,7 +805,7 @@ static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path,
return {};
}
auto process = orbis::g_context.createProcess(childPid);
auto process = orbis::g_context->createProcess(childPid);
auto logFd = ::open(("log-" + std::to_string(childPid) + ".txt").c_str(),
O_CREAT | O_TRUNC | O_WRONLY, 0666);
@ -918,14 +920,14 @@ int main(int argc, const char *argv[]) {
return 1;
}
orbis::g_context.deviceEventEmitter = orbis::knew<orbis::EventEmitter>();
bool enableAudioIpmi = false;
bool asRoot = false;
bool isSystem = false;
bool isSafeMode = false;
int argIndex = 1;
orbis::initializeAllocator();
while (argIndex < argc) {
if (argv[argIndex] == std::string_view("--mount") ||
argv[argIndex] == std::string_view("-m")) {
@ -1041,9 +1043,10 @@ int main(int argc, const char *argv[]) {
}
setupSigHandlers();
orbis::constructAllGlobals();
orbis::g_context->deviceEventEmitter = orbis::knew<orbis::EventEmitter>();
rx::startWatchdog();
rx::createGpuDevice();
vfs::initialize();
@ -1057,8 +1060,8 @@ int main(int argc, const char *argv[]) {
rx::thread::initialize();
// vm::printHostStats();
orbis::g_context.allocatePid();
auto initProcess = orbis::g_context.createProcess(asRoot ? 1 : 10);
orbis::g_context->allocatePid();
auto initProcess = orbis::g_context->createProcess(asRoot ? 1 : 10);
// pthread_setname_np(pthread_self(), "10.MAINTHREAD");
int status = 0;
@ -1149,20 +1152,20 @@ int main(int argc, const char *argv[]) {
vm::initialize(initProcess->pid);
auto bigAppBudget = orbis::g_context.createProcessTypeBudget(
auto bigAppBudget = orbis::g_context->createProcessTypeBudget(
orbis::Budget::ProcessType::BigApp, "big app budget", bigAppBudgetInfo);
// FIXME: define following budgets
orbis::g_context.createProcessTypeBudget(orbis::Budget::ProcessType::MiniApp,
"mini-app budget", bigAppBudgetInfo);
orbis::g_context.createProcessTypeBudget(orbis::Budget::ProcessType::System,
"system budget", bigAppBudgetInfo);
orbis::g_context.createProcessTypeBudget(
orbis::g_context->createProcessTypeBudget(
orbis::Budget::ProcessType::MiniApp, "mini-app budget", bigAppBudgetInfo);
orbis::g_context->createProcessTypeBudget(orbis::Budget::ProcessType::System,
"system budget", bigAppBudgetInfo);
orbis::g_context->createProcessTypeBudget(
orbis::Budget::ProcessType::NonGameMiniApp, "non-game mini-app budget",
bigAppBudgetInfo);
if (isSystem) {
orbis::g_context.safeMode = isSafeMode ? 1 : 0;
orbis::g_context->safeMode = isSafeMode ? 1 : 0;
initProcess->authInfo = {.unk0 = 0x380000000000000f,
.caps =
{
@ -1209,7 +1212,7 @@ int main(int argc, const char *argv[]) {
};
initProcess->budgetProcessType = orbis::Budget::ProcessType::BigApp;
initProcess->budgetId = orbis::g_context.budgets.insert(bigAppBudget);
initProcess->budgetId = orbis::g_context->budgets.insert(bigAppBudget);
initProcess->isInSandbox = true;
}
@ -1259,55 +1262,53 @@ int main(int argc, const char *argv[]) {
auto execEnv = guestCreateExecEnv(mainThread, executableModule, isSystem);
if (isSystem && executableModule->dynType == orbis::DynType::None) {
orbis::g_context.fwType = orbis::FwType::Ps5;
orbis::g_context->fwType = orbis::FwType::Ps5;
executableModule->dynType = orbis::DynType::Ps5;
}
guestInitDev();
guestInitFd(mainThread);
orbis::constructAllGlobals();
// data transfer mode
// 0 - normal
// 1 - source
// 2 - ?
orbis::g_context.regMgrInt[0x2110000] = 0;
orbis::g_context->regMgrInt[0x2110000] = 0;
orbis::g_context.regMgrInt[0x20b0000] = 1; // prefer X
orbis::g_context.regMgrInt[0x2020000] = 1; // region
orbis::g_context->regMgrInt[0x20b0000] = 1; // prefer X
orbis::g_context->regMgrInt[0x2020000] = 1; // region
// orbis::g_context.regMgrInt[0x2130000] = 0x1601;
orbis::g_context.regMgrInt[0x2130000] = 0;
orbis::g_context.regMgrInt[0x73800200] = 1;
orbis::g_context.regMgrInt[0x73800300] = 0;
orbis::g_context.regMgrInt[0x73800400] = 0;
orbis::g_context.regMgrInt[0x73800500] = 0; // enable log
// orbis::g_context->regMgrInt[0x2130000] = 0x1601;
orbis::g_context->regMgrInt[0x2130000] = 0;
orbis::g_context->regMgrInt[0x73800200] = 1;
orbis::g_context->regMgrInt[0x73800300] = 0;
orbis::g_context->regMgrInt[0x73800400] = 0;
orbis::g_context->regMgrInt[0x73800500] = 0; // enable log
// user settings
orbis::g_context.regMgrInt[0x7800100] = 0;
orbis::g_context.regMgrInt[0x7810100] = 0;
orbis::g_context.regMgrInt[0x7820100] = 0;
orbis::g_context.regMgrInt[0x7830100] = 0;
orbis::g_context.regMgrInt[0x7840100] = 0;
orbis::g_context.regMgrInt[0x7850100] = 0;
orbis::g_context.regMgrInt[0x7860100] = 0;
orbis::g_context.regMgrInt[0x7870100] = 0;
orbis::g_context.regMgrInt[0x7880100] = 0;
orbis::g_context.regMgrInt[0x7890100] = 0;
orbis::g_context.regMgrInt[0x78a0100] = 0;
orbis::g_context.regMgrInt[0x78b0100] = 0;
orbis::g_context.regMgrInt[0x78c0100] = 0;
orbis::g_context.regMgrInt[0x78d0100] = 0;
orbis::g_context.regMgrInt[0x78e0100] = 0;
orbis::g_context.regMgrInt[0x78f0100] = 0;
orbis::g_context->regMgrInt[0x7800100] = 0;
orbis::g_context->regMgrInt[0x7810100] = 0;
orbis::g_context->regMgrInt[0x7820100] = 0;
orbis::g_context->regMgrInt[0x7830100] = 0;
orbis::g_context->regMgrInt[0x7840100] = 0;
orbis::g_context->regMgrInt[0x7850100] = 0;
orbis::g_context->regMgrInt[0x7860100] = 0;
orbis::g_context->regMgrInt[0x7870100] = 0;
orbis::g_context->regMgrInt[0x7880100] = 0;
orbis::g_context->regMgrInt[0x7890100] = 0;
orbis::g_context->regMgrInt[0x78a0100] = 0;
orbis::g_context->regMgrInt[0x78b0100] = 0;
orbis::g_context->regMgrInt[0x78c0100] = 0;
orbis::g_context->regMgrInt[0x78d0100] = 0;
orbis::g_context->regMgrInt[0x78e0100] = 0;
orbis::g_context->regMgrInt[0x78f0100] = 0;
orbis::g_context.regMgrInt[0x2040000] = 0; // do not require initial setup
orbis::g_context.regMgrInt[0x2800600] = 0; // IDU version
orbis::g_context.regMgrInt[0x2860100] = 0; // IDU mode
orbis::g_context.regMgrInt[0x2860300] = 0; // Arcade mode
orbis::g_context.regMgrInt[0x7010000] = 0; // auto login
orbis::g_context.regMgrInt[0x9010000] = 0; // video out color effect
orbis::g_context->regMgrInt[0x2040000] = 0; // do not require initial setup
orbis::g_context->regMgrInt[0x2800600] = 0; // IDU version
orbis::g_context->regMgrInt[0x2860100] = 0; // IDU mode
orbis::g_context->regMgrInt[0x2860300] = 0; // Arcade mode
orbis::g_context->regMgrInt[0x7010000] = 0; // auto login
orbis::g_context->regMgrInt[0x9010000] = 0; // video out color effect
if (!isSystem) {
ipmi::createMiniSysCoreObjects(initProcess);
@ -1342,8 +1343,8 @@ int main(int argc, const char *argv[]) {
}});
// confirmed to work and known method of initialization since 5.05
// version
if (orbis::g_context.fwType != orbis::FwType::Ps5 &&
orbis::g_context.fwSdkVersion >= 0x5050000) {
if (orbis::g_context->fwType != orbis::FwType::Ps5 &&
orbis::g_context->fwSdkVersion >= 0x5050000) {
auto fakeIpmiThread = createGuestThread();
ipmi::audioIpmiClient =
ipmi::createIpmiClient(fakeIpmiThread, "SceSysAudioSystemIpc");
@ -1370,7 +1371,7 @@ int main(int argc, const char *argv[]) {
int32_t unk8 = 0x2;
char unk9[24]{0};
} data2;
std::uint32_t method = orbis::g_context.fwSdkVersion >= 0x8000000
std::uint32_t method = orbis::g_context->fwSdkVersion >= 0x8000000
? 0x1234002c
: 0x1234002b;
ipmi::audioIpmiClient.sendSyncMessage(method, data1, data2);
@ -1378,7 +1379,7 @@ int main(int argc, const char *argv[]) {
}
}
if (orbis::g_context.fwType == orbis::FwType::Ps5 && !isSystem) {
if (orbis::g_context->fwType == orbis::FwType::Ps5 && !isSystem) {
ipmi::createIpmiServer(initProcess, "SceShareLibIpmiService");
ipmi::createIpmiServer(initProcess, "SceSysAvControlIpc");
ipmi::createShm("SceAvControl", 0xa02, 0x1a4, 4096);

View file

@ -214,7 +214,7 @@ orbis::SysResult dmem_mmap(orbis::Thread *thread, orbis::caddr_t addr,
orbis::size_t len, orbis::sint memoryType,
orbis::sint prot, sint flags,
orbis::off_t directMemoryStart) {
auto dmem = static_cast<DmemDevice *>(orbis::g_context.dmemDevice.get());
auto dmem = static_cast<DmemDevice *>(orbis::g_context->dmemDevice.get());
void *address = addr;
auto result = dmem->mmap(&address, len, prot, flags, directMemoryStart);
if (result != ErrorCode{}) {
@ -303,7 +303,7 @@ orbis::SysResult open(orbis::Thread *thread, orbis::ptr<const char> path,
orbis::SysResult shm_open(orbis::Thread *thread, const char *path,
orbis::sint flags, orbis::sint mode,
rx::Ref<orbis::File> *file) {
auto dev = static_cast<IoDevice *>(orbis::g_context.shmDevice.get());
auto dev = static_cast<IoDevice *>(orbis::g_context->shmDevice.get());
return dev->open(file, path, flags, mode, thread);
}
orbis::SysResult unlink(orbis::Thread *thread, orbis::ptr<const char> path) {
@ -326,7 +326,7 @@ orbis::SysResult rename(Thread *thread, ptr<const char> from,
orbis::SysResult blockpool_open(orbis::Thread *thread,
rx::Ref<orbis::File> *file) {
auto dev = static_cast<IoDevice *>(orbis::g_context.blockpoolDevice.get());
auto dev = static_cast<IoDevice *>(orbis::g_context->blockpoolDevice.get());
return dev->open(file, nullptr, 0, 0, thread);
}
@ -334,7 +334,7 @@ orbis::SysResult blockpool_map(orbis::Thread *thread, orbis::caddr_t addr,
orbis::size_t len, orbis::sint prot,
orbis::sint flags) {
auto blockpool =
static_cast<BlockPoolDevice *>(orbis::g_context.blockpoolDevice.get());
static_cast<BlockPoolDevice *>(orbis::g_context->blockpoolDevice.get());
void *address = addr;
auto result = blockpool->map(&address, len, prot, flags, thread);
if (result != ErrorCode{}) {
@ -347,7 +347,7 @@ orbis::SysResult blockpool_map(orbis::Thread *thread, orbis::caddr_t addr,
orbis::SysResult blockpool_unmap(orbis::Thread *thread, orbis::caddr_t addr,
orbis::size_t len) {
auto blockpool =
static_cast<BlockPoolDevice *>(orbis::g_context.blockpoolDevice.get());
static_cast<BlockPoolDevice *>(orbis::g_context->blockpoolDevice.get());
return blockpool->unmap(addr, len, thread);
}
@ -379,7 +379,7 @@ orbis::SysResult socketPair(orbis::Thread *thread, orbis::sint domain,
}
orbis::SysResult shm_unlink(orbis::Thread *thread, const char *path) {
auto dev = static_cast<IoDevice *>(orbis::g_context.shmDevice.get());
auto dev = static_cast<IoDevice *>(orbis::g_context->shmDevice.get());
return dev->unlink(path, false, thread);
}
@ -760,7 +760,7 @@ SysResult processNeeded(Thread *thread) {
}
SysResult fork(Thread *thread, slong flags) {
auto childPid = g_context.allocatePid() * 10000 + 1;
auto childPid = g_context->allocatePid() * 10000 + 1;
ORBIS_LOG_TODO(__FUNCTION__, flags, childPid, thread->tid);
thread->where();
auto flag = knew<std::atomic<bool>>();
@ -783,7 +783,7 @@ SysResult fork(Thread *thread, slong flags) {
return {};
}
auto process = g_context.createProcess(childPid);
auto process = g_context->createProcess(childPid);
process->hostPid = ::getpid();
process->sysent = thread->tproc->sysent;
process->onSysEnter = thread->tproc->onSysEnter;

View file

@ -970,8 +970,8 @@ void *vm::map(void *addr, std::uint64_t len, std::int32_t prot,
}
if (auto thr = orbis::g_currentThread) {
std::lock_guard lock(orbis::g_context.gpuDeviceMtx);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
std::lock_guard lock(orbis::g_context->gpuDeviceMtx);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.submitMapMemory(thr->tproc->pid, address, len, -1, -1, prot,
address - kMinAddress);
}
@ -1027,7 +1027,7 @@ bool vm::unmap(void *addr, std::uint64_t size) {
gBlocks[(address >> kBlockShift) - kFirstBlock].removeFlags(
(address & kBlockMask) >> kPageShift, pages, ~0);
if (auto thr = orbis::g_currentThread) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.submitUnmapMemory(thr->tproc->pid, address, size);
}
} else {
@ -1072,7 +1072,7 @@ bool vm::protect(void *addr, std::uint64_t size, std::int32_t prot) {
if (auto thr = orbis::g_currentThread) {
std::println("memory prot: {:x}", prot);
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context.gpuDevice}) {
if (auto gpu = amdgpu::DeviceCtl{orbis::g_context->gpuDevice}) {
gpu.submitProtectMemory(thr->tproc->pid, address, size, prot);
}
} else if (prot >> 4) {