diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-28 00:14:14 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-10-13 11:19:13 +0200 |
commit | 1dbfd5ed82fd2b6b0ba6df98e2e23aaf3cd1a197 (patch) | |
tree | 3214217a66047c49aaa48ea3e860dec9ac7899bb /arch/arm/cpu/cache.c | |
parent | 3d76ff9aeada3607e913e4627237c6fd7b5acc05 (diff) | |
download | barebox-1dbfd5ed82fd2b6b0ba6df98e2e23aaf3cd1a197.tar.gz barebox-1dbfd5ed82fd2b6b0ba6df98e2e23aaf3cd1a197.tar.xz |
ARM: Support multiple ARM architectures
The different ARM architectures need different cache functions. This
patch makes them selectable during runtime.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/cpu/cache.c')
-rw-r--r-- | arch/arm/cpu/cache.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c new file mode 100644 index 0000000000..1254609bb6 --- /dev/null +++ b/arch/arm/cpu/cache.c @@ -0,0 +1,103 @@ +#include <common.h> +#include <init.h> +#include <asm/mmu.h> +#include <asm/cache.h> +#include <asm/system_info.h> + +int arm_architecture; + +struct cache_fns { + void (*dma_clean_range)(unsigned long start, unsigned long end); + void (*dma_flush_range)(unsigned long start, unsigned long end); + void (*dma_inv_range)(unsigned long start, unsigned long end); + void (*mmu_cache_on)(void); + void (*mmu_cache_off)(void); + void (*mmu_cache_flush)(void); +}; + +struct cache_fns *cache_fns; + +#define DEFINE_CPU_FNS(arch) \ + void arch##_dma_clean_range(unsigned long start, unsigned long end); \ + void arch##_dma_flush_range(unsigned long start, unsigned long end); \ + void arch##_dma_inv_range(unsigned long start, unsigned long end); \ + void arch##_mmu_cache_on(void); \ + void arch##_mmu_cache_off(void); \ + void arch##_mmu_cache_flush(void); \ + \ + static struct cache_fns __maybe_unused cache_fns_arm##arch = { \ + .dma_clean_range = arch##_dma_clean_range, \ + .dma_flush_range = arch##_dma_flush_range, \ + .dma_inv_range = arch##_dma_inv_range, \ + .mmu_cache_on = arch##_mmu_cache_on, \ + .mmu_cache_off = arch##_mmu_cache_off, \ + .mmu_cache_flush = arch##_mmu_cache_flush, \ + }; + +DEFINE_CPU_FNS(v4) +DEFINE_CPU_FNS(v5) +DEFINE_CPU_FNS(v6) +DEFINE_CPU_FNS(v7) + +void __dma_clean_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_clean_range(start, end); +} + +void __dma_flush_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_flush_range(start, end); +} + +void __dma_inv_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_inv_range(start, end); +} + +void __mmu_cache_on(void) +{ + cache_fns->mmu_cache_on(); +} + +void __mmu_cache_off(void) +{ + cache_fns->mmu_cache_off(); +} + +void __mmu_cache_flush(void) +{ + cache_fns->mmu_cache_flush(); +} + +int arm_set_cache_functions(void) +{ + switch (cpu_architecture()) { +#ifdef CONFIG_CPU_32v4T + case CPU_ARCH_ARMv4T: + cache_fns = &cache_fns_armv4; + break; +#endif +#ifdef CONFIG_CPU_32v5 + case CPU_ARCH_ARMv5: + case CPU_ARCH_ARMv5T: + case CPU_ARCH_ARMv5TE: + case CPU_ARCH_ARMv5TEJ: + cache_fns = &cache_fns_armv5; + break; +#endif +#ifdef CONFIG_CPU_32v6 + case CPU_ARCH_ARMv6: + cache_fns = &cache_fns_armv6; + break; +#endif +#ifdef CONFIG_CPU_32v7 + case CPU_ARCH_ARMv7: + cache_fns = &cache_fns_armv7; + break; +#endif + default: + BUG(); + } + + return 0; +} |