diff options
author | York Sun <york.sun@nxp.com> | 2017-03-06 09:02:34 -0800 |
---|---|---|
committer | York Sun <york.sun@nxp.com> | 2017-03-14 08:44:03 -0700 |
commit | 4961eafc25d0bfa7ac5f88ec78a7f7501c202fbb (patch) | |
tree | f1e66358f067240368b3b3b70514f7b8b3c49dc5 /arch | |
parent | 7f9b9f318ff152bd8d2e8b573708e2bdc088c1b1 (diff) |
armv8: layerscape: Update early MMU for DDR after initialization
In early MMU table, DDR has to be mapped as device memory to avoid
speculative access. After DDR is initialized, it needs to be updated
to normal memory to allow code execution. To simplify the code,
dram_init() is moved into a common file as a weak function.
Signed-off-by: York Sun <york.sun@nxp.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 76 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-fsl-layerscape/cpu.h | 12 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-fsl-layerscape/mmu.h | 2 |
3 files changed, 87 insertions, 3 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index d82f6d1b82..7e66ee08b5 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -753,3 +753,79 @@ void efi_add_known_memory(void) } } #endif + +/* + * Before DDR size is known, early MMU table have DDR mapped as device memory + * to avoid speculative access. To relocate U-Boot to DDR, "normal memory" + * needs to be set for these mappings. + * If a special case configures DDR with holes in the mapping, the holes need + * to be marked as invalid. This is not implemented in this function. + */ +void update_early_mmu_table(void) +{ + if (!gd->arch.tlb_addr) + return; + + if (gd->ram_size <= CONFIG_SYS_FSL_DRAM_SIZE1) { + mmu_change_region_attr( + CONFIG_SYS_SDRAM_BASE, + gd->ram_size, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | + PTE_BLOCK_NS | + PTE_TYPE_VALID); + } else { + mmu_change_region_attr( + CONFIG_SYS_SDRAM_BASE, + CONFIG_SYS_DDR_BLOCK1_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | + PTE_BLOCK_NS | + PTE_TYPE_VALID); +#ifdef CONFIG_SYS_DDR_BLOCK3_BASE +#ifndef CONFIG_SYS_DDR_BLOCK2_SIZE +#error "Missing CONFIG_SYS_DDR_BLOCK2_SIZE" +#endif + if (gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE > + CONFIG_SYS_DDR_BLOCK2_SIZE) { + mmu_change_region_attr( + CONFIG_SYS_DDR_BLOCK2_BASE, + CONFIG_SYS_DDR_BLOCK2_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | + PTE_BLOCK_NS | + PTE_TYPE_VALID); + mmu_change_region_attr( + CONFIG_SYS_DDR_BLOCK3_BASE, + gd->ram_size - + CONFIG_SYS_DDR_BLOCK1_SIZE - + CONFIG_SYS_DDR_BLOCK2_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | + PTE_BLOCK_NS | + PTE_TYPE_VALID); + } else +#endif + { + mmu_change_region_attr( + CONFIG_SYS_DDR_BLOCK2_BASE, + gd->ram_size - + CONFIG_SYS_DDR_BLOCK1_SIZE, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE | + PTE_BLOCK_NS | + PTE_TYPE_VALID); + } + } +} + +__weak int dram_init(void) +{ + gd->ram_size = initdram(0); +#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) + /* This will break-before-make MMU for DDR */ + update_early_mmu_table(); +#endif + + return 0; +} diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index 4ea4aeaf4c..bcf3e3863e 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -115,7 +115,11 @@ static struct mm_region early_map[] = { }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_SIZE1, +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) PTE_BLOCK_MEMTYPE(MT_NORMAL) | +#else /* Start with nGnRnE and PXN and UXN to prevent speculative access */ + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN | +#endif PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, /* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */ @@ -130,7 +134,7 @@ static struct mm_region early_map[] = { }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_SIZE2, - PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, #elif defined(CONFIG_FSL_LSCH2) @@ -158,12 +162,16 @@ static struct mm_region early_map[] = { }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_SIZE1, +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) PTE_BLOCK_MEMTYPE(MT_NORMAL) | +#else /* Start with nGnRnE and PXN and UXN to prevent speculative access */ + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN | +#endif PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_SIZE2, - PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, #endif diff --git a/arch/arm/include/asm/arch-fsl-layerscape/mmu.h b/arch/arm/include/asm/arch-fsl-layerscape/mmu.h index d54eacd4a0..d232bec1e4 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/mmu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/mmu.h @@ -6,5 +6,5 @@ #ifndef _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_ #define _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_ -#include <asm/arch-armv8/mmu.h> +void update_early_mmu_table(void); #endif /* _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_ */ |