★★★ 友情連結 : 個人部落格導讀首頁—點選此處 ★★★
以SCTLR寄存器來闡述在armv7、armv8-arch64、armv8-arch64的使用方式
(其實大多數的系統寄存器,都是這種處理方式)
SCTLR是系統控制寄存器(SCTLR : system control registers)
在ARMV8上有如下sctlr寄存器
(aarch64)
SCTLR_EL1
SCTLR_EL2
SCTLR_EL3
(aarch32)
SCTLR (NS) – banked
HSCTLR
SCTLR (S) – banked
在ARMV8上有如下sctlr寄存器
SCTLR寄存器的位定義
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP35ENBRlT6VkaNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyAjM3IDNwATM1EDMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
SCTLR的使用方式
SCTLR是system control register,系統控制寄存器。如果跑了雙系統(linux,tee),那麼在兩份系統中對于該寄存器會産生不同的配置的,如linux中enable mmu,tee中disable mmu, 這樣就導緻在兩份系統中的SCTLR值不同.
那麼我們看看ARM的設計
(1)、在armv7中,這些通用的系統寄存器是有兩組的,即根據SCR.NS比特位的不同,會自動通路相應的那一組寄存器。也就是說,你在linux中和在tee中讀寫的SCTLR是兩個不同的寄存器;
(2)、在armv8-arch64中,有SCTLR_EL1、SCTLR_EL2、SCTLR_EL3三個系統控制寄存器,這裡我們隻看SCTLR_EL1. 該寄存器隻有一組,在雙系統切換時(linux,tee),會在ATF代碼中save/restore 該寄存器. 其實對于大多數通用的系統寄存器都是如此.
(3)、在armv8-arch32中,SCTLR_EL1的低32位map成了SCTLR,該寄存器也是隻有一組,在雙系統切換時(linux,tee),也需在ATF代碼中save/restore 該寄存器
在armv8-arch64中,是以MRS/MSR來通路SCR寄存器的,而在armv7/armv8-arch32中是以操作協處理器cp15來通路的
例如:
(1)、armv8-arch64 enable MMU
__enable_mmu:
mrs x18, sctlr_el1 // preserve old SCTLR_EL1 value
mrs x1, ID_AA64MMFR0_EL1
ubfx x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
b.ne __no_granule_support
msr ttbr0_el1, x25 // load TTBR0
msr ttbr1_el1, x26 // load TTBR1
isb
msr sctlr_el1, x0 //将x0寫入到sctlr_el1
isb
/*
* Invalidate the local I-cache so that any instructions fetched
* speculatively from the PoC are discarded, since they may have
* been dynamically patched at the PoU.
*/
ic iallu
dsb nsh
isb
(2)、armv8-arch32或armv7 enable MMU
ENTRY(__turn_mmu_on)
mov r0, r0
instr_sync
mcr p15, 0, r0, c1, c0, 0 @ write control reg //操作協處理器,将r0寫入到sctlr
mrc p15, 0, r3, c0, c0, 0 @ read id reg
instr_sync
mov r3, r3
mov r3, r13
ret r3
__turn_mmu_on_end:
ENDPROC(__turn_mmu_on)