参照元†
- 例外ベクタからジャンプする先となるスタブ関数を作成するためのマクロ。
- FIXME: スーパバイザコール例外のときの動作を説明。
- 基本的には、例外発生 -> 例外ベクタ -> スタブ関数 -> 例外ハンドラへ制御が移る。
- 例外発生時の動作は下記の通り。
ただしスーパバイザコール例外(swi/svc)だけは動作が違うので注意。
例: IRQ(割り込み例外)、動作モード 0b0000(ユーザモード)の場合
----------
(例外発生)
-> ベース(0xffff0000) + オフセット(0x18) = 0xffff0018 へジャンプ
※ベースは CONFIG_VECTORS_BASE を参照
※オフセットは ARM アーキテクチャマニュアルの例外の章を参照
0xffff0018:
b vector_irq
-> スタブ関数へジャンプ
※例外ベクタテーブルの詳細は __vectors_start を参照
vector_irq:
動作モードを判定
-> CPSR[0:4] が動作モードを表す(0b00000 〜 0b11111 の 32種類)
ジャンプ先のアドレスを取得
-> ジャンプ先のアドレステーブルはスタブ関数の後ろにくっついている
b __irq_usr
-> 例外ハンドラへジャンプ
- スタブ関数とアドレステーブルの構造は下記の通り。
先頭 --> +----------+
| |
| stub | <-- vector_stub マクロで各種スタブ関数を生成する
| 関数 |
| |
vector_ --> +----------+
stub の | 0 用 | <-- 各モード用のハンドラのアドレス
ラベル 1: +----------+ 1エントリ 4バイト
| 1 用 |
+----------+
| ... |
+----------+
| 15 用 |
+----------+
- name
- 生成する関数の名前
- 例えば hogehoge を指定すると、
vector_hogehoge スタブ関数が定義される。
- mode
- correction
返り値†
/*
* Vector stubs.
*
* This code is copied to 0xffff0200 so we can use branches in the
* vectors, rather than ldr's. Note that this code must not
* exceed 0x300 bytes.
*
* Common stub entry macro:
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*
* SP points to a minimal amount of processor-private memory, the address
* of which is copied into r0 for the mode specific abort handler.
*/
.macro vector_stub, name, mode, correction=0
.align 5
vector_\name:
.if \correction
sub lr, lr, #\correction
.endif
@
@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
@ (parent CPSR)
@
stmia sp, {r0, lr} @ save r0, lr
mrs lr, spsr
str lr, [sp, #8] @ save spsr
@
@ Prepare for SVC32 mode. IRQs remain disabled.
@
mrs r0, cpsr
eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
msr spsr_cxsf, r0
@
@ the branch table must immediately follow this code
@
and lr, lr, #0x0f
THUMB( adr r0, 1f )
THUMB( ldr lr, [r0, lr, lsl #2] )
mov r0, sp
ARM( ldr lr, [pc, lr, lsl #2] )
movs pc, lr @ branch to handler in SVC mode
ENDPROC(vector_\name)
.align 2
@ handler addresses follow this label
1:
.endm
コメント†