diff options
author | Tom Rini <trini@konsulko.com> | 2017-11-28 16:54:30 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-11-28 16:54:30 -0500 |
commit | fcc8250c2f7c982f3593a8eecf737f8e2c95f222 (patch) | |
tree | 13752b14c2e60b4dce2124fa34b79d2b3aa3c7c8 /arch | |
parent | 74a4818415852560b43ee990ce47c68582bef4ca (diff) | |
parent | caead80a66271d2de809acf410f8648c31ed5805 (diff) |
Merge git://git.denx.de/u-boot-mips
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/cpu/u-boot.lds | 6 | ||||
-rw-r--r-- | arch/mips/include/asm/system.h | 13 | ||||
-rw-r--r-- | arch/mips/lib/cache.c | 30 |
3 files changed, 35 insertions, 14 deletions
diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index bd5536f013..fc943af923 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -5,12 +5,6 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#if defined(CONFIG_64BIT) -#define PTR_COUNT_SHIFT 3 -#else -#define PTR_COUNT_SHIFT 2 -#endif - OUTPUT_ARCH(mips) ENTRY(_start) SECTIONS diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h index c9c5961462..eaf1b2290d 100644 --- a/arch/mips/include/asm/system.h +++ b/arch/mips/include/asm/system.h @@ -14,8 +14,10 @@ #ifndef _ASM_SYSTEM_H #define _ASM_SYSTEM_H +#include <asm/asm.h> #include <asm/sgidefs.h> #include <asm/ptrace.h> +#include <linux/stringify.h> #if 0 #include <linux/kernel.h> #endif @@ -270,4 +272,15 @@ static inline void execution_hazard_barrier(void) ".set reorder"); } +static inline void instruction_hazard_barrier(void) +{ + unsigned long tmp; + + asm volatile( + __stringify(PTR_LA) "\t%0, 1f\n" + " jr.hb %0\n" + "1: .insn" + : "=&r"(tmp)); +} + #endif /* _ASM_SYSTEM_H */ diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index 91b037f87d..e305f3207a 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -10,7 +10,9 @@ #ifdef CONFIG_MIPS_L2_CACHE #include <asm/cm.h> #endif +#include <asm/io.h> #include <asm/mipsregs.h> +#include <asm/system.h> DECLARE_GLOBAL_DATA_PTR; @@ -96,6 +98,9 @@ static inline unsigned long scache_line_size(void) const unsigned int cache_ops[] = { ops }; \ unsigned int i; \ \ + if (!lsize) \ + break; \ + \ for (; addr <= aend; addr += lsize) { \ for (i = 0; i < ARRAY_SIZE(cache_ops); i++) \ mips_cache(cache_ops[i], addr); \ @@ -116,19 +121,24 @@ void flush_cache(ulong start_addr, ulong size) /* flush I-cache & D-cache simultaneously */ cache_loop(start_addr, start_addr + size, ilsize, HIT_WRITEBACK_INV_D, HIT_INVALIDATE_I); - return; + goto ops_done; } /* flush D-cache */ cache_loop(start_addr, start_addr + size, dlsize, HIT_WRITEBACK_INV_D); /* flush L2 cache */ - if (slsize) - cache_loop(start_addr, start_addr + size, slsize, - HIT_WRITEBACK_INV_SD); + cache_loop(start_addr, start_addr + size, slsize, HIT_WRITEBACK_INV_SD); /* flush I-cache */ cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I); + +ops_done: + /* ensure cache ops complete before any further memory accesses */ + sync(); + + /* ensure the pipeline doesn't contain now-invalid instructions */ + instruction_hazard_barrier(); } void flush_dcache_range(ulong start_addr, ulong stop) @@ -143,8 +153,10 @@ void flush_dcache_range(ulong start_addr, ulong stop) cache_loop(start_addr, stop, lsize, HIT_WRITEBACK_INV_D); /* flush L2 cache */ - if (slsize) - cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD); + cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD); + + /* ensure cache ops complete before any further memory accesses */ + sync(); } void invalidate_dcache_range(ulong start_addr, ulong stop) @@ -157,8 +169,10 @@ void invalidate_dcache_range(ulong start_addr, ulong stop) return; /* invalidate L2 cache */ - if (slsize) - cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD); + cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD); cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_D); + + /* ensure cache ops complete before any further memory accesses */ + sync(); } |