1 // SPDX-License-Identifier: GPL-2.0+
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 /* for now: just dummy functions to satisfy the linker */
13 #include <asm/cache.h>
14 #include <asm/global_data.h>
16 DECLARE_GLOBAL_DATA_PTR;
19 * Flush range from all levels of d-cache/unified-cache.
20 * Affects the range [start, start + size - 1].
22 __weak void flush_cache(unsigned long start, unsigned long size)
24 flush_dcache_range(start, start + size);
28 * Default implementation:
29 * do a range flush for the entire range
31 __weak void flush_dcache_all(void)
37 * Default implementation of enable_caches()
38 * Real implementation should be in platform code
40 __weak void enable_caches(void)
42 puts("WARNING: Caches not enabled\n");
45 __weak void invalidate_dcache_range(unsigned long start, unsigned long stop)
47 /* An empty stub, real implementation should be in platform code */
49 __weak void flush_dcache_range(unsigned long start, unsigned long stop)
51 /* An empty stub, real implementation should be in platform code */
54 int check_cache_range(unsigned long start, unsigned long stop)
58 if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
61 if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
65 warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
72 #ifdef CONFIG_SYS_NONCACHED_MEMORY
74 * Reserve one MMU section worth of address space below the malloc() area that
75 * will be mapped uncached.
77 static unsigned long noncached_start;
78 static unsigned long noncached_end;
79 static unsigned long noncached_next;
81 void noncached_set_region(void)
83 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
84 mmu_set_region_dcache_behaviour(noncached_start,
85 noncached_end - noncached_start,
90 int noncached_init(void)
92 phys_addr_t start, end;
95 /* If this calculation changes, update board_f.c:reserve_noncached() */
96 end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
97 size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
100 debug("mapping memory %pa-%pa non-cached\n", &start, &end);
102 noncached_start = start;
104 noncached_next = start;
106 noncached_set_region();
111 phys_addr_t noncached_alloc(size_t size, size_t align)
113 phys_addr_t next = ALIGN(noncached_next, align);
115 if (next >= noncached_end || (noncached_end - next) < size)
118 debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
119 noncached_next = next + size;
123 #endif /* CONFIG_SYS_NONCACHED_MEMORY */
125 #if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
126 void invalidate_l2_cache(void)
128 unsigned int val = 0;
130 asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
131 : : "r" (val) : "cc");
136 int arch_reserve_mmu(void)
138 return arm_reserve_mmu();
141 __weak int arm_reserve_mmu(void)
143 #if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
144 /* reserve TLB table */
145 gd->arch.tlb_size = PGTABLE_SIZE;
146 gd->relocaddr -= gd->arch.tlb_size;
148 /* round down to next 64 kB limit */
149 gd->relocaddr &= ~(0x10000 - 1);
151 gd->arch.tlb_addr = gd->relocaddr;
152 debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
153 gd->arch.tlb_addr + gd->arch.tlb_size);
155 #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
157 * Record allocated tlb_addr in case gd->tlb_addr to be overwritten
158 * with location within secure ram.
160 gd->arch.tlb_allocated = gd->arch.tlb_addr;