Arm通用計時器簡介

所有使用Arm處理器的系統中都會包含一個標準化的通用定時器(Generic Timer)框架。這個通用定時器系統提供了一個系統計數器(System Counter)和一組定時器(Timer)。其結構如下圖:

可以看到,系統計數器是全局唯一的,並且全局共享,對系統中的所有Arm核心進行廣播。這個計數器以一個固定的頻率遞增(頻率範圍通常從1MHz到50MHz不等)。同時,這個系統計數器還是一直存在的,哪怕系統處於待機狀態,所有內核都被關閉了,它仍然可以工作。計數器的寬度有56位至64位,計數到達最大值後會回滾。

每一個Arm核都配備一組專門爲自己服務的定時器。定時器到期了之後會通過私有的PPI(Private Peripheral Interrupt)向通用中斷控制器發中斷請求。按照不同的指令集擴展,每組都有最多7個定時器,但無論如何最基本的都會提供4個,它們分別是:

  • EL1 physical timer:給操作系統用的物理定時器;
  • EL1 virtual timer:給操作系統用的虛擬定時器;
  • Non-secure EL2 physical timer:給虛擬機的宿主系統用的定時器;
  • EL3 physical timer:給運行於EL3內的固件程序使用的定時器。

對於系統計數器來說,可以通過讀取控制寄存器CNTPCT_EL0來獲得當前的系統計數值(無論處於哪個異常級別),也就是通過以下彙編指令:

MRS Xn, CNTPCT_EL0

這條指令是可以亂序執行的,使用的時候要適當保護。確切的說,這是讀取物理計數器的值,系統中其實還存在一個虛擬計數器的值,這個虛擬計數器主要也是給虛擬機的宿主系統用的。虛擬計數器的值和物理計數器的值有如下對應關係:

虛擬計數器 = 物理計數器 - 偏移

這個偏移的值是通過控制寄存器CNTVOFF_EL2設置的,看名字就知道只能在EL2或EL3層纔有權限設置和訪問,如果不設置的話,默認值是0,也就是虛擬計數器和物理計數器的值一致。如果想得到虛擬計數器的值,可以通過讀取CNTVCT_EL0控制寄存器來獲得。

系統計數器的頻率主要通過控制寄存器CNTFRQ_EL0來控制。頻率是可以隨意設定的,但只能在EL3下設置,也就是說在系統固件程序裏。在其它的異常級別裏(EL2到EL0)都不能設置,但是可以通過讀取這個CNTFRQ_EL0寄存器來獲得在固件中設置好的頻率。

對於Arm定時器來說,總體有兩種工作方式:

  1. 到一個絕對時間之後就觸發;
  2. 從現在開始再過一定時間間隔之後觸發。

Arm定時器通過兩類寄存器來實現以上兩種工作方式。一類叫做比較寄存器(CVAL),還有一類叫做定時寄存器(TVAL)。

比較寄存器有64位,如果設置了之後,當系統計數器達到或超過了這個值之後(CVAL<系統計數器),就會觸發定時器中斷。通過這種方式來實現第一類定時任務,。

定時寄存器有32位,如果設置了之後,會將比較寄存器設置成當前系統計數器加上設置的定時寄存器的值(CVAL=系統計數器+TVAL),後面就一樣了,當系統計數器達到或超過了這個值後,就會觸發定時中斷。通過這種方式來實現第二種定時任務。

可以看出來,無論那種類型的定時器都是單次出發的(One Shot),如果想要週期觸發,必須在中斷處理程序中重新設置。這也剛好滿足Linux系統中對於高精度定時器的要求。

除了設置定時條件的寄存器,其實每組定時器都還有一個控制寄存器(CTL),其只有最低三位有意義,其它的60位全是保留的,設置成0:

最低三位分別是:

  • ENABLE:是否打開定時器,使其工作;
  • IMASK:中斷掩碼,如果設置成1,則即使定時器是工作的,仍然不會發出中斷;
  • ISTATUS:如果定時器打開的話,且滿足了觸發條件,則將這一位設置成1。

所以很簡單,如果想讓定時器按照要求發出中斷的話,必須將Enable位設置成1,且IMASK位必須設置成0。

定時中斷滿足觸發條件後,其並不會自己消失。如果在中斷處理程序中不做處理的話,那同一個觸發條件會不停的觸發中斷。

前面說到了,每個Arm核都有4個私有定時器,每個定時器都有一個比較寄存器、一個定時寄存器、一個控制寄存器,所以一共應該有12個寄存器可以操作,將它們的命名總結如下:

定時器類型 比較寄存器名 定時寄存器名 控制寄存器名 訪問異常級別
EL1 physical timer CNTP_CVAL_EL0 CNTP_TVAL_EL0 CNTP_CTL_EL0 EL0和EL1
EL1 virtual timer CNTV_CVAL_EL0 CNTV_TVAL_EL0 CNTV_CTL_EL0 EL0和EL1
Non-secure EL2 physical timer CNTHP_CVAL_EL2 CNTHP_TVAL_EL2 CNTHP_CTL_EL2 NS.EL2
EL3 physical timer CNTPS_CVAL_EL1 CNTPS_TVAL_EL1 CNTPS_CTL_EL1 EL3和S.EL1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章