Browse Source

add atmosphere changes from 21.0.0 branch + correct prepo struct

pull/3004/head
Maufeat 3 months ago
parent
commit
9c3828f0d5
  1. 1
      src/core/hle/kernel/k_auto_object.cpp
  2. 10
      src/core/hle/kernel/k_auto_object.h
  3. 22
      src/core/hle/kernel/k_condition_variable.cpp
  4. 3
      src/core/hle/kernel/k_scheduler.cpp
  5. 2154
      src/core/hle/kernel/k_thread.cpp
  6. 25
      src/core/hle/kernel/k_thread.h
  7. 37
      src/core/hle/service/filesystem/fsp/fsp_srv.cpp
  8. 21
      src/core/hle/service/prepo/prepo.cpp

1
src/core/hle/kernel/k_auto_object.cpp

@ -8,6 +8,7 @@ namespace Kernel {
KAutoObject* KAutoObject::Create(KAutoObject* obj) {
obj->m_ref_count = 1;
obj->m_class_token = obj->GetTypeObj().GetClassToken();
return obj;
}

10
src/core/hle/kernel/k_auto_object.h

@ -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{}; // neu: gespeicherter Klassentoken zur Devitalisierung
};
class KAutoObjectWithListContainer;

22
src/core/hle/kernel/k_condition_variable.cpp

@ -23,8 +23,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 +133,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 +207,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 +225,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 +261,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 +305,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);
}

3
src/core/hle/kernel/k_scheduler.cpp

@ -381,6 +381,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() {

2154
src/core/hle/kernel/k_thread.cpp
File diff suppressed because it is too large
View File

25
src/core/hle/kernel/k_thread.h

@ -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 {

37
src/core/hle/service/filesystem/fsp/fsp_srv.cpp

@ -298,8 +298,41 @@ Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface,
Result FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(OutInterface<IFileSystem> out_interface,
FileSys::SaveDataSpaceId space_id,
FileSys::SaveDataAttribute attribute) {
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
R_RETURN(OpenSaveDataFileSystem(out_interface, space_id, attribute));
LOG_INFO(Service_FS, "called, space_id={}, {}",
space_id, attribute.DebugInfo());
R_UNLESS(attribute.system_save_data_id != FileSys::InvalidSystemSaveDataId,
FileSys::ResultInvalidArgument);
if (attribute.program_id == 0) {
attribute.program_id = program_id;
}
FileSys::VirtualDir dir{};
R_TRY(save_data_controller->OpenSaveData(&dir, space_id, attribute));
FileSys::StorageId id{};
switch (space_id) {
case FileSys::SaveDataSpaceId::User:
id = FileSys::StorageId::NandUser;
break;
case FileSys::SaveDataSpaceId::SdSystem:
case FileSys::SaveDataSpaceId::SdUser:
id = FileSys::StorageId::SdCard;
break;
case FileSys::SaveDataSpaceId::System:
id = FileSys::StorageId::NandSystem;
break;
case FileSys::SaveDataSpaceId::Temporary:
case FileSys::SaveDataSpaceId::ProperSystem:
case FileSys::SaveDataSpaceId::SafeMode:
ASSERT(false);
}
*out_interface =
std::make_shared<IFileSystem>(system, std::move(dir), SizeGetter::FromStorageId(fsc, id));
R_SUCCEED();
}
Result FSP_SRV::OpenReadOnlySaveDataFileSystem(OutInterface<IFileSystem> out_interface,

21
src/core/hle/service/prepo/prepo.cpp

@ -3,6 +3,9 @@
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/uuid.h"
#include <cstring>
#include "core/core.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/ipc_helpers.h"
@ -145,10 +148,12 @@ private:
const auto data1 = ctx.ReadBufferA(0);
const auto data2 = ctx.ReadBufferX(0);
Common::UUID uuid{};
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
LOG_ERROR(Service_PREPO,
"called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, "
"data2_size={:016X}",
user_id[1], user_id[0], title_id, data1.size(), data2.size());
"called, user_id={}, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
uuid.FormattedString(), title_id, data1.size(), data2.size());
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2},
@ -182,16 +187,20 @@ private:
void SaveSystemReportWithUser(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
// 21.0.0+: field0 (u64), user_id (u128), title_id (u64)
const auto field0 = rp.PopRaw<u64>();
const auto user_id = rp.PopRaw<u128>();
const auto title_id = rp.PopRaw<u64>();
const auto reserved = rp.PopRaw<u64>();
const auto data_x = ctx.ReadBufferX(0);
const auto data_a = ctx.ReadBufferA(0);
Common::UUID uuid{};
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
LOG_ERROR(Service_PREPO,
"called, user_id={:016X}{:016X}, title_id={:016X}, reserved={}, data_a_size={}, data_x_size={}",
user_id[1], user_id[0], title_id, reserved, data_a.size(), data_x.size());
"called, user_id={}, field0={:016X}, title_id={:016X}, data_a_size={}, data_x_size={}",
uuid.FormattedString(), field0, title_id, data_a.size(), data_x.size());
const auto& reporter{system.GetReporter()};
reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data_a, data_x},

Loading…
Cancel
Save