慢慢欣赏arm64内核启动9 primary_entry之el2_setup代码第七部分

分析代码

	cbz	x2, install_el2_stub

	mov	w0, #BOOT_CPU_MODE_EL2		// This CPU booted in EL2
	isb
	ret

SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL)
	/*
	 * When VHE is not in use, early init of EL2 and EL1 needs to be
	 * done here.
	 * When VHE _is_ in use, EL1 will not be used in the host and
	 * requires no configuration, and all non-hyp-specific EL2 setup
	 * will be done via the _EL1 system register aliases in __cpu_setup.
	 */
	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
	msr	sctlr_el1, x0

	/* Coprocessor traps. */
	mov	x0, #0x33ff
	msr	cptr_el2, x0			// Disable copro. traps to EL2

	/* SVE register access */
	mrs	x1, id_aa64pfr0_el1
	ubfx	x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
	cbz	x1, 7f

	bic	x0, x0, #CPTR_EL2_TZ		// Also disable SVE traps
	msr	cptr_el2, x0			// Disable copro. traps to EL2
	isb
	mov	x1, #ZCR_ELx_LEN_MASK		// SVE: Enable full vector
	msr_s	SYS_ZCR_EL2, x1			// length for EL1.

	/* Hypervisor stub */
7:	adr_l	x0, __hyp_stub_vectors
	msr	vbar_el2, x0

	/* spsr */
	mov	x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
		      PSR_MODE_EL1h)
	msr	spsr_el2, x0
	msr	elr_el2, lr
	mov	w0, #BOOT_CPU_MODE_EL2		// This CPU booted in EL2
	eret
SYM_FUNC_END(el2_setup)

install_el2_stub

el2_setup分析了这么多,终于到了结尾部分。但是这段代码还是较长。我们一点点分析。
第1行代码:x2寄存器如果为0,则跳转到函数 install_el2_stub 执行;
其中,x2寄存器始终保存 VHE 的值,也就是说,如果当前 PE 不支持 VHE,则执行 install_el2_stub,我们分析一下 函数 install_el2_stub

第7行代码就是函数 install_el2_stub 的开头部分,这个函数看名字像是个桩函数,安装 el2 异常模式的桩,这是啥意思呢,我们先看一下注释吧。

第8行到14行是注释部分,我们尝试翻译一下:
如果 PE 不支持 VHE 模式,那么第一阶段的启动过程中,对异常模式 EL1/EL2 的初始化到此结束了;
但是如果 PE 支持 VHE 模式,那么主机侧不需要 EL1 异常模式,并且 EL1 异常模式也不需要配置,所有非hyp特有的EL2设置都将在函数__cpu_setup中通过EL1系统寄存器别名完成。
这段话表面翻译起来,还是绕,只能等到后续真正分析 __cpu_setup 再慢慢消化了。

第15行到16行代码在 el2_setup 的前面的章节分析过。

CPTR_EL2

第18行到第20行涉及到寄存器 CPTR_EL2, Architectural Feature Trap Register (EL2),该寄存器的含义如下:
Controls:
    Trapping to EL2 of access to CPACR, CPACR_EL1, trace functionality, and to SVE, Advanced SIMD and floating-point functionality.
    EL2 access to trace functionality, and to SVE, Advanced SIMD and floating-point functionality.
该寄存器用于控制对特定架构特性的陷阱(trap)行为。
具体来说,CPTR_EL2寄存器允许EL2(虚拟化扩展的虚拟监控程序Hypervisor运行的级别)管理对处理器某些功能的访问,当这些功能被访问时,可以决定是否将它们重定向为陷阱(trap)异常,以便EL2可以进行处理。
CPTR_EL2寄存器中的每一位都对应一个特定的架构特性或指令集扩展。当某位被设置为1时,表示对应的特性或指令集扩展的访问将被陷阱到EL2。这允许Hypervisor对底层硬件功能进行更细粒度的控制,防止客户操作系统(运行在EL1或更低级别)直接访问这些特性。
通过控制对特定架构特性的访问,CPTR_EL2有助于在虚拟化环境中实现安全隔离。它确保只有Hypervisor能够访问或控制那些可能对系统稳定性或安全性产生影响的特性。
根据具体的应用场景和安全需求,Hypervisor可以通过编程方式配置CPTR_EL2寄存器,灵活地启用或禁用对特定架构特性的陷阱。这种灵活性使得ARM64架构能够支持多种不同的虚拟化解决方案和场景。
魔数字0x33ff 主要涉及2个位域
TFP, bit [10]
Traps accesses to SVE, Advanced SIMD and floating-point functionality to EL2 when it is enabled in the current Security state, from both Execution states.
    0b'0 This control does not cause any instructions to be trapped.
    0b'1 Any attempt at EL0, EL1 or EL2, to execute an instruction that uses the registers associated with SVE, Advanced SIMD and floating-point execution is trapped to EL2 when it is enabled in the current Security state, subject to the exception prioritization rules, unless it is trapped by CPTR_EL2.TZ.
TZ, bit [8]
When SVE is implemented:
    Traps execution at EL2, EL1, or EL0 of SVE instructions and instructions that access SVE System registers to EL2 when it is enabled in the current Security state.
        0b'0 This control does not cause any instruction to be trapped.
        0b'1 This control causes these instructions to be trapped, subject to the exception prioritization rules.
        This field resets to an architecturally UNKNOWN value.
Otherwise:
    Reserved, RES1.

SVE

第22行到第25行涉及到 SVE寄存器的访问控制。
寄存器 ID_AA64PFR0_EL1 在前面的章节讲解过,宏 ID_AA64PFR0_SVE_SHIFT 的定义如下

#define ID_AA64PFR0_SVE_SHIFT		32

相关位域定义如下:
SVE, bits [35:32]
    From ARMv8.2:
        Scalable Vector Extension. Defined values are:
        0b'0000SVE is not implemented.
        0b'0001SVE is implemented.
        All other values are reserved.
    Otherwise:
        Reserved, RES0.
含义是:是否支持 SVE 矢量,如果不支持 SVE,则直接跳转到第34行。

第27行到第31行是对 SVE 的配置

异常向量入口

第33行到第35行异常向量入口地址的配置,当然,当前情况下,只是配置了个桩

第34行将 __hyp_stub_vectors 的地址加载到了x0寄存器;

第35行将 x0的值赋值给了寄存器 vbar_el2
VBAR_EL2, Vector Base Address Register (EL2)的含义如下:
Holds the vector base address for any exception that is taken to EL2.
也就是说,传递给EL2异常模式下的异常向量的入口地址。

异常模式EL2到EL1的切换

第37行到第43行是整个 el2_setup 的核心部分之一。主要作用就是当前 PE 如果不支持 VHE,那么需要从当前的EL2异常模式切换到EL1异常模式继续运行。

涉及到的宏定义如下:

#define PSR_F_BIT	0x00000040
#define PSR_I_BIT	0x00000080
#define PSR_A_BIT	0x00000100
#define PSR_D_BIT	0x00000200
#define PSR_MODE_EL1h	0x00000005


切换前需要设置两个寄存器:
    elr_el2:EL1从lr寄存器保留的地址继续运行的地址, lr保留的是 install_el2_stub 函数的返回地址;
    spsr_el2:EL2的状态保留在 spsr_el2寄存器(Saved Program Status Register (EL2))
        其中异常返回前(When exception taken from AArch64 state:),位域bits[3:0]的含义如下:
        M[3:0], bits [3:0]
        AArch64 state (Exception level and selected SP) that an exception was taken from.
        0b'0000    EL0t.
        0b'0100    EL1t.
        0b'0101    EL1h.
        Other values are reserved, and returning to an Exception level that is using AArch64 with a reserved
        value in this field is treated as an illegal exception return.
        The bits in this field are interpreted as follows:
            M[3:2] holds the Exception Level.
            M[1] is unused and is RES0 for all non-reserved values.
            M[0] is used to select the SP:
                0 means the SP is always SP0.
                1 means the exception SP is determined by the EL.
        This field resets to an architecturally UNKNOWN value.
        根据上面芯片手册的描述,我们得知,位域M[3:0]表示异常等级切换后,需要切换回的异常等级模式,根据宏定义 PSR_MODE_EL1h 的定义,我们得知切换到 EL1, 并且使用 SP1 作为堆栈
        其它涉及的位域bits[9:6]表示屏蔽所有的异常干扰

第42行将启动的异常模式EL2 保留在 w0中。

第43行 eret 进行模式切换,从EL2模式切换到EL1模式运行,切换到 install_el2_stub 函数的返回地址继续运行,也就是第3行继续运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值