armv8 架构arm64 lookup_processor_type分析

文件位置:"arch/arm64/kernel/head.S"

kernel版本:4.0.0

ENTRY(lookup_processor_type)
	adr	x1, __lookup_processor_type_data    // x1 =pa(__lookup_processor_type_data),adr获取到的是__lookup_processor_type_data的物理地址
	ldp	x2, x3, [x1]        // x2 = .   x3 = cpu_table va,即x2为__lookup_processor_type_data处的虚拟地址
                            // 由于 pa = va - PAGE_OFFFSET + PHYS_OFFSET    
                            // 所以 va - pa = PHYS_OFFSET - PAGE_OFFSET
	sub	x1, x1, x2			// get offset between VA and PA     x1 = va - pa
                                                  // PHYS_OFFSET-PAGE_OFFSET
	add	x3, x3, x1			// convert VA to PA // x3 = pa(cpu_tale) 转换cpu_table处的虚拟地址为物理地址
1:
	ldp	w5, w6, [x3]			// load cpu_id_val and cpu_id_mask  	w5 =cpu_id_val = 0x000f0000 , w6 = cpu_id_mask = 0x000f0000
	cbz	w5, 2f				// end of list? cpu_table 以全0结构体结尾
	and	w6, w6, w0          // w0为processor ID,与上掩码, 根据kernel启动log,发现读出来的processor id 为 0x411fd070 , 或者 0x412fc09a 
							// 发现 processor_id & 0x000f0000 = 0x000f0000,即16~19位为全1,所以只要读出来的值,此4位为1,则验证ok
	cmp	w5, w6				// 比较 w6 和 0x000f0000 是否相等
	b.eq	3f				// 相等则退出,跳到3f处
	add	x3, x3, #CPU_INFO_SZ	// 如果不相等,则 将 cpu_info跳到下一个结构体中
	b	1b						//然后继续和processor id 对比
2:
	mov	x3, #0				// unknown processor	如果都不相等,则将 最后一个cpu_info结构体设置为0
3:
	mov	x0, x3				// 将结果返回给 x0 ,此处返回的是 cpu_info结构体的地址
	ret
ENDPROC(lookup_processor_type)

猜你喜欢

转载自blog.csdn.net/qq_30025621/article/details/89396400