飞腾CPU虚拟化相关代码分析(三)——函数set_cpu_boot_mode_flag
基本描述
根据CPU启动模式,来设置__boot_cpu_mode全局数组变量。
函数输入输出描述
- 输入:
- 寄存器w0
函数el2_setup的输出,寄存器w0, 参见飞腾CPU虚拟化相关代码分析(一)
- long类型的__boot_cpu_mode[2]数组
__boot_cpu_mode[0] 静态初始化为BOOT_CPU_MODE_EL2,
__boot_cpu_mode[1] 静态初始化为BOOT_CPU_MODE_EL1,
- 输出:
__boot_cpu_mode[2]数组
- 汇编函数set_cpu_boot_mode_flag调用之后,只有两种情况:
- 该数组的两个元素都为BOOT_CPU_MODE_EL2
- 该数组的两个元素都为BOOT_CPU_MODE_EL1
- 后续两个C语言函数用该数组做输入,进行判断
- 函数is_hyp_mode_available( ),判断内核是否能够支持虚拟化
static inline bool is_hyp_mode_available(void)
{
return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 &&
__boot_cpu_mode[1] == BOOT_CPU_MODE_EL2);
}
- 函数is_hyp_mode_mismatched( ), 这个函数如果返回真,表示进入内核时的权限级状态不明确。
__boot_cpu_mode全局数组变量
该全局数组变量,在head.S中以汇编方式进行定义和静态初始化,在include/asm/virt.h中进行C语言声明。
- 定义
ENTRY(__boot_cpu_mode)
.long BOOT_CPU_MODE_EL2
.long BOOT_CPU_MODE_EL1
- 声明
extern u32 __boot_cpu_mode[2];
函数分析
set_cpu_boot_mode_flag:
adr_l x1, __boot_cpu_mode
/*将64位地址读到寄存器x1*/
cmp w0, #BOOT_CPU_MODE_EL2
b.ne 1f
add x1, x1, #4
1: str w0, [x1]
/*运行到这里的时候,该函数的功能已经完成,
由于该数组是全局数组,所以退出之前要全局同步*/
dmb sy
/*保证前面的数据访存指令全部完成*/
dc ivac, x1
/*进行数据缓存同步到内存中*/
ret
ENDPROC(set_cpu_boot_mode_flag)