Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | // SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2004 Texas Insturments * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger <mgroeger@sysgo.de> * * (C) Copyright 2002 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> */ /* * CPU specific code */ #include <command.h> #include <cpu_func.h> #include <irq_func.h> #include <asm/cache.h> #include <asm/system.h> #include <asm/arm11.h> static void cache_flush(void); int cleanup_before_linux (void) { /* * this function is called just before we call linux * it prepares the processor for linux * * we turn off caches etc ... */ disable_interrupts(); /* turn off I/D-cache */ icache_disable(); dcache_disable(); /* flush I/D-cache */ cache_flush(); return 0; } void allow_unaligned(void) { arm11_arch_cp15_allow_unaligned(); } static void cache_flush(void) { unsigned long i = 0; /* clean entire data cache */ asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i)); /* invalidate both caches and flush btb */ asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i)); /* mem barrier to sync things */ asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i)); } #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) void invalidate_dcache_all(void) { asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0)); } void flush_dcache_all(void) { asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0)); asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); } void invalidate_dcache_range(unsigned long start, unsigned long stop) { if (!check_cache_range(start, stop)) return; while (start < stop) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); start += CONFIG_SYS_CACHELINE_SIZE; } } void flush_dcache_range(unsigned long start, unsigned long stop) { if (!check_cache_range(start, stop)) return; while (start < stop) { asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start)); start += CONFIG_SYS_CACHELINE_SIZE; } asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); } #else /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */ void invalidate_dcache_all(void) { } void flush_dcache_all(void) { } #endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */ #if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) void enable_caches(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) icache_enable(); #endif #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) dcache_enable(); #endif } #endif #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) /* Invalidate entire I-cache */ void invalidate_icache_all(void) { unsigned long i = 0; asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i)); } #else void invalidate_icache_all(void) {} #endif |