ARM Interrupt

Reading time ~1 minute

CPSR & SPSR

CPSR: Current program status register(当前程序状态寄存器),在任何处理器模式下被访问。它包含了条件标志位、中断禁止位、当前处理器模式标志以及其他的一些控制和状态位。CPSR在用户级编程时用于存储条件码。

SPSR: Saved program status register(程序状态保存寄存器),每一种处理器模式下都有一个状态寄存器SPSR,SPSR用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。当特定的异常中断发生时,SPSR用于存放当前程序状态寄存器(CPSR)的内容。在异常中断退出时,可以用SPSR来恢复CPSR。

除了用户模式和系统模式,其余模式下都有一个私有SPSR保存状态寄存器,用来保存切换模式之前的执行状态,之所以用户模式和系统模式没有SPSR是因为,通常CPU大部分时间执行在用户模式下,当产生异常或系统调用时会分别进入另外几种模式,保存用户模式下的状态,当切换回原来模式时,直接恢复SPSR的值到CPSR就可以了,因此,用户模式和系统模式下不需要SPSR。当用户在用户模式或系统模式下访问SPSR,将产生不可预知的后果。

CPSR & SPSR访问指令

ARM处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传输数据,程序状态寄存器访问指令包括以下两个条件:

  • MRS: Move to Register from State register (程序状态寄存器到通用寄存器的数据传输指令)
  • MSR: Move to State register from Register (通用寄存器到程序状态寄存器的数据传输指令)

MRS 指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下几种情况:

  • 当需要改变程序状态寄存器的内容时,可用MRS 将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
  • 当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。

指令示例:

  • MRS R0,CPSR ;传送CPSR 的内容到R0
  • MRS R0,SPSR ;传送SPSR 的内容到R0

MSR指令可以对状态寄存器CPSRSPSR进行写操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。 由于xPSR寄存器代表了CPU的状态,其每个位有特殊意义,在执行对xPSR状态寄存器写入时(读取时不存在该用法),为了防止误操作和方便记忆,将xPSR里32位分成四个区域,每个区域用小写字母表示:

c  控制域屏蔽 psr[7..0]
x  扩展域屏蔽 psr[15..8]
s  状态域屏蔽 psr[23..16]
f  标志域屏蔽 psr[31..24]
注意:区域名必须为小写字母

向对应区域进行执行写入时,使用xPSR_x可以指定写入区域,而不影响状态寄存器其它位,如:

使能IRQ中断:

ENABLE_IRQ
    MRS    R0, CPSR	      ; 将CPSR寄存器内容读出到R0
    BIC    R0, R0,#0x80     ; 清掉CPSR中的I控制位
    MSR    CPSR_c,R0         ; 将修改后的值写回 CPSR寄存器的对应控制域
    MOV    PC,LR             ; 返回上一层函数

禁用IRQ中断:

DISABLE_IRQ
    MRS    R0, CPSR	            ; 将CPSR寄存器内容读出到R0
    ORR    R0, R0,#0x80           ; 设置CPSR中的I控制位
    MSR    CPSR_c,R0               ; 将修改后的值写回 CPSR寄存器的对应控制域
    MOV    PC,LR                   ; 返回上一层函数

BIC & ORR

BIC指令的格式为:

BIC{条件}{S}  目的寄存器,操作数1,操作数2

BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应是一个寄存器, 操作数2可以是一个寄存器、被移位的寄存器、或一个立即数。操作数2为32位的掩码,如果在 掩码中置了某一位1,则清除这一位。未设置的掩码位保持不变。 指令示例:

bic r0, r0, #0x1f

0x1f = 11111b 其含义:清除 r0 的bit[4:0]位。

ORR指令的格式为:

ORR{条件}{S}  目的寄存器,操作数1,操作数2

ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数1应该是一 个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操 作数1的某些位。 指令示例:

ORR R0,R0,#3          ;  该指令设置R0的0、1位,其余位保持不变。
orr r0, r0, #0xd3		; 0xd3 = 1101 0011
				; 将r0与0xd3作算数或运算,然后将结果返还给r0,
				; 即把r0的bit[7:6]和bit[4]和bit[2:0]置为1。

Linux_generic_block_layer

## 块设备层分析 ##IO无论是经过EXT3文件系统还是块设备文件,最终都要通过writeback机制将数据刷新到磁盘,除非用户在对文件进行读写的时候采用了`Direct IO`的方式。为了提高性能,文件系统或者是裸设备都会采用Linux的cache机制对数据读写性能进行...… Continue reading

Linux_driver

Published on February 22, 2017

Linux Direct I/O

Published on January 12, 2017