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_debugPausePausedCoreList;
|
||||||
static atomic_uint g_debugPauseSingleStepCoreList;
|
static atomic_uint g_debugPauseSingleStepCoreList;
|
||||||
|
|
||||||
void debugPauseSgiHandler(void)
|
static inline void debugSetThisCorePaused(void)
|
||||||
{
|
{
|
||||||
currentCoreCtx->wasPaused = true;
|
currentCoreCtx->wasPaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugPauseSgiHandler(void)
|
||||||
|
{
|
||||||
|
debugSetThisCorePaused();
|
||||||
barrierWait(&g_debugPauseBarrier);
|
barrierWait(&g_debugPauseBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +81,7 @@ void debugPauseCores(u32 coreList)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remainingList & BIT(currentCoreCtx->coreId)) {
|
if (remainingList & BIT(currentCoreCtx->coreId)) {
|
||||||
currentCoreCtx->wasPaused = true;
|
debugSetThisCorePaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
unmaskIrq();
|
unmaskIrq();
|
||||||
|
|
|
@ -176,8 +176,9 @@ _saveMostRegisters:
|
||||||
mrs x21, sp_el0
|
mrs x21, sp_el0
|
||||||
mrs x22, elr_el2
|
mrs x22, elr_el2
|
||||||
mrs x23, spsr_el2
|
mrs x23, spsr_el2
|
||||||
mov x24, x28 // far_el2
|
mrs x24, esr_el2
|
||||||
mov x25, x29 // cntpct_el0
|
mov x25, x28 // far_el2
|
||||||
|
mov x26, x29 // cntpct_el0
|
||||||
|
|
||||||
// See SAVE_MOST_REGISTERS macro
|
// See SAVE_MOST_REGISTERS macro
|
||||||
ldp x28, x29, [sp, #-0x20]
|
ldp x28, x29, [sp, #-0x20]
|
||||||
|
@ -187,7 +188,7 @@ _saveMostRegisters:
|
||||||
stp x19, x20, [sp, #0xF0]
|
stp x19, x20, [sp, #0xF0]
|
||||||
stp x21, x22, [sp, #0x100]
|
stp x21, x22, [sp, #0x100]
|
||||||
stp x23, x24, [sp, #0x110]
|
stp x23, x24, [sp, #0x110]
|
||||||
stp x25, xzr, [sp, #0x120]
|
stp x25, x26, [sp, #0x120]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -310,7 +311,6 @@ UNKNOWN_EXCEPTION _serrorSpx
|
||||||
|
|
||||||
EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST
|
EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
mrs x1, esr_el2
|
|
||||||
bl handleLowerElSyncException
|
bl handleLowerElSyncException
|
||||||
EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST
|
EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST
|
||||||
|
|
||||||
|
@ -328,7 +328,6 @@ UNKNOWN_EXCEPTION _serrorA64
|
||||||
|
|
||||||
EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST
|
EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
mrs x1, esr_el2
|
|
||||||
bl handleLowerElSyncException
|
bl handleLowerElSyncException
|
||||||
EXCEPTION_HANDLER_END _synchA32, EXCEPTION_TYPE_GUEST
|
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("sp_el1\t\t%016llx\n", frame->sp_el1);
|
||||||
DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0);
|
DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0);
|
||||||
DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0);
|
if (frame == currentCoreCtx->guestFrame) {
|
||||||
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0);
|
DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0);
|
||||||
|
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
(void)frame;
|
(void)frame;
|
||||||
(void)sameEl;
|
(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) {
|
switch (esr.ec) {
|
||||||
case Exception_CP15RTTrap:
|
case Exception_CP15RTTrap:
|
||||||
handleMcrMrcCP15Trap(frame, esr);
|
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);
|
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);
|
dumpStackFrame(frame, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,24 +19,6 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "core_ctx.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
|
// Adapted from https://developer.arm.com/docs/ddi0596/a/a64-shared-pseudocode-functions/shared-exceptions-pseudocode
|
||||||
typedef enum ExceptionClass {
|
typedef enum ExceptionClass {
|
||||||
Exception_Uncategorized = 0x0,
|
Exception_Uncategorized = 0x0,
|
||||||
|
@ -88,6 +70,25 @@ typedef struct ExceptionSyndromeRegister {
|
||||||
u32 res0 : 32;
|
u32 res0 : 32;
|
||||||
} ExceptionSyndromeRegister;
|
} 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)
|
static inline bool spsrIsA32(u64 spsr)
|
||||||
{
|
{
|
||||||
return (spsr & 0x10) != 0;
|
return (spsr & 0x10) != 0;
|
||||||
|
@ -139,7 +140,3 @@ void skipFaultingInstruction(ExceptionStackFrame *frame, u32 size);
|
||||||
void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl);
|
void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl);
|
||||||
|
|
||||||
void exceptionEnterInterruptibleHypervisorCode(void);
|
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 irqId = iar & 0x3FF;
|
||||||
u32 srcCore = (iar >> 10) & 7;
|
u32 srcCore = (iar >> 10) & 7;
|
||||||
|
|
||||||
|
frame->esr_el2.ec = Exception_Uncategorized;
|
||||||
DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId);
|
DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId);
|
||||||
|
|
||||||
if (irqId == GIC_IRQID_SPURIOUS) {
|
if (irqId == GIC_IRQID_SPURIOUS) {
|
||||||
|
|
|
@ -55,7 +55,6 @@ void initIrq(void);
|
||||||
void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive);
|
void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive);
|
||||||
bool irqIsGuest(u16 id);
|
bool irqIsGuest(u16 id);
|
||||||
void irqSetAffinity(u16 id, u8 affinityMask);
|
void irqSetAffinity(u16 id, u8 affinityMask);
|
||||||
void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32);
|
|
||||||
|
|
||||||
static inline void generateSgiForAllOthers(ThermosphereSgi id)
|
static inline void generateSgiForAllOthers(ThermosphereSgi id)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue