接上文。
2.5 初始化cpu状态(__cpu_setup)
虽然在异常初始化流程中已经设置了sctlr_el1等系统控制寄存器,但在打开mmu前还需要其它一些准备工作。
......
# arch/arm64/mm/proc.S
/*
* __cpu_setup
*
* Initialise the processor for turning the MMU on.
*
* Output:
* Return in x0 the value of the SCTLR_EL1 register.
*/
.pushsection ".idmap.text", "awx" '放在.idmap.text段中'
SYM_FUNC_START(__cpu_setup)
tlbi vmalle1 // Invalidate local TLB
dsb nsh
mov x1, #3 << 20
msr cpacr_el1, x1 // Enable FP/ASIMD ---(2.5.1)
mov x1, #1 << 12 // Reset mdscr_el1 and disable ---(2.5.2)
msr mdscr_el1, x1 // access to the DCC from EL0
isb // Unmask debug exceptions now,
enable_dbg // since this is per-cpu ---(2.5.3)
reset_pmuserenr_el0 x1 // Disable PMU access from EL0 关闭EL0访问PMU
reset_amuserenr_el0 x1 // Disable AMU access from EL0 关闭EL0访问AMU
/*
* Default values for VMSA control registers. These will be adjusted
* below depending on detected CPU features.
*/
//name .req register name: 为寄存器定义一个别名
mair .req x17 //定义X17寄存器的别名 mair
tcr .req x16 //定义X16寄存器的别名 tcr
mov_q mair, MAIR_EL1_SET // //---(2.5.4)
mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ //---(2.5.5)
TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS
#ifdef CONFIG_ARM64_MTE //---(2.5.6)
/*
* Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported
* (ID_AA64PFR1_EL1[11:8] > 1).
*/
mrs x10, ID_AA64PFR1_EL1
ubfx x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4
cmp x10, #ID_AA64PFR1_MTE
b.lt 1f
/* Normal Tagged memory type at the corresponding MAIR index */
mov x10, #MAIR_ATTR_NORMAL_TAGGED
bfi mair, x10, #(8 * MT_NORMAL_TAGGED), #8
mov x10, #KERNEL_GCR_EL1
msr_s SYS_GCR_EL1, x10
/*
* If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
* RGSR_EL1.SEED must be non-zero for IRG to produce
* pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
* must initialize it.
*/
mrs x10, CNTVCT_EL0
ands x10, x10, #SYS_RGSR_EL1_SEED_MASK
csinc x10, x10, xzr, ne
lsl x10, x10, #SYS_RGSR_EL1_SEED_SHIFT
msr_s SYS_RGSR_EL1, x10
/* clear any pending tag check faults in TFSR*_EL1 */
msr_s SYS_TFSR_EL1, xzr
msr_s SYS_TFSRE0_EL1, xzr
/* set the TCR_EL1 bits */
mov_q x10, TCR_MTE_FLAGS
orr tcr, tcr, x10
1:
#endif
tcr_clear_errata_bits tcr, x9, x5 // ---(2.5.7)
#ifdef CONFIG_ARM64_VA_BITS_52 //假设我使用的48bit
ldr_l x9, vabits_actual
sub x9, xzr, x9
add x9, x9, #64
tcr_set_t1sz tcr, x9
#else
ldr_l x9, idmap_t0sz // ---(2.5.8-1)idmap_t0sz = TCR_T0SZ(VA_BITS_MIN) = 16
#endif
tcr_set_t0sz tcr, x9 // ---(2.5.8-2)tcr寄存器的T0SZ域
/*
* Set the IPS bits in TCR_EL1.
*/
tcr_compute_pa_size tcr, #TCR_IPS_SHIFT, x5, x6 // ---(2.5.9)
#ifdef CONFIG_ARM64_HW_AFDBM // ---(2.5.10)
/*
* Enable hardware update of the Access Flags bit.
* Hardware dirty bit management is enabled later,
* via capabilities.
*/
mrs x9, ID_AA64MMFR1_EL1
and x9, x9, #0xf
cbz x9, 1f
orr tcr, tcr, #TCR_HA // hardware Access flag update
1:
#endif /* CONFIG_ARM64_HW_AFDBM */
msr mair_el1, mair //Memory Attribute Indirection Register (EL1)真正的设置动作
msr tcr_el1, tcr //Translation Control Register (EL1)真正的设置动作
/*
* Prepare SCTLR
*/
mov_q x0, INIT_SCTLR_EL1_MMU_ON // ---(2.5.11)
ret // return to head.S
.unreq mair //.unreq用来取消一个寄存器的别名