Merge pull request #4616 from wwylele/core-global-clean

Cleanup System::GetInstance reference - Part 1
This commit is contained in:
Weiyi Wang 2019-02-25 10:22:02 -05:00 committed by GitHub
commit c265f3f507
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 234 additions and 160 deletions

View file

@ -16,11 +16,11 @@
namespace Kernel {
ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread> dst_thread,
VAddr src_address, VAddr dst_address,
ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, SharedPtr<Thread> src_thread,
SharedPtr<Thread> dst_thread, VAddr src_address,
VAddr dst_address,
std::vector<MappedBufferContext>& mapped_buffer_context,
bool reply) {
Memory::MemorySystem& memory = Core::System::GetInstance().Memory();
auto& src_process = src_thread->owner_process;
auto& dst_process = dst_thread->owner_process;

View file

@ -10,6 +10,10 @@
#include "core/hle/ipc.h"
#include "core/hle/kernel/thread.h"
namespace Memory {
class MemorySystem;
}
namespace Kernel {
struct MappedBufferContext {
@ -23,8 +27,9 @@ struct MappedBufferContext {
};
/// Performs IPC command buffer translation from one process to another.
ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread> dst_thread,
VAddr src_address, VAddr dst_address,
ResultCode TranslateCommandBuffer(Memory::MemorySystem& memory, SharedPtr<Thread> src_thread,
SharedPtr<Thread> dst_thread, VAddr src_address,
VAddr dst_address,
std::vector<MappedBufferContext>& mapped_buffer_context,
bool reply);
} // namespace Kernel

View file

@ -16,12 +16,15 @@
namespace Kernel {
/// Initialize the kernel
KernelSystem::KernelSystem(Memory::MemorySystem& memory, u32 system_mode) : memory(memory) {
KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
std::function<void()> prepare_reschedule_callback, u32 system_mode)
: memory(memory), timing(timing),
prepare_reschedule_callback(std::move(prepare_reschedule_callback)) {
MemoryInit(system_mode);
resource_limits = std::make_unique<ResourceLimitList>(*this);
thread_manager = std::make_unique<ThreadManager>(*this);
timer_manager = std::make_unique<TimerManager>();
timer_manager = std::make_unique<TimerManager>(timing);
}
/// Shutdown the kernel

View file

@ -6,6 +6,7 @@
#include <array>
#include <atomic>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
@ -27,6 +28,10 @@ namespace Memory {
class MemorySystem;
}
namespace Core {
class Timing;
}
namespace Kernel {
class AddressArbiter;
@ -78,7 +83,8 @@ using SharedPtr = boost::intrusive_ptr<T>;
class KernelSystem {
public:
explicit KernelSystem(Memory::MemorySystem& memory, u32 system_mode);
explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
std::function<void()> prepare_reschedule_callback, u32 system_mode);
~KernelSystem();
/**
@ -224,14 +230,22 @@ public:
/// Adds a port to the named port table
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
void PrepareReschedule() {
prepare_reschedule_callback();
}
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
std::unordered_map<std::string, SharedPtr<ClientPort>> named_ports;
Memory::MemorySystem& memory;
Core::Timing& timing;
private:
void MemoryInit(u32 mem_type);
std::function<void()> prepare_reschedule_callback;
std::unique_ptr<ResourceLimitList> resource_limits;
std::atomic<u32> next_object_id{0};

View file

@ -66,7 +66,7 @@ void KernelSystem::MemoryInit(u32 mem_type) {
config_mem.sys_mem_alloc = memory_regions[1].size;
config_mem.base_mem_alloc = memory_regions[2].size;
shared_page_handler = std::make_unique<SharedPage::Handler>();
shared_page_handler = std::make_unique<SharedPage::Handler>(timing);
}
MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) {

View file

@ -24,7 +24,7 @@ void ReleaseThreadMutexes(Thread* thread) {
thread->held_mutexes.clear();
}
Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel) {}
Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {}
Mutex::~Mutex() {}
SharedPtr<Mutex> KernelSystem::CreateMutex(bool initial_locked, std::string name) {
@ -54,7 +54,7 @@ void Mutex::Acquire(Thread* thread) {
thread->held_mutexes.insert(this);
holding_thread = thread;
thread->UpdatePriority();
Core::System::GetInstance().PrepareReschedule();
kernel.PrepareReschedule();
}
lock_count++;
@ -87,7 +87,7 @@ ResultCode Mutex::Release(Thread* thread) {
holding_thread->UpdatePriority();
holding_thread = nullptr;
WakeupAllWaitingThreads();
Core::System::GetInstance().PrepareReschedule();
kernel.PrepareReschedule();
}
return RESULT_SUCCESS;

View file

@ -57,6 +57,7 @@ private:
~Mutex() override;
friend class KernelSystem;
KernelSystem& kernel;
};
/**

View file

@ -37,7 +37,7 @@ static std::chrono::seconds GetInitTime() {
}
}
Handler::Handler() {
Handler::Handler(Core::Timing& timing) : timing(timing) {
std::memset(&shared_page, 0, sizeof(shared_page));
shared_page.running_hw = 0x1; // product
@ -54,9 +54,9 @@ Handler::Handler() {
init_time = GetInitTime();
using namespace std::placeholders;
update_time_event = Core::System::GetInstance().CoreTiming().RegisterEvent(
"SharedPage::UpdateTimeCallback", std::bind(&Handler::UpdateTimeCallback, this, _1, _2));
Core::System::GetInstance().CoreTiming().ScheduleEvent(0, update_time_event);
update_time_event = timing.RegisterEvent("SharedPage::UpdateTimeCallback",
std::bind(&Handler::UpdateTimeCallback, this, _1, _2));
timing.ScheduleEvent(0, update_time_event);
float slidestate =
Settings::values.toggle_3d ? (float_le)Settings::values.factor_3d / 100 : 0.0f;
@ -66,8 +66,7 @@ Handler::Handler() {
/// Gets system time in 3DS format. The epoch is Jan 1900, and the unit is millisecond.
u64 Handler::GetSystemTime() const {
std::chrono::milliseconds now =
init_time + std::chrono::duration_cast<std::chrono::milliseconds>(
Core::System::GetInstance().CoreTiming().GetGlobalTimeUs());
init_time + std::chrono::duration_cast<std::chrono::milliseconds>(timing.GetGlobalTimeUs());
// 3DS system does't allow user to set a time before Jan 1 2000,
// so we use it as an auxiliary epoch to calculate the console time.
@ -98,15 +97,14 @@ void Handler::UpdateTimeCallback(u64 userdata, int cycles_late) {
shared_page.date_time_counter % 2 ? shared_page.date_time_0 : shared_page.date_time_1;
date_time.date_time = GetSystemTime();
date_time.update_tick = Core::System::GetInstance().CoreTiming().GetTicks();
date_time.update_tick = timing.GetTicks();
date_time.tick_to_second_coefficient = BASE_CLOCK_RATE_ARM11;
date_time.tick_offset = 0;
++shared_page.date_time_counter;
// system time is updated hourly
Core::System::GetInstance().CoreTiming().ScheduleEvent(msToCycles(60 * 60 * 1000) - cycles_late,
update_time_event);
timing.ScheduleEvent(msToCycles(60 * 60 * 1000) - cycles_late, update_time_event);
}
void Handler::SetMacAddress(const MacAddress& addr) {

View file

@ -23,7 +23,8 @@
namespace Core {
struct TimingEventType;
}
class Timing;
} // namespace Core
namespace SharedPage {
@ -83,7 +84,7 @@ static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE,
class Handler {
public:
Handler();
Handler(Core::Timing& timing);
void SetMacAddress(const MacAddress&);
@ -98,6 +99,7 @@ public:
private:
u64 GetSystemTime() const;
void UpdateTimeCallback(u64 userdata, int cycles_late);
Core::Timing& timing;
Core::TimingEventType* update_time_event;
std::chrono::seconds init_time;

View file

@ -592,7 +592,8 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle
}
}
static ResultCode ReceiveIPCRequest(SharedPtr<ServerSession> server_session,
static ResultCode ReceiveIPCRequest(Memory::MemorySystem& memory,
SharedPtr<ServerSession> server_session,
SharedPtr<Thread> thread) {
if (server_session->parent->client == nullptr) {
return ERR_SESSION_CLOSED_BY_REMOTE;
@ -602,7 +603,7 @@ static ResultCode ReceiveIPCRequest(SharedPtr<ServerSession> server_session,
VAddr source_address = server_session->currently_handling->GetCommandBufferAddress();
ResultCode translation_result =
TranslateCommandBuffer(server_session->currently_handling, thread, source_address,
TranslateCommandBuffer(memory, server_session->currently_handling, thread, source_address,
target_address, server_session->mapped_buffer_context, false);
// If a translation error occurred, immediately resume the client thread.
@ -669,7 +670,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co
VAddr target_address = request_thread->GetCommandBufferAddress();
ResultCode translation_result =
TranslateCommandBuffer(thread, request_thread, source_address, target_address,
TranslateCommandBuffer(memory, thread, request_thread, source_address, target_address,
session->mapped_buffer_context, true);
// Note: The real kernel seems to always panic if the Server->Client buffer translation
@ -705,7 +706,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co
return RESULT_SUCCESS;
auto server_session = static_cast<ServerSession*>(object);
return ReceiveIPCRequest(server_session, thread);
return ReceiveIPCRequest(memory, server_session, thread);
}
// No objects were ready to be acquired, prepare to suspend the thread.
@ -721,8 +722,9 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co
thread->wait_objects = std::move(objects);
thread->wakeup_callback = [](ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object) {
thread->wakeup_callback = [& memory = this->memory](ThreadWakeupReason reason,
SharedPtr<Thread> thread,
SharedPtr<WaitObject> object) {
ASSERT(thread->status == ThreadStatus::WaitSynchAny);
ASSERT(reason == ThreadWakeupReason::Signal);
@ -730,7 +732,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co
if (object->GetHandleType() == HandleType::ServerSession) {
auto server_session = DynamicObjectCast<ServerSession>(object);
result = ReceiveIPCRequest(server_session, thread);
result = ReceiveIPCRequest(memory, server_session, thread);
}
thread->SetWaitSynchronizationResult(result);

View file

@ -38,7 +38,7 @@ u32 ThreadManager::NewThreadId() {
}
Thread::Thread(KernelSystem& kernel)
: WaitObject(kernel), context(Core::CPU().NewContext()),
: WaitObject(kernel), context(kernel.GetThreadManager().NewContext()),
thread_manager(kernel.GetThreadManager()) {}
Thread::~Thread() {}
@ -48,8 +48,7 @@ Thread* ThreadManager::GetCurrentThread() const {
void Thread::Stop() {
// Cancel any outstanding wakeup events for this thread
Core::System::GetInstance().CoreTiming().UnscheduleEvent(thread_manager.ThreadWakeupEventType,
thread_id);
thread_manager.kernel.timing.UnscheduleEvent(thread_manager.ThreadWakeupEventType, thread_id);
thread_manager.wakeup_callback_table.erase(thread_id);
// Clean up thread from ready queue
@ -81,12 +80,12 @@ void Thread::Stop() {
void ThreadManager::SwitchContext(Thread* new_thread) {
Thread* previous_thread = GetCurrentThread();
Core::Timing& timing = Core::System::GetInstance().CoreTiming();
Core::Timing& timing = kernel.timing;
// Save context for previous thread
if (previous_thread) {
previous_thread->last_running_ticks = timing.GetTicks();
Core::CPU().SaveContext(previous_thread->context);
cpu->SaveContext(previous_thread->context);
if (previous_thread->status == ThreadStatus::Running) {
// This is only the case when a reschedule is triggered without the current thread
@ -117,8 +116,8 @@ void ThreadManager::SwitchContext(Thread* new_thread) {
&current_thread->owner_process->vm_manager.page_table);
}
Core::CPU().LoadContext(new_thread->context);
Core::CPU().SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
cpu->LoadContext(new_thread->context);
cpu->SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
} else {
current_thread = nullptr;
// Note: We do not reset the current process and current page table when idling because
@ -186,8 +185,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
if (nanoseconds == -1)
return;
Core::System::GetInstance().CoreTiming().ScheduleEvent(
nsToCycles(nanoseconds), thread_manager.ThreadWakeupEventType, thread_id);
thread_manager.kernel.timing.ScheduleEvent(nsToCycles(nanoseconds),
thread_manager.ThreadWakeupEventType, thread_id);
}
void Thread::ResumeFromWait() {
@ -225,7 +224,7 @@ void Thread::ResumeFromWait() {
thread_manager.ready_queue.push_back(current_priority, this);
status = ThreadStatus::Ready;
Core::System::GetInstance().PrepareReschedule();
thread_manager.kernel.PrepareReschedule();
}
void ThreadManager::DebugThreadQueue() {
@ -320,7 +319,7 @@ ResultVal<SharedPtr<Thread>> KernelSystem::CreateThread(std::string name, VAddr
thread->entry_point = entry_point;
thread->stack_top = stack_top;
thread->nominal_priority = thread->current_priority = priority;
thread->last_running_ticks = Core::System::GetInstance().CoreTiming().GetTicks();
thread->last_running_ticks = timing.GetTicks();
thread->processor_id = processor_id;
thread->wait_objects.clear();
thread->wait_address = 0;
@ -462,9 +461,10 @@ VAddr Thread::GetCommandBufferAddress() const {
}
ThreadManager::ThreadManager(Kernel::KernelSystem& kernel) : kernel(kernel) {
ThreadWakeupEventType = Core::System::GetInstance().CoreTiming().RegisterEvent(
"ThreadWakeupCallback",
[this](u64 thread_id, s64 cycle_late) { ThreadWakeupCallback(thread_id, cycle_late); });
ThreadWakeupEventType =
kernel.timing.RegisterEvent("ThreadWakeupCallback", [this](u64 thread_id, s64 cycle_late) {
ThreadWakeupCallback(thread_id, cycle_late);
});
}
ThreadManager::~ThreadManager() {

View file

@ -101,6 +101,14 @@ public:
*/
const std::vector<SharedPtr<Thread>>& GetThreadList();
void SetCPU(ARM_Interface& cpu) {
this->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
@ -122,6 +130,7 @@ private:
void ThreadWakeupCallback(u64 thread_id, s64 cycles_late);
Kernel::KernelSystem& kernel;
ARM_Interface* cpu;
u32 next_thread_id = 1;
SharedPtr<Thread> current_thread;

View file

@ -14,7 +14,8 @@
namespace Kernel {
Timer::Timer(KernelSystem& kernel) : WaitObject(kernel), timer_manager(kernel.GetTimerManager()) {}
Timer::Timer(KernelSystem& kernel)
: WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {}
Timer::~Timer() {
Cancel();
timer_manager.timer_callback_table.erase(callback_id);
@ -56,14 +57,13 @@ void Timer::Set(s64 initial, s64 interval) {
// Immediately invoke the callback
Signal(0);
} else {
Core::System::GetInstance().CoreTiming().ScheduleEvent(
nsToCycles(initial), timer_manager.timer_callback_event_type, callback_id);
kernel.timing.ScheduleEvent(nsToCycles(initial), timer_manager.timer_callback_event_type,
callback_id);
}
}
void Timer::Cancel() {
Core::System::GetInstance().CoreTiming().UnscheduleEvent(
timer_manager.timer_callback_event_type, callback_id);
kernel.timing.UnscheduleEvent(timer_manager.timer_callback_event_type, callback_id);
}
void Timer::Clear() {
@ -87,9 +87,8 @@ void Timer::Signal(s64 cycles_late) {
if (interval_delay != 0) {
// Reschedule the timer with the interval delay
Core::System::GetInstance().CoreTiming().ScheduleEvent(
nsToCycles(interval_delay) - cycles_late, timer_manager.timer_callback_event_type,
callback_id);
kernel.timing.ScheduleEvent(nsToCycles(interval_delay) - cycles_late,
timer_manager.timer_callback_event_type, callback_id);
}
}
@ -105,10 +104,11 @@ void TimerManager::TimerCallback(u64 callback_id, s64 cycles_late) {
timer->Signal(cycles_late);
}
TimerManager::TimerManager() {
timer_callback_event_type = Core::System::GetInstance().CoreTiming().RegisterEvent(
"TimerCallback",
[this](u64 thread_id, s64 cycle_late) { TimerCallback(thread_id, cycle_late); });
TimerManager::TimerManager(Core::Timing& timing) : timing(timing) {
timer_callback_event_type =
timing.RegisterEvent("TimerCallback", [this](u64 thread_id, s64 cycle_late) {
TimerCallback(thread_id, cycle_late);
});
}
} // namespace Kernel

View file

@ -9,16 +9,22 @@
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
namespace Core {
class Timing;
}
namespace Kernel {
class TimerManager {
public:
TimerManager();
TimerManager(Core::Timing& timing);
private:
/// The timer callback event, called when a timer is fired
void TimerCallback(u64 callback_id, s64 cycles_late);
Core::Timing& timing;
/// The event type of the generic timer callback event
Core::TimingEventType* timer_callback_event_type = nullptr;
@ -93,6 +99,7 @@ private:
/// ID used as userdata to reference this object when inserting into the CoreTiming queue.
u64 callback_id;
KernelSystem& kernel;
TimerManager& timer_manager;
friend class KernelSystem;

View file

@ -72,11 +72,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc
case RelocationType::AbsoluteAddress:
case RelocationType::AbsoluteAddress2:
memory.Write32(target_address, symbol_address + addend);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
cpu.InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::RelativeAddress:
memory.Write32(target_address, symbol_address + addend - target_future_address);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
cpu.InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
case RelocationType::ArmBranch:
@ -99,7 +99,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc
case RelocationType::AbsoluteAddress2:
case RelocationType::RelativeAddress:
memory.Write32(target_address, 0);
Core::CPU().InvalidateCacheRange(target_address, sizeof(u32));
cpu.InvalidateCacheRange(target_address, sizeof(u32));
break;
case RelocationType::ThumbBranch:
case RelocationType::ArmBranch:
@ -548,7 +548,7 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
static_relocation_table_offset +
GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
CROHelper crs(crs_address, process, memory);
CROHelper crs(crs_address, process, memory, cpu);
u32 offset_export_num = GetField(StaticAnonymousSymbolNum);
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} static anonymous symbols", ModuleName(),
offset_export_num);
@ -759,7 +759,7 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
if (!relocation_entry.is_batch_resolved) {
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
std::string symbol_name =
memory.ReadCString(entry.name_offset, import_strings_size);
u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
@ -861,7 +861,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size);
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
if (want_cro_name == source.ModuleName()) {
LOG_INFO(Service_LDR, "CRO \"{}\" imports {} indexed symbols from \"{}\"",
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
@ -1071,7 +1071,7 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
ResultCode result = ForEachAutoLinkCRO(
process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
process, memory, cpu, crs_address, [&](CROHelper source) -> ResultVal<bool> {
u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
if (symbol_address != 0) {
@ -1301,7 +1301,7 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
}
// Exports symbols to other modules
result = ForEachAutoLinkCRO(process, memory, crs_address,
result = ForEachAutoLinkCRO(process, memory, cpu, crs_address,
[this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ApplyExportNamedSymbol(target);
if (result.IsError())
@ -1346,7 +1346,7 @@ ResultCode CROHelper::Unlink(VAddr crs_address) {
// Resets all symbols in other modules imported from this module
// Note: the RO service seems only searching in auto-link modules
result = ForEachAutoLinkCRO(process, memory, crs_address,
result = ForEachAutoLinkCRO(process, memory, cpu, crs_address,
[this](CROHelper target) -> ResultVal<bool> {
ResultCode result = ResetExportNamedSymbol(target);
if (result.IsError())
@ -1387,13 +1387,13 @@ void CROHelper::InitCRS() {
}
void CROHelper::Register(VAddr crs_address, bool auto_link) {
CROHelper crs(crs_address, process, memory);
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory);
CROHelper crs(crs_address, process, memory, cpu);
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory, cpu);
if (head.module_address) {
// there are already CROs registered
// register as the new tail
CROHelper tail(head.PreviousModule(), process, memory);
CROHelper tail(head.PreviousModule(), process, memory, cpu);
// link with the old tail
ASSERT(tail.NextModule() == 0);
@ -1419,11 +1419,11 @@ void CROHelper::Register(VAddr crs_address, bool auto_link) {
}
void CROHelper::Unregister(VAddr crs_address) {
CROHelper crs(crs_address, process, memory);
CROHelper next_head(crs.NextModule(), process, memory);
CROHelper previous_head(crs.PreviousModule(), process, memory);
CROHelper next(NextModule(), process, memory);
CROHelper previous(PreviousModule(), process, memory);
CROHelper crs(crs_address, process, memory, cpu);
CROHelper next_head(crs.NextModule(), process, memory, cpu);
CROHelper previous_head(crs.PreviousModule(), process, memory, cpu);
CROHelper next(NextModule(), process, memory, cpu);
CROHelper previous(PreviousModule(), process, memory, cpu);
if (module_address == next_head.module_address ||
module_address == previous_head.module_address) {

View file

@ -15,6 +15,8 @@ namespace Kernel {
class Process;
}
class ARM_Interface;
namespace Service::LDR {
#define ASSERT_CRO_STRUCT(name, size) \
@ -31,8 +33,9 @@ static constexpr u32 CRO_HASH_SIZE = 0x80;
class CROHelper final {
public:
// TODO (wwylele): pass in the process handle for memory access
explicit CROHelper(VAddr cro_address, Kernel::Process& process, Memory::MemorySystem& memory)
: module_address(cro_address), process(process), memory(memory) {}
explicit CROHelper(VAddr cro_address, Kernel::Process& process, Memory::MemorySystem& memory,
ARM_Interface& cpu)
: module_address(cro_address), process(process), memory(memory), cpu(cpu) {}
std::string ModuleName() const {
return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
@ -142,6 +145,7 @@ private:
const VAddr module_address; ///< the virtual address of this module
Kernel::Process& process; ///< the owner process of this module
Memory::MemorySystem& memory;
ARM_Interface& cpu;
/**
* Each item in this enum represents a u32 field in the header begin from address+0x80,
@ -471,10 +475,11 @@ private:
*/
template <typename FunctionObject>
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Memory::MemorySystem& memory,
VAddr crs_address, FunctionObject func) {
ARM_Interface& cpu, VAddr crs_address,
FunctionObject func) {
VAddr current = crs_address;
while (current != 0) {
CROHelper cro(current, process, memory);
CROHelper cro(current, process, memory, cpu);
CASCADE_RESULT(bool next, func(cro));
if (!next)
break;

View file

@ -115,7 +115,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) {
return;
}
CROHelper crs(crs_address, *process, system.Memory());
CROHelper crs(crs_address, *process, system.Memory(), system.CPU());
crs.InitCRS();
result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true);
@ -249,7 +249,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
return;
}
CROHelper cro(cro_address, *process, system.Memory());
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
result = cro.VerifyHash(cro_size, crr_address);
if (result.IsError()) {
@ -313,7 +313,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
}
}
Core::CPU().InvalidateCacheRange(cro_address, cro_size);
system.CPU().InvalidateCacheRange(cro_address, cro_size);
LOG_INFO(Service_LDR, "CRO \"{}\" loaded at 0x{:08X}, fixed_end=0x{:08X}", cro.ModuleName(),
cro_address, cro_address + fix_size);
@ -331,7 +331,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}, zero={}, cro_buffer_ptr=0x{:08X}",
cro_address, zero, cro_buffer_ptr);
CROHelper cro(cro_address, *process, system.Memory());
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -386,7 +386,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
LOG_ERROR(Service_LDR, "Error unmapping CRO {:08X}", result.raw);
}
Core::CPU().InvalidateCacheRange(cro_address, fixed_size);
system.CPU().InvalidateCacheRange(cro_address, fixed_size);
rb.Push(result);
}
@ -398,7 +398,7 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process, system.Memory());
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -438,7 +438,7 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process, system.Memory());
CROHelper cro(cro_address, *process, system.Memory(), system.CPU());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -487,7 +487,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
return;
}
CROHelper crs(slot->loaded_crs, *process, system.Memory());
CROHelper crs(slot->loaded_crs, *process, system.Memory(), system.CPU());
crs.Unrebase(true);
ResultCode result = RESULT_SUCCESS;