STR learning
/*STR learning
*write by chen00.xi @11.19
*/
1. involved Arm instructions:
MSR /MRS/CPS:
程序状态寄存器指令1
1.MRS 程序状态寄存器到通用寄存器的数据传送指令
格式:MRS{<cond>} <Rd>,CPSR/SPSR;
功能:用于将程序状态寄存器的内容传送到目标寄存器Rd中。
当进入中断服务程序或进程切换时,该指令可用来保存当前状态寄存器的值。
例如:
MRS R0,CPSR
;状态寄存器CPSR的值存入寄存器R0中
程序状态寄存器指令2
2.MSR 通用寄存器到程序状态寄存器的数据传送指令
格式:MSR{<cond>} CPSR/SPSR_<field>,<op1>;
功能:用于将寄存器Rd的值传送到程序状态寄存器中。
当退出中断服务程序或进程切换时,该指令可用来恢复状态寄存器的值。
操作数op1可以是通用寄存器或立即数。
<field>:用来设置状态寄存器中需要操作的位。
32位的状态寄存器可以分为4个域:
位[31:24]为条件标志位域,用f表示。
位[23:16]为状态位域,用s表示。
位[15:8]为扩展位域,用x表示。
位[7:0]为控制位域,用c表示。
例如:MSR CPSR_f,R0
;用R0的值修改CPSR的条件标志域
MSR CPSR_fsxc,#5; CPSR的值修改为5
3.CPS
用于更改:
(1) One or more of the CPSR.{A,I,F} interrupt mask bits.
(2) CPSR.M mode field.
如果在 User Mode下执行,则不起作用,相当于NOP指令.
指令格式:
CPS<effect> <iflags>{,#<mode>}
CPS #<mode>
<effect> :
IE -> Enable Interrupt
ID -> Disable Interrupt
如果过<effect>域指定了,则影响的CPSR位,由<iflags>指定.
<iflags> :
a -> 设置A bit
i -> 设置I bit
f -> 设置F bit
<mode> :指定目标Mode的编码.
DMB/DSB/ISB:
DMB
数据内存屏障可作为内存屏障使用。 它可确保会先检测到程序中位于 DMB 指令
前的所有显式内存访问指令,然后再检测到程序中位于 DMB 指令后的显式内存
访问指令。 它不影响其他指令在处理器上的执行顺序。
option 的允许值为:
SY 完整的系统 DMB 操作。 这是缺省值,可以省略。
ST 存储完成后才可执行的 DMB 操作。
ISH 仅对内部可共享域执行的 DMB 操作。
ISHST 只有当存储完成后才可执行的 DMB 操作,并且只对内部可共享域
执行。
NSH 只可完成于统一点的 DMB 操作。
DSB
数据同步屏障是一种特殊的内存屏障。 只有当此指令执行完毕后,才会执行程
序中位于此指令后的指令。 当满足以下条件时,此指令才会完成:
位于此指令前的所有显式内存访问均完成。
位于此指令前的所有高速缓存、跳转预测和 TLB 维护操作全部完成。
option 的允许值为:
SY 完整的系统 DSB 操作。 这是缺省值,可以省略。
ST 存储完成后才可执行的 DSB 操作。
ISH 仅对内部可共享域执行的 DSB 操作。
ISHST 只有当存储完成后才可执行的 DSB 操作,并且只对内部可共享域
执行。
NSH 只可完成于统一点的 DSB 操作。
NSHST 只有当存储完成后才可执行的 DSB 操作,并且只会完成于统一
点。
OSH 仅对外部可共享域执行的 DSB 操作。
OSHST 只有当存储完成后才可执行的 DSB 操作,并且只对外部可共享域
执行。
ISB
指令同步屏障可刷新处理器中的流水线,以便在 ISB 指令完成后,才从高速缓
存或内存中提取位于该指令后的所有其他指令。 这可确保提取时间晚于 ISB 指
令的指令能够检测到 ISB 指令执行前就已经执行的上下文更改操作(例如更改
ASID 或已完成的 TLB 维护操作、跳转预测维护操作以及对 CP15 寄存器所做的
所有更改)的执行效果
此外,ISB 指令可确保程序中位于其后的所有跳转指令总会被写入跳转预测逻
辑,其写入上下文可确保 ISB 指令后的指令均可检测到这些跳转指令。 这是指
令流能够正确执行的前提条件。
option 的允许值为:
SY 完整的系统 ISB 操作。 这是缺省设置,可以省略。
总之:
DMB: 数据存储器隔离;
DSB: 数据同步隔离,比DMB严格。
ISB: 指令同步隔离,最严格:会清洗流水线,以保证所有它前面的指令都执行完毕之后
WFE/WFI:
SDM/STM:
LDM 批量数据加载指令
格式:
LDM{<cond>}{<type>} <Rn>{!},<regs>{^};
功能:从一片连续的内存单元读取数据到各个寄存器中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。
该指令一般用于多个寄存器数据的出栈。
type字段种类:
IA:每次传送后地址加1。
IB:每次传送前地址加1。
DA:每次传送后地址减1。
DB:每次传送前地址减1。
FD:满递减堆栈。
ED:空递减堆栈。
FA:满递增堆栈。
EA:空递增堆栈。
注意:有一个约定,编号低的寄存器在存储数据或者加载数据时对应于存储器的低地址。
STM 批量数据存储指令
格式:STM{<cond>}{<type>} <Rn>{!},<regs>{^};
功能:将各个寄存器的值存入一片连续的内存单元中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。
该指令一般用于多个寄存器数据的入栈。
{^}:指示指令所用的寄存器为用户模式下的寄存器。
其他参数用法同LDM指令。
例如:
STMEA R13!,{R0-R12,PC}
;将寄存器R0~R12以及程序计数器PC的值保存到R13指示的堆栈中
总结:
stmdb sp!, {fp, ip, lr, pc} //sp=sp-4,sp=pc;先压PC
//sp=sp-4,sp=lr;再压lr
//sp=sp-4,sp=ip;再压ip
//sp=sp-4,sp=fp;再压fp
ldmia sp, {fp, sp, pc} //和stmdb成对使用,
//fp=sp,sp=sp+4;先弹fp
//sp=sp,sp=sp+4;先弹sp,此处的弹出不会影响sp,因为ldmia是一个机器周期执行完的。
//pc=sp,sp=sp+4;先弹pc
2. involved register
secure cpu 和normal cpu,resume时恢复寄存器:
CPU0,2,3 |
CPU1 |
|
NSACR |
|
SCR |
|
SWD_CPSR |
TTBR0 |
TTBR0 |
DACR |
DACR |
VBAR |
VBAR |
MVBAR |
MVBAR |
MONITOR_SP_OFF |
MONITOR_SP_OFF |
SVC_SP_OFF |
SVC_SP_OFF |
SCTLR |
SCTLR |
ACTLR |
ACTLR |
NWD_PC |
NWD_PC |
SCR 设置一次:
这样做的原因是因为, 当前只考虑了,只有cpu1才能进入到swd的情况,resume之后,恢复cpu1的swd状态,而并不需要考虑cpu0,2,3的swd状态。
Banked 寄存器:
NSACR/ACTLR/SCR也是banked的????
3. MMU/CACHE
TLB:
通过使用一个高速、容量相对较小的存储器来存储近期用到的页表条目(段、大页、小页、极小页描述符),避免每次地址转换都到主存中查找,这样就大幅提高性能。这个存储器用来帮助快速地进行地址转换,成为转译查找缓存(Translation Lookaside Buffers, TLB)
当CPU发出一个虚拟地址时,MMU首先访问TLB。如果TLB中含有能转换这个虚拟地址的描述符,则直接利用此描述符进行地址转换和权限检查,否则MMU访问页表找到描述符后再进行地址转换和权限检查,并将这个描述符填入TLB中,下次再使用这个虚拟地址时就直接使用TLB用的描述符。
使用TLB需要保证TLB中的内容与页表一致,在启动MMU之前,页表中的内容发生变化后,尤其要注意。一般的做法是在启动MMU之前使整个TLB无效,改变页表时,使所涉及的虚拟地址对应的TLB中条目无效。
PS. 代码中: invalidateUnifiedTLB
Cache
Cache有以下两个操作:
② ”清空“(clean):把Cache或Write buffer中已经脏的(修改过,但未写入主存)数据写入主存
②”使无效“(Invalidate):使之不能再使用,并不将脏的数据写入主存。
一般情况下, 系统内置了指令Cache(ICaches)、数据Cache(DCaches)、写缓存(Write buffer),需要用到描述符中的C位(Ctt)和B位(Btt)
1)指令Cache(ICaches)
系统刚上电或复位时,ICaches中的内容是无效的,并且ICaches功能关闭。往Icr位(CP15协处理器中寄存器1的第12位)写1可以启动ICaches,写0停止ICaches
ICaches一般在MMU开启后使用,此时描述符的C位用来表示一段内存是否可以被Cache。若Ctt=1,允许Cache,否则不允许。如果MMU没有开启,ICaches也可以被使用,此时CPU读取指令时所涉及的内存都被当做允许Cache
ICaches关闭时,CPU每次取指都要读取主存,性能低,所以通常尽早启动ICaches
ICaches开启后,CPU每次取指时都会先在ICaches中查看是否能找到所用指令,而不管Ctt是0还是1。如果找到成为Cache命中,找不到称为Cache丢失,ICaches被开启后,CPU的取指有如下三种情况:
①Cache命中且Ctt为1时,从ICaches中取指,返回CPU
②Cache丢失且Ctt为1时,CPU从主存中取指,并且把指令缓存到Cache中
③Ctt为0时,CPU从主存中取指
2)数据Cache(DCaches)
与ICaches相似,系统刚上电或复位时,DCaches中的内容无效,并且DCaches功能关闭,Write buffer中的内容也是被废弃不用的。往Ccr位(CP15协处理器 中寄存器1的第二位)写1启动DCaches,写0停止DCaches。Write buffer和DCaches紧密结合,额米有专门的控制来开启和停止它
与ICaches不同,DCaches功能必须在MMU开启之后才能被使用。
DCaches被关闭时,CPU每次都去内存取数据。
DCaches被开启后,CPU每次读写数据时都会先在DCaches中查看是否能找到所要的数据,不管Ctt是0还是1,找到了成为Cache命中,找不到成为Cache丢失。
通过下表可知DCaches和Write buffer在Ccr,Ctt,Btt各种取值下,如何工作,Ctt and Ccr 意为 Ctt与Ccr进行逻辑与后的值
使用Cache时需要保证Cache、Write buffer的内容和主存内容一致,保证下面两个原则:
①清空DCaches,使主存数据得到更新
②使无效ICaches,使CPU取指时重新读取主存
在实际编写程序时,要注意如下几点:
① 开启MMU前,使无效ICaches,DCaches和Write buffer
②关闭MMU前,清空ICaches、DCaches,即将”脏“数据写到主存上
③如果代码有变,使无效ICaches,这样CPU取指时会从新读取主存
④使用DMA操作可以被Cache的内存时,将内存的数据发送出去时,要清空Cache;将内存的数据读入时,要使无效Cache
⑤改变页表中地址映射关系时也要慎重考虑
⑥开启ICaches或DCaches时,要考虑ICaches或DCaches中的内容是否与主存保持一致
⑦对于I/O地址空间,不使用Cache和Write buffer
http://www.cnblogs.com/hpunix/articles/98635.html
http://www.linuxidc.com/Linux/2011-09/43526p4.htm
8.Other
Changing from Secure to Non-secure state
Monitor mode is provided to support switching between Secure and Non-secure states. Except in Monitor mode and
Hyp mode, the security state is controlled by the SCR.NS bit. Software executing in a Secure PL1 mode can change
the SCR, but ARM strongly recommends that software obeys the following rules for changing SCR.NS:
• To avoid security holes, software must not:
— Change from Secure to Non-secure state by using an MSR or CPS instruction to switch from Monitor
mode to some other mode while SCR.NS is 1.
— Use an MCR instruction that writes SCR.NS to change from Secure to Non-secure state. This means
ARM recommends that software does not alter SCR.NS in any mode except Monitor mode. ARM
deprecates changing SCR.NS in any other mode.
• The usual mechanism for changing from Secure to Non-secure state is an exception return.To return to
Non-secure state, software executing in Monitor mode sets SCR.NS to 1 and then performs the exception
return.