ARMv8學習 —— SP_EL0和SP_ELx


 

在AArch64狀態下,SP對應的物理寄存器有如下四個(某一時刻只能對應下面其中一個):

  • SP_EL0和SP_EL1
  • SP_EL2
  • SP_EL3

如何使用呢?

1、如果程序運行在EL0,那么使用的是SP_EL0

2、如果程序運行在其他Exception level下,可以使用SP_EL0和當前Exception level所對應的SP_ELx

3、默認情況下,進入異常后,使用的是當前Exception level對應的SP_ELx。即:發生的進入EL1的異常,那么在跳轉到EL1的異常處理入口后,會自動切到SP_EL1,此時SP對應的就是SP_EL1. 當然,可以在異常通過操作PSTATE.SP將SP強制切到SP_EL0

4、即便不是在異常處理程序中,也可以通過操作PSTATE.SP將SP強制切到SP_EL0或者SP_ELx

5、比如程序正運行在EL1,此時使用的SP是SP_EL0,突然發生了一個進入EL1的異常,在跳轉到異常處理入口后,SP會自動切到SP_EL1,在異常返回后,SP又會自動切回到原先的SP_EL0

6、后綴t和h:

  t 表示使用的是SP_EL0

  h 表示使用的是SP_ELx

 驗證

下面使用DS5仿真的實驗,驗證一下上面的說法。

系統復位后,默認是在EL3,並且是secure模式。

第73行,將SP切到SP_EL0,然后設置SP的值為0x77,此時的寄存器狀態如下:

第77行,將SP切到SP_EL3,然后將SP設置為0x88,此時的寄存器狀態如下:

 

 

第81行,將SP重新切回SP_EL0,此時的寄存器狀態如下:

 

第83行,訪問ICC_SRE_EL2會觸發sync異常,因為在secure模式下不存在EL2,觸發異常后,會進入EL3的“Current EL with SP0”分支,因為發生異常時使用的是SP_EL0,下面是進入異常處理程序后的寄存器信息:

 

可以看到,此時SPSel的值是1,Mode的值為EL3h,說明此時SP用的是SP_ELx。此時SPSR_EL3的值是0x3CC,SPSR的含義如下:

M[3:0]的值是0xC,含義如下,表示發生異常前系統的模式和狀態:AArch64、EL3、SP_EL0

 

 下面是異常處理函數:

 1 //
 2 // Current EL with SP0
 3 //
 4 el3_vectors:
 5 c0sync3:
 6     mrs x0, elr_el3
 7     add x0, x0, #4
 8     msr elr_el3, x0
 9 
10     mov x0, #0x1
11     msr spsel, x0
12     eret

第6到8行的作用是異常返回時跳轉到觸發異常的指令的下一條指令執行,當第12執行完畢,ELR_EL3的值會設置給PC,SPSR_EL3的值會設置給PSTATE,所以SP會重新切回到SP_EL0:

 

 第85行的作用是將SP切換到SP_EL3,此時的寄存器內容如下:

 

 緊接着第86行,再次觸發異常:

此時會跳轉到EL3的“Current EL with SPx”分支執行:

 1 //
 2 // Current EL with SPx
 3 //
 4     .balign 0x80
 5 cxsync3:
 6     mrs x0, elr_el3
 7     add x0, x0, #4
 8     msr elr_el3, x0
 9 
10     mov x0, #0x0
11     msr spsel, x0
12     eret

 

第12行,異常返回后,寄存器內容如下:

 

完。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM