Message ID | 20220817090611.3292993-4-pro@denx.de |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | ARM: imx6: dh-imx6: Enable d-cache early in SPL | expand |
On 8/17/22 11:06, Philip Oberfichtner wrote: [...] > +void spl_board_prepare_for_boot(void) > +{ > + /* > + * Flush dcache. The dcache_disable() does not do any cache flushing, it just disables the Dcache enable C-bit. > Without it U-Boot proper would hang at random locations. Presumably this is > + * due to dirty cache lines remaining after SPL passes control. When U-Boot proper later on > + * calls invalidate_dcache_all(), those dirty cache lines will get lost. > + */ What about falcon boot mode starting Linux from SPL, could it fail the same way ? > + dcache_disable(); > +} [...]
Hi, thanks for the feedback. On Wed, 2022-08-17 at 11:24 +0200, Marek Vasut wrote: > On 8/17/22 11:06, Philip Oberfichtner wrote: > > [...] > > > +void spl_board_prepare_for_boot(void) > > +{ > > + /* > > + * Flush dcache. > > The dcache_disable() does not do any cache flushing, it just disables > the Dcache enable C-bit. See the following objdump jumping to flush_dcache_all(). The implementation of dcache_disable() is in arch/arm/lib/cache-cp15.c. $ ${CROSS_COMPILE}objdump spl/u-boot-spl --disassemble=dcache_disable spl/u-boot-spl: file format elf32-littlearm Disassembly of section .text: 0090b498 <dcache_disable>: 90b498: b510 push {r4, lr} 90b49a: ee11 3f10 mrc 15, 0, r3, cr1, cr0, {0} 90b49e: 075b lsls r3, r3, #29 90b4a0: d509 bpl.n 90b4b6 <dcache_disable+0x1e> 90b4a2: ee11 4f10 mrc 15, 0, r4, cr1, cr0, {0} 90b4a6: f7ff fbfb bl 90aca0 <flush_dcache_all> 90b4aa: f024 0405 bic.w r4, r4, #5 90b4ae: ee01 4f10 mcr 15, 0, r4, cr1, cr0, {0} 90b4b2: f3bf 8f6f isb sy 90b4b6: bd10 pop {r4, pc} $ I'll add a note to the comment about flush_dcache_all() being called. > > > Without it U-Boot proper would hang at random locations. Presumably > > this is > > + * due to dirty cache lines remaining after SPL passes > > control. When U-Boot proper later on > > + * calls invalidate_dcache_all(), those dirty cache lines > > will get lost. > > + */ > > What about falcon boot mode starting Linux from SPL, could it fail > the > same way ? Yes, assuming my dirty-cache-line hypothesis is correct. I'll generalize the comment in V5. > > > + dcache_disable(); > > +} > > [...]
On 8/17/22 12:19, Philip Oberfichtner wrote: > Hi, > > thanks for the feedback. > > On Wed, 2022-08-17 at 11:24 +0200, Marek Vasut wrote: >> On 8/17/22 11:06, Philip Oberfichtner wrote: >> >> [...] >> >>> +void spl_board_prepare_for_boot(void) >>> +{ >>> + /* >>> + * Flush dcache. >> >> The dcache_disable() does not do any cache flushing, it just disables >> the Dcache enable C-bit. > > See the following objdump jumping to flush_dcache_all(). The > implementation of dcache_disable() is in arch/arm/lib/cache-cp15.c. > > $ ${CROSS_COMPILE}objdump spl/u-boot-spl --disassemble=dcache_disable > > spl/u-boot-spl: file format elf32-littlearm > > > Disassembly of section .text: > > 0090b498 <dcache_disable>: > 90b498: b510 push {r4, lr} > 90b49a: ee11 3f10 mrc 15, 0, r3, cr1, cr0, {0} > 90b49e: 075b lsls r3, r3, #29 > 90b4a0: d509 bpl.n 90b4b6 <dcache_disable+0x1e> > 90b4a2: ee11 4f10 mrc 15, 0, r4, cr1, cr0, {0} > 90b4a6: f7ff fbfb bl 90aca0 <flush_dcache_all> > 90b4aa: f024 0405 bic.w r4, r4, #5 > 90b4ae: ee01 4f10 mcr 15, 0, r4, cr1, cr0, {0} > 90b4b2: f3bf 8f6f isb sy > 90b4b6: bd10 pop {r4, pc} > $ > > I'll add a note to the comment about flush_dcache_all() being called. Doh, now I see it in there too, among the wall of ifdeffery in cache_disable() . Thanks [...]
diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..580b98811c 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <cpu_func.h> #include <init.h> #include <asm/arch/clock.h> #include <asm/arch/crm_regs.h> @@ -14,11 +15,13 @@ #include <asm/arch/mx6-ddr.h> #include <asm/arch/mx6-pins.h> #include <asm/arch/sys_proto.h> +#include <asm/cache.h> #include <asm/gpio.h> #include <asm/mach-imx/boot_mode.h> #include <asm/mach-imx/iomux-v3.h> #include <asm/mach-imx/mxc_i2c.h> #include <asm/io.h> +#include <asm/system.h> #include <errno.h> #include <fuse.h> #include <fsl_esdhc_imx.h> @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,24 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* + * Flush dcache. Without it U-Boot proper would hang at random locations. Presumably this is + * due to dirty cache lines remaining after SPL passes control. When U-Boot proper later on + * calls invalidate_dcache_all(), those dirty cache lines will get lost. + */ + dcache_disable(); +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 051816f719..1be6ae62ce 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x17800000 CONFIG_SYS_MALLOC_F_LEN=0x1000