ARM中断进入和退出分析

来源:互联网 发布:淘宝网怎么绑定支付宝 编辑:程序博客网 时间:2024/09/21 09:04

个人觉得中断进入和退出比较重要,本文是根据:杜春雷的《ARM体系结构与编程》中第九章  异常中断处理  整理而来

0x00复位(reset): 1   svc 

复位引脚有效产生复位异常中断,程序跳转到子程序执行;复位情况加电,复位按键直接跳转到复位中断服务子程序

0x04未定义指令(undefined instruction):6   und

0x08软件中断:用户自定义的中断指令,目的是为了获取到特权 6   svc

0x0c指令取中止 5   abt

0x10数据访问中止 2    abt

0x14

0x18外部中断请求(IRQ) 4 fiq

0x1c快中断请求(FIQ) 3   irq

 

0b10000  usr

0b10001  FIQ

0b10010  irq

0b10011  supervisor

0b10111  abort

0b11011  undefined

0b11111   system

 

中断向量表大小是32字节,每个中断占4字节。里面存放跳转指令,使pc跳转到服务子程序入口地址。

 

处理器对异常中断响应过程:

 

保存当前处理器的状态寄存器cpsr的 内容保存到异常发生的spsr内。

设置当前cpsr:m0-m4进入相应模式;t 位:thumb还是arm;fiq 置1禁止;irq置1禁止;

FIQ中断比IRQ中断优先级高,如果进入IRQ中断,可以不禁止FIQ;但如果是FIQ中断,则要屏蔽所有中断。

设置lr为返回地址,pc赋值跳转到相应的子程序;

 

1.       复位中断

当处理器复位引脚有效时,产生复位中断,处理器中止当前指令,当引脚无效时,处理器执行中断现场保护。

Lr_(svc/und/abt/irq/fiq) = addr + 4         //保存返回地址

Spsr_(svc/und/abt/irq/fiq)=cpsr      //保存当前处理器状态

Cpsr[4:0] = 0x.                 //设置模式(进入中断对应的特权模式)

Cpsrp[5] = 0                      //设置ARM模式(1:thumb模式)

If<exception_mode> == reset or fiq

Cpsr[6] = 1                    /如果是中断或复位则禁止中断(因为快中断优先级高)

Cpsr[7] = 1                     //无条件禁止快中断

Pc = 0x                      //跳转到中断子程序入口地址

上面的操作是cpu完成的。

 

下面现场恢复是有程序员完成的;

从异常中断中返回

1.       恢复中断前的处理器状态,spsr_mode 内容复制到cpsr中;

2.       返回到发生异常中断的指令的下一条指令去执行lr_mode寄存器内容复制到pc

3.       复位中断不要返回; 

 

==================================================

SWI和未定义指令异常:

 

ARM9处理器的三级流水线 

Pc :    取值(表示指令a正在被取值,接下来是译码,然后执行)

Pc -4           译码

P 8                 执行

 

pc永远指向正在取值的指令

 

Pc = 当前执行指令 + 8


未定义指令和swi软件中断指令返回的地址是:mov pc, lr_mode;

因为在中断发生时,ld_mode = pc  4;就是把现在执行的指令的下一条指令保存,也即是把译码的指令地址保存起来

因为undefined/swi中断发生时,pc没有更新。

所以ld_mode = pc -4;保存的是下一条要执行的指令

 

==========================================================

FIQ、IRQ异常:

处理器是执行完当前指令后再去检查是否有irq/fiq中断

Irq/FIQ中断时先执行当前执行,然后查询IRQ/FIQ中断引脚,已经判断是否允许irq/fiq中断。只有引脚有效和系统允许才发生异常中断。所以当irq和fiq中断发生时,pc的值已经改变了。指向当前中断指令的后面第三个:pc  12;

 

更新前:正在执行irq/fiq要发生的指令

                    取值    译码    执行

Pc + 4:a

   Pc   :      b

P 4:                    c

P 8:                               d

  

更新后:irq/fiq已经发生

             取值    译码    执行

Pc + 4:

Pc   :      a

P 4:              b

P 8:                       c(没有执行因为有中断,但是已经在执行的队列中)

执行过:pc  12                         d

 

当发生异常时先把pc  4 的值保存到lr_mode寄存器中:指向中断发生指令后的第2条指令;

所以:subs  pc,lr,#4 ;==》pc = lr  4,lr =pc -4 è 返回给pc = pc -8;

如果最后要直接用堆栈调用pc则存入堆栈时要把lr再减4;(因为处理器保存的pc-4,跳转要pc - 8)

Subbs lr,lr,#4

Stmfd sp!,(reglist,lr)

..

Ldmfd sp!,{reglist,pc}^


=====================================================================

指令预取中止:

 指令预取中止异常:在指令预取时,如果目标地址是非法的,该指令将被标记是有问题的。

流水线上之前的指令继续执行,当执行到有问题的指令时,处理器产生预取值指令中止异常中断;预取指令中止的服务子程序最后是要返回到出问题的指令地址,再执行。

  预取值指令中断是指令本身问题,所以pc的值没有更新值所以pc指向当前执行指令的后第二个。处理器保存的是pc -4即:指向当前问题指令(执行指令)的下一条;因为要返回有问题指令(即当前指令)所以要再减4,操作和上面相同;

 

===================================================================

 数据访问中止异常:

和上面的预取指令异常一样,最后中断子程序都要返回到出问题的指令地址上再次执行。但是不同的是预取指令中止异常时pc的值没有更新,而数据访问中止异常pc已经更新了。所以处理器保存在lr的pc-4是指向问题指令的后两条,要返回到问题指令所以还得lr-8。自己可以画下流水线图。

0 0