Message ID | 1613874427-17961-1-git-send-email-ye.li@nxp.com |
---|---|
State | Changes Requested |
Delegated to: | Stefano Babic |
Headers | show |
Series | arm: mach-imx: Fix speculative instruction prefetch issue | expand |
Hi Ye, this patch is quite old and it looks like it was forgotten - I apply it and runs CI, but it breaks most arm board. So I have to drop it. Best regards, Stefano Babic On 21.02.21 03:27, Ye Li wrote: > Default ARM32 MMU setting in u-boot sets XN bit to entire 4GB space no > matter which DCACHE option is used, and set domain permission to manager. > This causes MMU ignores the access check and XN bit, so speculative > instruction can fetch from entire space. > > This patch sets the DDR, ROM, OCRAM without XN bit, and set domain to client > to enable the XN and access check. So speculative instruction fetch can only > happens on these 3 regions to avoid prefetch from peripherals and invalid > regions. > > Signed-off-by: Ye Li <ye.li@nxp.com> > Reviewed-by: Peng Fan <peng.fan@nxp.com> > --- > arch/arm/mach-imx/cache.c | 49 ++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 42 insertions(+), 7 deletions(-) > > diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c > index 4e3b49a..8486c2d 100644 > --- a/arch/arm/mach-imx/cache.c > +++ b/arch/arm/mach-imx/cache.c > @@ -10,6 +10,10 @@ > #include <asm/pl310.h> > #include <asm/io.h> > #include <asm/mach-imx/sys_proto.h> > +#include <asm/global_data.h> > +#include <log.h> > + > +DECLARE_GLOBAL_DATA_PTR; > > static void enable_ca7_smp(void) > { > @@ -40,13 +44,13 @@ static void enable_ca7_smp(void) > } > > #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) > + > +#define ARMV7_DOMAIN_CLIENT 1 > +#define ARMV7_DOMAIN_MASK (0x3 << 0) > +#define IMX_ARMV7_DCACHE_OPTION (DCACHE_DEFAULT_OPTION & ~TTB_SECT_XN_MASK) > + > void enable_caches(void) > { > -#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) > - enum dcache_option option = DCACHE_WRITETHROUGH; > -#else > - enum dcache_option option = DCACHE_WRITEBACK; > -#endif > /* Avoid random hang when download by usb */ > invalidate_dcache_all(); > > @@ -59,11 +63,42 @@ void enable_caches(void) > /* Enable caching on OCRAM and ROM */ > mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, > ROMCP_ARB_END_ADDR, > - option); > + IMX_ARMV7_DCACHE_OPTION); > mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, > IRAM_SIZE, > - option); > + IMX_ARMV7_DCACHE_OPTION); > +} > + > +void dram_bank_mmu_setup(int bank) > +{ > + struct bd_info *bd = gd->bd; > + int i; > + > + /* bd->bi_dram is available only after relocation */ > + if ((gd->flags & GD_FLG_RELOC) == 0) > + return; > + > + debug("%s: bank: %d\n", __func__, bank); > + for (i = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT; > + i < (bd->bi_dram[bank].start >> MMU_SECTION_SHIFT) + > + (bd->bi_dram[bank].size >> MMU_SECTION_SHIFT); > + i++) > + set_section_dcache(i, IMX_ARMV7_DCACHE_OPTION); > } > + > +void arm_init_domains(void) > +{ > + u32 reg; > + > + reg = get_dacr(); > + /* > + * Set domain to client to do access and XN check > + */ > + reg &= ~ARMV7_DOMAIN_MASK; > + reg |= ARMV7_DOMAIN_CLIENT; > + set_dacr(reg); > +} > + > #else > void enable_caches(void) > { >
diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c index 4e3b49a..8486c2d 100644 --- a/arch/arm/mach-imx/cache.c +++ b/arch/arm/mach-imx/cache.c @@ -10,6 +10,10 @@ #include <asm/pl310.h> #include <asm/io.h> #include <asm/mach-imx/sys_proto.h> +#include <asm/global_data.h> +#include <log.h> + +DECLARE_GLOBAL_DATA_PTR; static void enable_ca7_smp(void) { @@ -40,13 +44,13 @@ static void enable_ca7_smp(void) } #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) + +#define ARMV7_DOMAIN_CLIENT 1 +#define ARMV7_DOMAIN_MASK (0x3 << 0) +#define IMX_ARMV7_DCACHE_OPTION (DCACHE_DEFAULT_OPTION & ~TTB_SECT_XN_MASK) + void enable_caches(void) { -#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) - enum dcache_option option = DCACHE_WRITETHROUGH; -#else - enum dcache_option option = DCACHE_WRITEBACK; -#endif /* Avoid random hang when download by usb */ invalidate_dcache_all(); @@ -59,11 +63,42 @@ void enable_caches(void) /* Enable caching on OCRAM and ROM */ mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, ROMCP_ARB_END_ADDR, - option); + IMX_ARMV7_DCACHE_OPTION); mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, IRAM_SIZE, - option); + IMX_ARMV7_DCACHE_OPTION); +} + +void dram_bank_mmu_setup(int bank) +{ + struct bd_info *bd = gd->bd; + int i; + + /* bd->bi_dram is available only after relocation */ + if ((gd->flags & GD_FLG_RELOC) == 0) + return; + + debug("%s: bank: %d\n", __func__, bank); + for (i = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT; + i < (bd->bi_dram[bank].start >> MMU_SECTION_SHIFT) + + (bd->bi_dram[bank].size >> MMU_SECTION_SHIFT); + i++) + set_section_dcache(i, IMX_ARMV7_DCACHE_OPTION); } + +void arm_init_domains(void) +{ + u32 reg; + + reg = get_dacr(); + /* + * Set domain to client to do access and XN check + */ + reg &= ~ARMV7_DOMAIN_MASK; + reg |= ARMV7_DOMAIN_CLIENT; + set_dacr(reg); +} + #else void enable_caches(void) {