citra/src/core/hle/kernel/kernel.cpp
bamsbamx dbfd830695 kernel: Let the kernel handle all page table changes when switching processes
It will both change the page table in memory and notify the CPU about the change by itself. This way there is no need to call memory.SetCurrentPageTable() when kernel.setCurrentProcess() and the management is kept internally in the kernel
2019-06-26 00:39:11 +02:00

92 lines
2.6 KiB
C++

// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/config_mem.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/shared_page.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
namespace Kernel {
/// Initialize the kernel
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>(timing);
}
/// Shutdown the kernel
KernelSystem::~KernelSystem() = default;
ResourceLimitList& KernelSystem::ResourceLimit() {
return *resource_limits;
}
const ResourceLimitList& KernelSystem::ResourceLimit() const {
return *resource_limits;
}
u32 KernelSystem::GenerateObjectID() {
return next_object_id++;
}
std::shared_ptr<Process> KernelSystem::GetCurrentProcess() const {
return current_process;
}
void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) {
current_process = process;
SetCurrentMemPageTable(&process->vm_manager.page_table);
}
void KernelSystem::SetCurrentMemPageTable(Memory::PageTable* page_table) {
memory.SetCurrentPageTable(page_table);
current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed
}
void KernelSystem::SetCPU(std::shared_ptr<ARM_Interface> cpu) {
current_cpu = cpu;
thread_manager->SetCPU(*cpu);
}
ThreadManager& KernelSystem::GetThreadManager() {
return *thread_manager;
}
const ThreadManager& KernelSystem::GetThreadManager() const {
return *thread_manager;
}
TimerManager& KernelSystem::GetTimerManager() {
return *timer_manager;
}
const TimerManager& KernelSystem::GetTimerManager() const {
return *timer_manager;
}
SharedPage::Handler& KernelSystem::GetSharedPageHandler() {
return *shared_page_handler;
}
const SharedPage::Handler& KernelSystem::GetSharedPageHandler() const {
return *shared_page_handler;
}
void KernelSystem::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
named_ports.emplace(std::move(name), std::move(port));
}
} // namespace Kernel