ARMv8: bug fix of mmu setup and code optimization
PATCH 1/1 ARMv8: bug fix of mmu setup and code optimization
From: David Feng <[email protected]>
1. Fix a bug of mmu_setup that variable i and j should be type long instead of int.
2. Give mmu_setup weak attribute so that other implementation can redfine it.
3. A more common set_pgtable_section().
4. Give device memory PXN and UXN attribute. CPU may speculatively prefetch instructions from device memory, but the IO subsystem of some implementation may not support this operation. The two attributes prevent this behavior.
--- arch/arm/cpu/armv8/cache_v8.c | 73 +++++++++++++++++++++++------------- arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 22 +++++------ arch/arm/include/asm/armv8/mmu.h | 71 +++++++++++++++++++---------------- 3 files changed, 95 insertions(+), 71 deletions(-)
arch/arm/cpu/armv8/cache_v8.c +46 -27
@@ -22,55 +22,74 @@ __weak void outer_cache_flush_range(unsigned long start, unsigned long end) {}__weak void outer_cache_inval_range (unsigned long start,unsigned long end) {}#ifndef CONFIG_SYS_DCACHE_OFF -void set_pgtable_section (u64 *page_table,u64 index,u64 section, -u64 memory_type) -{ -u64 value; - value = section |PMD_TYPE_SECT |PMD_SECT_AF ; - value |=PMD_ATTRINDX (memory_type); - page_table[index] = value; +/* 42 bits virtual address */ +#define VA_BITS (42) + +/* 42 bits physical address */ +#define TCR_EL1_IPS_BITS TCR_EL1_IPS_BITS_42 +#define TCR_EL2_IPS_BITS TCR_EL2_IPS_BITS_42 +#define TCR_EL3_IPS_BITS TCR_EL3_IPS_BITS_42 + +/* PTWs cacheable, inner/outer WBWA and inner-shareable */ +#define TCR_FLAGS (TCR_TG0_64K | \ + TCR_SHARED_INNER | \ + TCR_ORGN_WBWA | \ + TCR_IRGN_WBWA | \ + TCR_T0SZ(VA_BITS)) + +void set_pgtable_section (u64 *page_table,u64 index,u64 output_address, +u64 memory_type,u64 extra_flags) +{ + page_table[index] = output_address |PMD_TYPE_SECT |PMD_SECT_AF | +PMD_SECT_SHARED_INNER |PMD_ATTRINDX (memory_type) | + extra_flags; }/* to activate the MMU we need to set up virtual memory */ -static void mmu_setup (void ) +void __weak mmu_setup (void ) { -int i, j, el; +int el; +u64 i, j, tcr;bd_t *bd = gd->bd;u64 *page_table = (u64 *)gd->arch.tlb_addr;/* Setup an identity-mapping for all spaces */ for (i =0 ; i < (PGTABLE_SIZE >>3 ); i++) {set_pgtable_section (page_table, i, i <<SECTION_SHIFT , -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE , +PMD_SECT_PXN |PMD_SECT_UXN ); + } -/* Setup an identity-mapping for all RAM space */ +/* +* Setup an identity-mapping for all RAM space. +* The secure or non-secure memory access make sense +* when u-boot running@el3 and is mostly implementation +* specific. +*/ for (i =0 ; i <CONFIG_NR_DRAM_BANKS ; i++) { -ulong start = bd->bi_dram[i].start; -ulong end = bd->bi_dram[i].start + bd->bi_dram[i].size; +u64 start = bd->bi_dram[i].start; +u64 end = bd->bi_dram[i].start + bd->bi_dram[i].size;for (j = start >>SECTION_SHIFT ; j < end >>SECTION_SHIFT ; j++) {set_pgtable_section (page_table, j, j <<SECTION_SHIFT , -MT_NORMAL ); +MT_NORMAL ,PMD_SECT_NS ); } }/* load TTBR0 */ + tcr =TCR_FLAGS ; el =current_el (); -if (el ==1 ) { -set_ttbr_tcr_mair (el, gd->arch.tlb_addr, -TCR_FLAGS |TCR_EL1_IPS_BITS , -MEMORY_ATTRIBUTES ); - }else if (el ==2 ) { -set_ttbr_tcr_mair (el, gd->arch.tlb_addr, -TCR_FLAGS |TCR_EL2_IPS_BITS , -MEMORY_ATTRIBUTES ); - }else { -set_ttbr_tcr_mair (el, gd->arch.tlb_addr, -TCR_FLAGS |TCR_EL3_IPS_BITS , -MEMORY_ATTRIBUTES ); - } +if (el ==1 ) + tcr |=TCR_EL1_IPS_BITS ; +else if (el ==2 ) + tcr |=TCR_EL2_IPS_BITS ; +else + tcr |=TCR_EL3_IPS_BITS ; + +set_ttbr_tcr_mair (el, gd->arch.tlb_addr, tcr,MEMORY_ATTRIBUTES ); +/* enable the mmu */ set_sctlr (get_sctlr () |CR_M ); }
arch/arm/cpu/armv8/fsl-lsch3/cpu.c +11 -11
@@ -82,11 +82,11 @@ static inline void early_mmu_setup(void) section_l2 =0 ;for (i =0 ; i <512 ; i++) {set_pgtable_section (level1_table_0, i, section_l1t0, -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE ,0 );set_pgtable_section (level1_table_1, i, section_l1t1, -MT_NORMAL ); +MT_NORMAL ,0 );set_pgtable_section (level2_table, i, section_l2, -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE ,0 ); section_l1t0 +=BLOCK_SIZE_L1 ; section_l1t1 +=BLOCK_SIZE_L1 ; section_l2 +=BLOCK_SIZE_L2 ;
@@ -108,13 +108,13 @@ static inline void early_mmu_setup(void)set_pgtable_section (level2_table,CONFIG_SYS_FSL_OCRAM_BASE >>SECTION_SHIFT_L2 ,CONFIG_SYS_FSL_OCRAM_BASE , -MT_NORMAL ); +MT_NORMAL ,0 );for (i =CONFIG_SYS_IFC_BASE >>SECTION_SHIFT_L2 ; i < (CONFIG_SYS_IFC_BASE +CONFIG_SYS_IFC_SIZE ) >>SECTION_SHIFT_L2 ; i++) { section_l2 = i <<SECTION_SHIFT_L2 ;set_pgtable_section (level2_table, i, - section_l2,MT_NORMAL ); + section_l2,MT_NORMAL ,0 ); } el =current_el ();
@@ -154,11 +154,11 @@ static inline void final_mmu_setup(void) section_l2 =0 ;for (i =0 ; i <512 ; i++) {set_pgtable_section (level1_table_0, i, section_l1t0, -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE ,0 );set_pgtable_section (level1_table_1, i, section_l1t1, -MT_NORMAL ); +MT_NORMAL ,0 );set_pgtable_section (level2_table_0, i, section_l2, -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE ,0 ); section_l1t0 +=BLOCK_SIZE_L1 ; section_l1t1 +=BLOCK_SIZE_L1 ; section_l2 +=BLOCK_SIZE_L2 ;
@@ -177,7 +177,7 @@ static inline void final_mmu_setup(void)set_pgtable_section (level2_table_0,CONFIG_SYS_FSL_OCRAM_BASE >>SECTION_SHIFT_L2 ,CONFIG_SYS_FSL_OCRAM_BASE , -MT_NORMAL ); +MT_NORMAL ,0 );/* * Fill in other part of tables if cache is needed
@@ -190,7 +190,7 @@ static inline void final_mmu_setup(void) section_l2 = section_base;for (i =0 ; i <512 ; i++) {set_pgtable_section (level2_table_1, i, section_l2, -MT_DEVICE_NGNRNE ); +MT_DEVICE_NGNRNE ,0 ); section_l2 +=BLOCK_SIZE_L2 ; } tbl_base =FINAL_QBMAN_CACHED_MEM & (BLOCK_SIZE_L1 -1 );
@@ -200,7 +200,7 @@ static inline void final_mmu_setup(void) i < tbl_limit >> SECTION_SHIFT_L2; i++) { section_l2 = section_base + (i <<SECTION_SHIFT_L2 );set_pgtable_section (level2_table_1, i, - section_l2,MT_NORMAL ); + section_l2,MT_NORMAL ,0 ); }/* flush new MMU table */
arch/arm/include/asm/armv8/mmu.h +38 -33
96 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 1/1 ARMv8: bug fix of mmu setup and code optimization
Hello fenghua at phytium.com.cn,
Quoted 12 lines · fenghua at phytium.com.cn
From: David Feng <[email protected]>
1. Fix a bug of
mmu_setupthat variable i and j should be type long instead of int.
2. Givemmu_setupweak attribute so that other implementation can redfine it.
3. A more commonset_pgtable_section().
4. Give device memory PXN and UXN attribute. CPU may speculatively prefetch instructions from device memory, but the IO subsystem of some implementation may not support this operation. The two attributes prevent this behavior.
Quoted 6 lines
Signed-off-by David Feng <[email protected]>--- arch/arm/cpu/armv8/cache_v8.c | 73 +++++++++++++++++++++++------------- arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 22 +++++------ arch/arm/include/asm/armv8/mmu.h | 71 +++++++++++++++++++---------------- 3 files changed, 95 insertions(+), 71 deletions(-)
This patch does not apply on current ARM tree; at least part of it must be rewritten.
Amicalement,
Signature · 1 line
Albert.