mirror of
https://github.com/starr-dusT/citra.git
synced 2024-10-02 10:26:17 -07:00

* Kernel/Process: Notify the CPUs that a new pagetable has been set every time the process they're executing changes. Previously the page table would only be changed when the current CPU's page table was changed, this lead to stale JIT states and the PC going to 0 when context-switching a different core inside the ThreadManager::SwitchContext function because the JIT for a new pagetable is only constructed upon receiving the change notification. * Kernel/Process: Use the relevant CPU's last process to determine when to switch its current process. Previously it was checking the kernel's current_process variable, which gets overwritten every time a CPU runs its slice. The rescheduling happens after all CPUs have run their slice so the code was effectively only checking the last CPU's process.
73 lines
2.2 KiB
C++
73 lines
2.2 KiB
C++
// Copyright 2016 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <dynarmic/A32/a32.h>
|
|
#include "common/common_types.h"
|
|
#include "core/arm/arm_interface.h"
|
|
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
|
|
|
|
namespace Memory {
|
|
struct PageTable;
|
|
class MemorySystem;
|
|
} // namespace Memory
|
|
|
|
namespace Core {
|
|
class System;
|
|
}
|
|
|
|
class DynarmicUserCallbacks;
|
|
|
|
class ARM_Dynarmic final : public ARM_Interface {
|
|
public:
|
|
ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, u32 id,
|
|
std::shared_ptr<Core::Timing::Timer> timer);
|
|
~ARM_Dynarmic() override;
|
|
|
|
void Run() override;
|
|
void Step() override;
|
|
|
|
void SetPC(u32 pc) override;
|
|
u32 GetPC() const override;
|
|
u32 GetReg(int index) const override;
|
|
void SetReg(int index, u32 value) override;
|
|
u32 GetVFPReg(int index) const override;
|
|
void SetVFPReg(int index, u32 value) override;
|
|
u32 GetVFPSystemReg(VFPSystemRegister reg) const override;
|
|
void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override;
|
|
u32 GetCPSR() const override;
|
|
void SetCPSR(u32 cpsr) override;
|
|
u32 GetCP15Register(CP15Register reg) override;
|
|
void SetCP15Register(CP15Register reg, u32 value) override;
|
|
|
|
std::unique_ptr<ThreadContext> NewContext() const override;
|
|
void SaveContext(const std::unique_ptr<ThreadContext>& arg) override;
|
|
void LoadContext(const std::unique_ptr<ThreadContext>& arg) override;
|
|
|
|
void PrepareReschedule() override;
|
|
|
|
void ClearInstructionCache() override;
|
|
void InvalidateCacheRange(u32 start_address, std::size_t length) override;
|
|
void PageTableChanged(Memory::PageTable* new_page_table) override;
|
|
|
|
private:
|
|
void ServeBreak();
|
|
|
|
friend class DynarmicUserCallbacks;
|
|
Core::System& system;
|
|
Memory::MemorySystem& memory;
|
|
std::unique_ptr<DynarmicUserCallbacks> cb;
|
|
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
|
|
|
|
u32 fpexc = 0;
|
|
CP15State cp15_state;
|
|
|
|
Dynarmic::A32::Jit* jit = nullptr;
|
|
Memory::PageTable* current_page_table = nullptr;
|
|
std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::A32::Jit>> jits;
|
|
};
|