戻る

ARM7TDMIについて

Apr 3, 2020

ARM7TDMIはGBAで使われているCPUのコアだがあまり情報が出回っていない部分がある. 特に割り込みの動作については質の良い情報がなかなか得られないのでここで詳しく解説したい.

ARMのレジスター

ARMのレジスターは37個ありどれも32bitである. 31個は一般レジスター(Rxx)で6個はステータスレジスター(xPSR)である. レジスターによってモードごとにバンクされたりする.
System/User FIQ Supervisor Abort IRQ Undefined
R0 R0 R0 R0 R0 R0
R1 R1 R1 R1 R1 R1
R2 R2 R2 R2 R2 R2
R3 R3 R3 R3 R3 R3
R4 R4 R4 R4 R4 R4
R5 R5 R5 R5 R5 R5
R6 R6 R6 R6 R6 R6
R7 R7 R7 R7 R7 R7
R8 R8_fiq R8 R8 R8 R8
R9 R9_fiq R9 R9 R9 R9
R10 R10_fiq R10 R10 R10 R10
R11 R11_fiq R11 R11 R11 R11
R12 R12_fiq R12 R12 R12 R12
R13 R13_fiq R13_svc R13_abt R13_irq R13_und
R14 R14_fiq R14_svc R14_abt R14_irq R14_und
R15 R15 R15 R15 R15 R15
CPSR CPSR CPSR CPSR CPSR CPSR
-- SPSR_fiq SPSR_svc SPSR_abt SPSR_irq SPSR_und

R13はSP(スタックポインター)として使われる(Thumb state). ARM stateでは普通のレジスタとして使って良い. 例外処理時にはバンクレジスターのR13_xxxに値が入るので元のSPにアクセスできないことに注意. R14はリンクレジスターでBLを呼び出す時に変更される. R15はPC(プログラムカウンター)として使われる.

ARM CPU Flags & Condition Field(cond)

条件実行で使われる. 例, Zフラグが1の時のみbeqでジャンプ, 0の時のみbneでジャンプするなど. thumbではフラグはジャンプ命令でしか使わないはず.

Current Program Status Register (CPSR)

Bit Expl. 説明
31 N : Sign Flag Signedの時セット
30 Z : Zero Flag 結果がZeroの時セット
29 C : Carry Flag 繰り上がり時, 繰り下がりなし時にセット
28 V : Overflow Flag オーバーフロー時にセット
27 Q : Sticky Overflow ? ARMv5TE以降でしか使わない
26-8 Reserved For future use
7 I : IRQ disable IRQ禁止時にセット
6 F : FIQ disable FIQ禁止時にセット
5 T : State Bit 0=ARM, 1=Thumb
4-0 M4-M0 : Mode Bits 下記を参照

Bit7-0 (Controll Bits,I,F,T,M4-M0)について

privileged modeの時に値を操作しても良い. Tビットは値を勝手に操作してはいけず, bx命令を使って切り替えること. M4-M0の値に対応するテーブル

Hex Expl.
10h User
11h FIQ
12h IRQ
13h Supervisor (SWI)
17h Abort
18h Undefined
1Fh System

Saved Program Status Registers (SPSR_(mode))

SPSRはCPSRの値を一時的に保存する役割があり, 例えるとPCに対するLRに相当する. 例外処理時に元のCPSRの値を入れ, 復帰時にCPSRに入れ直すことができる. 割り込みが入れ子になっている場合は手動で別に管理しなくてはならない.

例外処理

そもそも割り込みとは例外処理の一つであるが他の例外も割り込みと呼ばれたりする. 例外が起きた時CPUはARMモードになりPCは例外に応じた例外ベクトルのアドレスを読み込む.

例外ベクトル

アドレス 優先順位 例外 モード 割り込みフラグ
BASE+00h 1 Reset Supervisor(_svc) I=1, F=1
BASE+04h 7 Undefined Instruction Undefined(_und) I=1, F=unchanged
BASE+08h 6 Software Interrupt(SWI) SuperVisor(_svc) I=1, F=unchanged
BASE+0Ch 5 Prefetch Abort Abort(_abt) I=1, F=unchanged
BASE+10h 2 Data Abort Abort(_abt) I=1, F=unchanged
BASE+14h ?? Address Exceeds 26bit Supervisor(_svc) I=1, F=unchanged
BASE+18h 4 IRQ IRQ(_irq) I=1, F=changed
BASE+1Ch 3 FIQ FIQ(_fiq) I=1, F=1

例外処理に入る時に実行される命令


R14_(new mode)=PC+nn ;save old PC, ie. return address
SPSR_(new mode)=CPSR ;save old flags
CPSR new T,M bits    ;set to T=0 (ARM state), and M4-0=new mode
CPSR new I bit       ;IRQs disabled (I=1), done by ALL exceptions
CPSR new F bit       ;FIQs disabled (F=1), done by Reset and FIQ only

上のPC+nnは例外によって異なる.

例外から戻る時に必要な実行手順

レジスタR0からR14までの中で例外処理に使われたものを元に戻す. そして例外に応じたリターン処理を実行してPCとCPSRを元に戻す, この時CPU state(Thumb or ARM)やFIQ, IRQ disable フラグも戻される.

注意: リターンアドレスはARM-styleで記述される. ARM stateから入ったのかThumb stateから入ったのかによらずに処理するため.

FIQ (Fast Interrupt Request)

一般のバンクレジスタ(R13_fiq, R14_fiq)の他に, さらに5つのバンクレジスタ(R8_fiq-R12_fiq)を持つ. バンクレジスタをもつレジスタは元の値をスタックに保存する処理が省ける. privileged mode (non-user mode)では, FIQはCPSRの F bit をセットすることで禁止できる.

IRQ (Normal Interrupt Request)

FIQと違いIRQはバンクレジスタを持たない. FIQよりも優先順位が低く, FIQ例外が実行されているときはIRQは禁止されている. priviledged(non-user mode)では, IRQはCPSRの I bit をセットすることで禁止できる.

IRQからのリターン処理:

SUBS PC,R14,4 ;both PC=R14_irq-4, and CPSR=SPSR_irq

Software Intrrupt(SWI)

swi命令から呼び出される. swi処理は他の例外と同様ARM stateで実行される

リターン処理:

MOVS PC,R14 ;both PC=R14_svc, and CPSR=SPSR_svc

Undifined Instruction Exception

CPUが実行できない命令に当たった時に送られる.

リターン処理:

MOVS PC,R14 ;both PC=R14_und, and CPSR=SPSR_und

Abort

GBAでは使われないが仮想メモリシステムで使われる, 詳細略.

Reset

PC=VVVV0000hとなりCPSRのT bit = 0(ARM state), F=1, I=1(disable FIQ and IRQ), M4-0=10011bとなる.(Supervisor mode)