From 154d61f55f250c9a8d7b4484e5c691040e1d95d0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 21 Feb 2023 03:20:49 -0700 Subject: [PATCH] kern: use different psr masks for 64 and 32-bit El0 threads --- .../include/mesosphere/arch/arm64/kern_cpu.hpp | 3 +++ .../source/arch/arm64/kern_exception_handlers.cpp | 10 ++++------ .../libmesosphere/source/arch/arm64/kern_k_debug.cpp | 10 ++++------ .../source/arch/arm64/kern_k_thread_context.cpp | 6 ++---- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp index 2876f7497..164042d5c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp @@ -36,6 +36,9 @@ namespace ams::kern::arch::arm64::cpu { #error "Unknown Board for cpu::NumCores" #endif + constexpr inline u32 El0Aarch64PsrMask = 0xF0000000; + constexpr inline u32 El0Aarch32PsrMask = 0xFE0FFE20; + /* Initialization. */ NOINLINE void InitializeInterruptThreads(s32 core_id); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index 52a2e5ced..cb14d2b93 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -25,8 +25,6 @@ namespace ams::kern::arch::arm64 { namespace { - constexpr inline u32 El0PsrMask = 0xFF0FFE20; - enum EsrEc : u32 { EsrEc_Unknown = 0b000000, EsrEc_WaitForInterruptOrEvent = 0b000001, @@ -134,7 +132,7 @@ namespace ams::kern::arch::arm64 { info->sp = context->sp; info->lr = context->x[30]; info->pc = context->pc; - info->pstate = (context->psr & El0PsrMask); + info->pstate = (context->psr & cpu::El0Aarch64PsrMask); info->afsr0 = afsr0; info->afsr1 = afsr1; info->esr = esr; @@ -151,7 +149,7 @@ namespace ams::kern::arch::arm64 { info->pc = context->pc; info->flags = 1; - info->status_64.pstate = (context->psr & El0PsrMask); + info->status_64.pstate = (context->psr & cpu::El0Aarch32PsrMask); info->status_64.afsr0 = afsr0; info->status_64.afsr1 = afsr1; info->status_64.esr = esr; @@ -399,7 +397,7 @@ namespace ams::kern::arch::arm64 { e_ctx->x[30] = info.info64.lr; e_ctx->sp = info.info64.sp; e_ctx->pc = info.info64.pc; - e_ctx->psr = (info.info64.pstate & El0PsrMask) | (e_ctx->psr & ~El0PsrMask); + e_ctx->psr = (info.info64.pstate & cpu::El0Aarch64PsrMask) | (e_ctx->psr & ~cpu::El0Aarch64PsrMask); } else { for (size_t i = 0; i < util::size(info.info32.r); ++i) { e_ctx->x[i] = info.info32.r[i]; @@ -407,7 +405,7 @@ namespace ams::kern::arch::arm64 { e_ctx->x[14] = info.info32.lr; e_ctx->x[13] = info.info32.sp; e_ctx->pc = info.info32.pc; - e_ctx->psr = (info.info32.status_64.pstate & El0PsrMask) | (e_ctx->psr & ~El0PsrMask); + e_ctx->psr = (info.info32.status_64.pstate & cpu::El0Aarch32PsrMask) | (e_ctx->psr & ~cpu::El0Aarch32PsrMask); } /* Note that PC was adjusted. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 032cdea31..fd2ee3821 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -37,8 +37,6 @@ namespace ams::kern::arch::arm64 { static_assert(ForbiddenWatchPointFlagsMask == 0xFFFFFFFF00F0E006ul); - constexpr inline u32 El0PsrMask = 0xFF0FFE20; - } uintptr_t KDebug::GetProgramCounter(const KThread &thread) { @@ -104,7 +102,7 @@ namespace ams::kern::arch::arm64 { out->lr = e_ctx->x[30]; out->sp = e_ctx->sp; out->pc = e_ctx->pc; - out->pstate = (e_ctx->psr & El0PsrMask); + out->pstate = (e_ctx->psr & cpu::El0Aarch64PsrMask); /* Adjust PC if we should. */ if (e_ctx->write == 0 && thread->IsCallingSvc()) { @@ -119,7 +117,7 @@ namespace ams::kern::arch::arm64 { out->lr = 0; out->sp = 0; out->pc = e_ctx->pc; - out->pstate = (e_ctx->psr & El0PsrMask); + out->pstate = (e_ctx->psr & cpu::El0Aarch32PsrMask); /* Adjust PC if we should. */ if (e_ctx->write == 0 && thread->IsCallingSvc()) { @@ -166,7 +164,7 @@ namespace ams::kern::arch::arm64 { e_ctx->x[30] = ctx.lr; e_ctx->sp = ctx.sp; e_ctx->pc = ctx.pc; - e_ctx->psr = ((ctx.pstate & El0PsrMask) | (e_ctx->psr & ~El0PsrMask)); + e_ctx->psr = ((ctx.pstate & cpu::El0Aarch64PsrMask) | (e_ctx->psr & ~cpu::El0Aarch64PsrMask)); e_ctx->tpidr = ctx.tpidr; } else { e_ctx->x[13] = static_cast(ctx.r[13]); @@ -174,7 +172,7 @@ namespace ams::kern::arch::arm64 { e_ctx->x[30] = 0; e_ctx->sp = 0; e_ctx->pc = static_cast(ctx.pc); - e_ctx->psr = ((ctx.pstate & El0PsrMask) | (e_ctx->psr & ~El0PsrMask)); + e_ctx->psr = ((ctx.pstate & cpu::El0Aarch32PsrMask) | (e_ctx->psr & ~cpu::El0Aarch32PsrMask)); e_ctx->tpidr = ctx.tpidr; } } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp index 926300601..0e93d95eb 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -40,8 +40,6 @@ namespace ams::kern::arch::arm64 { namespace { - constexpr inline u32 El0PsrMask = 0xFF0FFE20; - ALWAYS_INLINE bool IsFpuEnabled() { return cpu::ArchitecturalFeatureAccessControlRegisterAccessor().IsFpEnabled(); } @@ -191,7 +189,7 @@ namespace ams::kern::arch::arm64 { out->lr = e_ctx->x[30]; out->sp = e_ctx->sp; out->pc = e_ctx->pc; - out->pstate = e_ctx->psr & El0PsrMask; + out->pstate = e_ctx->psr & cpu::El0Aarch64PsrMask; /* Get the thread's general purpose registers. */ if (thread->IsCallingSvc()) { @@ -227,7 +225,7 @@ namespace ams::kern::arch::arm64 { } else { /* Set special registers. */ out->pc = static_cast(e_ctx->pc); - out->pstate = e_ctx->psr & El0PsrMask; + out->pstate = e_ctx->psr & cpu::El0Aarch32PsrMask; /* Get the thread's general purpose registers. */ for (size_t i = 0; i < 15; ++i) {