慢慢欣赏arm64内核启动22 primary_entry之__cpu_setup代码第四部分

展示代码

	/*
	 * Set the IPS bits in TCR_EL1.
	 */
	tcr_compute_pa_size x10, #TCR_IPS_SHIFT, x5, x6

分析代码

第1到第3行是注释,含义是设置 TCR_EL1 的 IPS 域

第4行涉及到宏定义 tcr_compute_pa_size 和 TCR_IPS_SHIFT

TCR_IPS_SHIFT 的宏作为第二个入参传入,定义其如下

#define TCR_IPS_SHIFT		32

其中,tcr_compute_pa_size 的定义如下

/*
 * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
 * ID_AA64MMFR0_EL1.PARange value
 *
 *	tcr:		register with the TCR_ELx value to be updated
 *	pos:		IPS or PS bitfield position
 *	tmp{0,1}:	temporary registers
 */
	.macro	tcr_compute_pa_size, tcr, pos, tmp0, tmp1
	mrs	\tmp0, ID_AA64MMFR0_EL1
	// Narrow PARange to fit the PS field in TCR_ELx
	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_PARANGE_SHIFT, #3
	mov	\tmp1, #ID_AA64MMFR0_PARANGE_MAX
	cmp	\tmp0, \tmp1
	csel	\tmp0, \tmp1, \tmp0, hi
	bfi	\tcr, \tmp0, \pos, #3
	.endm

根据注释分析,该宏定义时给第一个入参 TCR 赋值,第三,第四个入参 tmp0 和 tmp1 是临时寄存器

在该宏定义里面,ID_AA64MMFR0_EL1, AArch64 Memory Model Feature Register 0
含义如下 Provides information about the implemented memory model and memory management support in AArch64 state
提供 EL1 异常模式下 内存模型和内存管理的信息,涉及到的宏定义如下

#define ID_AA64MMFR0_PARANGE_SHIFT	0

该宏首先提取 位域 PARange[2:0] bit 到 tmp0
PARange, bits [3:0]
Physical Address range supported. Defined values are:
    0b0000        32 bits, 4GB.
    0b0001        36 bits, 64GB.
    0b0010        40 bits, 1TB.
    0b0011        42 bits, 4TB.
    0b0100        44 bits, 16TB.
    0b0101        48 bits, 256TB.
    0b0110        52 bits, 4PB.
我们可以看到 bit[3] 始终为0, 所以可以忽略掉。

#ifdef CONFIG_ARM64_PA_BITS_52
#define ID_AA64MMFR0_PARANGE_MAX	ID_AA64MMFR0_PARANGE_52
#else
#define ID_AA64MMFR0_PARANGE_MAX	ID_AA64MMFR0_PARANGE_48
#endif
#define ID_AA64MMFR0_PARANGE_48		0x5


cmp    \tmp0, \tmp1 比较 tmp0 和 tmp1 的大小,并根据比较的结果更新条件标志位,但是不存储比较的结果。

CSEL 指令的含义如下:
CSEL  Xd, Xn, Xm, cond
    Xd:目标寄存器,计算结果将被存入此寄存器。
    Xn:第一个源操作数,如果条件满足,它的值将被复制到Xd。
    Xm:第二个源操作数,如果条件不满足,它的值将被复制到Xd。
    cond:条件码,根据上一条 cmp 指令更新的条件标志位决定了选择Xn还是Xm。条件码可以是EQ(等于)、NE(不等于)、HS(无符号数大于/等于)、LO(无符号数小于)、MI(负数)、PL(非负数)、VS(上溢出)、VC(没有上溢出)、GE(大于等于)、LT(小于)、GT(大于)、LE(小于等于)等,或者是AL(无条件执行)。
也就是说,如果有一个条件比较操作,你想根据比较的结果来决定是设置寄存器的值还是保持不变,你可以使用csel指令来实现这一点。如果条件满足,它将执行类似于三元运算符的操作:Xd = condition ? Xn : Xm
所以,csel 指令选择 tmp0 和 tmp1 中较小的一个存储在 tmp0

BFI(Bit Field Insert)指令用于将一个寄存器中的位字段插入到另一个寄存器的指定位置。BFI指令的格式如下:
BFI 目标寄存器, 源寄存器, #lsb, #宽度
    目标寄存器:将被插入位字段的寄存器。
    源寄存器:包含要插入的位字段的寄存器。
  lsb:在目标寄存器中插入位字段的最低位的位置。
    宽度:要插入的位字段的宽度。
所以宏定义的最后一句话的含义是将 tmp0 的最低 3bit 插入到 tcr 的 bit[32 + 3, 32], tcr 也就是 x10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值