1 /* 2 * (C) Copyright 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* for now: just dummy functions to satisfy the linker */ 9 10 #include <common.h> 11 #include <malloc.h> 12 13 __weak void flush_cache(unsigned long start, unsigned long size) 14 { 15 #if defined(CONFIG_CPU_ARM1136) 16 17 #if !defined(CONFIG_SYS_ICACHE_OFF) 18 asm("mcr p15, 0, r1, c7, c5, 0"); /* invalidate I cache */ 19 #endif 20 21 #if !defined(CONFIG_SYS_DCACHE_OFF) 22 asm("mcr p15, 0, r1, c7, c14, 0"); /* Clean+invalidate D cache */ 23 #endif 24 25 #endif /* CONFIG_CPU_ARM1136 */ 26 27 #ifdef CONFIG_CPU_ARM926EJS 28 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) 29 /* test and clean, page 2-23 of arm926ejs manual */ 30 asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); 31 /* disable write buffer as well (page 2-22) */ 32 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); 33 #endif 34 #endif /* CONFIG_CPU_ARM926EJS */ 35 return; 36 } 37 38 /* 39 * Default implementation: 40 * do a range flush for the entire range 41 */ 42 __weak void flush_dcache_all(void) 43 { 44 flush_cache(0, ~0); 45 } 46 47 /* 48 * Default implementation of enable_caches() 49 * Real implementation should be in platform code 50 */ 51 __weak void enable_caches(void) 52 { 53 puts("WARNING: Caches not enabled\n"); 54 } 55 56 #ifdef CONFIG_SYS_NONCACHED_MEMORY 57 /* 58 * Reserve one MMU section worth of address space below the malloc() area that 59 * will be mapped uncached. 60 */ 61 static unsigned long noncached_start; 62 static unsigned long noncached_end; 63 static unsigned long noncached_next; 64 65 void noncached_init(void) 66 { 67 phys_addr_t start, end; 68 size_t size; 69 70 end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; 71 size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); 72 start = end - size; 73 74 debug("mapping memory %pa-%pa non-cached\n", &start, &end); 75 76 noncached_start = start; 77 noncached_end = end; 78 noncached_next = start; 79 80 #ifndef CONFIG_SYS_DCACHE_OFF 81 mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF); 82 #endif 83 } 84 85 phys_addr_t noncached_alloc(size_t size, size_t align) 86 { 87 phys_addr_t next = ALIGN(noncached_next, align); 88 89 if (next >= noncached_end || (noncached_end - next) < size) 90 return 0; 91 92 debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); 93 noncached_next = next + size; 94 95 return next; 96 } 97 #endif /* CONFIG_SYS_NONCACHED_MEMORY */ 98