diff --git a/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index d816b155..408f0518 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -40,6 +40,8 @@ namespace ams::kern::arm64::cpu { MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(TcrEl1, tcr_el1) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(MairEl1, mair_el1) + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(VbarEl1, vbar_el1) + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(SctlrEl1, sctlr_el1) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CpuActlrEl1, s3_1_c15_c2_0) @@ -47,6 +49,24 @@ namespace ams::kern::arm64::cpu { MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CsselrEl1, csselr_el1) + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(OslarEl1, oslar_el1) + + #define FOR_I_IN_0_TO_15(HANDLER, ...) \ + HANDLER(0, ## __VA_ARGS__) HANDLER(1, ## __VA_ARGS__) HANDLER(2, ## __VA_ARGS__) HANDLER(3, ## __VA_ARGS__) \ + HANDLER(4, ## __VA_ARGS__) HANDLER(5, ## __VA_ARGS__) HANDLER(6, ## __VA_ARGS__) HANDLER(7, ## __VA_ARGS__) \ + HANDLER(8, ## __VA_ARGS__) HANDLER(9, ## __VA_ARGS__) HANDLER(10, ## __VA_ARGS__) HANDLER(11, ## __VA_ARGS__) \ + HANDLER(12, ## __VA_ARGS__) HANDLER(13, ## __VA_ARGS__) HANDLER(14, ## __VA_ARGS__) HANDLER(15, ## __VA_ARGS__) \ + + #define MESOSPHERE_CPU_DEFINE_DBG_SYSREG_ACCESSORS(ID, ...) \ + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(DbgWcr##ID##El1, dbgwcr##ID##_el1) \ + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(DbgWvr##ID##El1, dbgwvr##ID##_el1) \ + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(DbgBcr##ID##El1, dbgbcr##ID##_el1) \ + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(DbgBvr##ID##El1, dbgbvr##ID##_el1) + + FOR_I_IN_0_TO_15(MESOSPHERE_CPU_DEFINE_DBG_SYSREG_ACCESSORS) + + #undef MESOSPHERE_CPU_DEFINE_DBG_SYSREG_ACCESSORS + /* Base class for register accessors. */ class GenericRegisterAccessorBase { NON_COPYABLE(GenericRegisterAccessorBase); @@ -63,6 +83,21 @@ namespace ams::kern::arm64::cpu { constexpr ALWAYS_INLINE u64 GetBits(size_t offset, size_t count) const { return (this->value >> offset) & ((1ul << count) - 1); } + + constexpr ALWAYS_INLINE void SetBits(size_t offset, size_t count, u64 value) { + const u64 mask = ((1ul << count) - 1) << offset; + this->value &= ~mask; + this->value |= (value & mask) << offset; + } + + constexpr ALWAYS_INLINE void SetBit(size_t offset, bool enabled) { + const u64 mask = 1ul << offset; + if (enabled) { + this->value |= mask; + } else { + this->value &= ~mask; + } + } }; template @@ -98,6 +133,43 @@ namespace ams::kern::arm64::cpu { return size_t(1) << (size_t(64) - shift_value); } }; + + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(DebugFeature) { + public: + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(DebugFeature, id_aa64dfr0_el1) + + constexpr ALWAYS_INLINE size_t GetNumWatchpoints() const { + return this->GetBits(20, 4); + } + + constexpr ALWAYS_INLINE size_t GetNumBreakpoints() const { + return this->GetBits(12, 4); + } + }; + + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(MonitorDebugSystemControl) { + public: + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(MonitorDebugSystemControl, mdscr_el1) + + constexpr ALWAYS_INLINE bool GetMde() const { + return this->GetBits(15, 1) != 0; + } + + constexpr ALWAYS_INLINE size_t GetTdcc() const { + return this->GetBits(12, 1) != 0; + } + + constexpr ALWAYS_INLINE decltype(auto) SetMde(bool set) { + this->SetBit(15, set); + return *this; + } + + constexpr ALWAYS_INLINE decltype(auto) SetTdcc(bool set) { + this->SetBit(12, set); + return *this; + } + }; + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(MultiprocessorAffinity) { public: MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(MultiprocessorAffinity, mpidr_el1) @@ -129,6 +201,21 @@ namespace ams::kern::arm64::cpu { MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(ThreadId, tpidr_el1) }; + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(OsLockAccess) { + public: + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(OsLockAccess, oslar_el1) + }; + + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(ContextId) { + public: + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(ContextId, contextidr_el1) + + constexpr ALWAYS_INLINE decltype(auto) SetProcId(u32 proc_id) { + this->SetBits(0, BITSIZEOF(proc_id), proc_id); + return *this; + } + }; + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(MainId) { public: enum class Implementer { @@ -197,6 +284,7 @@ namespace ams::kern::arm64::cpu { /* TODO: Other bitfield accessors? */ }; + #undef FOR_I_IN_0_TO_15 #undef MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS #undef MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS #undef MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS