linux kenrel mair_el1 是如何内核页表关联的
mair寄存器---Provides the memory attribute encodings corresponding to the possible
AttrIndx values in a Long-descriptor format translation table entry for stage 1 translations at EL1
PTE页表 字段描述
各个bit描述
代码中的描述:
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
*/
#define PTE_ATTRINDX(t) (_AT(pteval_t, (t)) << 2)//属性索引,是和mair 寄存器关联的,mair一上电就配置了,后面就是选择索引号
#define PTE_ATTRINDX_MASK (_AT(pteval_t, 7) << 2) //共3bit选择mair中的attr0--attr7其中一个
#define __pgprot_modify(prot,mask,bits) \
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
/*
* Mark the prot value as uncacheable and unbufferable.
*/
#define pgprot_noncached(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) //
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
#define pgprot_cache(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL) | PTE_PXN | PTE_UXN)
/*
* Memory types available.
*/
#define MT_DEVICE_nGnRnE 0
#define MT_DEVICE_nGnRE 1
#define MT_DEVICE_GRE 2
#define MT_NORMAL_NC 3
#define MT_NORMAL 4
mair寄存器在哪里配置的,在启动汇编中,有2个情况,次核和主核
arch/arm64/mm/proc.S:195:ENTRY(__cpu_setup)
/*
* __cpu_setup
*
* Initialise the processor for turning the MMU on. Return in x0 the
* value of the SCTLR_EL1 register.
*/
ENTRY(__cpu_setup)
ic iallu // I+BTB cache invalidate
tlbi vmalle1is // invalidate I + D TLBs
dsb ish
mov x0, #3 << 20
msr cpacr_el1, x0 // Enable FP/ASIMD
mov x0, #1 << 12 // Reset mdscr_el1 and disable
msr mdscr_el1, x0 // access to the DCC from EL0
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
/*
* Memory region attributes for LPAE:
*
* n = AttrIndx[2:0]
* n MAIR
* DEVICE_nGnRnE 000 00000000
* DEVICE_nGnRE 001 00000100
* DEVICE_GRE 010 00001100
* NORMAL_NC 011 01000100
* NORMAL 100 11111111
*/
ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
MAIR(0x04, MT_DEVICE_nGnRE) | \
MAIR(0x0c, MT_DEVICE_GRE) | \
MAIR(0x44, MT_NORMAL_NC) | \
MAIR(0xff, MT_NORMAL) //#define MAIR(attr, mt) ((attr) << ((mt) * 8))
msr mair_el1, x5
/*
* Prepare SCTLR
*/
adr x5, crval
ldp w5, w6, [x5]
mrs x0, sctlr_el1
bic x0, x0, x5 // clear bits
orr x0, x0, x6 // set bits
/*
* Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
* both user and kernel.
*/
ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0
tcr_set_idmap_t0sz x10, x9
/*
* Read the PARange bits from ID_AA64MMFR0_EL1 and set the IPS bits in
* TCR_EL1.
*/
mrs x9, ID_AA64MMFR0_EL1
bfi x10, x9, #32, #3
msr tcr_el1, x10
ret // return to head.S
ENDPROC(__cpu_setup)
ENTRY(secondary_startup)
/*
* Common entry point for secondary CPUs.
*/
adrp x25, idmap_pg_dir
adrp x26, swapper_pg_dir
bl __cpu_setup // initialise processor 次核启动调用设置
ldr x21, =secondary_data
ldr x27, =__secondary_switched // address to jump to after enabling the MMU
b __enable_mmu
ENDPROC(secondary_startup)
230 ENTRY(stext)《------head.S,kernel entrypoint启动调用,主核情况
231 bl preserve_boot_args
232 bl el2_setup // Drop to EL1, w20=cpu_boot_mode
233 adrp x24, __PHYS_OFFSET
234 bl set_cpu_boot_mode_flag
235
236 bl __vet_fdt
237 bl __create_page_tables // x25=TTBR0, x26=TTBR1
238 /*
239 * The following calls CPU setup code, see arch/arm64/mm/proc.S for
240 * details.
241 * On return, the CPU will be ready for the MMU to be turned on and
242 * the TCR will have been set.
243 */
244 ldr x27, =__mmap_switched // address to jump to after
245 // MMU has been enabled
246 adr_l lr, __enable_mmu // return (PIC) address
247 b __cpu_setup // initialise processor
248 ENDPROC(stext)