diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp index c3c915a23..e9ca675ec 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp @@ -232,7 +232,7 @@ namespace ams::kern::arch::arm64::cpu { } ALWAYS_INLINE void SetExceptionThreadStackTop(uintptr_t top) { - SetTpidrEl1(top); + cpu::SetCntvCvalEl0(top); } ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index 7a5fe499c..d8c936e25 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -74,6 +74,7 @@ namespace ams::kern::arch::arm64::cpu { MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntkCtlEl1, cntkctl_el1) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCtlEl0, cntp_ctl_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCvalEl0, cntp_cval_el0) + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntvCvalEl0, cntv_cval_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(Daif, daif) diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager_asm.s b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager_asm.s index bdc23c714..db198a294 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager_asm.s +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager_asm.s @@ -95,9 +95,10 @@ _ZN3ams4kern5board8nintendo2nx13KSleepManager15CpuSleepHandlerEmm: mrs x2, tpidr_el1 stp x1, x2, [x0], #0x10 - /* Save the virtual resumption entrypoint. */ + /* Save the virtual resumption entrypoint and cntv_cval_el0. */ adr x1, 77f - stp x1, xzr, [x0], #0x10 + mrs x2, cntv_cval_el0 + stp x1, x2, [x0], #0x10 /* Get the current core id. */ mrs x0, mpidr_el1 @@ -245,12 +246,13 @@ _ZN3ams4kern5board8nintendo2nx13KSleepManager11ResumeEntryEm: msr tcr_el1, x1 msr mair_el1, x2 - /* Get sctlr, tpidr, and the entrypoint. */ - ldp x1, x2, [x0], #0x10 - ldp x3, xzr, [x0], #0x10 + /* Get sctlr, tpidr, the entrypoint, and cntv_cval_el0. */ + ldp x1, x2, [x0], #0x10 + ldp x3, x4, [x0], #0x10 /* Set the global context back into x18/tpidr. */ msr tpidr_el1, x2 + msr cntv_cval_el0, x4 dsb sy isb diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 98cd02ed8..6ca985e31 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -125,9 +125,6 @@ namespace ams::kern::init { /* Ensure our first argument is page aligned (as we will map it if it is non-zero). */ MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(misc_unk_debug_phys_addr, PageSize)); - /* Clear TPIDR_EL1 to zero. */ - cpu::ThreadIdRegisterAccessor(0).Store(); - /* Restore the page allocator state setup by kernel loader. */ g_initial_page_allocator.InitializeFromState(initial_page_allocator_state); @@ -476,6 +473,7 @@ namespace ams::kern::init { void InitializeExceptionVectors() { cpu::SetVbarEl1(reinterpret_cast(::ams::kern::ExceptionVectors)); + cpu::SetTpidrEl1(0); cpu::SetExceptionThreadStackTop(0); cpu::EnsureInstructionConsistency(); } diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index e6c8288af..398440c7d 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -227,9 +227,9 @@ _ZN3ams4kern4init16InvokeEntrypointEPKNS1_14KInitArgumentsE: /* Ensure that the exception vectors are setup. */ bl _ZN3ams4kern4init26InitializeExceptionVectorsEv - /* Setup the exception stack in tpidr_el1. */ + /* Setup the exception stack in cntv_cval_el0. */ ldr x1, [x20, #0x58] - msr tpidr_el1, x1 + msr cntv_cval_el0, x1 /* Jump to the entrypoint. */ ldr x1, [x20, #0x40] diff --git a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s index f7645ee1e..2c8f1936d 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -281,8 +281,8 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: .global _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv .type _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv, %function _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: - /* Nintendo uses the "unused" virtual timer compare value as a scratch register. */ - msr cntv_cval_el0, x0 + /* Nintendo uses tpidr_el1 as a scratch register. */ + msr tpidr_el1, x0 /* Get and parse the exception syndrome register. */ mrs x0, esr_el1 @@ -297,18 +297,21 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: b.eq 5f 1: /* The exception is not a data abort or instruction abort caused by a TLB conflict. */ - /* Load the exception stack top from tpidr_el1. */ - mrs x0, tpidr_el1 + /* Load the exception stack top from otherwise "unused" virtual timer compare value. */ + mrs x0, cntv_cval_el0 /* Setup the stack for a generic exception handle */ + lsl x0, x0, #8 + asr x0, x0, #8 sub x0, x0, #0x20 - str x1, [x0, #16] + str x1, [x0, #8] mov x1, sp str x1, [x0] mov sp, x0 - ldr x1, [x0, #16] - mrs x0, cntv_cval_el0 + ldr x1, [x0, #8] + mrs x0, tpidr_el1 str x0, [sp, #8] + str x1, [sp, #16] /* Check again if this is a data abort from EL1. */ mrs x0, esr_el1 @@ -406,7 +409,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: isb /* Restore x0 from scratch. */ - mrs x0, cntv_cval_el0 + mrs x0, tpidr_el1 /* Return from the exception. */ eret @@ -474,21 +477,22 @@ _ZN3ams4kern4arch5arm6425FpuAccessExceptionHandlerEv: .global _ZN3ams4kern4arch5arm6421EL1SystemErrorHandlerEv .type _ZN3ams4kern4arch5arm6421EL1SystemErrorHandlerEv, %function _ZN3ams4kern4arch5arm6421EL1SystemErrorHandlerEv: - /* Nintendo uses the "unused" virtual timer compare value as a scratch register. */ - msr cntv_cval_el0, x0 + /* Nintendo uses tpidr_el1 as a scratch register. */ + msr tpidr_el1, x0 - /* Load the exception stack top from tpidr_el1. */ - mrs x0, tpidr_el1 + /* Load the exception stack top from otherwise "unused" virtual timer compare value. */ + mrs x0, cntv_cval_el0 /* Setup the stack for a generic exception handle */ + lsl x0, x0, #8 + asr x0, x0, #8 sub x0, x0, #0x20 - str x1, [x0, #16] + str x1, [x0, #8] mov x1, sp str x1, [x0] mov sp, x0 - ldr x1, [x0, #16] - mrs x0, cntv_cval_el0 - str x0, [sp, #8] + ldr x1, [x0, #8] + mrs x0, tpidr_el1 /* Create a KExceptionContext to pass to HandleException. */ sub sp, sp, #0x120 diff --git a/mesosphere/kernel_ldr/source/arch/arm64/start.s b/mesosphere/kernel_ldr/source/arch/arm64/start.s index f8610ae72..9254d065f 100644 --- a/mesosphere/kernel_ldr/source/arch/arm64/start.s +++ b/mesosphere/kernel_ldr/source/arch/arm64/start.s @@ -89,7 +89,8 @@ _main: bl _ZN3ams4kern4init3Elf18CallInitArrayFuncsEmm /* Setup system registers, for detection of errors during init later. */ - msr tpidr_el1, xzr /* Clear TPIDR_EL1 */ + msr tpidr_el1, xzr + msr cntv_cval_el0, xzr adr x0, __external_references adr x1, _start ldr x0, [x0, #0x30]