[U-Boot] [PATCH V2 1/4] ARM: tegra: ensure nvtboot_boot_x0 alignment

From: Stephen Warren swarren@nvidia.com
nvtboot_boot_x0 is a 64-bit variable and hence must be 64-bit aligned. So far this has happened by accident! Fix the code so this is guaranteed.
This fixes the following build error: ... relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `nvtboot_boot_x0' ...
Signed-off-by: Stephen Warren swarren@nvidia.com --- v2: New patch. --- arch/arm/mach-tegra/tegra186/nvtboot_ll.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_ll.S b/arch/arm/mach-tegra/tegra186/nvtboot_ll.S index 1eab890958c7..899c9cccbe84 100644 --- a/arch/arm/mach-tegra/tegra186/nvtboot_ll.S +++ b/arch/arm/mach-tegra/tegra186/nvtboot_ll.S @@ -9,6 +9,7 @@ #include <config.h> #include <linux/linkage.h>
+.align 8 .globl nvtboot_boot_x0 nvtboot_boot_x0: .dword 0

From: Stephen Warren swarren@nvidia.com
When performing a cache disable function, code must not access DRAM. That is because when the cache is disabled, it will be bypassed and all loads and stores will be serviced by RAM. This prevents accessing any dirty data in the cache. In turn, this means the stack cannot be used, since that is in RAM. To guarantee that code doesn't use RAM (and in particular the stack) __asm_flush_l3_cache() must be manually implemented in assembly, rather than implemented in C since the compiler won't know not to touch RAM.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v2: New patch. --- arch/arm/mach-tegra/tegra186/cache.S | 25 +++++++++++++++++++++++++ arch/arm/mach-tegra/tegra186/cache.c | 23 ----------------------- 2 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 arch/arm/mach-tegra/tegra186/cache.S delete mode 100644 arch/arm/mach-tegra/tegra186/cache.c
diff --git a/arch/arm/mach-tegra/tegra186/cache.S b/arch/arm/mach-tegra/tegra186/cache.S new file mode 100644 index 000000000000..d876cd93b432 --- /dev/null +++ b/arch/arm/mach-tegra/tegra186/cache.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <config.h> +#include <linux/linkage.h> + +#define SMC_SIP_INVOKE_MCE 0x82FFFF00 +#define MCE_SMC_ROC_FLUSH_CACHE (SMC_SIP_INVOKE_MCE | 11) + +ENTRY(__asm_flush_l3_cache) + mov x0, #(MCE_SMC_ROC_FLUSH_CACHE & 0xffff) + movk x0, #(MCE_SMC_ROC_FLUSH_CACHE >> 16), lsl #16 + mov x1, #0 + mov x2, #0 + mov x3, #0 + mov x4, #0 + mov x5, #0 + mov x6, #0 + smc #0 + mov x0, #0 + ret +ENDPROC(__asm_flush_l3_cache) diff --git a/arch/arm/mach-tegra/tegra186/cache.c b/arch/arm/mach-tegra/tegra186/cache.c deleted file mode 100644 index adaed8968eb9..000000000000 --- a/arch/arm/mach-tegra/tegra186/cache.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016, NVIDIA CORPORATION. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include <common.h> -#include <asm/system.h> - -#define SMC_SIP_INVOKE_MCE 0x82FFFF00 -#define MCE_SMC_ROC_FLUSH_CACHE 11 - -int __asm_flush_l3_cache(void) -{ - struct pt_regs regs = {0}; - - isb(); - - regs.regs[0] = SMC_SIP_INVOKE_MCE | MCE_SMC_ROC_FLUSH_CACHE; - smc_call(®s); - - return 0; -}

From: Stephen Warren swarren@nvidia.com
SoC-specific logic may be required for all forms of cache-wide operations; invalidate and flush of both dcache and icache (note that only 3 of the 4 possible combinations make sense, since the icache never contains dirty lines). This patch adds an optional hook for all implemented cache-wide operations, and renames the one existing hook to better represent exactly which operation it is implementing. A dummy no-op implementation of each hook is provided.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v2: * Implement all dummy/weak functions in assembly, since some cache operations cannot access DRAM/stack. * Rename hook functions with __asm prefix etc. --- arch/arm/cpu/armv8/cache.S | 18 +++++++++++++++--- arch/arm/cpu/armv8/cache_v8.c | 8 +++++--- arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 4 ++-- arch/arm/include/asm/system.h | 4 +++- arch/arm/mach-tegra/tegra186/cache.S | 4 ++-- 5 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S index 46f25e63f01d..f1deaa723024 100644 --- a/arch/arm/cpu/armv8/cache.S +++ b/arch/arm/cpu/armv8/cache.S @@ -150,11 +150,23 @@ ENTRY(__asm_invalidate_icache_all) ret ENDPROC(__asm_invalidate_icache_all)
-ENTRY(__asm_flush_l3_cache) +ENTRY(__asm_invalidate_l3_dcache) mov x0, #0 /* return status as success */ ret -ENDPROC(__asm_flush_l3_cache) - .weak __asm_flush_l3_cache +ENDPROC(__asm_invalidate_l3_dcache) + .weak __asm_invalidate_l3_dcache + +ENTRY(__asm_flush_l3_dcache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(__asm_flush_l3_dcache) + .weak __asm_flush_l3_dcache + +ENTRY(__asm_invalidate_l3_icache) + mov x0, #0 /* return status as success */ + ret +ENDPROC(__asm_invalidate_l3_icache) + .weak __asm_invalidate_l3_icache
/* * void __asm_switch_ttbr(ulong new_ttbr) diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index cd3f6c10ae12..6c5630c0a84c 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -421,19 +421,20 @@ __weak void mmu_setup(void) void invalidate_dcache_all(void) { __asm_invalidate_dcache_all(); + __asm_invalidate_l3_dcache(); }
/* * Performs a clean & invalidation of the entire data cache at all levels. * This function needs to be inline to avoid using stack. - * __asm_flush_l3_cache return status of timeout + * __asm_flush_l3_dcache return status of timeout */ inline void flush_dcache_all(void) { int ret;
__asm_flush_dcache_all(); - ret = __asm_flush_l3_cache(); + ret = __asm_flush_l3_dcache(); if (ret) debug("flushing dcache returns 0x%x\n", ret); else @@ -623,7 +624,7 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
void icache_enable(void) { - __asm_invalidate_icache_all(); + invalidate_icache_all(); set_sctlr(get_sctlr() | CR_I); }
@@ -640,6 +641,7 @@ int icache_status(void) void invalidate_icache_all(void) { __asm_invalidate_icache_all(); + __asm_invalidate_l3_icache(); }
#else /* CONFIG_SYS_ICACHE_OFF */ diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index 5d0b7a45c354..5700b1fb6543 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -245,7 +245,7 @@ hnf_set_pstate:
ret
-ENTRY(__asm_flush_l3_cache) +ENTRY(__asm_flush_l3_dcache) /* * Return status in x0 * success 0 @@ -275,7 +275,7 @@ ENTRY(__asm_flush_l3_cache) mov x0, x8 mov lr, x29 ret -ENDPROC(__asm_flush_l3_cache) +ENDPROC(__asm_flush_l3_dcache) #endif
#ifdef CONFIG_MP diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index c18e1e3a10ee..5e9a9f850b65 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -93,7 +93,9 @@ void __asm_invalidate_dcache_all(void); void __asm_flush_dcache_range(u64 start, u64 end); void __asm_invalidate_tlb_all(void); void __asm_invalidate_icache_all(void); -int __asm_flush_l3_cache(void); +int __asm_invalidate_l3_dcache(void); +int __asm_flush_l3_dcache(void); +int __asm_invalidate_l3_icache(void); void __asm_switch_ttbr(u64 new_ttbr);
void armv8_switch_to_el2(void); diff --git a/arch/arm/mach-tegra/tegra186/cache.S b/arch/arm/mach-tegra/tegra186/cache.S index d876cd93b432..3ca3f3c8af68 100644 --- a/arch/arm/mach-tegra/tegra186/cache.S +++ b/arch/arm/mach-tegra/tegra186/cache.S @@ -10,7 +10,7 @@ #define SMC_SIP_INVOKE_MCE 0x82FFFF00 #define MCE_SMC_ROC_FLUSH_CACHE (SMC_SIP_INVOKE_MCE | 11)
-ENTRY(__asm_flush_l3_cache) +ENTRY(__asm_flush_l3_dcache) mov x0, #(MCE_SMC_ROC_FLUSH_CACHE & 0xffff) movk x0, #(MCE_SMC_ROC_FLUSH_CACHE >> 16), lsl #16 mov x1, #0 @@ -22,4 +22,4 @@ ENTRY(__asm_flush_l3_cache) smc #0 mov x0, #0 ret -ENDPROC(__asm_flush_l3_cache) +ENDPROC(__asm_flush_l3_dcache)

On 19 October 2016 at 15:18, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
SoC-specific logic may be required for all forms of cache-wide operations; invalidate and flush of both dcache and icache (note that only 3 of the 4 possible combinations make sense, since the icache never contains dirty lines). This patch adds an optional hook for all implemented cache-wide operations, and renames the one existing hook to better represent exactly which operation it is implementing. A dummy no-op implementation of each hook is provided.
Signed-off-by: Stephen Warren swarren@nvidia.com
v2:
- Implement all dummy/weak functions in assembly, since some cache operations cannot access DRAM/stack.
- Rename hook functions with __asm prefix etc.
arch/arm/cpu/armv8/cache.S | 18 +++++++++++++++--- arch/arm/cpu/armv8/cache_v8.c | 8 +++++--- arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 4 ++-- arch/arm/include/asm/system.h | 4 +++- arch/arm/mach-tegra/tegra186/cache.S | 4 ++-- 5 files changed, 27 insertions(+), 11 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Stephen Warren swarren@nvidia.com
An SMC call is required for all cache-wide operations on Tegra186. This patch implements the two missing hooks now that U-Boot supports them, and fixes the mapping of "hook name" to SMC call code.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v2: Implement the functions in assembly. --- arch/arm/mach-tegra/tegra186/cache.S | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-tegra/tegra186/cache.S b/arch/arm/mach-tegra/tegra186/cache.S index 3ca3f3c8af68..3061dc2ecff2 100644 --- a/arch/arm/mach-tegra/tegra186/cache.S +++ b/arch/arm/mach-tegra/tegra186/cache.S @@ -9,10 +9,10 @@
#define SMC_SIP_INVOKE_MCE 0x82FFFF00 #define MCE_SMC_ROC_FLUSH_CACHE (SMC_SIP_INVOKE_MCE | 11) +#define MCE_SMC_ROC_FLUSH_CACHE_ONLY (SMC_SIP_INVOKE_MCE | 14) +#define MCE_SMC_ROC_CLEAN_CACHE_ONLY (SMC_SIP_INVOKE_MCE | 15)
-ENTRY(__asm_flush_l3_dcache) - mov x0, #(MCE_SMC_ROC_FLUSH_CACHE & 0xffff) - movk x0, #(MCE_SMC_ROC_FLUSH_CACHE >> 16), lsl #16 +ENTRY(__asm_tegra_cache_smc) mov x1, #0 mov x2, #0 mov x3, #0 @@ -22,4 +22,22 @@ ENTRY(__asm_flush_l3_dcache) smc #0 mov x0, #0 ret +ENDPROC(__asm_invalidate_l3_dcache) + +ENTRY(__asm_invalidate_l3_dcache) + mov x0, #(MCE_SMC_ROC_FLUSH_CACHE_ONLY & 0xffff) + movk x0, #(MCE_SMC_ROC_FLUSH_CACHE_ONLY >> 16), lsl #16 + b __asm_tegra_cache_smc +ENDPROC(__asm_invalidate_l3_dcache) + +ENTRY(__asm_flush_l3_dcache) + mov x0, #(MCE_SMC_ROC_CLEAN_CACHE_ONLY & 0xffff) + movk x0, #(MCE_SMC_ROC_CLEAN_CACHE_ONLY >> 16), lsl #16 + b __asm_tegra_cache_smc ENDPROC(__asm_flush_l3_dcache) + +ENTRY(__asm_invalidate_l3_icache) + mov x0, #(MCE_SMC_ROC_FLUSH_CACHE & 0xffff) + movk x0, #(MCE_SMC_ROC_FLUSH_CACHE >> 16), lsl #16 + b __asm_tegra_cache_smc +ENDPROC(__asm_invalidate_l3_icache)

On 10/19/2016 03:18 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
nvtboot_boot_x0 is a 64-bit variable and hence must be 64-bit aligned. So far this has happened by accident! Fix the code so this is guaranteed.
This fixes the following build error: ... relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `nvtboot_boot_x0' ...
TomW, I assume you'll be applying this soon? Simon ack'd patch 3 a while back, and that's the only thing that touches non-Tegra logic. I assume he's OK with the other patches.

I'll take a look today, thanks.
-----Original Message----- From: Stephen Warren [mailto:swarren@wwwdotorg.org] Sent: Thursday, October 27, 2016 10:41 AM To: Tom Warren TWarren@nvidia.com Cc: u-boot@lists.denx.de; Simon Glass sjg@chromium.org; Stephen Warren swarren@nvidia.com; Tom Rini trini@konsulko.com Subject: Re: [U-Boot] [PATCH V2 1/4] ARM: tegra: ensure nvtboot_boot_x0 alignment
On 10/19/2016 03:18 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
nvtboot_boot_x0 is a 64-bit variable and hence must be 64-bit aligned. So far this has happened by accident! Fix the code so this is guaranteed.
This fixes the following build error: ... relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `nvtboot_boot_x0' ...
TomW, I assume you'll be applying this soon? Simon ack'd patch 3 a while back, and that's the only thing that touches non-Tegra logic. I assume he's OK with the other patches.
----------------------------------------------------------------------------------- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. -----------------------------------------------------------------------------------
participants (3)
-
Simon Glass
-
Stephen Warren
-
Tom Warren