新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > ARM存储器之:协处理器CP15

ARM存储器之:协处理器CP15

作者: 时间:2013-09-30 来源:网络 收藏

本文引用地址:https://www.eepw.com.cn/article/257013.htm

15.1.1寄存器访问指令

通常对的访问使用以下两种指令。

MCR:将寄存器的值写入寄存器中;

MRC:将CP15寄存器的值写入寄存器中。

注意

通过访问指令CDP、LDC和STC指令对CP15进行访问将产生不可预知的结果。

其中,CDP为协处理器数据操作指令,这个指令初始化一些与协处理器相关的操作;

LDC为一个或多个字的协处理器数据读取指令,此指令从读取数据到指定的协处理器中;

STC为一个或多个32位字的协处理器数据写入指令,此指令初始化一个协处理器的写操作,从给定的协处理器把数据传送到中。

指令MCR和MRC指令访问CP15寄存器使用通用语法。

语法格式为:

MCR{cond>}p15,opcode1=0>,Rd>,CRn>,CRm>{,opcode2>}

MRC{cond>}p15,opcode1=0>,Rd>,CRn>,CRm>{,opcode2>}

其中:

cond>为指令的执行条件。当cond>条件域为空时,指令无条件执行;

opcode1>在标准的MRC指令中,为协处理器的opcode1>,即操作数1。对于CP15来说,此操作数恒为0,即0b000。当针对CP15的MRC指令中opcode1>不为0时,指令的操作结果不可预知;

Rd>为寄存器,在ARM和协处理器交换数据时使用。在MRC指令中作为目的寄存器,在MCR中作为源寄存器。

注意

r15不能作为ARM寄存器出现在MRC或MCR指令中,如果r15作为Rd>出现在这里,那么指令的执行结果不可预知。

CRn>是CP15协处理器指令中用到的主要寄存器。在MRC指令中为源寄存器,在MCR中为目的寄存器。CP15协处理器的寄存器c0、c1、…、c15均可出现在这里。

CRm>是附加的协处理器寄存器,用于区分同一个编号的不同物理寄存器和访问类型。当指令中不需要提供附加信息时,将CRm>指定为C0,否则指令的操作结果不可预知。

opcode2>提供附加信息,用于区分同一个编号的不同物理寄存器,当指令中没有指定附加信息时,省略opcode2>或者将其指定为0,否则指令的操作结果不可预知。

MCR和MRC指令只能操作在特权模式下,如果处理器运行在用户模式,指令的执行结果不可预知。

注意

在用户模式下,如果要访问系统控制协处理器,通常的做法是由操作系统提供SWI软中断调用来完成系统模式的切换。由于不同型号的ARM处理器对此管理差别很大,所以建议用户在应用时将SWI作为一个独立的模块来管理并向上提供通用接口,以屏蔽不同型号处理器之间的差异。

例15.1给出了一个典型的利用SWI进行模式切换的例子。

【例15.1】

典型的在SWI中进行模式切换的例子。利用此例,调用SWI0来完成系统模式切换。

EHT_SWI

LDRsp,=EHT_Exception_Stack ;更新SWI堆栈指针

ADDsp,sp,#EXCEPTION_SIZE ;得到栈顶指针

STMDBsp!,{r0-r2,lr} ;保存程序中用到的寄存器

MRSr0,SPSR ;得到SPSR

STMDBsp!,{r0} ;保持SPSR

LDRr0,[lr,#-4] ;计算SWI指令地址

BICr0,r0,#0xFF000000 ;提取中断向量号

CMPr0,#MAX_SWI ;检测中断向量范围

LDRLSpc,[pc,r0,LSL#2] ;如果在范围内,跳转到软中断向量表

BEHT_SWI_Exit ;为定义的SWI指令出口

EHT_Jump_Table

DCDEHT_SU_Switch

DCDEHT_Disable_Interrupts

;*********************************************************************************

;用户可在此添加更多的自定义软中断,在此SWI0作为系统保留的软中断,调用例程EHT_SU_Switch,来进行模式切换

;*********************************************************************************

EHT_SU_Switch

MMU_DISABLE ;转换前禁用MMU

LDMIAsp!,{r0} ;从堆栈中取出SPSR

BICr0,r0,#MODE_MASK ;清除模式位

ORRr0,r0,#SYS_MODE ;设置程序状态字的supper模式位

STMDBsp!,{r0} ;从新将SPSR放入堆栈

BEHT_SWI_Exit

EHT_Disable_Interrupts

LDMIAsp!,{r0} ;从堆栈中读出SPSR

ORRr0,r0,#LOCKOUT ;禁止中断

STMDBsp!,{r0} ;存储SPSR到中断

;BEHT_SWI_Exit

EHT_SWI_Exit

LDMIAsp!,{r0} ;从堆栈中读出SPSR

MSRSPSR_cf,r0 ;将SPSR放入SPSR_cf

LDMIAsp!,{r0-r2,pc}^ ;寄存器出栈并返回

END



评论


相关推荐

技术专区

关闭