diff --git a/arch/arm/cpu/armv7m/cpu.c b/arch/arm/cpu/armv7m/cpu.c index b4440d3f3f8..bea0e1d3263 100644 --- a/arch/arm/cpu/armv7m/cpu.c +++ b/arch/arm/cpu/armv7m/cpu.c @@ -57,7 +57,7 @@ void reset_cpu(void) | V7M_AIRCR_SYSRESET, &V7M_SCB->aircr); } -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_arch_fixups(struct spl_image_info *spl_image) { spl_image->entry_point |= 0x1; } diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index a7899857658..672ec16d483 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -58,6 +58,60 @@ static int get_effective_el(void) return el; } +int mem_map_from_dram_banks(unsigned int index, unsigned int len, u64 attrs) +{ + unsigned int i; + int ret = fdtdec_setup_memory_banksize(); + + if (ret) { + log_err("%s: Failed to setup dram banks\n", __func__); + return ret; + } + + if (index + CONFIG_NR_DRAM_BANKS >= len) { + log_err("%s: Provided mem_map array has insufficient size for DRAM entries\n", + __func__); + return -ENOMEM; + } + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + mem_map[index].virt = gd->bd->bi_dram[i].start; + mem_map[index].phys = gd->bd->bi_dram[i].start; + mem_map[index].size = gd->bd->bi_dram[i].size; + mem_map[index].attrs = attrs; + index++; + } + + memset(&mem_map[index], 0, sizeof(mem_map[index])); + + return 0; +} + +int mmu_unmap_reserved_mem(const char *name, bool check_nomap) +{ + void *fdt = (void *)gd->fdt_blob; + char node_path[128]; + fdt_addr_t addr; + fdt_size_t size; + int ret; + + snprintf(node_path, sizeof(node_path), "/reserved-memory/%s", name); + ret = fdt_path_offset(fdt, node_path); + if (ret < 0) + return ret; + + if (check_nomap && !fdtdec_get_bool(fdt, ret, "no-map")) + return -EINVAL; + + addr = fdtdec_get_addr_size(fdt, ret, "reg", &size); + if (addr == FDT_ADDR_T_NONE) + return -1; + + mmu_change_region_attr_nobreak(addr, size, PTE_TYPE_FAULT); + + return 0; +} + u64 get_tcr(u64 *pips, u64 *pva_bits) { int el = get_effective_el(); @@ -830,16 +884,15 @@ void flush_dcache_range(unsigned long start, unsigned long stop) void dcache_enable(void) { /* The data cache is not active unless the mmu is enabled */ - if (!(get_sctlr() & CR_M)) { - invalidate_dcache_all(); - __asm_invalidate_tlb_all(); + if (!mmu_status()) mmu_setup(); - } /* Set up page tables only once (it is done also by mmu_setup()) */ if (!gd->arch.tlb_fillptr) setup_all_pgtables(); + invalidate_dcache_all(); + __asm_invalidate_tlb_all(); set_sctlr(get_sctlr() | CR_C); } diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 6af8cd111a4..8aa5f9721c4 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -194,9 +194,34 @@ struct mm_region { u64 attrs; }; +/* Used as the memory map for MMU configuration by mmu_setup */ extern struct mm_region *mem_map; void setup_pgtables(void); + +/** + * mem_map_from_dram_banks() - Populate mem_map with entries corresponding to + * dram banks as per the gd. This should be called prior to mmu_setup. + * + * @index: The entry in mem_map to start the over-write + * @len: The size of mem_map + */ +int mem_map_from_dram_banks(unsigned int index, unsigned int len, u64 attrs); + +/** + * mmu_unmap_reserved_mem() - Unmaps a reserved-memory node as PTE_TYPE_FAULT + * once MMU is configured by mmu_setup. + * + * @name: The name of the node under "/reserved-memory/" path + * @check_nomap: Check if the node is marked "no-map" before unmapping it + */ +int mmu_unmap_reserved_mem(const char *name, bool check_nomap); + u64 get_tcr(u64 *pips, u64 *pva_bits); + +/** + * mmu_setup() - Sets up the mmu page tables as per mem_map + */ +void mmu_setup(void); #endif #endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm/mach-k3/arm64/arm64-mmu.c b/arch/arm/mach-k3/arm64/arm64-mmu.c index 0e07b1b7ce0..f999af143fb 100644 --- a/arch/arm/mach-k3/arm64/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64/arm64-mmu.c @@ -11,44 +11,38 @@ #include #include +#include +#include -struct mm_region k3_mem_map[] = { - { +struct mm_region k3_mem_map[K3_MEM_MAP_LEN] = { + { /* SoC Peripherals */ .virt = 0x0UL, .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - .virt = 0x80000000UL, - .phys = 0x80000000UL, - .size = 0x1e780000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0xa0000000UL, - .phys = 0xa0000000UL, - .size = 0x60000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0x880000000UL, - .phys = 0x880000000UL, - .size = 0x80000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { + }, { /* Flash Peripherals */ .virt = 0x500000000UL, .phys = 0x500000000UL, .size = 0x380000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ + }, [K3_MEM_MAP_FIRST_BANK_IDX] = { /* First DRAM Bank of size 2G */ + .virt = CFG_SYS_SDRAM_BASE, + .phys = CFG_SYS_SDRAM_BASE, + .size = SZ_2G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { /* List terminator */ 0, } }; struct mm_region *mem_map = k3_mem_map; + +u64 get_page_table_size(void) +{ + return SZ_128K; +} diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 5483ac9906c..7c06764af82 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 #define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002 @@ -258,6 +261,47 @@ void board_prep_linux(struct bootm_headers *images) ROUND(images->os.end, CONFIG_SYS_CACHELINE_SIZE)); } + +void enable_caches(void) +{ + void *fdt = (void *)gd->fdt_blob; + int ret; + + ret = mem_map_from_dram_banks(K3_MEM_MAP_FIRST_BANK_IDX, K3_MEM_MAP_LEN, + PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE); + if (ret) + debug("%s: Failed to setup dram banks\n", __func__); + + mmu_setup(); + + if (CONFIG_K3_ATF_LOAD_ADDR >= CFG_SYS_SDRAM_BASE) { + ret = fdt_fixup_reserved(fdt, "tfa", CONFIG_K3_ATF_LOAD_ADDR, + 0x80000); + if (ret) + printf("%s: Failed to perform tfa fixups (%s)\n", + __func__, fdt_strerror(ret)); + ret = mmu_unmap_reserved_mem("tfa", true); + if (ret) + printf("%s: Failed to unmap tfa reserved mem (%d)\n", + __func__, ret); + } + + if (CONFIG_K3_OPTEE_LOAD_ADDR >= CFG_SYS_SDRAM_BASE) { + ret = fdt_fixup_reserved(fdt, "optee", + CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); + if (ret) + printf("%s: Failed to perform optee fixups (%s)\n", + __func__, fdt_strerror(ret)); + ret = mmu_unmap_reserved_mem("optee", true); + if (ret) + printf("%s: Failed to unmap optee reserved mem (%d)\n", + __func__, ret); + } + + icache_enable(); + dcache_enable(); +} #endif void spl_enable_cache(void) @@ -303,6 +347,17 @@ static __maybe_unused void k3_dma_remove(void) pr_warn("DMA Device not found (err=%d)\n", rc); } +void spl_perform_arch_fixups(struct spl_image_info *spl_image) +{ + void *fdt = spl_image_fdt_addr(spl_image); + + if (!fdt) + return; + + fdt_fixup_reserved(fdt, "tfa", CONFIG_K3_ATF_LOAD_ADDR, 0x80000); + fdt_fixup_reserved(fdt, "optee", CONFIG_K3_OPTEE_LOAD_ADDR, 0x1800000); +} + void spl_board_prepare_for_boot(void) { #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) diff --git a/arch/arm/mach-k3/include/mach/k3-ddr.h b/arch/arm/mach-k3/include/mach/k3-ddr.h index 39e6725bb9b..207e60b2763 100644 --- a/arch/arm/mach-k3/include/mach/k3-ddr.h +++ b/arch/arm/mach-k3/include/mach/k3-ddr.h @@ -8,6 +8,12 @@ #include +/* We need 3 extra entries for: + * SoC peripherals, flash and the sentinel value. + */ +#define K3_MEM_MAP_LEN ((CONFIG_NR_DRAM_BANKS) + 3) +#define K3_MEM_MAP_FIRST_BANK_IDX 2 + int dram_init(void); int dram_init_banksize(void); diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c index 1bfd120adc4..561bddd12a6 100644 --- a/arch/arm/mach-rockchip/spl-boot-order.c +++ b/arch/arm/mach-rockchip/spl-boot-order.c @@ -240,7 +240,7 @@ int spl_decode_boot_device(u32 boot_device, char *buf, size_t buflen) #endif } -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_arch_fixups(struct spl_image_info *spl_image) { const char *bootrom_ofpath = board_spl_was_booted_from(); void *blob = spl_image_fdt_addr(spl_image); diff --git a/arch/arm/mach-socfpga/spl_soc64.c b/arch/arm/mach-socfpga/spl_soc64.c index 651d9fc9cb8..fa7b1506ce6 100644 --- a/arch/arm/mach-socfpga/spl_soc64.c +++ b/arch/arm/mach-socfpga/spl_soc64.c @@ -130,7 +130,7 @@ u32 spl_boot_mode(const u32 boot_device) #endif /* board specific function prior loading SSBL / U-Boot */ -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_arch_fixups(struct spl_image_info *spl_image) { int ret; struct udevice *dev; diff --git a/board/beagle/beagley-ai/beagley-ai.c b/board/beagle/beagley-ai/beagley-ai.c index 26fa54e27bb..500cc3060c3 100644 --- a/board/beagle/beagley-ai/beagley-ai.c +++ b/board/beagle/beagley-ai/beagley-ai.c @@ -32,7 +32,7 @@ int dram_init_banksize(void) } #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index bd9326d6b1b..d98b2c6e809 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -776,7 +776,7 @@ int ft_board_setup(void *blob, struct bd_info *bd) #endif #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { dh_stm32_ks8851_fixup(spl_image_fdt_addr(spl_image)); } diff --git a/board/phytec/phycore_am62x/phycore-am62x.c b/board/phytec/phycore_am62x/phycore-am62x.c index 51da864aa80..3cdcbf2ecc9 100644 --- a/board/phytec/phycore_am62x/phycore-am62x.c +++ b/board/phytec/phycore_am62x/phycore-am62x.c @@ -199,7 +199,7 @@ int do_board_detect(void) #endif #if IS_ENABLED(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS) && IS_ENABLED(CONFIG_K3_INLINE_ECC)) fixup_ddr_driver_for_ecc(spl_image); diff --git a/board/phytec/phycore_am64x/phycore-am64x.c b/board/phytec/phycore_am64x/phycore-am64x.c index 33c39376ceb..114aa217023 100644 --- a/board/phytec/phycore_am64x/phycore-am64x.c +++ b/board/phytec/phycore_am64x/phycore-am64x.c @@ -118,7 +118,7 @@ int do_board_detect(void) #endif #if IS_ENABLED(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS) && IS_ENABLED(CONFIG_K3_INLINE_ECC)) fixup_ddr_driver_for_ecc(spl_image); diff --git a/board/renesas/sparrowhawk/sparrowhawk.c b/board/renesas/sparrowhawk/sparrowhawk.c index a4eda852743..f5b1a5614b1 100644 --- a/board/renesas/sparrowhawk/sparrowhawk.c +++ b/board/renesas/sparrowhawk/sparrowhawk.c @@ -134,7 +134,7 @@ unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) return CONFIG_SYS_SPI_U_BOOT_OFFS; } -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { void *blob = spl_image_fdt_addr(spl_image); int err, offs; diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c index 420a8cf8d91..48b034af305 100644 --- a/board/starfive/visionfive2/spl.c +++ b/board/starfive/visionfive2/spl.c @@ -20,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; #define JH7110_CLK_CPU_ROOT_SHIFT 24 #define JH7110_CLK_CPU_ROOT_MASK GENMASK(29, 24) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { /* Update the memory size which read from eeprom or DT */ if (spl_image->fdt_addr) diff --git a/board/ti/am62ax/evm.c b/board/ti/am62ax/evm.c index a445f983255..da6c31176cd 100644 --- a/board/ti/am62ax/evm.c +++ b/board/ti/am62ax/evm.c @@ -17,7 +17,7 @@ #include "../common/fdt_ops.h" #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/am62dx/evm.c b/board/ti/am62dx/evm.c index 1d8216128c9..0924954c738 100644 --- a/board/ti/am62dx/evm.c +++ b/board/ti/am62dx/evm.c @@ -17,7 +17,7 @@ #include "../common/fdt_ops.h" #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/am62px/evm.c b/board/ti/am62px/evm.c index c06e3878d67..85c332b9339 100644 --- a/board/ti/am62px/evm.c +++ b/board/ti/am62px/evm.c @@ -50,7 +50,7 @@ void spl_board_init(void) #endif #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index d7b07a0d34d..c2c7a0216b9 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -91,7 +91,7 @@ void spl_board_init(void) } -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/am64x/evm.c b/board/ti/am64x/evm.c index 8e89b3b15df..f9bb593e4c6 100644 --- a/board/ti/am64x/evm.c +++ b/board/ti/am64x/evm.c @@ -98,7 +98,7 @@ static int fixup_usb_boot(const void *fdt_blob) } #endif -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c index 1527eaf1e16..e030fe7dc87 100644 --- a/board/ti/j721e/evm.c +++ b/board/ti/j721e/evm.c @@ -127,7 +127,7 @@ static void __maybe_unused detect_enable_hyperflash(void *blob) #if defined(CONFIG_XPL_BUILD) && (defined(CONFIG_TARGET_J7200_A72_EVM) || defined(CONFIG_TARGET_J7200_R5_EVM) || \ defined(CONFIG_TARGET_J721E_A72_EVM) || defined(CONFIG_TARGET_J721E_R5_EVM)) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { detect_enable_hyperflash(spl_image->fdt_addr); } diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 5d3b84607d8..b6d1964146d 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -40,7 +40,7 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) } #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/j722s/evm.c b/board/ti/j722s/evm.c index 32d767cb7d2..1173adc072b 100644 --- a/board/ti/j722s/evm.c +++ b/board/ti/j722s/evm.c @@ -24,7 +24,7 @@ void spl_board_init(void) #endif #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/board/ti/j784s4/evm.c b/board/ti/j784s4/evm.c index 6335676081a..cabb3017ee1 100644 --- a/board/ti/j784s4/evm.c +++ b/board/ti/j784s4/evm.c @@ -42,7 +42,7 @@ struct efi_capsule_update_info update_info = { }; #if defined(CONFIG_XPL_BUILD) -void spl_perform_fixups(struct spl_image_info *spl_image) +void spl_perform_board_fixups(struct spl_image_info *spl_image) { if (IS_ENABLED(CONFIG_K3_DDRSS)) { if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) diff --git a/common/spl/spl.c b/common/spl/spl.c index 8c20b75b178..64313cb8dfe 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -120,8 +120,13 @@ int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool for } #endif -/* Weak default function for arch/board-specific fixups to the spl_image_info */ -void __weak spl_perform_fixups(struct spl_image_info *spl_image) +/* Weak default function for arch specific fixups to the spl_image_info */ +void __weak spl_perform_arch_fixups(struct spl_image_info *spl_image) +{ +} + +/* Weak default function for board specific fixups to the spl_image_info */ +void __weak spl_perform_board_fixups(struct spl_image_info *spl_image) { } @@ -776,7 +781,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2) hang(); } - spl_perform_fixups(&spl_image); + spl_perform_arch_fixups(&spl_image); + spl_perform_board_fixups(&spl_image); os = spl_image.os; if (os == IH_OS_U_BOOT) { diff --git a/include/spl.h b/include/spl.h index 7c10c7f792e..cf45d411ecb 100644 --- a/include/spl.h +++ b/include/spl.h @@ -1116,10 +1116,16 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, ulong board_spl_fit_size_align(ulong size); /** - * spl_perform_fixups() - arch/board-specific callback before processing - * the boot-payload + * spl_perform_arch_fixups() - arch specific callback before processing the + * boot-payload */ -void spl_perform_fixups(struct spl_image_info *spl_image); +void spl_perform_arch_fixups(struct spl_image_info *spl_image); + +/** + * spl_perform_board_fixups() - board specific callback before processing the + * boot-payload + */ +void spl_perform_board_fixups(struct spl_image_info *spl_image); /* * spl_get_load_buffer() - get buffer for loading partial image data