pureikyubu/Docs/RE/context.txt
ogamespec@gmail.com 7b3118623b
2011-06-29 14:19:07 +00:00

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)
{
...
}