mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
kern: optimize hw-single-step management
This commit is contained in:
parent
05ea0c53d7
commit
9e7b56b33c
7 changed files with 102 additions and 125 deletions
|
@ -265,6 +265,10 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
return this->GetBits(12, 1) != 0;
|
return this->GetBits(12, 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE bool GetSoftwareStep() const {
|
||||||
|
return this->GetBits(0, 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE decltype(auto) SetMde(bool set) {
|
constexpr ALWAYS_INLINE decltype(auto) SetMde(bool set) {
|
||||||
this->SetBit(15, set);
|
this->SetBit(15, set);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -274,6 +278,11 @@ namespace ams::kern::arch::arm64::cpu {
|
||||||
this->SetBit(12, set);
|
this->SetBit(12, set);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE decltype(auto) SetSoftwareStep(bool set) {
|
||||||
|
this->SetBit(0, set);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(MultiprocessorAffinity) {
|
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(MultiprocessorAffinity) {
|
||||||
|
|
|
@ -109,6 +109,15 @@ namespace ams::kern::arch::arm64 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we should, clear the thread's state as single-step. */
|
||||||
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
if (AMS_UNLIKELY(GetCurrentThread().IsSingleStep())) {
|
||||||
|
GetCurrentThread().ClearSingleStep();
|
||||||
|
cpu::MonitorDebugSystemControlRegisterAccessor().SetSoftwareStep(false).Store();
|
||||||
|
cpu::EnsureInstructionConsistency();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If we should process the user exception (and it's not a breakpoint), try to enter. */
|
/* If we should process the user exception (and it's not a breakpoint), try to enter. */
|
||||||
const bool is_software_break = (ec == EsrEc_Unknown || ec == EsrEc_IllegalExecution || ec == EsrEc_BkptInstruction || ec == EsrEc_BrkInstruction);
|
const bool is_software_break = (ec == EsrEc_Unknown || ec == EsrEc_IllegalExecution || ec == EsrEc_BkptInstruction || ec == EsrEc_BrkInstruction);
|
||||||
const bool is_breakpoint = (ec == EsrEc_BreakPointEl0 || ec == EsrEc_SoftwareStepEl0 || ec == EsrEc_WatchPointEl0);
|
const bool is_breakpoint = (ec == EsrEc_BreakPointEl0 || ec == EsrEc_SoftwareStepEl0 || ec == EsrEc_WatchPointEl0);
|
||||||
|
@ -290,16 +299,40 @@ namespace ams::kern::arch::arm64 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print that an exception occurred. */
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
MESOSPHERE_RELEASE_LOG("Exception occurred. %016lx\n", GetCurrentProcess().GetProgramId());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Print the current thread's registers. */
|
if (ec != EsrEc_SoftwareStepEl0) {
|
||||||
KDebug::PrintRegister();
|
/* If the exception wasn't single-step, print details. */
|
||||||
|
MESOSPHERE_RELEASE_LOG("Exception occurred. %016lx\n", GetCurrentProcess().GetProgramId());
|
||||||
|
|
||||||
/* Print a backtrace. */
|
{
|
||||||
KDebug::PrintBacktrace();
|
/* Print the current thread's registers. */
|
||||||
|
KDebug::PrintRegister();
|
||||||
|
|
||||||
|
/* Print a backtrace. */
|
||||||
|
KDebug::PrintBacktrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If the exception was single-step and we have no debug object, we should just return. */
|
||||||
|
if (AMS_UNLIKELY(!cur_process.IsAttachedToDebugger())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* Print that an exception occurred. */
|
||||||
|
MESOSPHERE_RELEASE_LOG("Exception occurred. %016lx\n", GetCurrentProcess().GetProgramId());
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Print the current thread's registers. */
|
||||||
|
KDebug::PrintRegister();
|
||||||
|
|
||||||
|
/* Print a backtrace. */
|
||||||
|
KDebug::PrintBacktrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If the SVC is handled, handle it. */
|
/* If the SVC is handled, handle it. */
|
||||||
if (!svc::ResultNotHandled::Includes(result)) {
|
if (!svc::ResultNotHandled::Includes(result)) {
|
||||||
|
@ -559,6 +592,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
KDpcManager::HandleDpc();
|
KDpcManager::HandleDpc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that we're no longer in an exception handler. */
|
/* Note that we're no longer in an exception handler. */
|
||||||
GetCurrentThread().ClearInExceptionHandler();
|
GetCurrentThread().ClearInExceptionHandler();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,39 +15,6 @@
|
||||||
*/
|
*/
|
||||||
#include <mesosphere/kern_select_assembly_offsets.h>
|
#include <mesosphere/kern_select_assembly_offsets.h>
|
||||||
|
|
||||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
/* Clear MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch, mdscr_el1
|
|
||||||
bic \scratch, \scratch, #1
|
|
||||||
msr mdscr_el1, \scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
/* Check if single-step is requested. */
|
|
||||||
ldrb \scratch1, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_SINGLE_STEP)]
|
|
||||||
tbz \scratch1, #0, .skip_single_step\@
|
|
||||||
|
|
||||||
/* If single-step is requested, enable the single-step machine by setting MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch2, mdscr_el1
|
|
||||||
orr \scratch2, \scratch2, #1
|
|
||||||
msr mdscr_el1, \scratch2
|
|
||||||
|
|
||||||
/* Since we're returning from an exception, set SPSR.SS so we actually advance an instruction. */
|
|
||||||
orr \spsr_value, \spsr_value, #(1 << 21)
|
|
||||||
|
|
||||||
isb
|
|
||||||
|
|
||||||
.skip_single_step\@:
|
|
||||||
.endm
|
|
||||||
#else
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
.endm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ams::kern::svc::CallReturnFromException64(Result result) */
|
/* ams::kern::svc::CallReturnFromException64(Result result) */
|
||||||
.section .text._ZN3ams4kern3svc25CallReturnFromException64Ev, "ax", %progbits
|
.section .text._ZN3ams4kern3svc25CallReturnFromException64Ev, "ax", %progbits
|
||||||
.global _ZN3ams4kern3svc25CallReturnFromException64Ev
|
.global _ZN3ams4kern3svc25CallReturnFromException64Ev
|
||||||
|
@ -123,7 +90,10 @@ _ZN3ams4kern3svc14RestoreContextEm:
|
||||||
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w0, x0, x10
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an exception, set SPSR.SS so that we advance an instruction if single-stepping. */
|
||||||
|
orr x22, x22, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr sp_el0, x8
|
msr sp_el0, x8
|
||||||
msr elr_el1, x9
|
msr elr_el1, x9
|
||||||
|
|
|
@ -16,39 +16,6 @@
|
||||||
#include <mesosphere/kern_build_config.hpp>
|
#include <mesosphere/kern_build_config.hpp>
|
||||||
#include <mesosphere/kern_select_assembly_offsets.h>
|
#include <mesosphere/kern_select_assembly_offsets.h>
|
||||||
|
|
||||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
/* Clear MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch, mdscr_el1
|
|
||||||
bic \scratch, \scratch, #1
|
|
||||||
msr mdscr_el1, \scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
/* Check if single-step is requested. */
|
|
||||||
ldrb \scratch1, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_SINGLE_STEP)]
|
|
||||||
tbz \scratch1, #0, .skip_single_step\@
|
|
||||||
|
|
||||||
/* If single-step is requested, enable the single-step machine by setting MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch2, mdscr_el1
|
|
||||||
orr \scratch2, \scratch2, #1
|
|
||||||
msr mdscr_el1, \scratch2
|
|
||||||
|
|
||||||
/* Since we're returning from an SVC, make sure SPSR.SS is cleared so we break instantly on the instruction after the SVC. */
|
|
||||||
bic \spsr_value, \spsr_value, #(1 << 21)
|
|
||||||
|
|
||||||
isb
|
|
||||||
|
|
||||||
.skip_single_step\@:
|
|
||||||
.endm
|
|
||||||
#else
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
.endm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ams::kern::arch::arm64::SvcHandler64() */
|
/* ams::kern::arch::arm64::SvcHandler64() */
|
||||||
.section .text._ZN3ams4kern4arch5arm6412SvcHandler64Ev, "ax", %progbits
|
.section .text._ZN3ams4kern4arch5arm6412SvcHandler64Ev, "ax", %progbits
|
||||||
.global _ZN3ams4kern4arch5arm6412SvcHandler64Ev
|
.global _ZN3ams4kern4arch5arm6412SvcHandler64Ev
|
||||||
|
@ -84,9 +51,6 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
|
||||||
stp x8, x9, [sp, #(EXCEPTION_CONTEXT_SP_PC)]
|
stp x8, x9, [sp, #(EXCEPTION_CONTEXT_SP_PC)]
|
||||||
stp x10, x11, [sp, #(EXCEPTION_CONTEXT_PSR_TPIDR)]
|
stp x10, x11, [sp, #(EXCEPTION_CONTEXT_PSR_TPIDR)]
|
||||||
|
|
||||||
/* Disable single-step. */
|
|
||||||
disable_single_step x8
|
|
||||||
|
|
||||||
/* Check if the SVC index is out of range. */
|
/* Check if the SVC index is out of range. */
|
||||||
mrs x8, esr_el1
|
mrs x8, esr_el1
|
||||||
and x8, x8, #0xFF
|
and x8, x8, #0xFF
|
||||||
|
@ -191,7 +155,10 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
|
||||||
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x9, x10, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w0, x0, x10
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an SVC, make sure SPSR.SS is cleared so that if we're single-stepping we break instantly on the instruction after the SVC. */
|
||||||
|
bic x10, x10, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr sp_el0, x8
|
msr sp_el0, x8
|
||||||
msr elr_el1, x9
|
msr elr_el1, x9
|
||||||
|
@ -243,7 +210,10 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
|
||||||
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x11, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
ldr x18, [sp, #(EXCEPTION_CONTEXT_X18)]
|
ldr x18, [sp, #(EXCEPTION_CONTEXT_X18)]
|
||||||
|
|
||||||
check_enable_single_step w12, x12, x10
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an SVC, make sure SPSR.SS is cleared so that if we're single-stepping we break instantly on the instruction after the SVC. */
|
||||||
|
bic x10, x10, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr sp_el0, x8
|
msr sp_el0, x8
|
||||||
msr elr_el1, x9
|
msr elr_el1, x9
|
||||||
|
@ -302,9 +272,6 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
|
||||||
stp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
|
stp x12, x13, [sp, #(EXCEPTION_CONTEXT_X12_X13)]
|
||||||
stp x14, xzr, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
|
stp x14, xzr, [sp, #(EXCEPTION_CONTEXT_X14_X15)]
|
||||||
|
|
||||||
/* Disable single-step. */
|
|
||||||
disable_single_step x8
|
|
||||||
|
|
||||||
/* Check if the SVC index is out of range. */
|
/* Check if the SVC index is out of range. */
|
||||||
mrs x16, esr_el1
|
mrs x16, esr_el1
|
||||||
and x16, x16, #0xFF
|
and x16, x16, #0xFF
|
||||||
|
@ -405,7 +372,10 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
|
||||||
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w0, x0, x20
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an SVC, make sure SPSR.SS is cleared so that if we're single-stepping we break instantly on the instruction after the SVC. */
|
||||||
|
bic x20, x20, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr elr_el1, x17
|
msr elr_el1, x17
|
||||||
msr spsr_el1, x20
|
msr spsr_el1, x20
|
||||||
|
@ -451,7 +421,10 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
|
||||||
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x17, x20, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x19, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w21, x21, x20
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an SVC, make sure SPSR.SS is cleared so that if we're single-stepping we break instantly on the instruction after the SVC. */
|
||||||
|
bic x20, x20, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr elr_el1, x17
|
msr elr_el1, x17
|
||||||
msr spsr_el1, x20
|
msr spsr_el1, x20
|
||||||
|
|
|
@ -372,6 +372,7 @@ namespace ams::kern {
|
||||||
new_state = state;
|
new_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
/* Clear single step on all threads. */
|
/* Clear single step on all threads. */
|
||||||
{
|
{
|
||||||
auto end = target->GetThreadList().end();
|
auto end = target->GetThreadList().end();
|
||||||
|
@ -379,6 +380,7 @@ namespace ams::kern {
|
||||||
it->ClearSingleStep();
|
it->ClearSingleStep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Detach from the process. */
|
/* Detach from the process. */
|
||||||
target->ClearDebugObject(new_state);
|
target->ClearDebugObject(new_state);
|
||||||
|
@ -900,8 +902,10 @@ namespace ams::kern {
|
||||||
{
|
{
|
||||||
auto end = process->GetThreadList().end();
|
auto end = process->GetThreadList().end();
|
||||||
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
|
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
|
||||||
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
/* Clear the thread's single-step state. */
|
/* Clear the thread's single-step state. */
|
||||||
it->ClearSingleStep();
|
it->ClearSingleStep();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (resume) {
|
if (resume) {
|
||||||
/* If the process isn't crashed, resume threads. */
|
/* If the process isn't crashed, resume threads. */
|
||||||
|
@ -993,7 +997,6 @@ namespace ams::kern {
|
||||||
/* If the event is an exception, set the result and clear single step. */
|
/* If the event is an exception, set the result and clear single step. */
|
||||||
if (event == ams::svc::DebugEvent_Exception) {
|
if (event == ams::svc::DebugEvent_Exception) {
|
||||||
GetCurrentThread().SetDebugExceptionResult(ResultSuccess());
|
GetCurrentThread().SetDebugExceptionResult(ResultSuccess());
|
||||||
GetCurrentThread().ClearSingleStep();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit our retry loop. */
|
/* Exit our retry loop. */
|
||||||
|
|
|
@ -15,39 +15,6 @@
|
||||||
*/
|
*/
|
||||||
#include <mesosphere/kern_select_assembly_offsets.h>
|
#include <mesosphere/kern_select_assembly_offsets.h>
|
||||||
|
|
||||||
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
/* Clear MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch, mdscr_el1
|
|
||||||
bic \scratch, \scratch, #1
|
|
||||||
msr mdscr_el1, \scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
/* Check if single-step is requested. */
|
|
||||||
ldrb \scratch1, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_IS_SINGLE_STEP)]
|
|
||||||
tbz \scratch1, #0, .skip_single_step\@
|
|
||||||
|
|
||||||
/* If single-step is requested, enable the single-step machine by setting MDSCR_EL1.SS. */
|
|
||||||
mrs \scratch2, mdscr_el1
|
|
||||||
orr \scratch2, \scratch2, #1
|
|
||||||
msr mdscr_el1, \scratch2
|
|
||||||
|
|
||||||
/* Since we're returning from an exception, set SPSR.SS so we actually advance an instruction. */
|
|
||||||
orr \spsr_value, \spsr_value, #(1 << 21)
|
|
||||||
|
|
||||||
isb
|
|
||||||
|
|
||||||
.skip_single_step\@:
|
|
||||||
.endm
|
|
||||||
#else
|
|
||||||
.macro disable_single_step, scratch
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro check_enable_single_step, scratch1, scratch2, spsr_value
|
|
||||||
.endm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ams::kern::arch::arm64::EL1IrqExceptionHandler() */
|
/* ams::kern::arch::arm64::EL1IrqExceptionHandler() */
|
||||||
.section .text._ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv, "ax", %progbits
|
.section .text._ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv, "ax", %progbits
|
||||||
.global _ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv
|
.global _ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv
|
||||||
|
@ -133,8 +100,6 @@ _ZN3ams4kern4arch5arm6422EL0IrqExceptionHandlerEv:
|
||||||
stp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
stp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
str x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
str x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
disable_single_step x0
|
|
||||||
|
|
||||||
/* Invoke KInterruptManager::HandleInterrupt(bool user_mode). */
|
/* Invoke KInterruptManager::HandleInterrupt(bool user_mode). */
|
||||||
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
|
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
|
||||||
mov x0, #1
|
mov x0, #1
|
||||||
|
@ -145,7 +110,10 @@ _ZN3ams4kern4arch5arm6422EL0IrqExceptionHandlerEv:
|
||||||
ldp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w0, x0, x22
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an exception, set SPSR.SS so that we advance an instruction if single-stepping. */
|
||||||
|
orr x22, x22, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr sp_el0, x20
|
msr sp_el0, x20
|
||||||
msr elr_el1, x21
|
msr elr_el1, x21
|
||||||
|
@ -239,8 +207,6 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv:
|
||||||
stp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
stp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
str x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
str x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
disable_single_step x16
|
|
||||||
|
|
||||||
/* Call ams::kern::arch::arm64::HandleException(ams::kern::arch::arm64::KExceptionContext *) */
|
/* Call ams::kern::arch::arm64::HandleException(ams::kern::arch::arm64::KExceptionContext *) */
|
||||||
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
|
ldr x18, [sp, #(EXCEPTION_CONTEXT_SIZE + THREAD_STACK_PARAMETERS_CUR_THREAD)]
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
|
@ -251,7 +217,10 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv:
|
||||||
ldp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
ldp x21, x22, [sp, #(EXCEPTION_CONTEXT_PC_PSR)]
|
||||||
ldr x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
ldr x23, [sp, #(EXCEPTION_CONTEXT_TPIDR)]
|
||||||
|
|
||||||
check_enable_single_step w0, x0, x22
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
/* Since we're returning from an exception, set SPSR.SS so that we advance an instruction if single-stepping. */
|
||||||
|
orr x22, x22, #(1 << 21)
|
||||||
|
#endif
|
||||||
|
|
||||||
msr sp_el0, x20
|
msr sp_el0, x20
|
||||||
msr elr_el1, x21
|
msr elr_el1, x21
|
||||||
|
|
|
@ -235,7 +235,26 @@ _ZN3ams4kern10KScheduler12ScheduleImplEv:
|
||||||
mov x0, x22
|
mov x0, x22
|
||||||
RESTORE_THREAD_CONTEXT(x0, x1, x2, 9f)
|
RESTORE_THREAD_CONTEXT(x0, x1, x2, 9f)
|
||||||
|
|
||||||
9: /* We're done restoring the thread context, and can return safely. */
|
9: /* Configure single-step, if we should. */
|
||||||
|
#if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP)
|
||||||
|
|
||||||
|
/* Get a reference to the new thread's stack parameters. */
|
||||||
|
add x2, sp, #0x1000
|
||||||
|
and x2, x2, #~(0x1000-1)
|
||||||
|
|
||||||
|
/* Read the single-step flag. */
|
||||||
|
ldurb w2, [x2, #-(THREAD_STACK_PARAMETERS_SIZE - THREAD_STACK_PARAMETERS_IS_SINGLE_STEP)]
|
||||||
|
|
||||||
|
/* Update the single-step bit in mdscr_el1. */
|
||||||
|
mrs x1, mdscr_el1
|
||||||
|
bic x1, x1, #1
|
||||||
|
orr x1, x1, x2
|
||||||
|
msr mdscr_el1, x1
|
||||||
|
|
||||||
|
isb
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We're done restoring the thread context, and can return safely. */
|
||||||
ret
|
ret
|
||||||
|
|
||||||
10: /* Our switch failed. */
|
10: /* Our switch failed. */
|
||||||
|
|
Loading…
Reference in a new issue