侵权投诉
订阅
纠错
加入自媒体

例说嵌入式开发之ARM协处理器CP15

2013-11-07 09:55
老猫
关注

  15.1.1  CP15寄存器访问指令

  通常对协处理器CP15的访问使用以下两种指令。

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

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

  注意

  通过协处理器访问指令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寄存器,在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中进行模式切换的例子。利用此例,调用SWI 0来完成系统模式切换。

  EHT_SWI

  LDR     sp,=EHT_Exception_Stack ;更新SWI堆栈指针

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

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

  MRS     r0,SPSR ;得到SPSR

  STMDB   sp!,{r0} ;保持SPSR

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

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

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

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

  B       EHT_SWI_Exit ;为定义的SWI指令出口

  EHT_Jump_Table

  DCD     EHT_SU_Switch

  DCD     EHT_Disable_Interrupts

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

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

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

  EHT_SU_Switch

  MMU_DISABLE ;转换前禁用MMU

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

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

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

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

  B       EHT_SWI_Exit

  EHT_Disable_Interrupts

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

  ORR     r0,r0,#LOCKOUT ;禁止中断

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

  ;    B       EHT_SWI_Exit

  EHT_SWI_Exit

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

  MSR     SPSR_cf,r0 ;将SPSR放入SPSR_cf

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

  END

  15.1.2  CP15中的寄存器

  表15.1给出了CP15主要寄存器的功能和作用。

例说嵌入式开发之ARM协处理器CP15

例说嵌入式开发之ARM协处理器CP15

  15.1.3  寄存器c0

  寄存器c0包含的是ARM本身或芯片生产厂商的一些标识信息。当使用MRC指令读c0寄存器时,根据第二个操作码opcode2的不同,读出的标识符也是不同的。操作码与标识符的对应关系如表15.2所示。寄存器c0是只读寄存器,当用MCR指令对其进行写操作时,指令的执行结果不可预知。

例说嵌入式开发之ARM协处理器CP15

表15.2 操作码和标识符的对应关系

  在操作码opcode2的取值中,主标识符(opcode2=0)是强制定义的,其他标识符由芯片的生产厂商定义。如果操作码opcode2指定的值未定义,指令将返回主标识符。其他标识符的值应与主标识符的值不同,可以由软件编程来实现,同时读取主标识符和其他标识符,并将两者的值进行比较。如果两个标识符值相同,说明未定义该标识符;如果两个标识符值不同,说明定义了该标识符,并且得到该标识符的值。

<上一页  1  2  3  4  下一页>  
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

文章纠错
x
*文字标题:
*纠错内容:
联系邮箱:
*验 证 码:

粤公网安备 44030502002758号