arm_interface.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-FileCopyrightText: 2014 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <span>
  6. #include <string>
  7. #include <vector>
  8. #include "common/common_funcs.h"
  9. #include "common/common_types.h"
  10. #include "core/hardware_properties.h"
  11. #include "core/hle/kernel/svc_types.h"
  12. namespace Common {
  13. struct PageTable;
  14. }
  15. namespace Kernel {
  16. enum class DebugWatchpointType : u8;
  17. struct DebugWatchpoint;
  18. class KThread;
  19. class KProcess;
  20. } // namespace Kernel
  21. namespace Core {
  22. using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>;
  23. // NOTE: these values match the HaltReason enum in Dynarmic
  24. enum class HaltReason : u64 {
  25. StepThread = 0x00000001,
  26. DataAbort = 0x00000004,
  27. BreakLoop = 0x02000000,
  28. SupervisorCall = 0x04000000,
  29. InstructionBreakpoint = 0x08000000,
  30. PrefetchAbort = 0x20000000,
  31. };
  32. DECLARE_ENUM_FLAG_OPERATORS(HaltReason);
  33. enum class Architecture {
  34. AArch64,
  35. AArch32,
  36. };
  37. /// Generic ARMv8 CPU interface
  38. class ArmInterface {
  39. public:
  40. SUYU_NON_COPYABLE(ArmInterface);
  41. SUYU_NON_MOVEABLE(ArmInterface);
  42. explicit ArmInterface(bool uses_wall_clock) : m_uses_wall_clock{uses_wall_clock} {}
  43. virtual ~ArmInterface() = default;
  44. // Perform any backend-specific initialization.
  45. virtual void Initialize() {}
  46. // Runs the CPU until an event happens.
  47. virtual HaltReason RunThread(Kernel::KThread* thread) = 0;
  48. // Runs the CPU for one instruction or until an event happens.
  49. virtual HaltReason StepThread(Kernel::KThread* thread) = 0;
  50. // Admits a backend-specific mechanism to lock the thread context.
  51. virtual void LockThread(Kernel::KThread* thread) {}
  52. virtual void UnlockThread(Kernel::KThread* thread) {}
  53. // Clear the entire instruction cache for this CPU.
  54. virtual void ClearInstructionCache() = 0;
  55. // Clear a range of the instruction cache for this CPU.
  56. virtual void InvalidateCacheRange(u64 addr, std::size_t size) = 0;
  57. // Get the current architecture.
  58. // This returns AArch64 when PSTATE.nRW == 0 and AArch32 when PSTATE.nRW == 1.
  59. virtual Architecture GetArchitecture() const = 0;
  60. // Context accessors.
  61. // These should not be called if the CPU is running.
  62. virtual void GetContext(Kernel::Svc::ThreadContext& ctx) const = 0;
  63. virtual void SetContext(const Kernel::Svc::ThreadContext& ctx) = 0;
  64. virtual void SetTpidrroEl0(u64 value) = 0;
  65. virtual void GetSvcArguments(std::span<uint64_t, 8> args) const = 0;
  66. virtual void SetSvcArguments(std::span<const uint64_t, 8> args) = 0;
  67. virtual u32 GetSvcNumber() const = 0;
  68. void SetWatchpointArray(const WatchpointArray* watchpoints) {
  69. m_watchpoints = watchpoints;
  70. }
  71. // Signal an interrupt for execution to halt as soon as possible.
  72. // It is safe to call this if the CPU is not running.
  73. virtual void SignalInterrupt(Kernel::KThread* thread) = 0;
  74. // Stack trace generation.
  75. void LogBacktrace(Kernel::KProcess* process) const;
  76. // Debug functionality.
  77. virtual const Kernel::DebugWatchpoint* HaltedWatchpoint() const = 0;
  78. virtual void RewindBreakpointInstruction() = 0;
  79. protected:
  80. const Kernel::DebugWatchpoint* MatchingWatchpoint(
  81. u64 addr, u64 size, Kernel::DebugWatchpointType access_type) const;
  82. protected:
  83. const WatchpointArray* m_watchpoints{};
  84. bool m_uses_wall_clock{};
  85. };
  86. } // namespace Core