linux aarch64 head.S el2_setup

2022/3/7 7:20:08

本文主要是介绍linux aarch64 head.S el2_setup,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

    el2_setup 

检查运行级别,如果是 EL1,简单设置 SCTRL_EL1 后就退出。

如果是 EL2级别,就要作很多EL2 需要的设置,然后切换到EL1 级别,然后退出。

 

<1>  使用  SP_EL{1,2}  寄存器作为 SP 寄存器。 

<2> 获取当前运行 级别到 X0,然后和 EL2 级别进行比较。 如果不相等,说明当前运行级别是 EL1, 进入 <3>; 如果相等,说明当前是 EL2 级别, 进入 <4>

<3>  设置 SCTRL_EL1 寄存器的 大小端 模式后就退出,返回 值在 X0 中,为 #BOOT_CPU_MODE_EL1

 1 /*
 2  * If we're fortunate enough to boot at EL2, ensure that the world is
 3  * sane before dropping to EL1.
 4  *
 5  * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
 6  * booted in EL1 or EL2 respectively.
 7  */
 8 SYM_FUNC_START(el2_setup)
 9     msr    SPsel, #1            // We want to use SP_EL{1,2}                                 (1)
10     mrs    x0, CurrentEL
11     cmp    x0, #CurrentEL_EL2                                                                 <2>
12     b.eq    1f
13     mov_q    x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
14     msr    sctlr_el1, x0                                                                      <3>
15     mov    w0, #BOOT_CPU_MODE_EL1        // This cpu booted in EL1
16     isb
17     ret
18 
19 1:    mov_q    x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)                                          <4>
20     msr    sctlr_el2, x0
21 
22   这儿省略很多代码
23 
24 
25     /* Stage-2 translation */
26     msr    vttbr_el2, xzr
27 
28     cbz    x2, install_el2_stub                                                                <5>
29 
30     mov    w0, #BOOT_CPU_MODE_EL2        // This CPU booted in EL2
31     isb
32     ret
33 
34 SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL)                                                  <6>
35     /*
36      * When VHE is not in use, early init of EL2 and EL1 needs to be
37      * done here.
38      * When VHE _is_ in use, EL1 will not be used in the host and
39      * requires no configuration, and all non-hyp-specific EL2 setup
40      * will be done via the _EL1 system register aliases in __cpu_setup.
41      */
42     mov_q    x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
43     msr    sctlr_el1, x0
44 
45     /* Coprocessor traps. */
46     mov    x0, #0x33ff
47     msr    cptr_el2, x0            // Disable copro. traps to EL2
48 
49     /* SVE register access */
50     mrs    x1, id_aa64pfr0_el1
51     ubfx    x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
52     cbz    x1, 7f
53 
54     bic    x0, x0, #CPTR_EL2_TZ        // Also disable SVE traps
55     msr    cptr_el2, x0            // Disable copro. traps to EL2
56     isb
57     mov    x1, #ZCR_ELx_LEN_MASK        // SVE: Enable full vector
58     msr_s    SYS_ZCR_EL2, x1            // length for EL1.
59 
60     /* Hypervisor stub */
61 7:    adr_l    x0, __hyp_stub_vectors
62     msr    vbar_el2, x0
63 
64     /* spsr */
65     mov    x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
66               PSR_MODE_EL1h)                                                                         <7>
67     msr    spsr_el2, x0
68     msr    elr_el2, lr
69     mov    w0, #BOOT_CPU_MODE_EL2        // This CPU booted in EL2
70     eret                                                                                             <8>
71 SYM_FUNC_END(el2_setup)

 

<4>   设置SCTRL_EL2 寄存器,大小端

 省略 很多 设置 EL2 模式下面需要设置的东西

 

<5>  调用 <6>处的函数 install_el2_stub ,函数返回时,已经切换回 EL1 级别,然后  返回 值在 X0 中,为 #BOOT_CPU_MODE_EL2     

 

<6>  被 <5> 调用,里面作了一些设置,我们只关心 <7> 这个地方,设置了  SPSR_EL2 寄存器,

 

<7> SPSR_EL2 寄存器里面填入  PSR_MODE_EL1h, 伪装成 从  EL1 级别 转入了 EL2 级别。

 

<8> 执行 ERET,PSTATE 装填 <7> 里面设置的 SPSR_EL2 寄存器里面的值,回到 EL1 级别。

 



这篇关于linux aarch64 head.S el2_setup的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程