mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-24 00:27:01 +02:00
[hle, kernel] Add support for FW21 and kernel changes (#3004)
- Adapts kernel changes from atmosphere for firmware 21.0.0.
- Fixes launch error of firmware 21.0.0 applets.
- Adds new commands for `prepo` (New `SaveSystemReport` & `SaveSystemReportWithUser`).
- Adds new commands for `IReadOnlyApplicationControlDataInterface` (cmd 19; incomplete!)
- Adds `{12010, nullptr, "SetButtonConfigLeft"},` undocumented IHidServer.
- Adds new commands for `ngc:u` (`Mask2` and `Check2`)
- Adds new commands for system settings server (GetHttpAuthConfig) for webapplet
- Removes incompatible firmware popup warning.
Signed-off-by: lizzie lizzie@eden-emu.dev
Co-authored by: maufeat sahyno1996@gmail.com
Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: JPikachu <jpikachu.eden@gmail.com>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3004
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
b690813196
commit
7d239df065
35 changed files with 1624 additions and 1363 deletions
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -8,6 +11,7 @@ namespace Kernel {
|
|||
|
||||
KAutoObject* KAutoObject::Create(KAutoObject* obj) {
|
||||
obj->m_ref_count = 1;
|
||||
obj->m_class_token = obj->GetTypeObj().GetClassToken();
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,10 @@ protected:
|
|||
return (this->GetClassToken() | rhs.GetClassToken()) == this->GetClassToken();
|
||||
}
|
||||
|
||||
static constexpr bool IsClassTokenDerivedFrom(ClassTokenType self, ClassTokenType base) {
|
||||
return (self | base) == self;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* m_name;
|
||||
ClassTokenType m_class_token;
|
||||
|
|
@ -84,6 +88,7 @@ private:
|
|||
|
||||
public:
|
||||
explicit KAutoObject(KernelCore& kernel) : m_kernel(kernel) {
|
||||
m_class_token = GetStaticTypeObj().GetClassToken();
|
||||
RegisterWithKernel();
|
||||
}
|
||||
virtual ~KAutoObject() = default;
|
||||
|
|
@ -107,11 +112,11 @@ public:
|
|||
}
|
||||
|
||||
bool IsDerivedFrom(const TypeObj& rhs) const {
|
||||
return this->GetTypeObj().IsDerivedFrom(rhs);
|
||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.GetClassToken());
|
||||
}
|
||||
|
||||
bool IsDerivedFrom(const KAutoObject& rhs) const {
|
||||
return this->IsDerivedFrom(rhs.GetTypeObj());
|
||||
return TypeObj::IsClassTokenDerivedFrom(m_class_token, rhs.m_class_token);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
|
|
@ -180,6 +185,7 @@ protected:
|
|||
|
||||
private:
|
||||
std::atomic<u32> m_ref_count{};
|
||||
ClassTokenType m_class_token{};
|
||||
};
|
||||
|
||||
class KAutoObjectWithListContainer;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -23,8 +26,8 @@ bool ReadFromUser(KernelCore& kernel, u32* out, KProcessAddress address) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) {
|
||||
GetCurrentMemory(kernel).Write32(GetInteger(address), *p);
|
||||
bool WriteToUser(KernelCore& kernel, KProcessAddress address, u32 val) {
|
||||
GetCurrentMemory(kernel).Write32(GetInteger(address), val);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +136,7 @@ Result KConditionVariable::SignalToAddress(KernelCore& kernel, KProcessAddress a
|
|||
|
||||
// Write the value to userspace.
|
||||
Result result{ResultSuccess};
|
||||
if (WriteToUser(kernel, addr, std::addressof(next_value))) [[likely]] {
|
||||
if (WriteToUser(kernel, addr, next_value)) {
|
||||
result = ResultSuccess;
|
||||
} else {
|
||||
result = ResultInvalidCurrentMemory;
|
||||
|
|
@ -207,13 +210,13 @@ void KConditionVariable::SignalImpl(KThread* thread) {
|
|||
|
||||
// TODO(bunnei): We should call CanAccessAtomic(..) here.
|
||||
can_access = true;
|
||||
if (can_access) [[likely]] {
|
||||
if (can_access) {
|
||||
UpdateLockAtomic(m_kernel, std::addressof(prev_tag), address, own_tag,
|
||||
Svc::HandleWaitMask);
|
||||
}
|
||||
}
|
||||
|
||||
if (can_access) [[likely]] {
|
||||
if (can_access) {
|
||||
if (prev_tag == Svc::InvalidHandle) {
|
||||
// If nobody held the lock previously, we're all good.
|
||||
thread->EndWait(ResultSuccess);
|
||||
|
|
@ -225,7 +228,7 @@ void KConditionVariable::SignalImpl(KThread* thread) {
|
|||
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
|
||||
.ReleasePointerUnsafe();
|
||||
|
||||
if (owner_thread) [[likely]] {
|
||||
if (owner_thread) {
|
||||
// Add the thread as a waiter on the owner.
|
||||
owner_thread->AddWaiter(thread);
|
||||
owner_thread->Close();
|
||||
|
|
@ -261,8 +264,8 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
|
|||
|
||||
// If we have no waiters, clear the has waiter flag.
|
||||
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
|
||||
const u32 has_waiter_flag{};
|
||||
WriteToUser(m_kernel, cv_key, std::addressof(has_waiter_flag));
|
||||
constexpr u32 HasNoWaiterFlag = 0;
|
||||
WriteToUser(m_kernel, cv_key, HasNoWaiterFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -305,13 +308,13 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti
|
|||
|
||||
// Write to the cv key.
|
||||
{
|
||||
const u32 has_waiter_flag = 1;
|
||||
WriteToUser(m_kernel, key, std::addressof(has_waiter_flag));
|
||||
constexpr u32 HasWaiterFlag = 1;
|
||||
WriteToUser(m_kernel, key, HasWaiterFlag);
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
}
|
||||
|
||||
// Write the value to userspace.
|
||||
if (!WriteToUser(m_kernel, addr, std::addressof(next_value))) {
|
||||
if (!WriteToUser(m_kernel, addr, next_value)) {
|
||||
slp.CancelSleep();
|
||||
R_THROW(ResultInvalidCurrentMemory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -6,7 +9,7 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
Result KHandleTable::Finalize() {
|
||||
void KHandleTable::Finalize() {
|
||||
// Get the table and clear our record of it.
|
||||
u16 saved_table_size = 0;
|
||||
{
|
||||
|
|
@ -22,8 +25,6 @@ Result KHandleTable::Finalize() {
|
|||
obj->Close();
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
bool KHandleTable::Remove(Handle handle) {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
return m_max_count;
|
||||
}
|
||||
|
||||
Result Finalize();
|
||||
void Finalize();
|
||||
bool Remove(Handle handle);
|
||||
|
||||
template <typename T = KAutoObject>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -381,6 +384,9 @@ void KScheduler::SwitchThread(KThread* next_thread) {
|
|||
|
||||
// Set the new Thread Local region.
|
||||
// cpu::SwitchThreadLocalRegion(GetInteger(next_thread->GetThreadLocalRegionAddress()));
|
||||
|
||||
// Update the thread's cpu time differential in TLS, if relevant.
|
||||
next_thread->UpdateTlsThreadCpuTime(cur_tick);
|
||||
}
|
||||
|
||||
void KScheduler::ScheduleImpl() {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -99,6 +99,12 @@ enum class DpcFlag : u32 {
|
|||
Terminated = (1 << 1),
|
||||
};
|
||||
|
||||
enum class ExceptionFlag : u8 {
|
||||
IsCallingSvc = 1 << 0,
|
||||
InExceptionHandler = 1 << 1,
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(ExceptionFlag);
|
||||
|
||||
enum class ThreadWaitReasonForDebugging : u32 {
|
||||
None, ///< Thread is not waiting
|
||||
Sleep, ///< Thread is waiting due to a SleepThread SVC
|
||||
|
|
@ -153,7 +159,7 @@ public:
|
|||
|
||||
/**
|
||||
* Sets the thread's current priority.
|
||||
* @param priority The new priority.
|
||||
* @param value The new priority.
|
||||
*/
|
||||
void SetPriority(s32 value) {
|
||||
m_priority = value;
|
||||
|
|
@ -340,6 +346,8 @@ public:
|
|||
void SetInterruptFlag();
|
||||
void ClearInterruptFlag();
|
||||
|
||||
void UpdateTlsThreadCpuTime(s64 switch_tick);
|
||||
|
||||
KThread* GetLockOwner() const;
|
||||
|
||||
const KAffinityMask& GetAffinityMask() const {
|
||||
|
|
@ -446,6 +454,7 @@ public:
|
|||
bool is_pinned;
|
||||
s32 disable_count;
|
||||
KThread* cur_thread;
|
||||
std::atomic<u8> exception_flags{0};
|
||||
};
|
||||
|
||||
StackParameters& GetStackParameters() {
|
||||
|
|
@ -456,6 +465,16 @@ public:
|
|||
return m_stack_parameters;
|
||||
}
|
||||
|
||||
void SetExceptionFlag(ExceptionFlag flag) {
|
||||
GetStackParameters().exception_flags.fetch_or(static_cast<u8>(flag), std::memory_order_relaxed);
|
||||
}
|
||||
void ClearExceptionFlag(ExceptionFlag flag) {
|
||||
GetStackParameters().exception_flags.fetch_and(static_cast<u8>(~static_cast<u8>(flag)), std::memory_order_relaxed);
|
||||
}
|
||||
bool IsExceptionFlagSet(ExceptionFlag flag) const {
|
||||
return (GetStackParameters().exception_flags.load(std::memory_order_relaxed) & static_cast<u8>(flag)) != 0;
|
||||
}
|
||||
|
||||
class QueueEntry {
|
||||
public:
|
||||
constexpr QueueEntry() = default;
|
||||
|
|
@ -511,10 +530,12 @@ public:
|
|||
|
||||
void SetInExceptionHandler() {
|
||||
this->GetStackParameters().is_in_exception_handler = true;
|
||||
SetExceptionFlag(ExceptionFlag::InExceptionHandler);
|
||||
}
|
||||
|
||||
void ClearInExceptionHandler() {
|
||||
this->GetStackParameters().is_in_exception_handler = false;
|
||||
ClearExceptionFlag(ExceptionFlag::InExceptionHandler);
|
||||
}
|
||||
|
||||
bool IsInExceptionHandler() const {
|
||||
|
|
@ -523,10 +544,12 @@ public:
|
|||
|
||||
void SetIsCallingSvc() {
|
||||
this->GetStackParameters().is_calling_svc = true;
|
||||
SetExceptionFlag(ExceptionFlag::IsCallingSvc);
|
||||
}
|
||||
|
||||
void ClearIsCallingSvc() {
|
||||
this->GetStackParameters().is_calling_svc = false;
|
||||
ClearExceptionFlag(ExceptionFlag::IsCallingSvc);
|
||||
}
|
||||
|
||||
bool IsCallingSvc() const {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -34,7 +37,8 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
|
|||
{
|
||||
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
|
||||
if (event.IsNotNull()) {
|
||||
R_RETURN(event->Clear());
|
||||
event->Clear();
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +46,8 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
|
|||
{
|
||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
||||
if (readable_event.IsNotNull()) {
|
||||
R_RETURN(readable_event->Clear());
|
||||
readable_event->Clear();
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue