mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@95 b871894f-2f95-9b40-918c-086798483c85
241 lines
7.3 KiB
C
241 lines
7.3 KiB
C
/*---------------------------------------------------------------------------*
|
|
Project: CtrBrom - libraries - OS
|
|
File: os_context.c
|
|
|
|
Copyright 2008 Nintendo. All rights reserved.
|
|
|
|
These coded instructions, statements, and computer programs contain
|
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
|
Company Ltd., and are protected by Federal copyright law. They may
|
|
not be disclosed to third parties or copied or duplicated in any form,
|
|
in whole or in part, without the prior written consent of Nintendo.
|
|
|
|
$Date:: $
|
|
$Rev$
|
|
$Author$
|
|
*---------------------------------------------------------------------------*/
|
|
#include <brom/os.h>
|
|
|
|
#define osPrintf(...) ((void)0)
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osInitContext
|
|
|
|
Description: Initialize context
|
|
|
|
Arguments: context context to be initialized
|
|
newpc program counter
|
|
newsp stack pointer
|
|
|
|
Returns: none
|
|
*---------------------------------------------------------------------------*/
|
|
#include <brom/code32.h>
|
|
asm void osInitContext(
|
|
register OSContext* context,
|
|
register u32 newpc,
|
|
register u32 newsp
|
|
)
|
|
{
|
|
#define context r0
|
|
#define newpc r1
|
|
#define newsp r2
|
|
|
|
// ---- 実行位置保存 (r0 = context)
|
|
add newpc, newpc, #4
|
|
str newpc, [ context, #OS_CONTEXT_PC_PLUS4 ]
|
|
|
|
// ---- スタック保存
|
|
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
|
str newsp, [ context, #OS_CONTEXT_SP_SVC ]
|
|
sub newsp, newsp, #HW_BROM_SVC_STACK_SIZE
|
|
#endif
|
|
tst newsp, #4
|
|
subne newsp, newsp, #4 // for 8byte-alignment
|
|
str newsp, [ context, #OS_CONTEXT_SP ]
|
|
|
|
// ---- ステータス作成
|
|
ands r1, newpc, #1
|
|
movne r1, #HW_PSR_SYS_MODE|HW_PSR_THUMB_STATE
|
|
moveq r1, #HW_PSR_SYS_MODE|HW_PSR_ARM_STATE
|
|
str r1, [ context, #OS_CONTEXT_CPSR ]
|
|
|
|
// ---- 他のレジスタをクリア
|
|
mov r1, #0
|
|
str r1, [ context, #OS_CONTEXT_R0 ]
|
|
str r1, [ context, #OS_CONTEXT_R1 ]
|
|
str r1, [ context, #OS_CONTEXT_R2 ]
|
|
str r1, [ context, #OS_CONTEXT_R3 ]
|
|
str r1, [ context, #OS_CONTEXT_R4 ]
|
|
str r1, [ context, #OS_CONTEXT_R5 ]
|
|
str r1, [ context, #OS_CONTEXT_R6 ]
|
|
str r1, [ context, #OS_CONTEXT_R7 ]
|
|
str r1, [ context, #OS_CONTEXT_R8 ]
|
|
str r1, [ context, #OS_CONTEXT_R9 ]
|
|
str r1, [ context, #OS_CONTEXT_R10 ]
|
|
str r1, [ context, #OS_CONTEXT_R11 ]
|
|
str r1, [ context, #OS_CONTEXT_R12 ]
|
|
str r1, [ context, #OS_CONTEXT_LR ]
|
|
|
|
bx lr // start here and swicth arm/thumb mode
|
|
|
|
#undef context
|
|
#undef newpc
|
|
#undef newsp
|
|
}
|
|
|
|
#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9)
|
|
#include <brom/itcm_begin.h>
|
|
#endif
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osSaveContext
|
|
|
|
Description: Save current context into specified memory
|
|
|
|
Arguments: context pointer to the memory to be stored the current context
|
|
|
|
Returns: 0 saving a context (normal)
|
|
1 if context are reloaded via osLoadContext
|
|
*---------------------------------------------------------------------------*/
|
|
asm BOOL osSaveContext( register OSContext* context )
|
|
{
|
|
#if 0 // defined(SDK_ARM9)
|
|
stmfd sp!, { lr, r0 }
|
|
add r0, r0, #OS_CONTEXT_CP_CONTEXT
|
|
ldr r1, =CP_SaveContext
|
|
blx r1
|
|
ldmfd sp!, { lr, r0 }
|
|
#endif
|
|
|
|
add r1, r0, #OS_CONTEXT_CPSR
|
|
|
|
//---- Save CPSR
|
|
mrs r2, cpsr
|
|
str r2, [ r1 ], #OS_CONTEXT_R0-OS_CONTEXT_CPSR // r1 moved to context.r0
|
|
|
|
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
|
//---- Save SP_svc
|
|
mov r0, #HW_PSR_SVC_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_FIQ_DISABLE|HW_PSR_ARM_STATE
|
|
msr cpsr_c, r0
|
|
str sp, [ r1, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0 ]
|
|
msr cpsr_c, r2
|
|
#endif
|
|
|
|
//---- Save others
|
|
mov r0, #1 // return value via osLoadContext
|
|
stmia r1, {r0-r14} // save R0-R14
|
|
add r0, pc, #8 // set PC_plus4 to do ("bx lr" + 4)
|
|
str r0, [r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0 ]
|
|
|
|
mov r0, #0 // regular return value
|
|
bx lr
|
|
}
|
|
|
|
|
|
#define OFFSETOF(x,y) (int)(&(((x*)0)->y))
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osLoadContext
|
|
|
|
Description: Reload specified context as current context
|
|
|
|
Arguments: context pointer to the memory to switch to the context
|
|
|
|
Returns: None
|
|
*---------------------------------------------------------------------------*/
|
|
asm void osLoadContext( register OSContext* context )
|
|
{
|
|
#if OS_CONTEXT_CPSR != 0
|
|
#pragma message(has changed!!!)
|
|
add r0, r0, #OS_CONTEXT_CPSR
|
|
#endif
|
|
|
|
#if 0 // defined(SDK_ARM9)
|
|
// call CPi_RestoreContext
|
|
stmfd sp!, { lr, r0 }
|
|
add r0, r0, #OS_CONTEXT_CP_CONTEXT
|
|
|
|
ldr r1, =CPi_RestoreContext
|
|
blx r1
|
|
ldmfd sp!, { lr, r0 }
|
|
#endif
|
|
|
|
//---- モードを svc に
|
|
mrs r1, cpsr
|
|
bic r1, r1, #HW_PSR_CPU_MODE_MASK
|
|
orr r1, r1, #HW_PSR_SVC_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_FIQ_DISABLE
|
|
msr cpsr_c, r1
|
|
|
|
//---- Load cpcr to spsr
|
|
ldr r1, [ r0 ], #OS_CONTEXT_R0-OS_CONTEXT_CPSR
|
|
msr spsr_fsxc, r1
|
|
|
|
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
|
//---- Load SP_svc
|
|
ldr sp, [ r0, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0 ]
|
|
#endif
|
|
|
|
//---- Load r0-r14
|
|
ldr lr, [ r0, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0 ]
|
|
ldmia r0, { r0 - r14 }^
|
|
nop
|
|
|
|
#if defined(SDK_ARM9)
|
|
#if 0 // don't need, because still spend more than 34 cycle for divider.
|
|
//---- CP_WaitDiv
|
|
stmfd sp!, { r0-r1 }
|
|
ldr r0, =REG_DIVCNT_ADDR
|
|
@00:
|
|
ldr r1, [r0]
|
|
and r1, r1, #REG_CP_DIVCNT_BUSY_MASK
|
|
bne @00
|
|
ldmfd sp!, { r0-r1 }
|
|
#endif
|
|
#endif
|
|
|
|
//---- Switch cpsr and Jump to (context->pc_plus4 - 4)
|
|
subs pc, lr, #4
|
|
}
|
|
#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9)
|
|
#include <brom/itcm_end.h>
|
|
#endif
|
|
|
|
#include <brom/codereset.h>
|
|
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: osDumpContext
|
|
|
|
Description: Performs exception initialization.
|
|
- installs the first level exception handlers
|
|
- set up exception table and common exception handler
|
|
|
|
Arguments: installDBIntegrator if TRUE, copy OSDBIntegrator into
|
|
low memory.
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void osDumpContext(OSContext *context)
|
|
{
|
|
#ifndef SDK_FINALROM
|
|
s32 i;
|
|
|
|
osPrintf("context=%08x\n", context);
|
|
if (context)
|
|
{
|
|
osPrintf("CPSR %08x\n", context->cpsr);
|
|
for (i = 0; i < 13; i++)
|
|
{
|
|
osPrintf("R%02d %08x\n", i, context->r[i]);
|
|
}
|
|
osPrintf("SP %08x\n", context->sp);
|
|
osPrintf("LR %08x\n", context->lr);
|
|
osPrintf("PC+4 %08x\n", context->pc_plus4);
|
|
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
|
osPrintf("SPsvc %08x\n", context->sp_svc);
|
|
#endif
|
|
}
|
|
#else
|
|
(void)context; // avoiding to unused warning
|
|
#endif
|
|
}
|