1.前言
在执行lookup_processor_type之前,head.S流程中会通过如下操作将参数x0传递给lookup_processor_type
// Move from State register to Register,x22=cpuid
//获取当前cpu id,保存在x22
mrs x22, midr_el1
// 将当前cpuid作为参数传递给lookup_processor_type
mov x0, x22
// 查看cpu类型,并保存到X0中
bl lookup_processor_type
2.lookup_processor_type
struct cpu_table的定义如下:
#arch/arm64/include/asm/cputable.h
struct cpu_info {
unsigned int cpu_id_val;
unsigned int cpu_id_mask;
const char *cpu_name;
unsigned long (*cpu_setup)(void);
};
cpu_table初始化为:
#./arch/arm64/kernel/cputable.c
struct cpu_info cpu_table[] = {
{
.cpu_id_val = 0x000f0000,
.cpu_id_mask = 0x000f0000,
.cpu_name = "AArch64 Processor",
.cpu_setup = __cpu_setup,
},
{ /* Empty */ },
};
/*
* This function gets the processor ID in w0 and searches the cpu_table[] for
* a match. It returns a pointer to the struct cpu_info it found. The
* cpu_table[] must end with an empty (all zeros) structure.
*
* This routine can be called via C code and it needs to work with the MMU
* both disabled and enabled (the offset is calculated automatically).
*/
ENTRY(lookup_processor_type)
//把标号__lookup_processor_type_data的物理地址赋给x1
adr x1, __lookup_processor_type_data
//从x1依次读入两个64位数据到x2,x3中,
//x2保存的是__lookup_processor_type_data的虚拟地址
//x3保存的是cpu_table的虚拟地址
ldp x2, x3, [x1]
// get offset between VA and PA
sub x1, x1, x2
// convert VA to PA//x3保存cpu_table的物理地址
add x3, x3, x1
1:
ldp w5, w6, [x3] // load cpu_id_val(w5) and cpu_id_mask(w6)
//比较w5(cpu_id_val ),如果结果为0就跳转(只能跳转到后面的指令);
//查看cpu_table即知这里cpu_id_val的值为0x000f0000
cbz w5, 2f // end of list?
//w0中的值为当前cpu id ,[19:16]bit表示Architecture,ARM64是0b1111
and w6, w6, w0
cmp w5, w6 //此处 w5 == w6,0x000f0000
b.eq 3f
add x3, x3, #CPU_INFO_SZ
b 1b
2:
mov x3, #0 // unknown processor
3:
mov x0, x3 //x3保存cpu_table中对应cpu id的表项的物理地址
ret
ENDPROC(lookup_processor_type)
.....
__lookup_processor_type_data:
.quad .
.quad cpu_table
.size __lookup_processor_type_data, . - __lookup_processor_type_data
补充知识: 通用寄存器用w表示说是在32位上下文中使用,用x表示说明是在64位上下文中使用
3. 总结
lookup_processor_type实际是将从MIDR_EL1读取到的CPU ID与cpu_table数组中保存的cpu_id_val进行匹配,如果匹配成功,则将cpu_table的物理地址保存到x0中并返回
参考文档
1.https://blog.csdn.net/xichangbao/article/details/51568782
2.https://www.cnblogs.com/smartjourneys/diary/2017/04/27/6774121.html
3.http://www.wowotech.net/armv8a_arch/arm64_initialize_1.html ARM64的启动过程之(一):内核第一个脚印
3.http://www.wowotech.net/armv8a_arch/create_page_tables.html ARM64的启动过程之(二):创建启动阶段的页表
4.http://www.wowotech.net/armv8a_arch/__cpu_setup.html ARM64的启动过程之(三):为打开MMU而进行的CPU初始化
5.http://www.wowotech.net/armv8a_arch/turn-on-mmu.html ARM64的启动过程之(四):打开MMU
6.https://blog.csdn.net/xichangbao/article/details/51568782 Kernel启动流程源码解析 1 head.S
7.https://blog.csdn.net/xichangbao/article/details/51605462 Kernel启动流程源码解析 2 head.S