mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-01 02:37:27 +01:00
kern: use different psr masks for 64 and 32-bit El0 threads
This commit is contained in:
parent
e7e3e7b374
commit
695c125721
@ -36,6 +36,9 @@ namespace ams::kern::arch::arm64::cpu {
|
|||||||
#error "Unknown Board for cpu::NumCores"
|
#error "Unknown Board for cpu::NumCores"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
constexpr inline u32 El0Aarch64PsrMask = 0xF0000000;
|
||||||
|
constexpr inline u32 El0Aarch32PsrMask = 0xFE0FFE20;
|
||||||
|
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
NOINLINE void InitializeInterruptThreads(s32 core_id);
|
NOINLINE void InitializeInterruptThreads(s32 core_id);
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr inline u32 El0PsrMask = 0xFF0FFE20;
|
|
||||||
|
|
||||||
enum EsrEc : u32 {
|
enum EsrEc : u32 {
|
||||||
EsrEc_Unknown = 0b000000,
|
EsrEc_Unknown = 0b000000,
|
||||||
EsrEc_WaitForInterruptOrEvent = 0b000001,
|
EsrEc_WaitForInterruptOrEvent = 0b000001,
|
||||||
@ -134,7 +132,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
info->sp = context->sp;
|
info->sp = context->sp;
|
||||||
info->lr = context->x[30];
|
info->lr = context->x[30];
|
||||||
info->pc = context->pc;
|
info->pc = context->pc;
|
||||||
info->pstate = (context->psr & El0PsrMask);
|
info->pstate = (context->psr & cpu::El0Aarch64PsrMask);
|
||||||
info->afsr0 = afsr0;
|
info->afsr0 = afsr0;
|
||||||
info->afsr1 = afsr1;
|
info->afsr1 = afsr1;
|
||||||
info->esr = esr;
|
info->esr = esr;
|
||||||
@ -151,7 +149,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
info->pc = context->pc;
|
info->pc = context->pc;
|
||||||
info->flags = 1;
|
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.afsr0 = afsr0;
|
||||||
info->status_64.afsr1 = afsr1;
|
info->status_64.afsr1 = afsr1;
|
||||||
info->status_64.esr = esr;
|
info->status_64.esr = esr;
|
||||||
@ -399,7 +397,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
e_ctx->x[30] = info.info64.lr;
|
e_ctx->x[30] = info.info64.lr;
|
||||||
e_ctx->sp = info.info64.sp;
|
e_ctx->sp = info.info64.sp;
|
||||||
e_ctx->pc = info.info64.pc;
|
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 {
|
} else {
|
||||||
for (size_t i = 0; i < util::size(info.info32.r); ++i) {
|
for (size_t i = 0; i < util::size(info.info32.r); ++i) {
|
||||||
e_ctx->x[i] = 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[14] = info.info32.lr;
|
||||||
e_ctx->x[13] = info.info32.sp;
|
e_ctx->x[13] = info.info32.sp;
|
||||||
e_ctx->pc = info.info32.pc;
|
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. */
|
/* Note that PC was adjusted. */
|
||||||
|
@ -37,8 +37,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
static_assert(ForbiddenWatchPointFlagsMask == 0xFFFFFFFF00F0E006ul);
|
static_assert(ForbiddenWatchPointFlagsMask == 0xFFFFFFFF00F0E006ul);
|
||||||
|
|
||||||
constexpr inline u32 El0PsrMask = 0xFF0FFE20;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t KDebug::GetProgramCounter(const KThread &thread) {
|
uintptr_t KDebug::GetProgramCounter(const KThread &thread) {
|
||||||
@ -104,7 +102,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
out->lr = e_ctx->x[30];
|
out->lr = e_ctx->x[30];
|
||||||
out->sp = e_ctx->sp;
|
out->sp = e_ctx->sp;
|
||||||
out->pc = e_ctx->pc;
|
out->pc = e_ctx->pc;
|
||||||
out->pstate = (e_ctx->psr & El0PsrMask);
|
out->pstate = (e_ctx->psr & cpu::El0Aarch64PsrMask);
|
||||||
|
|
||||||
/* Adjust PC if we should. */
|
/* Adjust PC if we should. */
|
||||||
if (e_ctx->write == 0 && thread->IsCallingSvc()) {
|
if (e_ctx->write == 0 && thread->IsCallingSvc()) {
|
||||||
@ -119,7 +117,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
out->lr = 0;
|
out->lr = 0;
|
||||||
out->sp = 0;
|
out->sp = 0;
|
||||||
out->pc = e_ctx->pc;
|
out->pc = e_ctx->pc;
|
||||||
out->pstate = (e_ctx->psr & El0PsrMask);
|
out->pstate = (e_ctx->psr & cpu::El0Aarch32PsrMask);
|
||||||
|
|
||||||
/* Adjust PC if we should. */
|
/* Adjust PC if we should. */
|
||||||
if (e_ctx->write == 0 && thread->IsCallingSvc()) {
|
if (e_ctx->write == 0 && thread->IsCallingSvc()) {
|
||||||
@ -166,7 +164,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
e_ctx->x[30] = ctx.lr;
|
e_ctx->x[30] = ctx.lr;
|
||||||
e_ctx->sp = ctx.sp;
|
e_ctx->sp = ctx.sp;
|
||||||
e_ctx->pc = ctx.pc;
|
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;
|
e_ctx->tpidr = ctx.tpidr;
|
||||||
} else {
|
} else {
|
||||||
e_ctx->x[13] = static_cast<u32>(ctx.r[13]);
|
e_ctx->x[13] = static_cast<u32>(ctx.r[13]);
|
||||||
@ -174,7 +172,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
e_ctx->x[30] = 0;
|
e_ctx->x[30] = 0;
|
||||||
e_ctx->sp = 0;
|
e_ctx->sp = 0;
|
||||||
e_ctx->pc = static_cast<u32>(ctx.pc);
|
e_ctx->pc = static_cast<u32>(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;
|
e_ctx->tpidr = ctx.tpidr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr inline u32 El0PsrMask = 0xFF0FFE20;
|
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsFpuEnabled() {
|
ALWAYS_INLINE bool IsFpuEnabled() {
|
||||||
return cpu::ArchitecturalFeatureAccessControlRegisterAccessor().IsFpEnabled();
|
return cpu::ArchitecturalFeatureAccessControlRegisterAccessor().IsFpEnabled();
|
||||||
}
|
}
|
||||||
@ -191,7 +189,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
out->lr = e_ctx->x[30];
|
out->lr = e_ctx->x[30];
|
||||||
out->sp = e_ctx->sp;
|
out->sp = e_ctx->sp;
|
||||||
out->pc = e_ctx->pc;
|
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. */
|
/* Get the thread's general purpose registers. */
|
||||||
if (thread->IsCallingSvc()) {
|
if (thread->IsCallingSvc()) {
|
||||||
@ -227,7 +225,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
} else {
|
} else {
|
||||||
/* Set special registers. */
|
/* Set special registers. */
|
||||||
out->pc = static_cast<u32>(e_ctx->pc);
|
out->pc = static_cast<u32>(e_ctx->pc);
|
||||||
out->pstate = e_ctx->psr & El0PsrMask;
|
out->pstate = e_ctx->psr & cpu::El0Aarch32PsrMask;
|
||||||
|
|
||||||
/* Get the thread's general purpose registers. */
|
/* Get the thread's general purpose registers. */
|
||||||
for (size_t i = 0; i < 15; ++i) {
|
for (size_t i = 0; i < 15; ++i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user