arch/arm64/kernel/head.S文件——el2_setup函数分析

本文详细解析ARM64架构下EL2模式的初始化流程,包括寄存器配置、内存模型、虚拟机模式选择(Hyp/VHE)、中断控制器设置、性能监控单元配置等关键步骤,以及不同模式下的返回机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该汇编函数,用w0寄存器保存返回值,返回值有两种:

BOOT_CPU_MODE_EL1:表示当前CPU跳入内核时处于权限级EL1

BOOT_CPU_MODE_EL2:表示当前CPU跳入内核时处于权限级EL2

//////////////////////////////////////

1)在权限级ELx下,寄存器SPsel被设置为1时,堆栈寄存器SP就是用寄存器SP_ELx。

          msr SPsel, #1

2)寄存器CurrentEL记录了当前CPU的权限级

          mrs x0, CurrentEL

          cmp x0, #CurrentEL_EL2

          b.eq  1f

          /*当前CPU权限级为EL1*/

1:

         /*跳转到此处,表明当前CPU权限级为EL2*/

 

3)如果当前CPU权限级为EL1,就直接配置EL1的系统控制寄存器,el2_setup函数直接返回BOOT_CPU_MODE_EL1。

系统控制寄存器 sctlr_el1

       ENDIAN_SET_EL1:关闭EL1/EL0的stage1阶段的地址翻译功能。

       SCTLR_EL1_RES1:将保留位11/20/22/28/29全部设置为1(具体原因,手册不详)

如果当前CPU权限级为EL2,也需要配置EL2的系统控制寄存器,然后进行后面一大段的EL2初始化过程,最终el2_setup函数返回BOOT_CPU_MODE_EL2。

系统控制寄存器 sctlr_el2

     ENDIAN_SET_EL2:关闭EL2的stage1阶段的地址翻译功能。

       SCTLR_EL2_RES1:将保留位4/5/11/16/18/22/23/28/29全部设置为1(具体原因,手册不详)

/////////////////////////////////////////////////////

后面的讨论全部都基于当前CPU处于EL2状态来讨论,ARM64支持两种虚拟机方式:Hyp和VHE两种方式。

1)Hyp模式下,宿主OS处于EL1状态,客户OS也处于EL1状态,客户OS陷入到EL2后,需要宿主OS帮助完成相关功能后,再次陷入EL2然后返回客户OS,即CPU需要两次陷入和四次上下文切换才能完成一次对客户OS的服务。

2)HVE模式下,宿主OS处于EL2状态,客户OS处于EL1状态,客户OS可以直接陷入EL2的宿主OS完成相关功能,然后直接返回客户OS,即CPU只需要一次陷入和两次上下文切换就可以完成一次对客户OS的服务。

//////////////////////////////////////////////////////

1)内存模型特征寄存器id_aa64mmfrl_el1的[8..11]这四位如果不全为零,表示CPU支持VHE模式;并根据Hyp/VHE模式来设置虚拟i机配置寄存器hcr_el2。

当CPU处于Hyp模式时,将虚拟机配置寄存器hcr_el2设置为HCR_HOST_NVHE_FLAGS

当CPU处于VHE模式时,将虚拟机配置寄存器hcr_el2设置为HCR_HOST_VHE_FLAGS

#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK)
#define HCR_HOST_VHE_FLAGS    (HCR_RW | HCR_TGE | HCR_E2H)

HCR_RW[31]:EL1设置为aarch64模式。

HCR_TGE[27]:将原本路由到EL1各类中断全部路由到EL2来处理,包括快速中断FMO、中断IMO、错误中断AMO全部设置为1。

其他的各个域手册不详。

2)设置计数器-定时器虚拟机控制器寄存器cnthctl_el2,清零计数器-定时器虚拟偏移寄存器cntvoff_el2。

在Hyp模式下,允许非安全态的EL0/EL1可以访问四个定时器寄存器:CNTP_CVAL_EL0、CNTP_TVAL_EL0、CNTP_CTL_EL0和CNTPCT_EL0;VHE模式下,在后面的代码会对EL0进行相关设置。

在Hyp和VHE模式下,都将虚拟偏移寄存器清零了。

3)GICv3相关寄存器设置工作

首先判断GIC版本,处理器特征寄存器id_aa64pfr0_el1的[24...27]这四位,0001表示GICv3。

              mrs    x0, id_aa64pfr0_el1
              ubfx    x0, x0, #24, #4
              cbz    x0, 3f

             /*当前处理器采用GICv3的中断控制器*/

3:        

             /* 如果直接跳转到这里,表示当前处理器没有采用GICv3版本的中断控制器*/

 

然后设置中断控制器系统寄存器使能寄存器ICC_SRE_EL2的SRE和Enable两个域:

         [0]位, SRE系统寄存器接口使能位。

         [3]位,Enable在非安全态下,EL1权限级访问寄存器ICC_SRE_EL1的使能位。

然后再次读出ICC_SRE_EL2,并判断SRE是否为零,如果不是零,就将中断控制器虚拟机控制寄存器ICH_HCR_EL2清零。中断控制器虚拟机控制寄存器ICH_HCR_EL2用于控制客户操作系统的中断环境。

注:此处我没有搞清楚SRE为零表示使能成功,还是非零表示使能成功。

注:寄存器ICH_HCR_EL2和寄存器ICC_SRE_EL2采用msr_s和mrs_s间接指令来访问,而不是常规的msr/mrs指令访问。

4)ID寄存器设置工作

CPU ID寄存器MIDR_EL1,CPU厂商号,体系结构,类型和版本号。

多CPU亲和属性寄存器MPIDR_EL1,主要用于软件调度提供依据。

虚拟机CPU ID寄存器VPIDR_EL2;虚拟机多CPU亲和属性寄存器VMPIDR_EL2。

将物理CPU两个属性直接复制给虚拟机CPU。

 

5)在32位兼容模式下,希望访问CP15不会陷入到EL2,所以就将HSTR_EL2清零。

 

6)判断CPU是否支持PMUv3,如果支持就获取事件计数器的个数,最多支持31个事件计数器。

              mrs    x1, id_aa64dfr0_el1
              sbfx    x0, x1, #8, #4
              cmp    x0, #1
              b.lt    4f
              mrs    x0, pmcr_el0
              ubfx    x0, x0, #11, #5  

4:       

              csel x3, xzr, x0, lt

注:在AArch64调试特征寄存器id_aa64dfr0_el1中, PMUver[8:11]位域描述了性能监控扩展版本。

        0000 表示CPU不支持性能监控扩展;0001表示支持PMUv3;其他表示厂家自定义,但不是PMUv3。

        性能监控器控制寄存器pmcr_el0的N[11..15]直接描述了事件计数器个数。

       此时,寄存器x3包含了事件计数器的个数。

 

7)在AArch64调试特征寄存器id_aa64dfr0_el1中,[32..35]这四位判断CPU是否支持SPE:如果为零,表示不支持。(飞腾当前不支持,我们直接跳转7f)。

       此时,,寄存器x3依然包含了事件计数器的个数。

8) 用寄存器x3配置mdcr_el2寄存器,主要是HPMN[0:4],即非安全态EL0/EL1可以访问的事件计数器个数。

9)内存模式特征寄存器id_aa64mmfr1_el1,通过ID_AA64MMFRI_LOR_SHIFT[16..19]判断EL0能否支持大小端两种模式:0000不支持两种模式;0001支持两种模式。如果支持两种模式就要将寄存器SYS_LORC_EL1清零。

10)将虚拟页表基址寄存器清零,寄存器vvtbr_el2用于指向非安全态EL0/EL1的stage2阶段页表基地址。

11)如果是VHE模式,直接返回w0为BOOT_CPU_MODE_EL2。如果是Hyp模式,就跳转到install_el2_stub汇编,再返回。

/////////////////////////////////////////

此时CPU都处于EL2模式,但是VHE返回方式和Hyp返回方式不同:

1)VHE模式返回到EL2模式,所以只需要常规返回,即设置返回值w0,用ret返回。

2)Hyp模式需要返回到EL1模式,在返回之前,需要设置好向量表,返回后的处理器状态,返回后的地址,以及返回值w0,用eret返回。

////////////////////////////////////////下面是Hyp模式的返回实现函数install_el2_stub

1)设置系统控制寄存器sctlr_el1,el2_setup函数最开始已经做过了,一模一样的。

2)设置体系结构特征陷入寄存器cptr_el2,该寄存器主要是控制FP和ASIMD运行相关的跟踪调试(CPACR和CPACR_EL1)寄存器访问是陷入EL2。

              TCPAC[31]    0    表示访问这些寄存器不发生EL2自陷;

              TTA[20]          0    表示访问跟踪相关系统寄存器不发生EL2自陷;

              TFP[10]          0    表示FP和ASIMD指令不会发生EL2自陷。

3)判断是否支持SVE,如果支持SVE,就将寄存器cptr_el2的CPTR_EL2_TZ[8]位清零(前面置过1)(不发生协处理器SVE自陷到EL2),设置寄存器SYS_ZCR_EL2为ZCR_ELx_LEN_MASK.

             AArch64处理器特征寄存器id_aa64pfr0_el1的 ID_AA64PFR0_SVE_SHIFT[32..35],为零表示CPU不支持SVE。

4)Hyp模式的返回前设置:包括向量基地址寄存器vbar_el2填写,返回后处理器状态寄存器spsr_el2设置,返回地址elr_el2,返回值w0,最后eret返回。

注:在Hyp模式下,向量表为__hyp_stub_vecotrs,这个向量表以后会被修改!

       返回后的处理器状态为 PSR_F_BIT、PSR_I_BIT、PSR_A_BIT、PSR_D_BIT、PSR_MODE_EL1h。

 

     

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值