mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-11 21:30:05 +00:00
arm: De-virtualize ThreadContext (#7119)
* arm: Move ARM_Interface to core namespace * arm: De-virtualize ThreadContext
This commit is contained in:
parent
8fe147b8f9
commit
3f1f0aa7c2
24 changed files with 159 additions and 345 deletions
|
@ -87,15 +87,14 @@ void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable>
|
|||
}
|
||||
}
|
||||
|
||||
void KernelSystem::SetCPUs(std::vector<std::shared_ptr<ARM_Interface>> cpus) {
|
||||
void KernelSystem::SetCPUs(std::vector<std::shared_ptr<Core::ARM_Interface>> cpus) {
|
||||
ASSERT(cpus.size() == thread_managers.size());
|
||||
u32 i = 0;
|
||||
for (const auto& cpu : cpus) {
|
||||
thread_managers[i++]->SetCPU(*cpu);
|
||||
for (u32 i = 0; i < cpus.size(); i++) {
|
||||
thread_managers[i]->SetCPU(*cpus[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void KernelSystem::SetRunningCPU(ARM_Interface* cpu) {
|
||||
void KernelSystem::SetRunningCPU(Core::ARM_Interface* cpu) {
|
||||
if (current_process) {
|
||||
stored_processes[current_cpu->GetID()] = current_process;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ class MemorySystem;
|
|||
}
|
||||
|
||||
namespace Core {
|
||||
class ARM_Interface;
|
||||
class Timing;
|
||||
}
|
||||
} // namespace Core
|
||||
|
||||
namespace IPCDebugger {
|
||||
class Recorder;
|
||||
|
@ -275,9 +276,9 @@ public:
|
|||
|
||||
void SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table);
|
||||
|
||||
void SetCPUs(std::vector<std::shared_ptr<ARM_Interface>> cpu);
|
||||
void SetCPUs(std::vector<std::shared_ptr<Core::ARM_Interface>> cpu);
|
||||
|
||||
void SetRunningCPU(ARM_Interface* cpu);
|
||||
void SetRunningCPU(Core::ARM_Interface* cpu);
|
||||
|
||||
ThreadManager& GetThreadManager(u32 core_id);
|
||||
const ThreadManager& GetThreadManager(u32 core_id) const;
|
||||
|
@ -324,7 +325,7 @@ public:
|
|||
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
|
||||
std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports;
|
||||
|
||||
ARM_Interface* current_cpu = nullptr;
|
||||
Core::ARM_Interface* current_cpu = nullptr;
|
||||
|
||||
Memory::MemorySystem& memory;
|
||||
|
||||
|
|
|
@ -255,6 +255,7 @@ private:
|
|||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int file_version);
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
BOOST_CLASS_EXPORT_KEY(Kernel::CodeSet)
|
||||
|
|
|
@ -1245,8 +1245,8 @@ ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr
|
|||
kernel.CreateThread(name, entry_point, priority, arg, processor_id, stack_top,
|
||||
current_process));
|
||||
|
||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||
thread->context.fpscr =
|
||||
FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000
|
||||
|
||||
CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(thread)));
|
||||
|
||||
|
|
|
@ -4,22 +4,16 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include "common/archives.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/math_util.h"
|
||||
#include "common/serialization/boost_flat_set.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/skyeye_common/armstate.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/mutex.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
@ -33,7 +27,7 @@ namespace Kernel {
|
|||
template <class Archive>
|
||||
void Thread::serialize(Archive& ar, const unsigned int file_version) {
|
||||
ar& boost::serialization::base_object<WaitObject>(*this);
|
||||
ar&* context.get();
|
||||
ar& context;
|
||||
ar& thread_id;
|
||||
ar& status;
|
||||
ar& entry_point;
|
||||
|
@ -63,9 +57,9 @@ void Thread::Acquire(Thread* thread) {
|
|||
}
|
||||
|
||||
Thread::Thread(KernelSystem& kernel, u32 core_id)
|
||||
: WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()),
|
||||
can_schedule(true), core_id(core_id), thread_manager(kernel.GetThreadManager(core_id)) {}
|
||||
Thread::~Thread() {}
|
||||
: WaitObject(kernel), core_id(core_id), thread_manager(kernel.GetThreadManager(core_id)) {}
|
||||
|
||||
Thread::~Thread() = default;
|
||||
|
||||
Thread* ThreadManager::GetCurrentThread() const {
|
||||
return current_thread.get();
|
||||
|
@ -318,13 +312,12 @@ void ThreadManager::DebugThreadQueue() {
|
|||
* @param entry_point Address of entry point for execution
|
||||
* @param arg User argument for thread
|
||||
*/
|
||||
static void ResetThreadContext(const std::unique_ptr<ARM_Interface::ThreadContext>& context,
|
||||
u32 stack_top, u32 entry_point, u32 arg) {
|
||||
context->Reset();
|
||||
context->SetCpuRegister(0, arg);
|
||||
context->SetProgramCounter(entry_point);
|
||||
context->SetStackPointer(stack_top);
|
||||
context->SetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode
|
||||
static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, u32 stack_top,
|
||||
u32 entry_point, u32 arg) {
|
||||
context.cpu_registers[0] = arg;
|
||||
context.SetProgramCounter(entry_point);
|
||||
context.SetStackPointer(stack_top);
|
||||
context.cpsr = USER32MODE | ((entry_point & 1) << 5); // Usermode and THUMB mode
|
||||
}
|
||||
|
||||
ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(
|
||||
|
@ -417,8 +410,8 @@ std::shared_ptr<Thread> SetupMainThread(KernelSystem& kernel, u32 entry_point, u
|
|||
|
||||
std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap();
|
||||
|
||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO |
|
||||
FPSCR_IXC); // 0x03C00010
|
||||
thread->context.fpscr =
|
||||
FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010
|
||||
|
||||
// Note: The newly created thread will be run when the scheduler fires.
|
||||
return thread;
|
||||
|
@ -447,11 +440,11 @@ void ThreadManager::Reschedule() {
|
|||
}
|
||||
|
||||
void Thread::SetWaitSynchronizationResult(ResultCode result) {
|
||||
context->SetCpuRegister(0, result.raw);
|
||||
context.cpu_registers[0] = result.raw;
|
||||
}
|
||||
|
||||
void Thread::SetWaitSynchronizationOutput(s32 output) {
|
||||
context->SetCpuRegister(1, output);
|
||||
context.cpu_registers[1] = output;
|
||||
}
|
||||
|
||||
s32 Thread::GetWaitObjectIndex(const WaitObject* object) const {
|
||||
|
|
|
@ -121,14 +121,10 @@ public:
|
|||
*/
|
||||
std::span<const std::shared_ptr<Thread>> GetThreadList();
|
||||
|
||||
void SetCPU(ARM_Interface& cpu_) {
|
||||
void SetCPU(Core::ARM_Interface& cpu_) {
|
||||
cpu = &cpu_;
|
||||
}
|
||||
|
||||
std::unique_ptr<ARM_Interface::ThreadContext> NewContext() {
|
||||
return cpu->NewContext();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Switches the CPU's active thread context to that of the specified thread
|
||||
|
@ -150,7 +146,7 @@ private:
|
|||
void ThreadWakeupCallback(u64 thread_id, s64 cycles_late);
|
||||
|
||||
Kernel::KernelSystem& kernel;
|
||||
ARM_Interface* cpu;
|
||||
Core::ARM_Interface* cpu;
|
||||
|
||||
std::shared_ptr<Thread> current_thread;
|
||||
Common::ThreadQueueList<Thread*, ThreadPrioLowest + 1> ready_queue;
|
||||
|
@ -271,7 +267,7 @@ public:
|
|||
*/
|
||||
void Stop();
|
||||
|
||||
/*
|
||||
/**
|
||||
* Returns the Thread Local Storage address of the current thread
|
||||
* @returns VAddr of the thread's TLS
|
||||
*/
|
||||
|
@ -279,7 +275,7 @@ public:
|
|||
return tls_address;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Returns the address of the current thread's command buffer, located in the TLS.
|
||||
* @returns VAddr of the thread's command buffer.
|
||||
*/
|
||||
|
@ -294,11 +290,11 @@ public:
|
|||
return status == ThreadStatus::WaitSynchAll;
|
||||
}
|
||||
|
||||
std::unique_ptr<ARM_Interface::ThreadContext> context;
|
||||
Core::ARM_Interface::ThreadContext context{};
|
||||
|
||||
u32 thread_id;
|
||||
|
||||
bool can_schedule;
|
||||
bool can_schedule{true};
|
||||
ThreadStatus status;
|
||||
VAddr entry_point;
|
||||
VAddr stack_top;
|
||||
|
@ -321,16 +317,16 @@ public:
|
|||
std::weak_ptr<Process> owner_process{}; ///< Process that owns this thread
|
||||
|
||||
/// Objects that the thread is waiting on, in the same order as they were
|
||||
// passed to WaitSynchronization1/N.
|
||||
/// passed to WaitSynchronization1/N.
|
||||
std::vector<std::shared_ptr<WaitObject>> wait_objects{};
|
||||
|
||||
VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
|
||||
|
||||
std::string name{};
|
||||
|
||||
// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
|
||||
// was waiting via WaitSynchronizationN then the object will be the last object that became
|
||||
// available. In case of a timeout, the object will be nullptr.
|
||||
/// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
|
||||
/// was waiting via WaitSynchronizationN then the object will be the last object that became
|
||||
/// available. In case of a timeout, the object will be nullptr.
|
||||
std::shared_ptr<WakeupCallback> wakeup_callback{};
|
||||
|
||||
const u32 core_id;
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace Kernel {
|
|||
class Process;
|
||||
}
|
||||
|
||||
class ARM_Interface;
|
||||
|
||||
namespace Service::LDR {
|
||||
|
||||
#define ASSERT_CRO_STRUCT(name, size) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue