early-access version 1310
This commit is contained in:
@@ -71,15 +71,8 @@ public:
|
||||
}
|
||||
|
||||
void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override {
|
||||
switch (exception) {
|
||||
case Dynarmic::A32::Exception::UndefinedInstruction:
|
||||
case Dynarmic::A32::Exception::UnpredictableInstruction:
|
||||
break;
|
||||
case Dynarmic::A32::Exception::Breakpoint:
|
||||
break;
|
||||
}
|
||||
LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
|
||||
static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
|
||||
exception, pc, MemoryReadCode(pc));
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
@@ -67,18 +67,18 @@ public:
|
||||
virtual void Refresh() = 0;
|
||||
|
||||
virtual bool HasEntry(u64 title_id, ContentRecordType type) const = 0;
|
||||
virtual bool HasEntry(ContentProviderEntry entry) const;
|
||||
bool HasEntry(ContentProviderEntry entry) const;
|
||||
|
||||
virtual std::optional<u32> GetEntryVersion(u64 title_id) const = 0;
|
||||
|
||||
virtual VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const = 0;
|
||||
virtual VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const;
|
||||
VirtualFile GetEntryUnparsed(ContentProviderEntry entry) const;
|
||||
|
||||
virtual VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const = 0;
|
||||
virtual VirtualFile GetEntryRaw(ContentProviderEntry entry) const;
|
||||
VirtualFile GetEntryRaw(ContentProviderEntry entry) const;
|
||||
|
||||
virtual std::unique_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const = 0;
|
||||
virtual std::unique_ptr<NCA> GetEntry(ContentProviderEntry entry) const;
|
||||
std::unique_ptr<NCA> GetEntry(ContentProviderEntry entry) const;
|
||||
|
||||
virtual std::vector<ContentProviderEntry> ListEntries() const;
|
||||
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#include "core/arm/exclusive_monitor.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_address_arbiter.h"
|
||||
@@ -18,7 +15,8 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
KAddressArbiter::KAddressArbiter(Core::System& system) : system{system}, kernel{system.Kernel()} {}
|
||||
KAddressArbiter::KAddressArbiter(Core::System& system_)
|
||||
: system{system_}, kernel{system.Kernel()} {}
|
||||
KAddressArbiter::~KAddressArbiter() = default;
|
||||
|
||||
namespace {
|
||||
@@ -278,6 +276,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement
|
||||
cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr);
|
||||
thread_tree.insert(*cur_thread);
|
||||
cur_thread->SetState(ThreadState::Waiting);
|
||||
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
|
||||
}
|
||||
|
||||
// Cancel the timer wait.
|
||||
@@ -341,6 +340,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
|
||||
cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr);
|
||||
thread_tree.insert(*cur_thread);
|
||||
cur_thread->SetState(ThreadState::Waiting);
|
||||
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
|
||||
}
|
||||
|
||||
// Cancel the timer wait.
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/assert.h"
|
||||
@@ -26,7 +23,7 @@ class KAddressArbiter {
|
||||
public:
|
||||
using ThreadTree = KConditionVariable::ThreadTree;
|
||||
|
||||
explicit KAddressArbiter(Core::System& system);
|
||||
explicit KAddressArbiter(Core::System& system_);
|
||||
~KAddressArbiter();
|
||||
|
||||
[[nodiscard]] ResultCode SignalToAddress(VAddr addr, Svc::SignalType type, s32 value,
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "core/arm/exclusive_monitor.h"
|
||||
@@ -63,8 +60,8 @@ bool UpdateLockAtomic(Core::System& system, u32* out, VAddr address, u32 if_zero
|
||||
|
||||
} // namespace
|
||||
|
||||
KConditionVariable::KConditionVariable(Core::System& system)
|
||||
: system{system}, kernel{system.Kernel()} {}
|
||||
KConditionVariable::KConditionVariable(Core::System& system_)
|
||||
: system{system_}, kernel{system.Kernel()} {}
|
||||
|
||||
KConditionVariable::~KConditionVariable() = default;
|
||||
|
||||
@@ -136,6 +133,7 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val
|
||||
cur_thread->SetAddressKey(addr, value);
|
||||
owner_thread->AddWaiter(cur_thread);
|
||||
cur_thread->SetState(ThreadState::Waiting);
|
||||
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar);
|
||||
cur_thread->SetMutexWaitAddressForDebugging(addr);
|
||||
}
|
||||
}
|
||||
@@ -318,6 +316,7 @@ ResultCode KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout)
|
||||
// If the timeout is non-zero, set the thread as waiting.
|
||||
if (timeout != 0) {
|
||||
cur_thread->SetState(ThreadState::Waiting);
|
||||
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar);
|
||||
cur_thread->SetMutexWaitAddressForDebugging(addr);
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/assert.h"
|
||||
@@ -25,7 +22,7 @@ class KConditionVariable {
|
||||
public:
|
||||
using ThreadTree = typename Thread::ConditionVariableThreadTreeType;
|
||||
|
||||
explicit KConditionVariable(Core::System& system);
|
||||
explicit KConditionVariable(Core::System& system_);
|
||||
~KConditionVariable();
|
||||
|
||||
// Arbitration
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/k_scheduler.h"
|
||||
@@ -75,12 +72,13 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
|
||||
}
|
||||
|
||||
// For debugging only
|
||||
thread->SetWaitObjectsForDebugging(objects, num_objects);
|
||||
thread->SetWaitObjectsForDebugging({objects, static_cast<std::size_t>(num_objects)});
|
||||
|
||||
// Mark the thread as waiting.
|
||||
thread->SetCancellable();
|
||||
thread->SetSyncedObject(nullptr, Svc::ResultTimedOut);
|
||||
thread->SetState(ThreadState::Waiting);
|
||||
thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization);
|
||||
}
|
||||
|
||||
// The lock/sleep is done, so we should be able to get our result.
|
||||
@@ -89,7 +87,7 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
|
||||
thread->ClearCancellable();
|
||||
|
||||
// For debugging only
|
||||
thread->SetWaitObjectsForDebugging(nullptr, 0);
|
||||
thread->SetWaitObjectsForDebugging({});
|
||||
|
||||
// Cancel the timer as needed.
|
||||
if (timer != InvalidHandle) {
|
||||
|
@@ -1,10 +1,7 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
@@ -605,6 +605,8 @@ void KernelCore::Suspend(bool in_suspention) {
|
||||
const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting;
|
||||
for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
|
||||
impl->suspend_threads[i]->SetState(state);
|
||||
impl->suspend_threads[i]->SetWaitReasonForDebugging(
|
||||
ThreadWaitReasonForDebugging::Suspended);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -301,7 +301,7 @@ public:
|
||||
|
||||
void LoadModule(CodeSet code_set, VAddr base_addr);
|
||||
|
||||
virtual bool IsSignaled() const override;
|
||||
bool IsSignaled() const override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-local storage management
|
||||
|
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
void Signal();
|
||||
|
||||
virtual bool IsSignaled() const override;
|
||||
bool IsSignaled() const override;
|
||||
|
||||
private:
|
||||
explicit ReadableEvent(KernelCore& kernel);
|
||||
|
@@ -79,7 +79,7 @@ public:
|
||||
/// waiting to be accepted by this port.
|
||||
void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
|
||||
|
||||
virtual bool IsSignaled() const override;
|
||||
bool IsSignaled() const override;
|
||||
|
||||
private:
|
||||
/// ServerSessions waiting to be accepted by the port
|
||||
|
@@ -124,7 +124,7 @@ public:
|
||||
convert_to_domain = true;
|
||||
}
|
||||
|
||||
virtual bool IsSignaled() const override;
|
||||
bool IsSignaled() const override;
|
||||
|
||||
private:
|
||||
/// Queues a sync request from the emulated application.
|
||||
|
@@ -347,6 +347,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||
{
|
||||
KScopedSchedulerLock lock(kernel);
|
||||
thread->SetState(ThreadState::Waiting);
|
||||
thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
|
||||
session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming());
|
||||
}
|
||||
|
||||
|
@@ -215,7 +215,10 @@ VAddr Thread::GetCommandBufferAddress() const {
|
||||
void Thread::SetState(ThreadState state) {
|
||||
KScopedSchedulerLock sl(kernel);
|
||||
|
||||
SetMutexWaitAddressForDebugging(0);
|
||||
// Clear debugging state
|
||||
SetMutexWaitAddressForDebugging({});
|
||||
SetWaitReasonForDebugging({});
|
||||
|
||||
const ThreadState old_state = thread_state;
|
||||
thread_state =
|
||||
static_cast<ThreadState>((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask));
|
||||
@@ -386,6 +389,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
|
||||
{
|
||||
KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
|
||||
SetState(ThreadState::Waiting);
|
||||
SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep);
|
||||
}
|
||||
|
||||
if (event_handle != InvalidHandle) {
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -113,6 +114,16 @@ enum class ThreadSchedFlags : u32 {
|
||||
KernelInitPauseFlag = 1 << 8,
|
||||
};
|
||||
|
||||
enum class ThreadWaitReasonForDebugging : u32 {
|
||||
None, ///< Thread is not waiting
|
||||
Sleep, ///< Thread is waiting due to a SleepThread SVC
|
||||
IPC, ///< Thread is waiting for the reply from an IPC request
|
||||
Synchronization, ///< Thread is waiting due to a WaitSynchronization SVC
|
||||
ConditionVar, ///< Thread is waiting due to a WaitProcessWideKey SVC
|
||||
Arbitration, ///< Thread is waiting due to a SignalToAddress/WaitForAddress SVC
|
||||
Suspended, ///< Thread is waiting due to process suspension
|
||||
};
|
||||
|
||||
class Thread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> {
|
||||
friend class KScheduler;
|
||||
friend class Process;
|
||||
@@ -514,11 +525,19 @@ public:
|
||||
disable_count--;
|
||||
}
|
||||
|
||||
void SetWaitObjectsForDebugging(KSynchronizationObject** objects, s32 num_objects) {
|
||||
void SetWaitReasonForDebugging(ThreadWaitReasonForDebugging reason) {
|
||||
wait_reason_for_debugging = reason;
|
||||
}
|
||||
|
||||
[[nodiscard]] ThreadWaitReasonForDebugging GetWaitReasonForDebugging() const {
|
||||
return wait_reason_for_debugging;
|
||||
}
|
||||
|
||||
void SetWaitObjectsForDebugging(const std::span<KSynchronizationObject*>& objects) {
|
||||
wait_objects_for_debugging.clear();
|
||||
wait_objects_for_debugging.reserve(num_objects);
|
||||
for (auto i = 0; i < num_objects; ++i) {
|
||||
wait_objects_for_debugging.emplace_back(objects[i]);
|
||||
wait_objects_for_debugging.reserve(objects.size());
|
||||
for (const auto& object : objects) {
|
||||
wait_objects_for_debugging.emplace_back(object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,11 +567,11 @@ public:
|
||||
return address_key_value;
|
||||
}
|
||||
|
||||
[[nodiscard]] void SetAddressKey(VAddr key) {
|
||||
void SetAddressKey(VAddr key) {
|
||||
address_key = key;
|
||||
}
|
||||
|
||||
[[nodiscard]] void SetAddressKey(VAddr key, u32 val) {
|
||||
void SetAddressKey(VAddr key, u32 val) {
|
||||
address_key = key;
|
||||
address_key_value = val;
|
||||
}
|
||||
@@ -560,11 +579,11 @@ public:
|
||||
private:
|
||||
static constexpr size_t PriorityInheritanceCountMax = 10;
|
||||
union SyncObjectBuffer {
|
||||
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects;
|
||||
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
|
||||
std::array<Handle,
|
||||
Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
|
||||
handles;
|
||||
constexpr SyncObjectBuffer() : sync_objects() {}
|
||||
constexpr SyncObjectBuffer() {}
|
||||
};
|
||||
static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
|
||||
|
||||
@@ -707,6 +726,9 @@ private:
|
||||
/// The current mutex wait address. This is used for debugging only.
|
||||
VAddr mutex_wait_address_for_debugging{};
|
||||
|
||||
/// The reason the thread is waiting. This is used for debugging only.
|
||||
ThreadWaitReasonForDebugging wait_reason_for_debugging{};
|
||||
|
||||
KSynchronizationObject* signaling_object;
|
||||
ResultCode signaling_result{RESULT_SUCCESS};
|
||||
|
||||
|
@@ -56,7 +56,7 @@ APM::APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& contro
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &APM::OpenSession, "OpenSession"},
|
||||
{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
|
||||
{6, nullptr, "IsCpuOverclockEnabled"},
|
||||
{6, &APM::IsCpuOverclockEnabled, "IsCpuOverclockEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -78,6 +78,14 @@ void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushEnum(controller.GetCurrentPerformanceMode());
|
||||
}
|
||||
|
||||
void APM::IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_APM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(false);
|
||||
}
|
||||
|
||||
APM_Sys::APM_Sys(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "apm:sys"}, controller{controller_} {
|
||||
// clang-format off
|
||||
|
@@ -20,6 +20,7 @@ public:
|
||||
private:
|
||||
void OpenSession(Kernel::HLERequestContext& ctx);
|
||||
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
|
||||
void IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Module> apm;
|
||||
Controller& controller;
|
||||
|
@@ -34,8 +34,7 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
case 0xa: {
|
||||
if (command.length == 0x1c) {
|
||||
LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
|
||||
Tegra::ChCommandHeaderList cmdlist(1);
|
||||
cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F};
|
||||
Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
|
||||
system.GPU().PushCommandBuffer(cmdlist);
|
||||
system.GPU().MemoryManager().InvalidateQueuedCaches();
|
||||
}
|
||||
|
@@ -29,8 +29,13 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
|
||||
return GetWaitbase(input, output);
|
||||
case 0x9:
|
||||
return MapBuffer(input, output);
|
||||
case 0xa:
|
||||
case 0xa: {
|
||||
if (command.length == 0x1c) {
|
||||
Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
|
||||
system.GPU().PushCommandBuffer(cmdlist);
|
||||
}
|
||||
return UnmapBuffer(input, output);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -180,9 +180,11 @@ u32 BufferQueue::Query(QueryType type) {
|
||||
switch (type) {
|
||||
case QueryType::NativeWindowFormat:
|
||||
return static_cast<u32>(PixelFormat::RGBA8888);
|
||||
case QueryType::NativeWindowWidth:
|
||||
case QueryType::NativeWindowHeight:
|
||||
break;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED();
|
||||
UNIMPLEMENTED_MSG("Unimplemented query type={}", type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user