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@220 b871894f-2f95-9b40-918c-086798483c85
304 lines
8.7 KiB
C
304 lines
8.7 KiB
C
/*---------------------------------------------------------------------------*
|
|
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
|
|
#ifndef SDK_NE1EMU
|
|
fmrx r12, fpexc
|
|
bic r12, r12, #HW_FPEXC_VFP_ENABLE
|
|
fmxr fpexc, r12
|
|
#endif // SDK_NE1EMU
|
|
#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_UDEF_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_cxsf, r12
|
|
ldmfd sp!, {r11, r12, lr}
|
|
add sp, sp, #12
|
|
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
|
|
// SVCモード
|
|
ldmfd sp!, {lr} // ※SP_svc
|
|
msr spsr_cxsf, lr
|
|
ldmfd sp!, {lr}
|
|
semi_vector
|
|
// セミホスティングアドレスはSVCモードでないとARMデバッガがエラーを出力
|
|
movs pc, lr
|
|
}
|
|
|
|
asm void i_stupSwiHandler( void )
|
|
{
|
|
INASM_EXTERN( _start )
|
|
|
|
// SVCモード
|
|
mrs sp, spsr
|
|
// ユーザモードならシステムモードへ
|
|
tst sp, #HW_PSR_SYS_MODE ^ HW_PSR_USR_MODE
|
|
orreq sp, sp, #HW_PSR_SYS_MODE
|
|
// 割り込み禁止
|
|
orr sp, sp, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
|
|
msr cpsr_cxsf, sp
|
|
|
|
// 呼び出し元のモード
|
|
sub sp, sp, #12
|
|
stmfd sp!, {r11, r12, lr}
|
|
add r12, sp, #24 // ユーザスタック内のSPSR_svc、LR_svc退避アドレスをコピー
|
|
msr cpsr_cxsf, #(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を退避
|
|
// ユーザモードならシステムモードへ
|
|
tst r11, #HW_PSR_SYS_MODE ^ HW_PSR_USR_MODE
|
|
orreq r11, r11, #HW_PSR_SYS_MODE
|
|
// 割り込み状態継承
|
|
msr cpsr_cxsf, 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_cxsf, r12
|
|
ldmfd sp!, {r11, r12, lr}
|
|
add sp, sp, #12
|
|
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
|
|
// SVCモード
|
|
ldmfd sp!, {lr} // ※SP_svc
|
|
msr spsr_cxsf, lr
|
|
ldmfd sp!, {lr}
|
|
movs pc, lr
|
|
|
|
LTORG
|
|
|
|
#include <../build/libraries/swi/common/swi_table.c>
|
|
}
|
|
|