ctr_firmware/trunk/bootrom/build/libraries/os/common/os_exception.c
nakasima e728496b11 r11,r12はFIQではバンクレジスタになるためCPUモード間の受け渡しはr0,r1へ変更。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@226 b871894f-2f95-9b40-918c-086798483c85
2009-01-28 08:30:54 +00:00

193 lines
6.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: CtrBrom - library - os
File: os_exception.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>
#include <brom/swi.h>
void i_osUndefInstHandler( void );
/*---------------------------------------------------------------------------*
Name: osInitException
Description: Initialize Exceptions for Application
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osInitException( void )
{
#ifdef SDK_ARM11
static BOOL isInit;
if ( isInit == FALSE )
{
isInit = TRUE;
*(OSExcpHandler*)HW_UNDEF_VECTOR_BUF = i_osUndefInstHandler;
}
#endif // SDK_ARM11
}
#ifdef SDK_ARM11
#include <brom/code32.h>
/*---------------------------------------------------------------------------*
Name: i_osUndefInstHandler
Description: Undefine Instruction handler
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
asm void i_osUndefInstHandler( void )
{
#ifdef SDK_ARM11
// 不正確データアボート有効化clear HW_PSR_IMPR_ABORT_DISABLE
msr cpsr_fsxc, #(HW_PSR_IRQ_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
#endif // SDK_ARM11
// UNDEFモード
mrs sp, spsr // ※SP_und
and sp, #HW_PSR_CPU_MODE_MASK
// ユーザモードならシステムモードへ
cmp sp, #HW_PSR_USR_MODE
moveq sp, #HW_PSR_SYS_MODE
// 割り込み禁止
orr sp, sp, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, sp
// アボート発生元のモード
sub sp, sp, #12
stmfd sp!, {r0-r1, lr}
add r1, sp, #24 // 呼び出し元のスタック内へ確保したSPSR_und、LR_und用スタックアドレスをコピー
msr cpsr_fsxc, #(HW_PSR_UNDEF_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// UNDEFモード
mov sp, r1 // ※SP_und
mov r1, lr
mrs r0, spsr
stmfd sp!, {r0, lr} // SPSR_und、LR_undを退避
tst r0, #HW_PSR_THUMB_STATE
bne i_osUndefInstTerminate
tst r0, #HW_PSR_JAVA_STATE
bne i_osUndefInstTerminate
// ユーザモードもしくはシステムモードのみVFP使用を許可
and lr, r0, #HW_PSR_CPU_MODE_MASK
// ユーザモードならシステムモードへ
cmp lr, #HW_PSR_USR_MODE
moveq lr, #HW_PSR_SYS_MODE
cmp lr, #HW_PSR_SYS_MODE
bne i_osUndefInstTerminate
// 割り込み禁止
orr lr, lr, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, lr
// アボート発生元のモード
tst r0, #HW_PSR_THUMB_STATE
subne r1, r1, #2 // Thumb code return address
subeq r1, r1, #4 // ARM code return address
ldr r0, [r1, #0] // called from ARM
mov r1, r0, lsl #4
sub r1, r1, #0xC0000000
cmp r1, #0x30000000
bhs i_osUndefInstTerminate
adr r1, i_osUndefCPHandlerTable
and r0, r0, #0x00000F00
ldr r0, [r1, r0, lsr #8-2]
blx r0
i_return
// 割り込み禁止
mrs r1, cpsr
orr r1, r1, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, r1
ldmfd sp!, {r0-r1, lr}
add sp, sp, #12
msr cpsr_fsxc, #(HW_PSR_UNDEF_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// UNDEFモード
ldmfd sp!, {lr} // ※SP_und
msr spsr_fsxc, lr
ldmfd sp!, {lr}
movs pc, lr
INASM_EXTERN( _VFP_Computation_Engine )
i_osUndefCPHandlerTable
DCD i_osUndefInstTerminate // CP 0
DCD i_osUndefInstTerminate // CP 1
DCD i_osUndefInstTerminate // CP 2
DCD i_osUndefInstTerminate // CP 3
DCD i_osUndefInstTerminate // CP 4
DCD i_osUndefInstTerminate // CP 5
DCD i_osUndefInstTerminate // CP 6
DCD i_osUndefInstTerminate // CP 7
DCD i_osUndefInstTerminate // CP 8
DCD i_osUndefInstTerminate // CP 9
DCD i_osUndefInstHandlerVFP // CP 10
DCD i_osUndefInstHandlerVFP // CP 11
DCD i_osUndefInstTerminate // CP 12
DCD i_osUndefInstTerminate // CP 13
DCD i_osUndefInstTerminate // CP 14
DCD i_osUndefInstTerminate // CP 15
}
asm void i_osUndefInstHandlerVFP( void )
{
// VFP enable
fmrx r1, fpexc
tst r1, #HW_FPEXC_VFP_ENABLE
LSYM(1)
bne BSYM(1) // Error
mov r0, #(HW_FPEXC_EXCEPTION_STATE | HW_FPEXC_FPINST2_VALID)
bic r1, r1, r0
orr r1, r1, #HW_FPEXC_VFP_ENABLE
fmxr fpexc, r1
ldr r1, =(HW_FPSCR_ROUND_NEAR_MODE << HW_FPSCR_ROUND_MODE_SFT \
| HW_FPSCR_VEC_LENGTH_1 << HW_FPSCR_VEC_LENGTH_SFT \
| HW_FPSCR_VEC_STRIDE_1 << HW_FPSCR_VEC_STRIDE_SFT \
| HW_FPSCR_DZE_ENABLE \
| HW_FPSCR_DEFAULT_NAN_MODE \
| HW_FPSCR_FLASH_TO_ZERO_MODE \
)
fmxr fpscr, r1
bx lr
}
asm void i_osUndefInstTerminate( void )
{
LSYM(1)
b BSYM(1)
bx lr
}
#include <brom/codereset.h>
#endif // SDK_ARM11