未定義命令例外ハンドラにてシステムモード固定ではなくアボート発生元のスタックを使用するように変更。

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@225 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
nakasima 2009-01-28 07:38:11 +00:00
parent d2027cb2fd
commit 98ee8bfa67
2 changed files with 56 additions and 30 deletions

View File

@ -222,13 +222,13 @@ asm void i_stupSwiSemihosting( void )
// 割り込み禁止 // 割り込み禁止
mrs r12, cpsr mrs r12, cpsr
orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_cxsf, r12 msr cpsr_fsxc, r12
ldmfd sp!, {r11, r12, lr} ldmfd sp!, {r11, r12, lr}
add sp, sp, #12 add sp, sp, #12
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード // SVCモード
ldmfd sp!, {lr} // ※SP_svc ldmfd sp!, {lr} // ※SP_svc
msr spsr_cxsf, lr msr spsr_fsxc, lr
ldmfd sp!, {lr} ldmfd sp!, {lr}
semi_vector semi_vector
// セミホスティングアドレスはSVCモードでないとARMデバッガがエラーを出力 // セミホスティングアドレスはSVCモードでないとARMデバッガがエラーを出力
@ -241,23 +241,23 @@ asm void i_stupSwiHandler( void )
// 不正確データアボート有効化clear HW_PSR_IMPR_ABORT_DISABLE // 不正確データアボート有効化clear HW_PSR_IMPR_ABORT_DISABLE
// FIQハンドラでのSWI使用時のSP_svc上書き防止のため最初にFIQを禁止IRQはHWが禁止する // FIQハンドラでのSWI使用時のSP_svc上書き防止のため最初にFIQを禁止IRQはHWが禁止する
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード // SVCモード
mrs sp, spsr // ※SP_svc mrs sp, spsr // ※SP_svc
and sp, #HW_PSR_CPU_MODE_MASK and sp, sp, #HW_PSR_CPU_MODE_MASK
// ユーザモードならシステムモードへ // ユーザモードならシステムモードへ
cmp sp, #HW_PSR_USR_MODE cmp sp, #HW_PSR_USR_MODE
moveq sp, #HW_PSR_SYS_MODE moveq sp, #HW_PSR_SYS_MODE
// 割り込み禁止 // 割り込み禁止
orr sp, sp, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) orr sp, sp, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_cxsf, sp msr cpsr_fsxc, sp
// 呼び出し元のモード // 呼び出し元のモード
sub sp, sp, #12 sub sp, sp, #12
stmfd sp!, {r11, r12, lr} // このタイミングでデータアボートハンドラがSWIを使用するとSVCレジスタは復帰不能 stmfd sp!, {r11, r12, lr} // このタイミングでデータアボートハンドラがSWIを使用するとSVCレジスタは復帰不能
add r12, sp, #24 // 呼び出し元のスタック内へ確保したSPSR_svc、LR_svc用スタックアドレスをコピー add r12, sp, #24 // 呼び出し元のスタック内へ確保したSPSR_svc、LR_svc用スタックアドレスをコピー
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード // SVCモード
mov sp, r12 // ※SP_svc mov sp, r12 // ※SP_svc
@ -269,7 +269,7 @@ asm void i_stupSwiHandler( void )
// ユーザモードならシステムモードへ // ユーザモードならシステムモードへ
tst r11, #HW_PSR_SYS_MODE ^ HW_PSR_USR_MODE tst r11, #HW_PSR_SYS_MODE ^ HW_PSR_USR_MODE
orreq r11, r11, #HW_PSR_SYS_MODE orreq r11, r11, #HW_PSR_SYS_MODE
msr cpsr_cxsf, r11 msr cpsr_fsxc, r11
// 呼び出し元のモード // 呼び出し元のモード
ldrh r11, [r12, #-2] // システムコールNo取得 ldrh r11, [r12, #-2] // システムコールNo取得
@ -292,13 +292,13 @@ swi_return
// 割り込み禁止 // 割り込み禁止
mrs r12, cpsr mrs r12, cpsr
orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_cxsf, r12 msr cpsr_fsxc, r12
ldmfd sp!, {r11, r12, lr} ldmfd sp!, {r11, r12, lr}
add sp, sp, #12 add sp, sp, #12
msr cpsr_cxsf, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE) msr cpsr_fsxc, #(HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// SVCモード // SVCモード
ldmfd sp!, {lr} // ※SP_svc ldmfd sp!, {lr} // ※SP_svc
msr spsr_cxsf, lr msr spsr_fsxc, lr
ldmfd sp!, {lr} ldmfd sp!, {lr}
movs pc, lr movs pc, lr

View File

@ -58,14 +58,32 @@ void osInitException( void )
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
asm void i_osUndefInstHandler( void ) asm void i_osUndefInstHandler( void )
{ {
// change into system mode #ifdef SDK_ARM11
msr cpsr_fsxc, #HW_PSR_SYS_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE // 不正確データアボート有効化clear HW_PSR_IMPR_ABORT_DISABLE
stmfd sp!, {r0, r12, lr, pc} // push to previous mode stack (8byte alignment) msr cpsr_fsxc, #(HW_PSR_IRQ_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
#endif // SDK_ARM11
// get LR and SPSR of UNDEF mode // UNDEFモード
msr cpsr_fsxc, #HW_PSR_UNDEF_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE 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, r12, lr}
add r12, sp, #24 // 呼び出し元のスタック内へ確保したSPSR_und、LR_und用スタックアドレスをコピー
msr cpsr_fsxc, #(HW_PSR_UNDEF_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
// UNDEFモード
mov sp, r12 // ※SP_und
mov r12, lr mov r12, lr
mrs r0, spsr mrs r0, spsr
stmfd sp!, {r0, lr} // SPSR_und、LR_undを退避
tst r0, #HW_PSR_THUMB_STATE tst r0, #HW_PSR_THUMB_STATE
bne i_osUndefInstTerminate bne i_osUndefInstTerminate
@ -73,23 +91,22 @@ asm void i_osUndefInstHandler( void )
tst r0, #HW_PSR_JAVA_STATE tst r0, #HW_PSR_JAVA_STATE
bne i_osUndefInstTerminate bne i_osUndefInstTerminate
// permit for only system and user mode to use VFP // ユーザモードもしくはシステムモードのみVFP使用を許可
and lr, r0, #HW_PSR_CPU_MODE_MASK 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 cmp lr, #HW_PSR_SYS_MODE
cmpne lr, #HW_PSR_USR_MODE
bne i_osUndefInstTerminate bne i_osUndefInstTerminate
// change into system mode // 割り込み禁止
msr cpsr_fsxc, #HW_PSR_SYS_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE orr lr, lr, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
msr cpsr_fsxc, lr
// アボート発生元のモード
tst r0, #HW_PSR_THUMB_STATE tst r0, #HW_PSR_THUMB_STATE
subne r12, r12, #2 // Thumb code return address subne r12, r12, #2 // Thumb code return address
subeq r12, r12, #4 // ARM code return address subeq r12, r12, #4 // ARM code return address
str r12, [sp, #4*3] // store LR_svc to return PC
stmfd sp!, {r0-r3} // push spsr (8byte alignment)
adr lr, i_return
ldr r0, [r12, #0] // called from ARM ldr r0, [r12, #0] // called from ARM
mov r12, r0, lsl #4 mov r12, r0, lsl #4
@ -99,13 +116,22 @@ asm void i_osUndefInstHandler( void )
adr r12, i_osUndefCPHandlerTable adr r12, i_osUndefCPHandlerTable
and r0, r0, #0x00000F00 and r0, r0, #0x00000F00
adr lr, i_return
ldr pc, [r12, r0, lsr #8-2] ldr pc, [r12, r0, lsr #8-2]
i_return i_return
ldmfd sp!, {r0-r3} // pop spsr // 割り込み禁止
// restore into previous mode mrs r12, cpsr
msr cpsr_fsxc, r0 orr r12, r12, #(HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE)
ldmfd sp!, {r0, r12, lr, pc} // pop from USR stack msr cpsr_fsxc, r12
ldmfd sp!, {r0, r12, 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 ) INASM_EXTERN( _VFP_Computation_Engine )