本文共 8834 字,大约阅读时间需要 29 分钟。
感性认识 当一个程序正常按照其设计运行,有一个事件打断了该程序的正常执行流程 那么这个事件就叫异常 异常是硬件概念异常的定义 当尝试执行的原子算术运算没有生成可普遍接受的结果时,就产生了运算异常。 原子和可接受的含义随时间和使用场合而异。// 请参见 W. Kahan 编著的《Handling Arithmetic Exceptions》。 例如,当某个程序尝试求负数的平方根时,会产生异常。这是无效运算异常的一个示例。异常在armv6下分为7个(缺页异常并不是armv6异常的一种,而是一种软件概念)七个异常对应5种异常处理器模式(特权) reset 和 swi 共享 SVC异常模式 data abort 和 Prefetch Abort 共享 ABT异常模式 attempted execution of an Undefined instruction UND异常模式 // Thumb指令集没有在ARMv5的非T变体上实现。如果通过在这些体系结构变体上设置T==1来选择Thumb指令集,则执行的下一条指令将导致未定义的指令异常(请参阅第A2-19页的未定义指令异常)。 IRQ, normal interrupt IRQ异常模式 FIQ, fast interrupt FIQ异常模式
同步异常是cpu内部发生的,和cpu指令地址完全相关比如 执行时先a后b 执行完a,执行完毕,检测异常,没有异常发生 执行完b(执行过程中发生异常),执行完毕,检测异常(检测到同步异常)异步异常是cpu外部发生的,和cpu指令地址不完全相关比如代码是先a后b,但是实际上跑了先b后a在a时发生了中断 a执行完毕后,此时不会先检测异常 而是 a执行完毕后,回退b的执行(b的执行结果被丢掉,包括回退pc指针).然后检测异常(检测到异步异常)所以 异步 是不确定中断会断在哪条指令上 因为 cpu会乱序执行异常探测时机 和 同步异步 没有任何关系 异常检测时机 : ROB退出 检查同步异常/异步异常 的时机最好应该放在指令从ROB退出的时候做 这样可以保证中断前的指令都执行完成,中断后的指令一条都没有执行异常如何探测 架构或实现相关 // TODO
同步异常 // 确定会会断在哪条指令上 来自cpu(不是soc)内部 当前程序本身引起的异常 cpu探测获得 undefined instruction/software interrupt/prefetch abort/data abort cpu何时探测到异常 :ROB退出异步 // 不确定会断在哪条指令上 来自cpu(不是soc)外部 不是当前程序本身引起的异常 从中断引脚获得 irq fiq reset cpu何时探测到异常 :ROB退出
Reset 具体芯片手册中有 reset 相关的 记录 1. Hardware reset : XnRESET 拉低 4个 CLK 2. Watchdog reset : 3. Wakeup reset : from SLEEP mode A. 设置PC跳转到复位中断向量(0xffff0000或0x00000000)时 // 此时并不会进入 reset异常,而是会 进入 data abort 异常Undefined instructions 与协处理器相关的指令(也只有这种指令)可能会产生未定义指令,armv6中下面这些指令会产生该异常 CDP/LDC/MCR/MCRR/MRC/MRRC/STCSoftware interrupt (SWI) SWI 指令Prefetch Abort (instruction fetch memory abort) 访存流程中,读取了无效指令,执行时产生 BKPT 指令Data Abort (data access memory abort) 访存流程中,读取数据 受限(或其他原因),产生nullIRQ (interrupt) 中断控制器产生FIQ (fast interrupt) 中断控制器产生
A2.6.2复位===================================== 1.发生原因: 当复位异常在处理器上被检测到时,ARM处理器立即停止当前指令的执行。 2.停止执行之后,执行以下操作: R14_svc = UNPREDICTABLE value SPSR_svc = UNPREDICTABLE value CPSR[4:0] = 0b10011 /* Enter Supervisor mode */ CPSR[5] = 0 /* Execute in ARM state */ CPSR[6] = 1 /* Disable fast interrupts */ CPSR[7] = 1 /* Disable normal interrupts */ CPSR[8] = 1 /* Disable Imprecise Aborts (v6 only) */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if high vectors configured then PC = 0xFFFF0000 else PC = 0x00000000 3.没有架构上定义的从重置返回的方式。// 即 不用返回 4.reset之后,ARM处理器将在地址0x00000000或0xFFFF0000处开始执行,并在svc模式下,中断被禁止。A2.6.3未定义的指令异常 // 未定义 并不是无效指令===================================== 1.发生原因 如果ARM处理器执行协处理器指令,它将等待任何外部协处理器确认它可以执行该指令。如果没有协处理器响应(即执行未定义的指令),则会发生未定义的指令异常。 未定义的指令异常可用于没有物理协处理器(硬件)的系统中协处理器的软件仿真,或用于通过软件仿真扩展通用指令集。 2.当发生未定义的指令异常时,执行以下操作: R14_und = address of next instruction after the Undefined instruction SPSR_und = CPSR CPSR[4:0] = 0b11011 /* Enter Undefined Instruction mode */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] is unchanged */ CPSR[7] = 1 /* Disable normal interrupts */ /* CPSR[8] is unchanged */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if high vectors configured then PC = 0xFFFF0004 else PC = 0x00000004 3.如何返回 在模拟未定义的指令使用后返回1: MOVS PC,R14 这将还原PC(从R14 und)和CPSR(从SPSR und)并返回到未定义指令之后的指令。 在模拟未定义的指令使用后返回2: 在某些协处理器设计中,一条协处理器指令引起的内部异常情况是通过拒绝响应后一条协处理器指令而不精确地发出信号的。 在这些情况下,未定义的指令处理程序将执行清除异常情况所需的任何操作,然后返回到第二条协处理器指令。 为此,请使用: SUBS PC,R14,#4 参考 A3.1 Instruction set encodingA2.6.4软件中断异常===================================== 1.发生原因 软件中断指令(SWI)进入监控模式,请求特定的监控(操作系统)功能。 2.执行SWI时,执行以下操作: R14_svc = address of next instruction after the SWI instruction SPSR_svc = CPSR CPSR[4:0] = 0b10011 /* Enter Supervisor mode */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] is unchanged */ CPSR[7] = 1 /* Disable normal interrupts */ /* CPSR[8] is unchanged */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if high vectors configured then PC = 0xFFFF0008 else PC = 0x00000008 3.在执行SWI操作后返回,请使用以下指令还原PC(从R14_svc)和CPSR(从SPSR_svc)并返回到SWI之后的指令: MOVS PC,R14 A2.6.5 Prefetch Abort(指令获取内存中止) // ===================================== 1.发生原因 1. 内存系统发出内存中止信号。响应指令获取激活中止会将获取的指令标记为无效。 如果处理器尝试执行无效指令,则会生成预取中止异常。 如果指令未执行(例如,在管道中执行分支的结果),则不会发生预取中止。 2. 在ARMv5及以上版本中,预取中止异常也可以作为执行BKPT指令的结果生成。 有关详细信息,请参阅第A4-14页的BKPT(ARM指令)和第A7-24页的BKPT(拇指指令)。 2.当试图执行中止的指令时,将执行以下操作: R14_abt = address of the aborted instruction + 4 SPSR_abt = CPSR CPSR[4:0] = 0b10111 /* Enter Abort mode */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] is unchanged */ CPSR[7] = 1 /* Disable normal interrupts */ CPSR[8] = 1 /* Disable Imprecise Data Aborts (v6 only) */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if high vectors configured then PC = 0xFFFF000C else PC = 0x0000000C 3.在修复中止的原因后返回,使用以下指令,这将恢复PC(从R14_abt)和CPSR(从SPSR_abt),并返回到中止的指令。 SUBS PC,R14,#4数据中止(数据访问存储器中止)===================================== 1.发生原因 存储器系统发出存储器中止信号。为响应数据访问(加载或存储)而激活中止会将数据标记为无效。 数据中止异常发生在以下任何指令或异常改变CPU状态之前。 2.执行以下操作: R14_abt = address of the aborted instruction + 8 SPSR_abt = CPSR CPSR[4:0] = 0b10111 /* Enter Abort mode */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] is unchanged */ CPSR[7] = 1 /* Disable normal interrupts */ CPSR[8] = 1 /* Disable Imprecise Data Aborts (v6 only) */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if high vectors configured then PC = 0xFFFF0010 else PC = 0x00000010 3.在修复中止异常后返回: SUBS PC,R14,#8 // 这将恢复PC(从R14_abt)和CPSR(从SPSR_abt),并返回以重新执行中止的指令。 SUBS PC,R14,#4 // 如果中止的指令不需要重新执行,请使用: 4.在内存中数据中止指令的影响 访问数据存储器的指令可以通过存储一个或多个值来修改存储器。 如果该指令中发生数据中止,则该指令存储到的每个内存位置的值根据以下不同情况而不同: •如果内存系统不允许对内存位置进行写访问,则保持不变 •否则无法预测。 5.访问数据存储器的指令如何修改寄存器 访问数据存储器的指令可以通过以下方式修改寄存器: •将值加载到一个或多个通用寄存器中,该寄存器可以包括PC。 •通过指定基址寄存器写回,其中地址计算中使用的基址寄存器有一个修改后的值写入其中。 如果指定了基址寄存器写回,并且基址寄存器是PC,则允许指定基址的所有指令都会产生不可预测的结果,因此只有PC以外的通用寄存器才能以这种方式合法地修改。 •将值加载到协处理器寄存器中。 •修改CPSR。 6.修改寄存器时,数据中止,会发生什么? 如果发生数据中止,这些寄存器中留下的值由以下规则确定: 1. 数据中止处理程序入口的PC值为0x00000010或0xFFFF0010,R14_abt值由中止指令的地址确定。两者都不受指令指定的任何PC加载结果的任何影响。 2. 如果未指定基址寄存器写回,则基址寄存器值不变。 即使指令加载了自己的基址寄存器,并且加载基址寄存器的内存访问发生在中止访问之前,也会出现这种情况。 例如,假设指令是: LDMIA R0,{ R0,R1,R2} 实现中定义 加载新的R0值,然后加载新的R1值,最后加载新的R2值。 如果在任何访问上发生数据中止,则指令的基址寄存器R0中的值保持不变。即使中止的是R1或R2的加载,而不是R0的加载,也会出现这种情况。 3. 如果指定了基址寄存器写回,则基址寄存器中剩余的值由实现的中止模型确定,如第A2-23页中止模型中所述。 4. 如果指令只加载一个通用寄存器,则该寄存器中的值不变。 5. 如果指令加载多个通用寄存器,则不可预测的值将留在既不是指令的PC寄存器也不是指令的基址寄存器的目标寄存器中。 6. 如果指令加载协处理器寄存器,则不可预测的值将保留在目标协处理器寄存器中,除非在特定协处理器的指令集描述中另有指定。 7. 未定义为在异常项上更新的CPSR位保持其当前值。 8.中止模型 ARM实现使用的中止模型是由实现定义的,是下列模型之一: 基还原中止模型 如果在指定基寄存器写回的指令中发生精确的数据中止,则基寄存器中的值不变。这是ARMv6及以上版本中唯一允许的中止模式。 基址更新中止模型 如果在指定基址寄存器写回的指令中发生精确的数据中止,基址寄存器写回仍会发生。ARMv6及以上版本禁止使用此型号。 在这两种情况下,中止模型在所有指令中统一应用。 对于某些指令,实现不使用基本还原中止模型,而对于其他指令,实现则不使用基本更新中止模型。 5. 不精确数据中止 例子: 写 缓冲区中保存的数据 到内存,然后形成外部错误. 发生时机: 与引起指令的执行是异步的,并且实际上可能在导致内存访问的指令失效后发生多个周期。 由于这个原因,不精确的数据中止 可能发生在处理器由于精确中止而处于中止模式的时候, 可能在中止模式下处于活动状态,但正在处理中断。 为了避免在这些情况下丢失中止模式状态(R14和SPSRY-ABT),这将导致处理器进入不可恢复状态,系统必须保持未决的不精确数据中止的存在,直到中止模式能够安全地进入。 不精确数据中止的屏蔽 从ARMv6开始,在CPSR(CPSR[8])中添加一个掩码,以控制何时不能接受不精确的中止。此位称为A位。 不精确数据中止导致在不屏蔽不精确数据中止时执行数据中止。 当不精确数据中止被屏蔽时,实现负责保持一个挂起的不精确中止的存在,直到该屏蔽被清除并且中止被采取为止。 由实现定义是否可以挂起多个不精确中止。 A位在执行预取中止、数据中止、IRQ或FIQ中断和复位时自动设置。位只能从特权模式更改。中断请求(IRQ)===================================== 1.发生原因 异常IRQ异常是通过断言处理器上的IRQ输入从外部生成的。 2. 当检测到IRQ时,将执行以下操作: R14_irq = address of next instruction to be executed + 4 SPSR_irq = CPSR CPSR[4:0] = 0b10010 /* Enter IRQ mode */ CPSR[5] = 0 /* Execute in ARM state */ /* CPSR[6] is unchanged */ CPSR[7] = 1 /* Disable normal interrupts */ CPSR[8] = 1 /* Disable Imprecise Data Aborts (v6 only) */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if VE==0 then if high vectors configured then PC = 0xFFFF0018 else PC = 0x00000018 else PC = IMPLEMENTATION DEFINED /* see page A2-26 */ 3.要在维护中断后返回,请使用:这将恢复PC(来自R14_irq)和CPSR(来自SPSR_irq),并恢复中断代码的执行。 SUBS PC,R14,#4 4. 优先级 它的优先级低于FIQ(见第A2-25页表A2-1),并且在输入FIQ序列时被屏蔽。 5. I位 当CPSR中的I位被设置时,中断被禁用。如果I位清除,ARM将在指令边界检查IRQ。 注意I位只能从特权模式更改。快速中断请求(FIQ)===================================== 1.发生原因 异常FIQ异常是通过断言处理器上的FIQ输入从外部生成的。 2.当检测到FIQ时,将执行以下操作: R14_fiq = address of next instruction to be executed + 4 SPSR_fiq = CPSR CPSR[4:0] = 0b10001 /* Enter FIQ mode */ CPSR[5] = 0 /* Execute in ARM state */ CPSR[6] = 1 /* Disable fast interrupts */ CPSR[7] = 1 /* Disable normal interrupts */ CPSR[8] = 1 /* Disable Imprecise Data Aborts (v6 only) */ CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */ if VE==0 then if high vectors configured then PC = 0xFFFF001C else PC = 0x0000001C else PC = IMPLEMENTATION DEFINED /* see page A2-26 */ 3.要在维护中断后返回,请使用:这将恢复PC(来自R14_fiq)和CPSR(来自SPSR_fiq),并恢复中断代码的执行。 SUBS PC,R14,#4 4. FIQ的快速处理原因 FIQ设计用于支持数据传输或信道处理,并具有足够的专用寄存器,以消除此类应用程序中保存寄存器的需要,从而最大限度地减少上下文切换的开销。 FIQ向量故意是最后一个向量,允许FIQ异常处理程序软件直接放在地址0x0000001C或0xFFFF001C,而不需要向量的分支指令。 5. F位 当CPSR中的F位被设置时,快速中断被禁用。如果F位是清除的,ARM会在指令边界检查FIQ。 注意F位只能从特权模式更改。
转载地址:http://ojigi.baihongyu.com/