Merge pull request #8637 from liamwhite/bad-interrupts
kernel: unlayer CPU interrupt handling
This commit is contained in:
commit
01bb5d5c4d
13 changed files with 64 additions and 152 deletions
|
@ -27,7 +27,6 @@ namespace Core {
|
|||
class System;
|
||||
class CPUInterruptHandler;
|
||||
|
||||
using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>;
|
||||
using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>;
|
||||
|
||||
/// Generic ARMv8 CPU interface
|
||||
|
@ -36,10 +35,8 @@ public:
|
|||
YUZU_NON_COPYABLE(ARM_Interface);
|
||||
YUZU_NON_MOVEABLE(ARM_Interface);
|
||||
|
||||
explicit ARM_Interface(System& system_, CPUInterrupts& interrupt_handlers_,
|
||||
bool uses_wall_clock_)
|
||||
: system{system_}, interrupt_handlers{interrupt_handlers_}, uses_wall_clock{
|
||||
uses_wall_clock_} {}
|
||||
explicit ARM_Interface(System& system_, bool uses_wall_clock_)
|
||||
: system{system_}, uses_wall_clock{uses_wall_clock_} {}
|
||||
virtual ~ARM_Interface() = default;
|
||||
|
||||
struct ThreadContext32 {
|
||||
|
@ -181,6 +178,9 @@ public:
|
|||
/// Signal an interrupt and ask the core to halt as soon as possible.
|
||||
virtual void SignalInterrupt() = 0;
|
||||
|
||||
/// Clear a previous interrupt.
|
||||
virtual void ClearInterrupt() = 0;
|
||||
|
||||
struct BacktraceEntry {
|
||||
std::string module;
|
||||
u64 address;
|
||||
|
@ -208,7 +208,6 @@ public:
|
|||
protected:
|
||||
/// System context that this ARM interface is running under.
|
||||
System& system;
|
||||
CPUInterrupts& interrupt_handlers;
|
||||
const WatchpointArray* watchpoints;
|
||||
bool uses_wall_clock;
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "core/arm/cpu_interrupt_handler.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
CPUInterruptHandler::CPUInterruptHandler() : interrupt_event{std::make_unique<Common::Event>()} {}
|
||||
|
||||
CPUInterruptHandler::~CPUInterruptHandler() = default;
|
||||
|
||||
void CPUInterruptHandler::SetInterrupt(bool is_interrupted_) {
|
||||
if (is_interrupted_) {
|
||||
interrupt_event->Set();
|
||||
}
|
||||
is_interrupted = is_interrupted_;
|
||||
}
|
||||
|
||||
void CPUInterruptHandler::AwaitInterrupt() {
|
||||
interrupt_event->Wait();
|
||||
}
|
||||
|
||||
} // namespace Core
|
|
@ -1,39 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace Common {
|
||||
class Event;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CPUInterruptHandler {
|
||||
public:
|
||||
CPUInterruptHandler();
|
||||
~CPUInterruptHandler();
|
||||
|
||||
CPUInterruptHandler(const CPUInterruptHandler&) = delete;
|
||||
CPUInterruptHandler& operator=(const CPUInterruptHandler&) = delete;
|
||||
|
||||
CPUInterruptHandler(CPUInterruptHandler&&) = delete;
|
||||
CPUInterruptHandler& operator=(CPUInterruptHandler&&) = delete;
|
||||
|
||||
bool IsInterrupted() const {
|
||||
return is_interrupted;
|
||||
}
|
||||
|
||||
void SetInterrupt(bool is_interrupted);
|
||||
|
||||
void AwaitInterrupt();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Common::Event> interrupt_event;
|
||||
std::atomic_bool is_interrupted{false};
|
||||
};
|
||||
|
||||
} // namespace Core
|
|
@ -11,7 +11,6 @@
|
|||
#include "common/logging/log.h"
|
||||
#include "common/page_table.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/arm/cpu_interrupt_handler.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
|
||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||
|
@ -318,11 +317,9 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() {
|
|||
LoadContext(breakpoint_context);
|
||||
}
|
||||
|
||||
ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_,
|
||||
bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
|
||||
std::size_t core_index_)
|
||||
: ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_},
|
||||
cb(std::make_unique<DynarmicCallbacks32>(*this)),
|
||||
ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
|
||||
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
|
||||
: ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
|
||||
cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_},
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)},
|
||||
null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {}
|
||||
|
@ -401,6 +398,10 @@ void ARM_Dynarmic_32::SignalInterrupt() {
|
|||
jit.load()->HaltExecution(break_loop);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ClearInterrupt() {
|
||||
jit.load()->ClearHalt(break_loop);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ClearInstructionCache() {
|
||||
jit.load()->ClearCache();
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ class System;
|
|||
|
||||
class ARM_Dynarmic_32 final : public ARM_Interface {
|
||||
public:
|
||||
ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_,
|
||||
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_);
|
||||
ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
|
||||
std::size_t core_index_);
|
||||
~ARM_Dynarmic_32() override;
|
||||
|
||||
void SetPC(u64 pc) override;
|
||||
|
@ -56,6 +56,7 @@ public:
|
|||
void LoadContext(const ThreadContext64& ctx) override {}
|
||||
|
||||
void SignalInterrupt() override;
|
||||
void ClearInterrupt() override;
|
||||
void ClearExclusiveState() override;
|
||||
|
||||
void ClearInstructionCache() override;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "common/logging/log.h"
|
||||
#include "common/page_table.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/arm/cpu_interrupt_handler.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||
#include "core/core.h"
|
||||
|
@ -378,10 +377,9 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() {
|
|||
LoadContext(breakpoint_context);
|
||||
}
|
||||
|
||||
ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_,
|
||||
bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
|
||||
std::size_t core_index_)
|
||||
: ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_},
|
||||
ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_,
|
||||
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_)
|
||||
: ARM_Interface{system_, uses_wall_clock_},
|
||||
cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_},
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)},
|
||||
null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {}
|
||||
|
@ -468,6 +466,10 @@ void ARM_Dynarmic_64::SignalInterrupt() {
|
|||
jit.load()->HaltExecution(break_loop);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ClearInterrupt() {
|
||||
jit.load()->ClearHalt(break_loop);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ClearInstructionCache() {
|
||||
jit.load()->ClearCache();
|
||||
}
|
||||
|
|
|
@ -20,14 +20,13 @@ class Memory;
|
|||
namespace Core {
|
||||
|
||||
class DynarmicCallbacks64;
|
||||
class CPUInterruptHandler;
|
||||
class DynarmicExclusiveMonitor;
|
||||
class System;
|
||||
|
||||
class ARM_Dynarmic_64 final : public ARM_Interface {
|
||||
public:
|
||||
ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_,
|
||||
ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_);
|
||||
ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_,
|
||||
std::size_t core_index_);
|
||||
~ARM_Dynarmic_64() override;
|
||||
|
||||
void SetPC(u64 pc) override;
|
||||
|
@ -50,6 +49,7 @@ public:
|
|||
void LoadContext(const ThreadContext64& ctx) override;
|
||||
|
||||
void SignalInterrupt() override;
|
||||
void ClearInterrupt() override;
|
||||
void ClearExclusiveState() override;
|
||||
|
||||
void ClearInstructionCache() override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue