mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
230 lines
4.4 KiB
Text
230 lines
4.4 KiB
Text
// Dolphin OS context RE by org
|
|
// OSContext.c
|
|
|
|
// OSLoMem.h
|
|
OSContext *__OSPhysicalContext AT_ADDRESS(OS_BASE_CACHED | 0x00C0);
|
|
OSContext *__OSCurrentContext AT_ADDRESS(OS_BASE_CACHED | 0x00D4);
|
|
|
|
[800000D8] - default thread (OSThread *)
|
|
|
|
void __OSLoadFPUContext(???, OSContext *context)
|
|
{
|
|
if(context->state & OS_CONTEXT_STATE_FPSAVED)
|
|
{
|
|
FPSCR = context.fpscr;
|
|
|
|
if(HID2[PSE])
|
|
{
|
|
PS[0] = context->psf[0];
|
|
.
|
|
.
|
|
.
|
|
PS[31] = context->psf[31];
|
|
}
|
|
else
|
|
{
|
|
FPR[0] = context->fpr[0];
|
|
.
|
|
.
|
|
.
|
|
FPR[31] = context->fpr[31];
|
|
}
|
|
}
|
|
}
|
|
|
|
void __OSSaveFPUContext(???, ???, OSContext *context)
|
|
{
|
|
context->state |= OS_CONTEXT_STATE_FPSAVED;
|
|
|
|
// save FPRs
|
|
context->fpr[0] = FPR[0];
|
|
.
|
|
.
|
|
.
|
|
context->fpr[31] = FPR[31];
|
|
|
|
// save FP state/control
|
|
context.fpscr = FPSCR;
|
|
|
|
// save paireds
|
|
if(HID2[PSE])
|
|
{
|
|
context->fpr[0] = FPR[0];
|
|
.
|
|
.
|
|
.
|
|
context->fpr[31] = FPR[31];
|
|
}
|
|
}
|
|
|
|
void OSLoadFPUContext(OSContext *context)
|
|
{
|
|
__OSLoadFPUContext(???, context);
|
|
}
|
|
|
|
void OSSaveFPUContext(OSContext *context)
|
|
{
|
|
__OSSaveFPUContext(???, ???, context);
|
|
}
|
|
|
|
void OSSetCurrentContext(OSContext *context)
|
|
{
|
|
__OSCurrentContext = context;
|
|
__OSPhysicalContext= OSCachedToPhysical(context);
|
|
|
|
if(context == __OSDefaultThread->context)
|
|
{
|
|
context.srr1 |= MSR_FP; // floating-point available
|
|
MSR[RI] = 1; // recoverable interrupt
|
|
}
|
|
else
|
|
{
|
|
context.srr1 &= ~MSR_FP;
|
|
MSR[FP] = 0;
|
|
MSR[RI] = 1;
|
|
__asm isync
|
|
}
|
|
}
|
|
|
|
OSContext *OSGetCurrentContext()
|
|
{
|
|
return __OSCurrentContext;
|
|
}
|
|
|
|
u32 OSSaveContext(OSContext *context)
|
|
{
|
|
// save GPRs
|
|
context.gpr[13...31] = GPR[13...31];
|
|
|
|
// save quantization regs (GQR0 is always zero)
|
|
context.gqr[1...7] = GQR[1...7];
|
|
|
|
// others
|
|
context.cr = CR;
|
|
context.srr0 = context.lr = LR;
|
|
context.srr1 = MSR;
|
|
context.ctr = CTR;
|
|
context.xer = XER;
|
|
|
|
// compiler pointers
|
|
context.gpr[1] = SP;
|
|
context.gpr[2] = SDA1;
|
|
|
|
context.gpr[12] = 1;
|
|
return 0;
|
|
}
|
|
|
|
void OSLoadContext(OSContext *context)
|
|
{
|
|
if(
|
|
context.srr0 >= __RAS_OSDisableInterrupts_begin &&
|
|
context.srr0 <= __RAS_OSDisableInterrupts_end )
|
|
{
|
|
context.srr0 = __RAS_OSDisableInterrupts_begin;
|
|
}
|
|
|
|
// restore GPRs
|
|
GPR[0...2] = context.gpr[0...2];
|
|
|
|
if(context.state & OS_CONTEXT_STATE_EXC)
|
|
{
|
|
context.state &= ~OS_CONTEXT_STATE_EXC;
|
|
GPR[5...31] = context.gpr[5...31];
|
|
}
|
|
else GPR[13...31] = context.gpr[13...31];
|
|
|
|
// restore GQRs (GQR0 is always 0)
|
|
GQR[1...7] = context.gqr[1...7];
|
|
|
|
// others
|
|
CR = context.cr;
|
|
LR = context.lr;
|
|
CTR = context.ctr;
|
|
XER = context.xer;
|
|
|
|
MSR[IE] = MSR[RI] = 0;
|
|
SRR0 = context.srr0;
|
|
SRR1 = context.srr1;
|
|
|
|
GPR[4] = context.gpr[4];
|
|
GPR[3] = context.gpr[3];
|
|
|
|
// return from interrupt (update PC and MSR)
|
|
__asm rfi
|
|
}
|
|
|
|
u32 OSGetStackPointer()
|
|
{
|
|
return GPR[1]; // SP
|
|
}
|
|
|
|
u32 OSSwitchStack(u32 newsp)
|
|
{
|
|
u32 oldsp = GPR[1];
|
|
GPR[1] = newsp;
|
|
return oldsp;
|
|
}
|
|
|
|
int OSSwitchFiber(u32 pc, u32 newsp)
|
|
{
|
|
u32 oldsp = GPR[1];
|
|
int rval;
|
|
GPR[1] = newsp;
|
|
rval = (void *)pc();
|
|
GPR[1] = oldsp;
|
|
return rval;
|
|
}
|
|
|
|
void OSClearContext(OSContext *context)
|
|
{
|
|
context.mode =
|
|
context.state = 0;
|
|
|
|
if(context == __OSDefaultThread->context)
|
|
{
|
|
__OSDefaultThread = NULL;
|
|
}
|
|
}
|
|
|
|
void OSInitContext(OSContext *context, u32 pc, u32 sp)
|
|
{
|
|
context.srr0 = pc;
|
|
context.gpr[1] = sp;
|
|
context.srr1 = 0x9032;
|
|
|
|
context.cr =
|
|
context.xer = 0;
|
|
|
|
context.gpr[2] = GPR[2];
|
|
context.gpr[3...31] = 0;
|
|
context.gpr[13] = GPR[13];
|
|
|
|
context.gqr[0...7] = 0;
|
|
|
|
OSClearContext(context);
|
|
}
|
|
|
|
void OSDumpContext(OSContext *context)
|
|
{
|
|
...
|
|
}
|
|
|
|
void OSSwitchFPUContext(__OSException exception, OSContext *context)
|
|
{
|
|
...
|
|
}
|
|
|
|
void __OSContextInit()
|
|
{
|
|
__OSSetExceptionHandler(
|
|
__OS_EXCEPTION_FLOATING_POINT,
|
|
OSSwitchFPUContext
|
|
);
|
|
|
|
DBPrintf("FPU-unavailable handler installed\n");
|
|
}
|
|
|
|
void OSFillFPUContext(OSContext *context)
|
|
{
|
|
...
|
|
}
|