mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-11 23:46:10 +01:00
thermosphere: cpu_on hook & skeleton for other PSCI functions
This commit is contained in:
parent
4a5d05f32b
commit
6d33ebceef
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
typedef struct CoreCtx {
|
typedef struct CoreCtx {
|
||||||
u64 kernelArgument;
|
u64 kernelArgument;
|
||||||
u64 kernelEntrypoint;
|
uintptr_t kernelEntrypoint;
|
||||||
u32 coreId; // @ 0x0C
|
u32 coreId; // @ 0x0C
|
||||||
} CoreCtx;
|
} CoreCtx;
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
#include "synchronization.h"
|
#include "synchronization.h"
|
||||||
|
#include "core_ctx.h"
|
||||||
|
|
||||||
// Currently in exception_vectors.s:
|
// Currently in exception_vectors.s:
|
||||||
extern const u32 doSmcIndirectCallImpl[];
|
extern const u32 doSmcIndirectCallImpl[];
|
||||||
extern const u32 doSmcIndirectCallImplSmcInstructionOffset, doSmcIndirectCallImplSize;
|
extern const u32 doSmcIndirectCallImplSmcInstructionOffset, doSmcIndirectCallImplSize;
|
||||||
|
|
||||||
|
// start.s
|
||||||
|
void start2(u64 contextId);
|
||||||
|
|
||||||
void doSmcIndirectCall(ExceptionStackFrame *frame, u32 smcId)
|
void doSmcIndirectCall(ExceptionStackFrame *frame, u32 smcId)
|
||||||
{
|
{
|
||||||
u32 codebuf[doSmcIndirectCallImplSize]; // note: potential VLA
|
u32 codebuf[doSmcIndirectCallImplSize]; // note: potential VLA
|
||||||
@ -18,11 +22,53 @@ void doSmcIndirectCall(ExceptionStackFrame *frame, u32 smcId)
|
|||||||
((void (*)(ExceptionStackFrame *))codebuf)(frame);
|
((void (*)(ExceptionStackFrame *))codebuf)(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void doCpuOnHook(ExceptionStackFrame *frame, u32 smcId)
|
||||||
|
{
|
||||||
|
// Note: preserve contexId which is passed by EL3, we'll save it later
|
||||||
|
u32 cpuId = (u32)frame->x[1]; // note: full affinity mask. Start.s checks that Aff1,2,3 are 0.
|
||||||
|
uintptr_t ep = frame->x[2];
|
||||||
|
// frame->x[3] is contextId
|
||||||
|
if (cpuId < 4) {
|
||||||
|
g_coreCtxs[cpuId].kernelEntrypoint = ep;
|
||||||
|
frame->x[2] = (uintptr_t)start2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handleSmcTrap(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr)
|
void handleSmcTrap(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr)
|
||||||
{
|
{
|
||||||
// TODO: Arm PSCI 0.2+ stuff
|
// TODO: Arm PSCI 0.2+ stuff
|
||||||
u32 smcId = esr.iss;
|
u32 smcId = esr.iss;
|
||||||
|
|
||||||
|
// Note: don't differenciate PSCI calls by smc immediate since HOS uses #1 for that
|
||||||
|
// Note: funcId is actually u32 according to Arm PSCI. Not sure what to do if x0>>32 != 0.
|
||||||
|
// NN doesn't truncate, Arm TF does.
|
||||||
|
// Note: clear NN ABI-breaking bits
|
||||||
|
u32 funcId = frame->x[0] & ~0xFF00;
|
||||||
|
switch (funcId) {
|
||||||
|
case 0xC4000001:
|
||||||
|
// CPU_SUSPEND
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case 0x84000002:
|
||||||
|
// CPU_OFF
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case 0xC4000003:
|
||||||
|
doCpuOnHook(frame, smcId);
|
||||||
|
break;
|
||||||
|
case 0x84000008:
|
||||||
|
// SYSTEM_OFF, not implemented by Nintendo
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case 0x84000009:
|
||||||
|
// SYSTEM_RESET, not implemented by Nintendo
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Other unimportant functions we don't care about
|
||||||
|
break;
|
||||||
|
}
|
||||||
doSmcIndirectCall(frame, smcId);
|
doSmcIndirectCall(frame, smcId);
|
||||||
skipFaultingInstruction(frame, 4);
|
skipFaultingInstruction(frame, 4);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ _initialKernelEntrypoint:
|
|||||||
start:
|
start:
|
||||||
mov x19, #1
|
mov x19, #1
|
||||||
b _startCommon
|
b _startCommon
|
||||||
|
.global start2
|
||||||
|
.type start2, %function
|
||||||
start2:
|
start2:
|
||||||
mov x19, xzr
|
mov x19, xzr
|
||||||
_startCommon:
|
_startCommon:
|
||||||
@ -57,8 +59,12 @@ _startCommon:
|
|||||||
isb
|
isb
|
||||||
|
|
||||||
// Get core ID
|
// Get core ID
|
||||||
|
// Ensure Aff0 is 4-1 at most (4 cores), and that Aff1, 2 and 3 are 0 (1 cluster only)
|
||||||
mrs x10, mpidr_el1
|
mrs x10, mpidr_el1
|
||||||
and x10, x10, #0xFF
|
and x10, x10, #0x00FFFFFF // Aff0 to 2
|
||||||
|
and x10, x10, #(0xFF << 32) // Aff3
|
||||||
|
cmp x10, #4
|
||||||
|
bhs .
|
||||||
|
|
||||||
// Set tmp stack (__stacks_top__ is aligned)
|
// Set tmp stack (__stacks_top__ is aligned)
|
||||||
adrp x8, __stacks_top__
|
adrp x8, __stacks_top__
|
||||||
|
Loading…
Reference in New Issue
Block a user