arm: De-virtualize ThreadContext (#7119)

* arm: Move ARM_Interface to core namespace

* arm: De-virtualize ThreadContext
This commit is contained in:
GPUCode 2023-11-07 03:55:30 +02:00 committed by GitHub
parent 8fe147b8f9
commit 3f1f0aa7c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 159 additions and 345 deletions

View file

@ -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;
}

View file

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

View file

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

View file

@ -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)));

View file

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

View file

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

View file

@ -15,8 +15,6 @@ namespace Kernel {
class Process;
}
class ARM_Interface;
namespace Service::LDR {
#define ASSERT_CRO_STRUCT(name, size) \