mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
thermosphere: add esr_el2 to exception frame
This commit is contained in:
parent
744491ca33
commit
418cabbd53
6 changed files with 39 additions and 34 deletions
|
@ -26,9 +26,14 @@ static Barrier g_debugPauseBarrier;
|
|||
static atomic_uint g_debugPausePausedCoreList;
|
||||
static atomic_uint g_debugPauseSingleStepCoreList;
|
||||
|
||||
void debugPauseSgiHandler(void)
|
||||
static inline void debugSetThisCorePaused(void)
|
||||
{
|
||||
currentCoreCtx->wasPaused = true;
|
||||
}
|
||||
|
||||
void debugPauseSgiHandler(void)
|
||||
{
|
||||
debugSetThisCorePaused();
|
||||
barrierWait(&g_debugPauseBarrier);
|
||||
}
|
||||
|
||||
|
@ -76,7 +81,7 @@ void debugPauseCores(u32 coreList)
|
|||
}
|
||||
|
||||
if (remainingList & BIT(currentCoreCtx->coreId)) {
|
||||
currentCoreCtx->wasPaused = true;
|
||||
debugSetThisCorePaused();
|
||||
}
|
||||
|
||||
unmaskIrq();
|
||||
|
|
|
@ -176,8 +176,9 @@ _saveMostRegisters:
|
|||
mrs x21, sp_el0
|
||||
mrs x22, elr_el2
|
||||
mrs x23, spsr_el2
|
||||
mov x24, x28 // far_el2
|
||||
mov x25, x29 // cntpct_el0
|
||||
mrs x24, esr_el2
|
||||
mov x25, x28 // far_el2
|
||||
mov x26, x29 // cntpct_el0
|
||||
|
||||
// See SAVE_MOST_REGISTERS macro
|
||||
ldp x28, x29, [sp, #-0x20]
|
||||
|
@ -187,7 +188,7 @@ _saveMostRegisters:
|
|||
stp x19, x20, [sp, #0xF0]
|
||||
stp x21, x22, [sp, #0x100]
|
||||
stp x23, x24, [sp, #0x110]
|
||||
stp x25, xzr, [sp, #0x120]
|
||||
stp x25, x26, [sp, #0x120]
|
||||
|
||||
ret
|
||||
|
||||
|
@ -310,7 +311,6 @@ UNKNOWN_EXCEPTION _serrorSpx
|
|||
|
||||
EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST
|
||||
mov x0, sp
|
||||
mrs x1, esr_el2
|
||||
bl handleLowerElSyncException
|
||||
EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST
|
||||
|
||||
|
@ -328,7 +328,6 @@ UNKNOWN_EXCEPTION _serrorA64
|
|||
|
||||
EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST
|
||||
mov x0, sp
|
||||
mrs x1, esr_el2
|
||||
bl handleLowerElSyncException
|
||||
EXCEPTION_HANDLER_END _synchA32, EXCEPTION_TYPE_GUEST
|
||||
|
||||
|
|
|
@ -69,8 +69,10 @@ void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl)
|
|||
}
|
||||
DEBUG("sp_el1\t\t%016llx\n", frame->sp_el1);
|
||||
DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0);
|
||||
DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0);
|
||||
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0);
|
||||
if (frame == currentCoreCtx->guestFrame) {
|
||||
DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0);
|
||||
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0);
|
||||
}
|
||||
#else
|
||||
(void)frame;
|
||||
(void)sameEl;
|
||||
|
@ -132,8 +134,9 @@ void exceptionReturnPreprocess(ExceptionStackFrame *frame)
|
|||
}
|
||||
}
|
||||
|
||||
void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr)
|
||||
void handleLowerElSyncException(ExceptionStackFrame *frame)
|
||||
{
|
||||
ExceptionSyndromeRegister esr = frame->esr_el2;
|
||||
switch (esr.ec) {
|
||||
case Exception_CP15RTTrap:
|
||||
handleMcrMrcCP15Trap(frame, esr);
|
||||
|
@ -171,8 +174,9 @@ void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeReg
|
|||
}
|
||||
}
|
||||
|
||||
void handleSameElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr)
|
||||
void handleSameElSyncException(ExceptionStackFrame *frame)
|
||||
{
|
||||
ExceptionSyndromeRegister esr = frame->esr_el2;
|
||||
DEBUG("Same EL sync exception on core %x, EC = 0x%02llx IL=%llu ISS=0x%06llx\n", currentCoreCtx->coreId, (u64)esr.ec, esr.il, esr.iss);
|
||||
dumpStackFrame(frame, true);
|
||||
}
|
||||
|
|
|
@ -19,24 +19,6 @@
|
|||
#include "utils.h"
|
||||
#include "core_ctx.h"
|
||||
|
||||
typedef struct ExceptionStackFrame {
|
||||
u64 x[31]; // x0 .. x30
|
||||
u64 sp_el1;
|
||||
union {
|
||||
u64 sp_el2;
|
||||
u64 sp_el0;
|
||||
};
|
||||
u64 elr_el2;
|
||||
u64 spsr_el2;
|
||||
u64 far_el2;
|
||||
u64 cntpct_el0;
|
||||
u64 cntp_ctl_el0;
|
||||
u64 cntv_ctl_el0;
|
||||
u64 reserved;
|
||||
} ExceptionStackFrame;
|
||||
|
||||
static_assert(sizeof(ExceptionStackFrame) == 0x140, "Wrong size for ExceptionStackFrame");
|
||||
|
||||
// Adapted from https://developer.arm.com/docs/ddi0596/a/a64-shared-pseudocode-functions/shared-exceptions-pseudocode
|
||||
typedef enum ExceptionClass {
|
||||
Exception_Uncategorized = 0x0,
|
||||
|
@ -88,6 +70,25 @@ typedef struct ExceptionSyndromeRegister {
|
|||
u32 res0 : 32;
|
||||
} ExceptionSyndromeRegister;
|
||||
|
||||
typedef struct ExceptionStackFrame {
|
||||
u64 x[31]; // x0 .. x30
|
||||
u64 sp_el1;
|
||||
union {
|
||||
u64 sp_el2;
|
||||
u64 sp_el0;
|
||||
};
|
||||
u64 elr_el2;
|
||||
u64 spsr_el2;
|
||||
ExceptionSyndromeRegister esr_el2;
|
||||
u64 far_el2;
|
||||
u64 cntpct_el0;
|
||||
u64 cntp_ctl_el0;
|
||||
u64 cntv_ctl_el0;
|
||||
} ExceptionStackFrame;
|
||||
|
||||
static_assert(offsetof(ExceptionStackFrame, far_el2) == 0x120, "Wrong definition for ExceptionStackFrame");
|
||||
static_assert(sizeof(ExceptionStackFrame) == 0x140, "Wrong size for ExceptionStackFrame");
|
||||
|
||||
static inline bool spsrIsA32(u64 spsr)
|
||||
{
|
||||
return (spsr & 0x10) != 0;
|
||||
|
@ -139,7 +140,3 @@ void skipFaultingInstruction(ExceptionStackFrame *frame, u32 size);
|
|||
void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl);
|
||||
|
||||
void exceptionEnterInterruptibleHypervisorCode(void);
|
||||
|
||||
void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr);
|
||||
void handleSameElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr);
|
||||
void handleUnknownException(u32 offset);
|
||||
|
|
|
@ -206,6 +206,7 @@ void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32)
|
|||
u32 irqId = iar & 0x3FF;
|
||||
u32 srcCore = (iar >> 10) & 7;
|
||||
|
||||
frame->esr_el2.ec = Exception_Uncategorized;
|
||||
DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId);
|
||||
|
||||
if (irqId == GIC_IRQID_SPURIOUS) {
|
||||
|
|
|
@ -55,7 +55,6 @@ void initIrq(void);
|
|||
void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive);
|
||||
bool irqIsGuest(u16 id);
|
||||
void irqSetAffinity(u16 id, u8 affinityMask);
|
||||
void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32);
|
||||
|
||||
static inline void generateSgiForAllOthers(ThermosphereSgi id)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue