From 8799c764dd35ae4ca41559571816e4904bff49f9 Mon Sep 17 00:00:00 2001 From: DH Date: Mon, 22 Sep 2025 03:32:18 +0300 Subject: [PATCH] orbis: initial budget implementation --- orbis-kernel/include/orbis/AuthInfo.hpp | 4 + orbis-kernel/include/orbis/Budget.hpp | 141 +++++++++++++ orbis-kernel/include/orbis/sys/sysproto.hpp | 18 +- orbis-kernel/include/orbis/thread/Process.hpp | 4 +- orbis-kernel/include/orbis/utils/BitSet.hpp | 58 ++++-- orbis-kernel/src/sys/sys_sce.cpp | 192 +++++++++++++++--- orbis-kernel/src/sys/sys_sysctl.cpp | 16 +- rpcsx/main.cpp | 98 ++++++++- rpcsx/orbis-kernel-config/orbis-config.hpp | 2 +- 9 files changed, 470 insertions(+), 63 deletions(-) create mode 100644 orbis-kernel/include/orbis/Budget.hpp diff --git a/orbis-kernel/include/orbis/AuthInfo.hpp b/orbis-kernel/include/orbis/AuthInfo.hpp index 164db0033..7e4aeeb5f 100644 --- a/orbis-kernel/include/orbis/AuthInfo.hpp +++ b/orbis-kernel/include/orbis/AuthInfo.hpp @@ -9,9 +9,13 @@ struct AuthInfo { uint64_t attrs[4]; uint64_t ucred[8]; + bool isSyscoreProcess() const { return ucred[2] == 0x3800000000000007; } + bool isShellUiProcess() const { return ucred[2] == 0x380000000000000f; } + bool hasUseHp3dPipeCapability() const { return ucred[2] == 0x3800000000000009; } + bool hasMmapSelfCapability() const { return ((ucred[4] >> 0x3a) & 1) != 1; } bool hasSystemCapability() const { return ((ucred[3] >> 0x3e) & 1) != 0; } bool hasSceProgramAttribute() const { return ((ucred[3] >> 0x1f) & 1) != 0; } diff --git a/orbis-kernel/include/orbis/Budget.hpp b/orbis-kernel/include/orbis/Budget.hpp new file mode 100644 index 000000000..553453f08 --- /dev/null +++ b/orbis-kernel/include/orbis/Budget.hpp @@ -0,0 +1,141 @@ +#pragma once + +#include "orbis-config.hpp" +#include "utils/BitSet.hpp" +#include "utils/Rc.hpp" +#include "utils/SharedMutex.hpp" +#include +#include +#include +#include + +namespace orbis { +enum class BudgetResource : uint32_t { + Invalid, + Dmem, + Vmem, + Fmem, + CpuSet, + File, + Socket, + Equeue, + Pipe, + Device, + Thread, + IpSocket, + + _count, +}; + +struct BudgetItem { + uint64_t total; + uint64_t used; +}; + +struct BudgetInfo { + BudgetResource resourceId; + uint32_t flags; // ? + BudgetItem item; +}; + +static_assert(sizeof(BudgetInfo) == 0x18); + +using BudgetInfoList = + std::array(BudgetResource::_count)>; + +class Budget : public RcBase { + using BudgetList = + std::array(BudgetResource::_count)>; + +public: + enum class ProcessType : orbis::uint32_t { + BigApp, + MiniApp, + System, + NonGameMiniApp, + _last = NonGameMiniApp + }; + + Budget(std::string_view name, ProcessType pType, + std::span budgets) + : mProcessType(pType) { + for (auto info : budgets) { + if (info.resourceId == BudgetResource::Invalid) { + continue; + } + + int resourceIndex = static_cast(info.resourceId); + + mUsed.set(resourceIndex); + mList[resourceIndex] = info.item; + } + + std::strncpy(mName, name.data(), std::min(name.size(), sizeof(mName))); + mName[sizeof(mName) - 1] = 0; + } + + [[nodiscard]] BudgetItem get(BudgetResource resourceId) const { + std::lock_guard lock(mMtx); + return mList[static_cast(resourceId)]; + } + + [[nodiscard]] BudgetList getBudgetList() const { + std::lock_guard lock(mMtx); + return mList; + } + + [[nodiscard]] std::pair getList() const { + auto budgetList = getBudgetList(); + + BudgetInfoList result{}; + int count = 0; + + for (auto resourceId : mUsed) { + result[count].resourceId = static_cast(resourceId); + result[count].item = budgetList[resourceId]; + count++; + } + + return {result, count}; + } + + bool acquire(BudgetResource resourceId, std::uint64_t size = 1) { + auto &budget = mList[static_cast(resourceId)]; + + std::lock_guard lock(mMtx); + + if (budget.used + size > budget.total) { + return false; + } + + budget.used += size; + return true; + } + + void release(BudgetResource resourceId, std::uint64_t size) { + auto &budget = mList[static_cast(resourceId)]; + + std::lock_guard lock(mMtx); + + if (size >= budget.used) { + budget.used = 0; + } else { + budget.used -= size; + } + } + + bool hasResource(BudgetResource resourceId) const { + return mUsed.test(static_cast(resourceId)); + } + + [[nodiscard]] int size() const { return mUsed.popcount(); } + [[nodiscard]] ProcessType processType() const { return mProcessType; } + +private: + mutable shared_mutex mMtx; + orbis::BitSet(BudgetResource::_count)> mUsed; + ProcessType mProcessType{}; + BudgetList mList; + char mName[32]{}; +}; +} // namespace orbis diff --git a/orbis-kernel/include/orbis/sys/sysproto.hpp b/orbis-kernel/include/orbis/sys/sysproto.hpp index bafafa81b..e15ac4a83 100644 --- a/orbis-kernel/include/orbis/sys/sysproto.hpp +++ b/orbis-kernel/include/orbis/sys/sysproto.hpp @@ -1,4 +1,5 @@ #include "orbis-config.hpp" +#include #include #include #include @@ -669,11 +670,14 @@ SysResult sys_opmc_disable(Thread *thread /* TODO */); SysResult sys_opmc_set_ctl(Thread *thread /* TODO */); SysResult sys_opmc_set_ctr(Thread *thread /* TODO */); 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, sint id, ptr a, - ptr count); -SysResult sys_budget_set(Thread *thread, slong budget); +SysResult sys_budget_create(Thread *thread, ptr name, + Budget::ProcessType processType, + ptr resources, orbis::uint count, + ptr invalidResources); +SysResult sys_budget_delete(Thread *thread, sint budget); +SysResult sys_budget_get(Thread *thread, sint id, ptr budgetInfo, + ptr count); +SysResult sys_budget_set(Thread *thread, sint budget); SysResult sys_virtual_query(Thread *thread, ptr addr, uint64_t unk, ptr info, size_t infosz); SysResult sys_mdbg_call(Thread *thread /* TODO */); @@ -726,7 +730,7 @@ SysResult sys_dynlib_get_info_ex(Thread *thread, SceKernelModule handle, ptr unk, ptr destModuleInfoEx); SysResult sys_budget_getid(Thread *thread); -SysResult sys_budget_get_ptype(Thread *thread, sint budgetId); +SysResult sys_budget_get_ptype(Thread *thread, sint pid); SysResult sys_get_paging_stats_of_all_threads(Thread *thread /* TODO */); SysResult sys_get_proc_type_info(Thread *thread, ptr destProcessInfo); SysResult sys_get_resident_count(Thread *thread, pid_t pid); @@ -773,7 +777,7 @@ SysResult sys_extend_page_table_pool(Thread *thread); SysResult sys_extend_page_table_pool2(Thread *thread); SysResult sys_get_kernel_mem_statistics(Thread *thread /* TODO */); SysResult sys_get_sdk_compiled_version(Thread *thread, ptr path); -SysResult sys_app_state_change(Thread *thread /* TODO */); +SysResult sys_app_state_change(Thread *thread, sint state); SysResult sys_dynlib_get_obj_member(Thread *thread, SceKernelModule handle, uint64_t index, ptr> addrp); SysResult sys_budget_get_ptype_of_budget(Thread *thread, sint budgetId); diff --git a/orbis-kernel/include/orbis/thread/Process.hpp b/orbis-kernel/include/orbis/thread/Process.hpp index e42a16be5..2068cfb2f 100644 --- a/orbis-kernel/include/orbis/thread/Process.hpp +++ b/orbis-kernel/include/orbis/thread/Process.hpp @@ -11,6 +11,7 @@ #include "cpuset.hpp" #include "orbis/AppInfo.hpp" #include "orbis/AuthInfo.hpp" +#include "orbis/Budget.hpp" #include "orbis/file.hpp" #include "orbis/module/Module.hpp" #include "orbis/utils/IdMap.hpp" @@ -74,7 +75,8 @@ struct Process final { kstring root = "/"; cpuset affinity{(1 << 7) - 1}; sint memoryContainer{1}; - sint budgetId{1}; + sint budgetId{}; + Budget::ProcessType budgetProcessType{}; bool isInSandbox = false; EventEmitter event; std::optional exitStatus; diff --git a/orbis-kernel/include/orbis/utils/BitSet.hpp b/orbis-kernel/include/orbis/utils/BitSet.hpp index 4ce028868..e1fa4ad0f 100644 --- a/orbis-kernel/include/orbis/utils/BitSet.hpp +++ b/orbis-kernel/include/orbis/utils/BitSet.hpp @@ -11,7 +11,31 @@ template struct BitSet { static constexpr auto ChunkCount = (Count + BitsPerChunk - 1) / BitsPerChunk; chunk_type _bits[ChunkCount]{}; - constexpr std::size_t countr_one() const { + struct iterator_end {}; + + struct iterator { + iterator() = default; + + constexpr iterator &operator++() { + offset = bitSet->countr_zero(offset + 1); + return *this; + } + constexpr bool operator==(const iterator_end &) const { + return offset >= Count; + } + constexpr std::size_t operator*() const { return offset; } + + private: + constexpr iterator(const BitSet *bitSet) + : bitSet(bitSet), offset(bitSet->countr_zero()) {} + + const BitSet *bitSet = nullptr; + std::size_t offset = 0; + + friend BitSet; + }; + + [[nodiscard]] constexpr std::size_t countr_one() const { std::size_t result = 0; for (auto bits : _bits) { auto count = std::countr_one(bits); @@ -25,7 +49,18 @@ template struct BitSet { return result; } - constexpr std::size_t countr_zero(std::size_t offset = 0) const { + [[nodiscard]] constexpr std::size_t popcount() const { + std::size_t result = 0; + + for (auto bits : _bits) { + result += std::popcount(bits); + } + + return result; + } + + [[nodiscard]] constexpr std::size_t + countr_zero(std::size_t offset = 0) const { std::size_t result = 0; if (auto chunkOffset = offset % BitsPerChunk) { @@ -47,21 +82,11 @@ template struct BitSet { break; } } - /* - for (auto bits : _bits) { - auto count = std::countr_zero(bits); - result += count; - - if (count != BitsPerChunk) { - break; - } - } - */ return result + offset; } - bool empty() const { + [[nodiscard]] constexpr bool empty() const { for (auto bits : _bits) { if (bits != 0) { return false; @@ -71,7 +96,7 @@ template struct BitSet { return true; } - bool full() const { + [[nodiscard]] constexpr bool full() const { if constexpr (Count < BitsPerChunk) { return _bits[0] == (static_cast(1) << Count) - 1; } @@ -95,10 +120,13 @@ template struct BitSet { << (index % BitsPerChunk); } - constexpr bool test(std::size_t index) const { + [[nodiscard]] constexpr bool test(std::size_t index) const { return (_bits[index / BitsPerChunk] & (static_cast(1) << (index % BitsPerChunk))) != 0; } + + [[nodiscard]] constexpr iterator begin() const { return iterator(this); } + [[nodiscard]] constexpr iterator_end end() const { return {}; } }; } // namespace utils } // namespace orbis diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index fde1085c4..420e8f5bd 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -18,6 +18,7 @@ #include #include #include +#include struct orbis::AppMountInfo { AppInfoEx appInfo; @@ -726,6 +727,8 @@ orbis::SysResult orbis::sys_suspend_process(Thread *thread, pid_t pid) { return {}; } orbis::SysResult orbis::sys_resume_process(Thread *thread, pid_t pid) { + ORBIS_LOG_FATAL(__FUNCTION__, pid); + // FIXME: implement return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_opmc_enable(Thread *thread /* TODO */) { @@ -743,42 +746,140 @@ orbis::SysResult orbis::sys_opmc_set_ctr(Thread *thread /* TODO */) { orbis::SysResult orbis::sys_opmc_get_ctr(Thread *thread /* TODO */) { return ErrorCode::NOSYS; } -orbis::SysResult orbis::sys_budget_create(Thread *thread /* TODO */) { - return ErrorCode::NOSYS; -} -orbis::SysResult orbis::sys_budget_delete(Thread *thread /* TODO */) { - return ErrorCode::NOSYS; -} -orbis::SysResult orbis::sys_budget_get(Thread *thread, sint id, ptr a, - ptr count) { - ORBIS_LOG_ERROR(__FUNCTION__, id, a, count); +orbis::SysResult orbis::sys_budget_create(Thread *thread, ptr name, + Budget::ProcessType processType, + ptr resources, + orbis::uint count, + ptr invalidResources) { + ORBIS_LOG_WARNING(__FUNCTION__, name, (int)processType, resources, count, + invalidResources); - struct budget { - uint32_t id; - uint32_t unk0; - uint64_t unk1; - uint64_t unk2; - }; + if (!thread->tproc->authInfo.hasSystemCapability()) { + return {}; + } + constexpr auto kMaxBudgets = std::to_underlying(BudgetResource::_count); - static_assert(sizeof(budget) == 0x18); + if (name == nullptr || count >= kMaxBudgets || + processType > Budget::ProcessType::_last) { + return ErrorCode::INVAL; + } - if (g_context.fwType == FwType::Ps5 && id == 1) { - std::uint32_t _count; - ORBIS_RET_ON_ERROR(orbis::uread(_count, count)); + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } - if (_count == 0) { - ORBIS_RET_ON_ERROR(orbis::uwrite(count, 1u)); - return {}; + char _name[32]{}; + ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), name)); + + BudgetInfo _resources[kMaxBudgets]; + ORBIS_RET_ON_ERROR(uread(_resources, resources, count)); + + auto processTypeBudget = g_context.getProcessTypeBudget(processType); + int invalidResourceCount = 0; + + for (auto &resource : std::span(_resources, count)) { + ORBIS_LOG_WARNING(__FUNCTION__, (int)resource.resourceId, resource.flags, + resource.item.total, resource.item.used); + + if (resource.resourceId >= BudgetResource::_count) { + resource.flags = 0x82000000; + invalidResourceCount++; + continue; } - ptr(a)->id = 4; + if (processTypeBudget->get(resource.resourceId).total < + resource.item.total) { + resource.flags = 0x81000000; + invalidResourceCount++; + continue; + } - ORBIS_RET_ON_ERROR(orbis::uwrite(count, 1u)); + resource.item.used = 0; } + + if (invalidResourceCount != 0) { + ORBIS_RET_ON_ERROR(uwrite(invalidResources, invalidResources, count)); + return ErrorCode::PERM; + } + + orbis::Ref budget = + orbis::knew(_name, processType, std::span(_resources, count)); + auto id = g_context.budgets.insert(budget); + thread->retval[0] = id; return {}; } -orbis::SysResult orbis::sys_budget_set(Thread *thread, slong budget) { - ORBIS_LOG_TODO(__FUNCTION__, budget); + +orbis::SysResult orbis::sys_budget_delete(Thread *thread, sint budget) { + ORBIS_LOG_WARNING(__FUNCTION__, budget); + + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } + + thread->where(); + return ErrorCode::NOSYS; +} + +orbis::SysResult orbis::sys_budget_get(Thread *thread, sint id, + ptr budgetInfo, + ptr count) { + ORBIS_LOG_WARNING(__FUNCTION__, id, budgetInfo, count); + + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } + + sint _count; + ORBIS_RET_ON_ERROR(uread(_count, count)); + if (_count < 1) { + return ErrorCode::INVAL; + } + + Ref budget; + bool isProcessTypeBudget = id < 0; + if (isProcessTypeBudget) { + id = -2 - id; + + if (id < 0 || id > std::to_underlying(Budget::ProcessType::_last)) { + return ErrorCode::SRCH; + } + + budget = + g_context.getProcessTypeBudget(static_cast(id)); + } else { + budget = g_context.budgets.get(id); + + if (!budget) { + return ErrorCode::SRCH; + } + } + + auto [items, resultCount] = budget->getList(); + + resultCount = std::min(resultCount, _count); + + if (isProcessTypeBudget) { + resultCount = std::min(resultCount, 10); + } + + ORBIS_RET_ON_ERROR(uwrite(budgetInfo, items.data(), items.size())); + ORBIS_RET_ON_ERROR(uwrite(count, resultCount)); + return {}; +} +orbis::SysResult orbis::sys_budget_set(Thread *thread, sint budgetId) { + ORBIS_LOG_WARNING(__FUNCTION__, budgetId); + + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } + + auto budget = g_context.budgets.get(budgetId); + if (!budget) { + return ErrorCode::SRCH; + } + + thread->tproc->budgetProcessType = budget->processType(); + thread->tproc->budgetId = budgetId; return {}; } orbis::SysResult orbis::sys_virtual_query(Thread *thread, ptr addr, @@ -1183,11 +1284,27 @@ orbis::sys_dynlib_get_info_ex(Thread *thread, SceKernelModule handle, return uwrite(destModuleInfoEx, result); } orbis::SysResult orbis::sys_budget_getid(Thread *thread) { + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } + thread->retval[0] = thread->tproc->budgetId; return {}; } -orbis::SysResult orbis::sys_budget_get_ptype(Thread *thread, sint budgetId) { - thread->retval[0] = budgetId; +orbis::SysResult orbis::sys_budget_get_ptype(Thread *thread, sint pid) { + orbis::Process *process; + + if (pid < 0 || pid == thread->tproc->pid) { + process = thread->tproc; + } else { + process = g_context.findProcessById(pid); + + if (!process) { + return ErrorCode::SRCH; + } + } + + thread->retval[0] = static_cast(process->budgetProcessType); return {}; } orbis::SysResult @@ -1538,7 +1655,12 @@ orbis::SysResult orbis::sys_get_sdk_compiled_version(Thread *thread, thread->retval[0] = g_context.sdkVersion; return {}; } -orbis::SysResult orbis::sys_app_state_change(Thread *thread /* TODO */) { +orbis::SysResult orbis::sys_app_state_change(Thread *thread, sint state) { + ORBIS_LOG_TODO(__FUNCTION__, state); + if (thread->tproc->authInfo.isSyscoreProcess()) { + // TODO + return {}; + } return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_dynlib_get_obj_member(Thread *thread, @@ -1554,7 +1676,17 @@ orbis::SysResult orbis::sys_dynlib_get_obj_member(Thread *thread, orbis::SysResult orbis::sys_budget_get_ptype_of_budget(Thread *thread, sint budgetId) { ORBIS_LOG_WARNING(__FUNCTION__, budgetId); - thread->retval[0] = budgetId; + if (!thread->tproc->authInfo.hasSystemCapability()) { + return ErrorCode::NOSYS; + } + + orbis::Ref budget = g_context.budgets.get(budgetId); + + if (!budget) { + return ErrorCode::SRCH; + } + + thread->retval[0] = static_cast(budget->processType()); return {}; } orbis::SysResult diff --git a/orbis-kernel/src/sys/sys_sysctl.cpp b/orbis-kernel/src/sys/sys_sysctl.cpp index dc13397c7..6fe5f8870 100644 --- a/orbis-kernel/src/sys/sys_sysctl.cpp +++ b/orbis-kernel/src/sys/sys_sysctl.cpp @@ -197,19 +197,25 @@ SysResult kern_sysctl(Thread *thread, ptr name, uint namelen, return ErrorCode::INVAL; } - *(uint64_t *)old = 5056ull * 1024 * 1024; + auto budget = g_context.budgets.get(thread->tproc->budgetId); + auto fmem = budget->get(BudgetResource::Fmem); + *(uint64_t *)old = fmem.total; return {}; } if (name[0] == vm && name[1] == budgets && name[2] == mlock_avail) { - if (*oldlenp != 16 || new_ != nullptr || newlen != 0) { + if ((*oldlenp != 16 && *oldlenp != 8) || new_ != nullptr || newlen != 0) { return ErrorCode::INVAL; } - // TODO + auto budget = g_context.budgets.get(thread->tproc->budgetId); + auto fmem = budget->get(BudgetResource::Fmem); + auto result = (uint64_t *)old; - result[0] = 0; - result[1] = 5056ull * 1024 * 1024; + result[0] = fmem.total - fmem.used; + if (*oldlenp == 16) { + result[1] = fmem.total; + } return {}; } } diff --git a/rpcsx/main.cpp b/rpcsx/main.cpp index 9575e1b9e..480f34580 100644 --- a/rpcsx/main.cpp +++ b/rpcsx/main.cpp @@ -1061,8 +1061,6 @@ int main(int argc, const char *argv[]) { auto initProcess = orbis::g_context.createProcess(asRoot ? 1 : 10); // pthread_setname_np(pthread_self(), "10.MAINTHREAD"); - vm::initialize(initProcess->pid); - int status = 0; initProcess->onSysEnter = onSysEnter; @@ -1073,6 +1071,96 @@ int main(int argc, const char *argv[]) { .unk4 = (isSystem ? orbis::slong(0x80000000'00000000) : 0), }}; + orbis::BudgetInfo bigAppBudgetInfo[]{ + { + .resourceId = orbis::BudgetResource::Dmem, + .flags = 0, + .item = + { + .total = 0x1'8000'0000, + }, + }, + { + .resourceId = orbis::BudgetResource::Vmem, + .flags = 0, + .item = + { + .total = 2ul * 1024 * 1024 * 1024, + }, + }, + { + .resourceId = orbis::BudgetResource::Fmem, + .flags = 0, + .item = + { + // vmem - reserved space for stack + .total = 2ul * 1024 * 1024 * 1024 - (64 * 1024 * 1024), + }, + }, + { + .resourceId = orbis::BudgetResource::CpuSet, + .flags = 0, + .item = + { + .total = 7, + }, + }, + { + .resourceId = orbis::BudgetResource::File, + .flags = 0, + .item = + { + .total = 4096, + }, + }, + { + .resourceId = orbis::BudgetResource::Socket, + .flags = 0, + .item = + { + .total = 4096, + }, + }, + { + .resourceId = orbis::BudgetResource::Equeue, + .flags = 0, + .item = + { + .total = 4096, + }, + }, + { + .resourceId = orbis::BudgetResource::Pipe, + .flags = 0, + .item = + { + .total = 4096, + }, + }, + { + .resourceId = orbis::BudgetResource::Device, + .flags = 0, + .item = + { + .total = 4096, + }, + }, + }; + + vm::initialize(initProcess->pid); + + 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::Budget::ProcessType::NonGameMiniApp, "non-game mini-app budget", + bigAppBudgetInfo); + if (isSystem) { orbis::g_context.safeMode = isSafeMode ? 1 : 0; initProcess->authInfo = {.unk0 = 0x380000000000000f, @@ -1099,7 +1187,7 @@ int main(int argc, const char *argv[]) { -1ul, -1ul, }}; - initProcess->budgetId = 0; + initProcess->budgetProcessType = orbis::Budget::ProcessType::System; initProcess->isInSandbox = false; } else { initProcess->authInfo = { @@ -1119,7 +1207,9 @@ int main(int argc, const char *argv[]) { 0xF0000000FFFF4000, }, }; - initProcess->budgetId = 1; + + initProcess->budgetProcessType = orbis::Budget::ProcessType::BigApp; + initProcess->budgetId = orbis::g_context.budgets.insert(bigAppBudget); initProcess->isInSandbox = true; } diff --git a/rpcsx/orbis-kernel-config/orbis-config.hpp b/rpcsx/orbis-kernel-config/orbis-config.hpp index 696843118..cdc8c99c3 100644 --- a/rpcsx/orbis-kernel-config/orbis-config.hpp +++ b/rpcsx/orbis-kernel-config/orbis-config.hpp @@ -100,7 +100,7 @@ template template [[nodiscard]] ErrorCode uread(T *result, ptr pointer, std::size_t count) { - return ureadRaw(&result, pointer, sizeof(T) * count); + return ureadRaw(result, pointer, sizeof(T) * count); } template