欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ARM体系架构—ARMv7-A指令集:协处理器指令

程序员文章站 2022-05-04 08:47:51
ARM体系架构—ARMv7-A指令集一、ARMv7-A指令集二、ARMv7-A协处理器二、ARMv7-A协处理器指令七、ARMv7-A伪指令一、ARMv7-A指令集ARMv7-A架构是32位处理器架构。也是load/store架构,即数据处理指令操作在通用寄存器完成,只有load/store指令可以访问内存。此外ARM指令集还有一大特点,就是ARM指令集几乎所有的指令都可以增加条件码。ARM指令集可以归为一下四类:数据处理操作(ALU操作例如ADD);内存操作(load/store);控制流(...

一、ARMv7-A指令集

ARMv7-A架构是32位处理器架构。也是load/store架构,即数据处理指令操作在通用寄存器完成,只有load/store指令可以访问内存。此外ARM指令集还有一大特点,就是ARM指令集几乎所有的指令都可以增加条件码。
ARM指令集可以归为一下四类:

  1. 数据处理操作(ALU操作例如ADD);
  2. 内存操作(load/store);
  3. 控制流(循环,跳转,条件码等);
  4. 系统(协处理器,debug,模式切换等等)。

本文重点介绍协处理器指令。

二、ARMv7-A协处理器

ARM体系架构支持协处理器,用于扩展ARM处理器功能。协处理器指令用于访问协处理器。协处理器支持16个协处理器,编号0-15,使用CP0-CP15(Coprocessor)描述。

CP0-CP15协处理器的基本功能如下:

  • CP15:提供系统控制功能。包括架构和特性ID,以及控制,状态信息和配置支持,还包括cache,TLB和MMU的控制。
  • CP14:提供硬件Debug功能。
  • CP10,CP11:共同支持浮点运算和向量操作。控制和配置浮点和高级SIMD扩展架构。
  • CP8,9,12,13:为ARM架构保留协处理器。
  • CP0-7:由厂家定义协处理功能。

关于协处理器详细介绍请参看《ARM体系架构—ARMv7-A协处理器》

ARM指令集提供了协处理器指令用于访问协处理器中的寄存器。如果协处理器指令访问协处理器在系统中不存在,则会报未定义指令异常(Undef)。

二、ARMv7-A协处理器指令

协处理指令可以分为5类:

  1. CDP:发起协处理器数据处理操作;
  2. MRC:数据从协处理器寄存器传送到ARM寄存器;
  3. MCR:数据从ARM寄存器传送到协处理器寄存器;
  4. LDC:数据从内存传送到协处理器寄存器;
  5. STC:数据从协处理器寄存器传送到内存。

同时也支持多寄存器指令:

  1. MRRC:数据从协处理器寄存器传送到两个ARM寄存器;
  2. MCRR:数据从两个ARM寄存器传送到协处理器寄存器;
  3. LDCL:数据从多个ARM寄存器传送到协处理器寄存器;
  4. STCL:数据从协处理器寄存器传送到多个ARM寄存器。

MCRR指令格式如下。
ARM体系架构—ARMv7-A指令集:协处理器指令

  • c:条件码;
  • coproc:协处理器名称;
  • opc1:协处理器操作码,0-15;
  • Rt:第一个ARM源寄存器;
  • Rt2:第二个ARM源寄存器;
  • CRm:协处理器寄存器。

MRRC指令格式如下。
ARM体系架构—ARMv7-A指令集:协处理器指令

  • c:条件码;
  • coproc:协处理器名称;
  • opc1:协处理器操作码,0-15;
  • Rt:第一个ARM目标寄存器;
  • Rt2:第二个ARM目标寄存器;
  • CRm:协处理器寄存器。

三、读懂Linux Kernel协处理器指令

看懂Linux Kernel ARM体系协处理器指令,才能做到学以致用。截取Linux Kernel5.6.4中ARMv7获取PGD(PGD即对应一级页表)的代码:

#ifdef CONFIG_ARM_LPAE /* 定义LPAE,系统物理地址寻址范围扩展到40bit */

#define cpu_get_ttbr(nr)					\
	({							\
		u64 ttbr;					\
		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
			: "=r" (ttbr));				\
		ttbr;						\
	})

#define cpu_get_pgd()	\
	({						\
		u64 pg = cpu_get_ttbr(0);		\
		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
		(pgd_t *)phys_to_virt(pg);		\
	})
#else /* 未定义LPAE,系统物理地址寻址范围是32bit */
#define cpu_get_pgd()	\
	({						\
		unsigned long pg;			\
		__asm__("mrc	p15, 0, %0, c2, c0, 0"	\
			 : "=r" (pg) : : "cc");		\
		pg &= ~0x3fff;				\
		(pgd_t *)phys_to_virt(pg);		\
	})
#endif

没有开启LPAE的情况,内联汇编语法“%0”引用输出参数pg,变量pg被“=r”限定为存储在寄存器中。
汇编语法“mrc p15, 0, %0, c2, c0, 0”在读取协处理器CP15中c2寄存器。

按照协处理器寄存器的32bit组织形式解析该汇编所访问的寄存器。

CP15协处理器保护c0-c15共16个寄存器,寄存器32位的组织形式如下:
CRn,opc1,CRm,opc2 {CRn, opc1, CRm, opc2}

  • CRn:第一个协处理器寄存器;
  • opc1:协处理器操作码;
  • CRm:第二个协处理器寄存器;
  • opc2:协处理器操作码。

对于32bit协处理器寄存器的访问,汇编代码解析结果如下:

  • CRn:c2;
  • CRm:c0;
  • opc1:0
  • opc2:0

由32bit寄存器对应图可以看出读取的是TTBR0寄存器,即将页表基址寄存器读取到pg变量中。
ARM体系架构—ARMv7-A指令集:协处理器指令
开启LPAE的情况,内联汇编语法“%Q0”引用输出参数ttbr,变量ttbr被“=r”限定为存储在寄存器中。
汇编语法“mrrc p15, 0, %Q0, %R0, c2”在读取协处理器CP15中c2寄存器,此时c2寄存器是64bit的。

按照协处理器寄存器的64bit组织形式解析该汇编所访问的寄存器。

寄存器64位的组织形式如下:
CRm,opc1 {CRm, opc1}

  • opc1:协处理器操作码;
  • CRm:协处理器寄存器;

对于64bit协处理器寄存器的访问,汇编代码解析结果如下:

  • CRm:c2;
  • opc1:0

由64bit寄存器对应图图可以看出读取的是TTBR0寄存器,即将页表基址寄存器读取到ttbr变量中。
ARM体系架构—ARMv7-A指令集:协处理器指令

本文地址:https://blog.csdn.net/liyuewuwunaile/article/details/107448059

相关标签: ARM体系架构