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 /* test and clean, page 2-23 of arm926ejs manual */ 29 asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); 30 /* disable write buffer as well (page 2-22) */ 31 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); 32 #endif /* CONFIG_CPU_ARM926EJS */ 33 return; 34 } 35 36 /* 37 * Default implementation: 38 * do a range flush for the entire range 39 */ 40 __weak void flush_dcache_all(void) 41 { 42 flush_cache(0, ~0); 43 } 44 45 /* 46 * Default implementation of enable_caches() 47 * Real implementation should be in platform code 48 */ 49 __weak void enable_caches(void) 50 { 51 puts("WARNING: Caches not enabled\n"); 52 } 53 54 #ifdef CONFIG_SYS_NONCACHED_MEMORY 55 /* 56 * Reserve one MMU section worth of address space below the malloc() area that 57 * will be mapped uncached. 58 */ 59 static unsigned long noncached_start; 60 static unsigned long noncached_end; 61 static unsigned long noncached_next; 62 63 void noncached_init(void) 64 { 65 phys_addr_t start, end; 66 size_t size; 67 68 end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; 69 size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); 70 start = end - size; 71 72 debug("mapping memory %pa-%pa non-cached\n", &start, &end); 73 74 noncached_start = start; 75 noncached_end = end; 76 noncached_next = start; 77 78 #ifndef CONFIG_SYS_DCACHE_OFF 79 mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF); 80 #endif 81 } 82 83 phys_addr_t noncached_alloc(size_t size, size_t align) 84 { 85 phys_addr_t next = ALIGN(noncached_next, align); 86 87 if (next >= noncached_end || (noncached_end - next) < size) 88 return 0; 89 90 debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); 91 noncached_next = next + size; 92 93 return next; 94 } 95 #endif /* CONFIG_SYS_NONCACHED_MEMORY */ 96