0%

ARM基础知识

ARM模式(处理器所在的模式)和寄存器总结

本文介绍了ARM V7架构下的处理器的模式、状态以及通用寄存器和部分CP15 bank

  1. ARM处理器模式

    USR,FIQ,IRQ,SVC,MON,ABT,HYP,UND,SYS

1-1:ARM处理器模式

  • USR:大多数应用运行的模式,非特权模式,运行在PL0
  • FIQ:快中断异常模式,运行在PL1
  • IRQ:普通中断模式,运行在PL1
  • SVC:当处理器复位或者执行特权指令的时候处理器进入此模式,运行在PL1
  • MON:MON模式在ARM V6之前是没有的,此模式主要作用就是实现安全拓展,运行在PL1
  • ABT:进行内存访问的时候处理器进入此模式,运行在PL1
  • HYP:主要为虚拟化拓展用,运行在PL2
  • UND:当执行一个未定义指令时,处理器进入此模式,运行在PL1
  • SYS:OS运行的模式,运行在PL1

CPU当前的模式和运行状态可以由CPSR得知

  1. ARM特权等级

    • PL0:应用程序处于的模式(User mode),此模式下不能改变一些配置设置,并且此模式下的只能进行非特权的内存访问
    • PL1:大多数软件在PL1下执行,只要不是在User mode和Hyp mode的模式都工作在此特权等级下
    • PL2:HYP mode就在PL2下,工作中一般用不到
  2. ARM通用寄存器概述

    ARM架构包含16个32位的通用寄存器(R0-R15),R0-R14可以用来一般的数据存储,但**R15存储了当前程序执行计数指针的值(PC)**,手动往R15里写值的话会改变程序执行流。R13一般被用来存储栈指针SP,R14用来存储函数的返回值LR

    image-20210926173944919

    3-1:ARM通用寄存器

    上图的R0-15在不同处理器模式下一些寄存器的作用是不同的,其中有一些物理寄存器所有模式下是共用的,也有一些寄物理寄存器在不同的处理器模式下独自拥有:

    ARM通用寄存器

    3-2:ARM Bank register

    由上图可以看出,所有的模式下R0-R7是共用的,也就是在User、Sys、FIQ…..等模式下访问到的R0-R7的寄存器值是都是相同的。但同时也不难看出比如在IRQ模式下,访问R13寄存器,那实际访问的是SP_svc寄存器,如果在FIQ模式下访问R13寄存器,那么实际访问到的是SP_fiq寄存器。

    ​ 需要注意的是:软件不会指定访问哪个模式下的哪个寄存器,而是由此时软件处于的处理器模式决定的,比如当前软件运行于User mode,那么此时访问R13,就实际访问SP_svc

    • R13:在所有的模式下都是OS的栈指针

    • R14:一般用来保存进入子程序的返回地址;当异常发生时,该异常模式对应的 R14 寄存器被设置成该异常模式将要返回的地址

    • R15:程序计数器,保存着当前程序的指令地址加上8个字节,也就是PC指针。原因是因为ARM的三级流水钱机制:Fetech->Decode->Execute,比如现在有三条指令inst1,inst2,inst2,当前正在执行的指令是inst1,那么执行inst1的过程也会对inst2进行Decode,inst3也同时在Fetech。对于32位的ARM处理器,那么一条指令为4字节,我们可以得到:

      1
      R15(PC) = 当前执行的程序位置 + 8个字节
    • CPSR:程序当前状态寄存器

      • 保存着当前的处理器模式
      • 中断标志
      • 处理器的状态,比如处于ARM还是Thumb等
      • 大小端
      • 执行状态

      我们知道当前中断执行完成之后需要恢复现场,那从图3.2可以看出,所有模式下的CPSR都是公用,那么显然会产生冲突。所以除了User和Sys模式,其他的7个模式在exception下都有各自的备份状态寄存器(SPSR),当exception发生时,CPSR的值会自动拷贝到SPSR,当exception退出时,可以使用SPSR来恢复CPSR。

      image-20211105162202921

      3-3:CPSR寄存器

      各个位含义如下:

      • N:ALU计算出的结果为负值
      • Z:ALU计算出的结果为0
      • C:ALU计算有进位产生
      • V:ALU计算有溢出产生
      • Q:饱和状态,仅ARM v5TE_J 架构支持
      • J:ARM core是否处于Jazelle状态
      • GE[3:0]:SIMD指令使用
      • IT[7:2]:Thumb2指令使用
      • E:大小端标志,0为小端,1为大端
      • A:disables asynchronous aborts.
      • I:是否使能IRQ
      • F:是否使能FIQ
      • T:ARM core是否处于Thumb状态
      • M[4:0]:确定处理器模式,见图1-1:ARM处理器模式
  3. ARM CP15协处理器控制寄存器

    功能:CP15一共有16个32位**(c0-c15**)的寄存器,一般用于存储管理和中断管理

    image-20211105170614405 4-1:CP15

    不同的CRn,opc1,opc2,CRm组合对应着不同的寄存器。图4-1:CP15里重要的参数解读如下:

    • CRn:CP15 协处理器的目标寄存器

    • CRm:协处理器中附加的目标寄存器或者源操作数寄存器,如果不需要附加信息就将
      CRm 设置为 C0,否则结果不可预测

    • opc1:要执行的操作码

    • opc2:可选的操作码,不用的时候置0

      CP15的读写通过MRC与MCR,读写格式为:

      1
      2
      MRC p15, Op1, Rt, CRn, CRm, Op2 ; read a CP15 register into an ARM register
      MCR p15, Op1, Rt, CRn, CRm, Op2 ; write a CP15 register from an ARM register

      Rt:ARM源寄存器,要写到CP15的寄存器的值就保存在此寄存器中,对于MRC来说,从CP15指定寄存器读出来的值就会保存在Rt里,对于MCR来说Rt就代表将要写入的寄存器

      c0寄存器详细描述:

      image-20211105173147594

      4-2:c0寄存器

当CRn=0,opc1=0,CRm=0,opc2=0时,就表示此时的c0就代表MIDR,同理当CRn=0,opc1=0,CRm=0,opc2=1时,此时的c0就代表CTR寄存器。当c0代表了MIDR时,MIDR各个位含义如下:

image-20211105173818098

4-2:c0作为MIDR

  • Bits [31:24] – implementer:处理器厂商编号,如果是0x41就代表ARM

  • Bits [23:20] – variant:ARM core的主版本号

  • Bits [19:16] – architecture:ARM架构,0xF代表ARM V7

  • Bits [15:4] – part number:ARM core版本号,如果是0xC08,就代表了Cotex-A8处理器

  • Bits [3:0] – revision:ARM core的次版本号

    c1寄存器详细描述:

    ![image-20211105180046638](c1 寄存器组.png)

    4-3:c1 寄存器组

    如图4-3,当CRn=1,opc1=0,CRm=0,opc2=0时,c1即为SCTLR寄存器,SCTLR寄存器就是系统控制寄存器,主要用来控制标准内存、系统一些外设并且提供ARM core的一些状态信息等。SCTLR只能在PL1或者更高的特权等级访问

    image-20211105213323780

    4-4:c1—SCTLR寄存器

    常用的位有:

    • EE:定义了异常的大小端

    • U:定义了内存对齐模型,多少字节对齐

    • FI:FIQ配置使能

    • V:中断向量表基地址选择位,如果为0的话中断向量基地址为0x00000000。软件可以使用 VBAR 来重映射此基地址,也就是中断向量表重定位。为 1 的话中断向量表基地址为0XFFFF0000,此基地址不能被重映射

    • I:I cache使能位,为0关闭,1开启

    • Z:分支预测使能位

    • C:D Cache 和缓存一致性使能位,为 0 的时候禁止 D Cache 和缓存一致性,为 1 时使能

    • A:内存对齐检查位,为1是开启内存检查

    • M:MMU使能位,为0禁止MMU,为1开启MMU

      c12寄存器详细描述:

      ​ c12常见的功能是作为VBAR寄存器,这样用户就可以通过软件的方式重新设置中断向量表地址

      image-20211106110535857

      4-5:c12—VBAR

      如图4-5,当CRn=12,opcl=0,CRm=0,opc2=0时,c12即为VBAR寄存器。

      常见的设置中断向量表地址的示例如下:

      1
      2
      ldr r0,=dest addr
      MCR p15,0,r0,c12,c0,0

      c15功能描述:

      ​ c15一般用来获取GIC地址,从而配置中断控制器相关功能

      image-20211106111738271

      4-6:c15—CBAR寄存器

      如图4-6,当CRn=15,opc1=4,CRm=0,opc2为0时,c15即为CBAR寄存器,CBAR寄存里保存的是内存映射 GIC 寄存器的物理基地址 。需要注意的是CBAR为只读寄存器,并且访问特权等级为PL1或者更高。

      访问CBAR可以使用:

      1
      MRC p15, 4, <Rt>, c15, c0, 0; Read Configuration Base Address Register

      通过上面命令可以获取到GIC的基地址,由于GIC是中断控制器,那我们就可以通过读GIC的一些寄存器来获取中断的一些状态,通过上面的命令我们已经得到了GIC BASE ADDR,由于GIC是CPU接口端寄存器,中断的的ID保存在GICC_IAR里,那只需要找到GICC_IAR相对CPU端接口基址的偏移量即可访问到GICC_IAR。GICC_IAR相对CPU端基地址偏移量是0x000C

      1
      2
      3
      MRC p15,4,r1,c15,c0,0;把GIC的基地址读到r1里
      ARR r1,r1,#0X2000;CPU端基地址为GIC基地址+0x2000
      LDR r0,[r1,#0XC];读取GICC_IAR的值,保存到r0