当前位置:文档之家› 关于ARM寄存器组及工作模式知识

关于ARM寄存器组及工作模式知识

关于ARM寄存器组及工作

模式知识

(周方辉)

2012/8/10 编改记录

目录

1 参考文献 (2)

1.1 内部参考文献 (2)

1.2 外部参考文献 (2)

2 名词解释 (2)

3 ARM核工作模式 (2)

3.1 程序状态寄存器 (3)

3.2 寄存器分组 (4)

3.3 何为特权(异常)模式 (6)

3.4 各种模式工作机制 (7)

3.5 各种模式工作返回用户模式机制 (9)

4 ARM核工作模式初始化参考代码 (11)

1参考文献

1.1内部参考文献

内部参考文献指的是周方辉自生的百度博文中的文件。

无内部参考文献。

1.2外部参考文献

外部参考文献指的是相对于上述内部参考文献以外的文件。

《ARMv8_ISA_PRD03-GENC-010197-24-0.pdf》

《cortex_a8_r3p2_trm.pdf》

《CortexA8TechRefManul.pdf》

2名词解释

CPSR:当前程序状态寄存器,其数值反映出当前程序运行的一些状态指示。

SPSR:保存程序状态寄存器,在程序调用等情况下,需要保存一下当前程序状态寄存器的值(SPSR<=CPSR),便于日后回复。

SP:堆栈指针寄存器,其值用于执行当前堆栈栈顶(或栈底)位置。

PC:程序指针寄存器,其值用于指向要执行的程序代码地址。

LR:连接返回寄存器,保存要返回的地址,PC<=LR。

3ARM核工作模式

常规CPU工作核心模块都是由:寄存器组和ALU两大模块组成,ALU完成数据的加工处理,寄存器用来保存数据,这些数据是直接参与ALU运算。ARM的处理器也不例外。

ARM处理器的寄存器分成许多组,不同的组完成不同环境下的工作,不过它们都共用一套ALU数据处理模块。ARM寄存器一般用了37个,Cortex A8的ARM核的寄存器多大40个。

我们学习ARM工作模式需要了解和解决下面问题:

ARM寄存器为什么要分组?又是如何分组?

各组与CPU工作模式是如何关联?

各个组或工作模式是如何切换的?

我们在学习ARM寄存器分组工作模式之前,先来看一下很特殊的一个寄存器——PSR 程序状态寄存器。

3.1程序状态寄存器

程序状态寄存器是一个32bits的寄存器,它记录和指示出当前程序运行状态。

格式如下:

条件状态位:

N:Negative/Less than,负数/小于0,而置1。

Z:Zero,为0时该位置1。

C:Carry/Borrow/Extend,发生了进位/借位/扩伸,该位将置1。

V:Overflow,溢出时该位置1。

它们之间关系:

Q:Sticky overflow,饱和计算溢出标志。(有符号运算,确保数的极性不会翻转)发生时溢出,该位置1。例如:假设8bits符号数据,125+9=127,133超过127成为负数,而Q算法保持127最大数,确保不会变成负数。

IT[7:0]:[7:2]用于IF….ELSE…条件执行状态位。

GE[3:0]:用于SIMD指令,大于或等于。

使能控制位:

A:A=1时,禁止不确定数据异常。

I:IRQ中断使能位,当其置1时,禁止IRQ发生。

F:FIQ中断使能位,当其置1时,禁止FIQ中断。

指令类别状态位:

J:Java state bit,当T为1时,J=0,表示执行Thumb指令状态,J=1表示执行ThumbEE 指令状态。

T:当其为1是表示执行Thumb指令状态(或ThumbEE,这依赖于J为要为1),当其为0时,表示执行ARM指令状态。

工作模式位:用来指示不同组寄存器与ALU协同工作

M[4:0]:工作模式,

b10000(0x10)用户模式(User);

b10001(0x11)快速中断模式(FIQ);

B10010(0x12)向量中断模式(IRQ);

B10011(0x13)管理模式(Supervisor);

B10111(0x17)异常模式(Abort),取数据失败时发生;

B11011(0x1B)未定义模式(Undefined),指令解码出错时发生;

B11111(0x1F)系统模式(System)

B10110(0x16)安全监视模式(Secure Monitor),主要用于安全交易。

E:大端和小端标志,0小端,1为大端存储。因为ARM总线都为32bits(4个字节)以上的,而数据的存取常规以8bits为(字节)单位,这样就会出现如何放置数据问题。

规定数据高位放在高字节,低位的放在低字节的成为小端存取;反之,称之为大端存取。

3.2寄存器分组

ARM芯片将寄存器分成很多个组,来运行不同模式下的程序,让CPU程序运行得更加稳健。

下图是ARM寄存器分组图:User、System、FIQ、Supervisor、Abort、IRQ、Undefined

和Secure monitor共8个组。其中User和System两个组的寄存器完全共用,Secure monitor 是Cortex A8的ARM核开始追加的模式。

8中寄存器各自拥有和可访问的寄存器:

其中17个寄存器是各个组共用,(特别是R0---R7是每个组都共用的,另外R8和R14在FIQ 模式中不共用,FIQ有自己的R8_fiq---R14_fiq替代它们),另外专多达23个专用的寄存器分散在各种模式组中。

另外,许多寄存器都有专门用途,并且使用别名来操作。例如:

R9->SB,静态基地址寄存器。

R10->SL,数据堆栈限制指针。

R11->FP,(frame pointer) 帧指针。

R12->IP,(Intra-Procedure-call Scratch Register)子程序内部调用暂存寄存器。

R13->SP,堆栈指针stack pointer

R14->LR,连接寄存器linker register,用于跳转后返回(PC<-LR)。

R15->PC,程序计数器program counter,用于指向程序执行代码。

ATPCS规则就使用了上述别名。

3.3何为特权(异常)模式

这8组寄存器中,处理User外,其余7中都为特权模式或异常模式。我们可以给特权模式作如下规定:

1、对PSR寄存器中的模式位组有修改能力。

2、除了能访问共用寄存器外,还有自己的一些专用寄存器(System特权模式除外)。目前为止,除了User模式外,其它的都属于特权模式。

何为异常模式:

1、异常模式都属于特权模式的类别。

2、都有自己的专用模式处理程序入口地址(又称异常向量表),为CPU提供实时高效

和智能服务。

虽然也是8(8x4=32字节)个地址(存放指令,仅有一条,多数为跳转指令),但是它们与8

我们发现,8中模式中Supervisor和Abort各占用了两个表项,而User、System和Monitor 没有任何关联,这是为什么?

其一User模式是程序正常运行模式,它不需要进行特殊的异常处理,即User不是异常模式,所以它没有占任何表项;

另外System是特权模式,但是它不是异常模式,所以也不需要占用任何表项,System 与User完全共用寄存器,同时有能力进行模式切换(修改PSR寄存器的模式位),所以它是其它特权模式与User模式的交互桥梁。

对于Secure Monitor模式来说,是安全模式,需要协处理器来启动该模块,方能工作。同时又并在8种模式之中,我推测,Reserved会留给该异常模式使用,但是需要认证。

何为中断模式:

1、属于异常模式。

2、ARM核用来接入核外部的异常事件,称之为中断,FIQ和IRQ两种。

各种模式关系图:

3.4各种模式工作机制

工作模式切换2种方式:

1、程序手动切换,在某种特权模式下,可以切换到另外一个特权模式下,不过User用户

模式没有这个能力,因为它不是特权模式。

2、异常切换,异常事件发生,可从User模式下切换到异常模式下,或从另外一种异常模

式下切换到该异常事件模式下。

CPSR、PC和SPSR_xxx、LR_xxx寄存器工作关系:

当发生异常时:LR_xxx将保存但前PC值,SPSR_xxx将保存CPSR,因为PC会继续存放异常模式下的指令地址,CPSR将继续反应异常模式下程序运行状态,所以要保存。发生异常时,这些动作硬件自动完成。

同理:当异常程序结束时,CPSR<=SPSR_xxx,PC<=LR_xxx,恢复正常程序运行。

各种SPSR_xxx进入模式时备份CPSR用,各种LR_xxx用来保存PC。退出异常时,用户在异常程序的末尾写入一条完成PC<=lr指令,就自动完成CPSR<=SPSR_xxx动作。

CPSR——〉SPSR_xxx和PC+4——〉LR_xxx为一条指令完成,并非两条指令;同理

SPSR_xxx——〉CPSR和LR_xxx——〉PC也是一同指令一气呵成完成。

R13_xxx寄存器用途(sp_xxx堆栈指针):

指示相应异常模式下,私有堆栈空间,该堆栈可以完成异常模式下函数程序的切换参数传递。

FIQ和IRQ特权模式(异常或叫中断模式):

这两个特权模式是为Cortex-A8核以外的异常提供了处理接口。如按键、ADC转换成功和RTC等,这类相对Cortex-A8核来说(虽然这所有模块可能跟CortexA8一起都在一颗芯片上,如S5PC100)是外部打断了Cortex-A8核的正常运行,所以又称之为FIQ和IRQ中断模式。

Cortex-A8对FIQ和IRQ中断是否响应,在CPSR中有F和I位来控制,它们值为0表示允许响应,为1表示禁止响应,即FIQ和IRQ是可屏蔽中断,但是不能禁止中断事件发生,只是Cortex-A8内核不做响应而已。

Supervisor特权模式(异常):

进入Supervisor异常模式,一般有两种方式:硬件方式芯片复位(上电复位和复位引脚引发)和软件方式执行swi指令。

Abort特权模式(异常):

Abort异常模式,有Cortex-A8内部硬件自动引发,对内存数据的存取和指令预取失败会引发该异常。

Undefined特权模式(异常):

Undefined异常,由Cortex-A8内部硬件自动引发,当执行一条无法识别的指令时,将发生该异常。

Secure Monitor特权(异常)模式:

Secure monitor异常,当有私密的数据程序(如货币交易)要执行时,用户软件调用SMI (SMC替代SMI指令)指令即可进入该模式。

System特权模式:

System特权模式是Cortex-A8的7个特权模式中唯一一个没有自己的程序入口地址,所以它不属于异常概念。Systemt特权模式有两个特点:

1、System特权模式下的工作寄存器与User用户模式下的寄存器完全一样,不多一个,

也不少一个。

2、System特权模式能操作CPSR_mod权限,也就是说可以切换各种特权模式,访问他

们的资源。

上述特点使得System特权模式为其它6种特权(异常)模式下访问User模式下的资源。也就是说,在6种异常特权模式下,通过将CPSR_mod设置成System模式下,来访问User模式下资源,完成后,再将CPSR_mod改回去就恢复原有异常模式。

默认嵌套是禁止的。

Thumb Execution Environment(ThumbEE),在Thumb-2基础上发展起来的,2005年发布,为Java之类服务。

进阶SIMD(NEON)64bit和128bit单指令多重指令集(SIMD)。

期中用户模式和系统模式共用寄存器组,为用户模式进入伪特权提供机制。

ARM中各个异常处理响应优先级:

Reset(Supervisor),优先级最高。

Data Abort,优先权次之。

FIQ,优先级排到第3位。

IRQ,优先级排到第4位。

Prefetch Abort,优先级排到第5等级

SWI,优先级排到第6等级。

Undefined,优先级低7位。

Secure Monitor,优先级最低。

3.5各种模式工作返回用户模式机制

异常程序相关的代码行为原则:

1.MOVS PC,LR 当PC作为目的寄存器时,S 表示pc给lr的同时,恢复SPSR_到CPSR

2.从SWI(管理模式)和undef异常返回:MOVS PC,LR

3.从FIQ, IQR和预取异常(prefect abort)返回:subs pc, lr, #4

4.从数据异常(Data Abort)返回:SUBS PC, LR, #8

5.如果LR之前被压栈的话使用LDM “^”: LDMFD SP ! , {PC}^

1、发生中断时,将CPSR保存到SPSR_xxx中,改变CPSR_mod,将返回地址保存到LR_xxx

中,将PC指向相应的中断向量地址。

2

注意:如果LR之前是被压入栈的,就用LDMxx sp!,{pc}^指令返回。

3、同时将SPSR_xxx恢复到CPSR中。

来自《CortexA8TechRefManul.pdf》文件如此描述:

《ARM_UAL.pdf》中给出,现在版本中使用SMC来替代SMI,同时也用SVC替代SWI

4ARM核工作模式初始化参考代码

以《S5PC100》的芯片内核为代表:

/*

*文档作用:A8芯片启动程序,使用汇编编写。

*/

.equ ELFIN_CLOCK_POWER_BASE, 0XE0100000

.equ GPG3CON, 0XE03001C0

.equ APLL_MASK_OFFSET, 0x00

.equ MPLL_MASK_OFFSET, 0X04

.equ EPLL_MASK_OFFSET, 0X08

.equ HPLL_MASK_OFFSET, 0X0C

.equ CLK_DIV0_OFFSET, 0X300

.equ CLK_DIV0_MASK, 0X3FFF

.equ CLK_DIV0_VAL, ((1<<0)|(0<<4)|(3<<8)|(1<<12)|(1<<16)) .equ APLL_CON_OFFSET, 0X100

.equ CLK_DIV1_VAL, ((1<<16)|(1<<12)|(1<<8)|(1<<4))

.equ CLK_DIV1_OFFSET, 0x304

.equ APLL_VAL, (1<<31 | 445<<16 | 4<<8 | 0)

.equ MPLL_VAL, (1<<31 | 89<<16 | 2<<8 | 1)

.equ EPLL_VAL, (1<<31 | 90<<16 | 3<<8 | 3)

.equ HPLL_VAL, (1<<31 | 133<<16 | 6<<8 | 2)

.equ CLK_SRC0_OFFSET, 0x200

.equ GPG3DAT, 0XE03001C4

.equ MPLL_CON_OFFSET, 0X104

.equ EPLL_CON_OFFSET, 0X108

.equ HPLL_CON_OFFSET, 0X10c

.extern mmu_setmtt;

.text

.global _start

_start:

b reset

ldr pc,_undefined_instruction

ldr pc,_software_interrupt

ldr pc,_prefetch_abort

ldr pc,_data_abort

ldr pc,_not_used

ldr pc,_irq

ldr pc,_fiq

_undefined_instruction:.word _undefined_instruction @空操作_software_interrupt:.word _software_interrupt @空操作

_prefetch_abort:.word _prefetch_abort @空操作

_data_abort:.word _data_abort @空操作

_not_used:.word _not_used @空操作

_irq:.word IRQ_Handler

_fiq:.word _fiq @空操作

reset:

@加载基地址《DDIO344k_cortex_A8_r3p2_tra.pdf中P94》

ldr r0,=0x34000

mcr p15,0,r0,c12,c0,0

@设置处理器访问权限,能访问特权和用户模式

m ov r0, #0xfffffff

mcr p15, 0, r0, c1, c0, 2

@设置EN=1,使用NEON和VFP模块

m ov r0, #0x40000000

fmxr fpexc, r0

@进入SVC模式

mrs r0,cpsr

bic r0,r0,#0x1f

orr r0,r0,#0xd3

msr cpsr,r0

ldr r0,=GPG3CON @init gpio for led

ldr r1,=0x1111

str r1,[r0]

/* 关闭WTD */

ldr r0,=0xea200000

mov r1,#0

str r1,[r0]

/*

* 初始化 core clock 和 bus clock.

*/

@《P166》输入时钟12MHz,屏蔽时间参数3600(0xE10)=300uS

ldr r0, =ELFIN_CLOCK_POWER_BASE /*0xe0100000*/@加载时钟配置寄存器的基地址

mov r1, #0xe00

orr r1, r1, #0x10@r1=0x310屏蔽时间值0.3mS

str r1, [r0, #APLL_MASK_OFFSET] @APLL_MASK=0xE10

str r1, [r0, #MPLL_MASK_OFFSET] @MPLL_MASK=0xE10

str r1, [r0, #EPLL_MASK_OFFSET] @EPLL_MASK=0xE10

str r1, [r0, #HPLL_MASK_OFFSET] @HPLL_MASK=0xE10

@设置CLK_DIV0(0xE010_0300)寄存器《P173》

@分频设置

@DOUTAPLL=MOUTapll/2

@ARMCLK = DOUTapll / 1,

@HCLK0 = DOUTarm / 4,

@PCLK0 = HCLK0 / 2,

@HCLK0_SECSS=DOUTd0_bus/2

ldr r1, [r0, #CLK_DIV0_OFFSET]

ldr r2, =CLK_DIV0_MASK

bic r1, r1, r2

ldr r2, =CLK_DIV0_VAL @(1<<16 | 1<<12 | 3<<8 | 0<<4 | 1<<0) orr r1, r1, r2

str r1, [r0, #CLK_DIV0_OFFSET]

@设置APLL_CON(0xE010_0100)寄存器《P167》

@将0x81bd0400(MDIV=0x1bd(445),SDIV=0,PDIV=4)值赋给APLL_CON寄存器@实现FOUTAPLL=(MDIV*(FIN/PDIV))/2^SDIV=1335MHz(50MHz到2000MHz)

ldr r1, =APLL_VAL @(1<<31 | 0x1bd<<16 | 0x4<<8 | 0)

str r1, [r0, #APLL_CON_OFFSET]

@设置CLK_DIV((0xE010_0304)寄存器《P174》

@DOUTAPLL2 = MOUTAPLL / 1

@DOUTMPLL = MOUTAMPLL / 2

@DOUTMPLL2 = MOUTAMPLL / 2

@DOUTD1_BUS= MOUTAMPLL / 2

@PCLK = DOUTD1_BUS / 2

ldr r1, [r0, #CLK_DIV1_OFFSET]

ldr r2, =CLK_DIV1_VAL

@CLK_DIV1_VAL=((1<<16)|(1<<12)|(1<<8)|(1<<4))=0x11110

orr r1, r1, r2

str r1, [r0, #CLK_DIV1_OFFSET]

@设置MPLL_CON(0xE010_0104)寄存器《P168》

@将0x80590201(MDIV=0x59(89),SDIV=1,PDIV=2)值存入到MPLL_CON寄存器中

@实现FOUTMPLL=(MDIV*(FIN/PDIV))/2^SDIV=267MHz(10MHz到600MHz之间)

ldr r1, =MPLL_VAL @MPLL_VAL=(1<<31 | 89<<16 | 2<<8 | 1)=0x80590201

str r1, [r0, #MPLL_CON_OFFSET]

@设置EPLL_CON(0xE010_0108)寄存器《P168》

@将0x805a0303(MDIV=0x5A(90),PDIV=3,SDIV=3)值保存到EPLL_CON寄存器中

@FOUTEPLL=(MDIV*(FIN/PDIV))/2^SDIV=45MHz

ldr r1, =EPLL_VAL @EPLL_VAL=(1<<31 | 90<<16 | 3<<8 | 3)=0x805a0303

str r1, [r0, #EPLL_CON_OFFSET]

@设置HPLL_CON(0xE010_010C)寄存器《P168》

@将0x80850602(MDIV=0x85(133),PDIV=6,SDIV=2)值保存到HPLL_CON寄存器中@FOUTHPLL=(MDIV*(FIN/PDIV))/2^SDIV=66MHz

ldr r1, =HPLL_VAL @HPLL_VAL=(1<<31 | 133<<16 | 6<<8 | 2)=0x80850602

str r1, [r0, #HPLL_CON_OFFSET]

@设置CLK_SRC0(0xE010_0200)寄存器《P169》

@CLK_SRC0[0]=1:FOUTAPLL MOUTAPLL =1335MHz

@CLK_SRC0[4]=1:FOUTMPLL MOUTMPLL =267MHZ

@CLK_SRC0[8]=1:FOUTEPLL MOUTEPLL =45MHz

@CLK_SRC0[12]=1:FOUTHPLL MOUTHPLL =66MHz

ldr r1, [r0, #CLK_SRC0_OFFSET]

ldr r2, =0x1111 @(1<<12 | 1<<8 | 1<<4 | 1 <<0)

orr r1, r1, r2

str r1, [r0, #CLK_SRC0_OFFSET]

@延时

mov r1, #0x10000

1:subs r1, r1, #1

bne 1b

init_stack:

ldr r0,stacktop /*get stack top pointer*/ /********svc mode stack********/

mov sp,r0

sub r0,#128*4 //512 byte for irq mode of stack /****irq mode stack**/

msr cpsr,#0xd2

mov sp,r0

sub r0,#128*4 //512 byte for irq mode of stack /***fiq mode stack***/

msr cpsr,#0xd1

mov sp,r0

sub r0,#128*4

/***abort mode stack***/

msr cpsr,#0xd7

mov sp,r0

sub r0,#128*4

/***undefine mode stack***/

msr cpsr,#0xdb

mov sp,r0

sub r0,#128*4

/*** sys mode and usr mode stack ***/

msr cpsr,#0x10

mov sp,r0 //2560 byte for user mode of stack

b main

.align 4

IRQ_Handler:

sub lr,lr,#4

stmfd sp!,{r0-r12,lr}

bl Entry_IRQ4C

ldmfd sp!,{r0-r12,pc}^

stacktop:.word stack+8*512

.data

stack: .space 8*512

相关主题
相关文档 最新文档