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 __weak void invalidate_dcache_range(unsigned long start, unsigned long stop) 57 { 58 /* An empty stub, real implementation should be in platform code */ 59 } 60 __weak void flush_dcache_range(unsigned long start, unsigned long stop) 61 { 62 /* An empty stub, real implementation should be in platform code */ 63 } 64 65 #ifdef CONFIG_SYS_NONCACHED_MEMORY 66 /* 67 * Reserve one MMU section worth of address space below the malloc() area that 68 * will be mapped uncached. 69 */ 70 static unsigned long noncached_start; 71 static unsigned long noncached_end; 72 static unsigned long noncached_next; 73 74 void noncached_init(void) 75 { 76 phys_addr_t start, end; 77 size_t size; 78 79 end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; 80 size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); 81 start = end - size; 82 83 debug("mapping memory %pa-%pa non-cached\n", &start, &end); 84 85 noncached_start = start; 86 noncached_end = end; 87 noncached_next = start; 88 89 #ifndef CONFIG_SYS_DCACHE_OFF 90 mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF); 91 #endif 92 } 93 94 phys_addr_t noncached_alloc(size_t size, size_t align) 95 { 96 phys_addr_t next = ALIGN(noncached_next, align); 97 98 if (next >= noncached_end || (noncached_end - next) < size) 99 return 0; 100 101 debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); 102 noncached_next = next + size; 103 104 return next; 105 } 106 #endif /* CONFIG_SYS_NONCACHED_MEMORY */ 107