ctr_firmware/trunk/bootrom/build/libraries/init/common/crt0_excp.c
nakasima 98ee8bfa67 未定義命令例外ハンドラにてシステムモード固定ではなくアボート発生元のスタックを使用するように変更。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@225 b871894f-2f95-9b40-918c-086798483c85
2009-01-28 07:38:11 +00:00

310 lines
9.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 - init
File: crt0_excpHandler.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/code32.h>
#include <brom/os.h>
#include <brom/swi.h>
/*---------------------------------------------------------------------------*
Name: stupInitExceptions
Description: Initialize Exceptions
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
asm void stupInitExceptions( void )
{
adr r2, i_stupExcpVennerCode
ldr r3, =HW_EXCP_VENEER_BUF
add r12, r3, #HW_EXCP_VENEER_BUF_SIZE
LSYM(0)
ldr r0, [r2], #4
ldm r0, {r0-r1}
stm r3!,{r0-r1}
cmp r3, r12
blt BSYM(0)
#ifdef SDK_ARM11
// disable VFP
#ifdef SDK_MG20EMU
fmrx r12, fpexc
bic r12, r12, #HW_FPEXC_VFP_ENABLE
fmxr fpexc, r12
#endif // SDK_MG20EMU
#endif // SDK_ARM11
bx lr
i_stupExcpVennerCode
DCD i_stupExcpTerminateCode // IRQ
DCD i_stupExcpTerminateCode // FIQ
DCD i_stupSwiVeneerCode // SWI osInit前にprint文を出したい可能性があるためここで設定
#ifdef BROM_ENABLE_SCATLD_VFP
INASM_EXTERN( i_osUndefInstHandler )
DCD i_osUndefInstHandler // UNDEF
#else // BROM_ENABLE_SCATLD_VFP
DCD i_stupExcpTerminateCode // UNDEF
#endif // BROM_ENABLE_SCATLD_VFP
DCD i_stupIAbtTerminateCode // IABT 命令アボートとデータアボートを区別するため別関数に
DCD i_stupExcpTerminateCode // DABT
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupExcpTerminateCode
Description: exception veneer code
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
asm void i_stupExcpTerminateCode( void )
{
ldr pc, =i_stupExcpTerminateCode
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupIAbtTerminateCode
Description: Prefetch Abort veneer code
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
asm void i_stupIAbtTerminateCode( void )
{
ldr pc, =i_stupIAbtTerminateCode
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupSwiVeneerCode
Description: SWI veneer code
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
asm void i_stupSwiVeneerCode( void )
{
ldr pc, =i_stupSwiHandler
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupIrqVeneer
Description: IRQ veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupIrqVeneer( void )
{
ldr pc, =HW_INTR_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupFiqVeneer
Description: FIQ veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupFiqVeneer( void )
{
ldr pc, =HW_FIQ_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupSwiVeneer
Description: SWI veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupSwiVeneer( void )
{
ldr pc, =HW_SWI_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupUndefVeneer
Description: Undefine Instruction veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupUndefVeneer( void )
{
ldr pc, =HW_UNDEF_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupIAbtVeneer
Description: Prefetch Abort veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupIAbtVeneer( void )
{
ldr pc, =HW_IABT_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupDAbtVeneer
Description: Data Abort veneer
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupDAbtVeneer( void )
{
ldr pc, =HW_DABT_VENEER_BUF
LTORG
}
/*---------------------------------------------------------------------------*
Name: i_stupSwiHandler
Description: SWI handler
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void i_stupSwiSemihosting( void )
{
// 割り込み禁止
mrs r12, cpsr
orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, r12
ldmfd sp!, {r11, r12, lr}
add sp, sp, #12
msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード
ldmfd sp!, {lr} // ※SP_svc
msr spsr_fsxc, lr
ldmfd sp!, {lr}
semi_vector
// セミホスティングアドレスはSVCモードでないとARMデバッガがエラーを出力
movs pc, lr
}
asm void i_stupSwiHandler( void )
{
INASM_EXTERN( _start )
// 不正確データアボート有効化clear HW_PSR_IMPR_ABORT_DISABLE
// FIQハンドラでのSWI使用時のSP_svc上書き防止のため最初にFIQを禁止IRQはHWが禁止する
msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード
mrs sp, spsr // ※SP_svc
and sp, 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!, {r11, r12, lr} // このタイミングでデータアボートハンドラがSWIを使用するとSVCレジスタは復帰不能
add r12, sp, #24 // 呼び出し元のスタック内へ確保したSPSR_svc、LR_svc用スタックアドレスをコピー
msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード
mov sp, r12 // ※SP_svc
mov r12, lr
mrs r11, spsr
stmfd sp!, {r11, lr} // SPSR_svc、LR_svcを退避
// 割り込み状態継承
and r11, r11, #(HW_PSR_CPU_MODE_MASK | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// ユーザモードならシステムモードへ
tst r11, #HW_PSR_SYS_MODE ^ HW_PSR_USR_MODE
orreq r11, r11, #HW_PSR_SYS_MODE
msr cpsr_fsxc, r11
// 呼び出し元のモード
ldrh r11, [r12, #-2] // システムコールNo取得
mov r11, r11, lsl #1
and r11, r11, #SVC_ID_PREMASK<<SVC_ID_SHIFT
cmp r11, #(SVC_ID_SEMIHOST_ARM & SVC_ID_PREMASK)<<SVC_ID_SHIFT // SVC_ID_SEMIHOST_ARM = 0x12
cmpne r11, #(SVC_ID_SEMIHOST_THUMB & SVC_ID_PREMASK)<<SVC_ID_SHIFT // SVC_ID_SEMIHOST_THUMB = 0xab
beq i_stupSwiSemihosting
adr r12, SWI_Table // システムコールアドレス 取得
ldrh r11, [r12, r11]
ldr r12, =HW_BROM
orr r12, r11, r12
blx r12
swi_return
// 割り込み禁止
mrs r12, cpsr
orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, r12
ldmfd sp!, {r11, r12, lr}
add sp, sp, #12
msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード
ldmfd sp!, {lr} // ※SP_svc
msr spsr_fsxc, lr
ldmfd sp!, {lr}
movs pc, lr
LTORG
#include <../build/libraries/swi/common/swi_table.c>
}