ARMv8學習 —— SP_EL0和SP_ELx

 

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

  • SP_EL0和SP_EL1
  • SP_EL2
  • SP_EL3

如何使用呢?spa

一、若是程序運行在EL0,那麼使用的是SP_EL03d

二、若是程序運行在其餘Exception level下,可使用SP_EL0和當前Exception level所對應的SP_ELxcode

三、默認狀況下,進入異常後,使用的是當前Exception level對應的SP_ELx。即:發生的進入EL1的異常,那麼在跳轉到EL1的異常處理入口後,會自動切到SP_EL1,此時SP對應的就是SP_EL1. 固然,能夠在異常經過操做PSTATE.SP將SP強制切到SP_EL0blog

四、即使不是在異常處理程序中,也能夠經過操做PSTATE.SP將SP強制切到SP_EL0或者SP_ELxit

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

六、後綴t和h:class

  t 表示使用的是SP_EL0程序

  h 表示使用的是SP_ELxim

 驗證

下面使用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,含義以下,表示發生異常前系統的模式和狀態:AArch6四、EL三、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行,異常返回後,寄存器內容以下:

 

完。

相關文章
相關標籤/搜索