1ea0364f1SPeter Tyser /* 2ea0364f1SPeter Tyser * (C) Copyright 2002 3ea0364f1SPeter Tyser * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4ea0364f1SPeter Tyser * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 6ea0364f1SPeter Tyser */ 7ea0364f1SPeter Tyser 8ea0364f1SPeter Tyser /* for now: just dummy functions to satisfy the linker */ 9ea0364f1SPeter Tyser 10ea0364f1SPeter Tyser #include <common.h> 111dfdd9baSThierry Reding #include <malloc.h> 12ea0364f1SPeter Tyser 13fcfddfd5SJeroen Hofstee __weak void flush_cache(unsigned long start, unsigned long size) 14ea0364f1SPeter Tyser { 153fd968e9SMasahiro Yamada #if defined(CONFIG_CPU_ARM1136) 16ea0364f1SPeter Tyser 17b4ee1491SAlbert ARIBAUD #if !defined(CONFIG_SYS_ICACHE_OFF) 18b4ee1491SAlbert ARIBAUD asm("mcr p15, 0, r1, c7, c5, 0"); /* invalidate I cache */ 19ea0364f1SPeter Tyser #endif 20b4ee1491SAlbert ARIBAUD 21b4ee1491SAlbert ARIBAUD #if !defined(CONFIG_SYS_DCACHE_OFF) 22b4ee1491SAlbert ARIBAUD asm("mcr p15, 0, r1, c7, c14, 0"); /* Clean+invalidate D cache */ 23b4ee1491SAlbert ARIBAUD #endif 24b4ee1491SAlbert ARIBAUD 253fd968e9SMasahiro Yamada #endif /* CONFIG_CPU_ARM1136 */ 26b4ee1491SAlbert ARIBAUD 275d7b131dSMasahiro Yamada #ifdef CONFIG_CPU_ARM926EJS 2899197a9eSHeiko Schocher #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) 29c3330e9dSHeiko Schocher /* test and clean, page 2-23 of arm926ejs manual */ 30c3330e9dSHeiko Schocher asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); 31c3330e9dSHeiko Schocher /* disable write buffer as well (page 2-22) */ 32c3330e9dSHeiko Schocher asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); 3399197a9eSHeiko Schocher #endif 345d7b131dSMasahiro Yamada #endif /* CONFIG_CPU_ARM926EJS */ 35ea0364f1SPeter Tyser return; 36ea0364f1SPeter Tyser } 37e05f0079SAneesh V 38e05f0079SAneesh V /* 39e05f0079SAneesh V * Default implementation: 40e05f0079SAneesh V * do a range flush for the entire range 41e05f0079SAneesh V */ 42fcfddfd5SJeroen Hofstee __weak void flush_dcache_all(void) 43e05f0079SAneesh V { 44e05f0079SAneesh V flush_cache(0, ~0); 45e05f0079SAneesh V } 46cba4b180SAneesh V 47cba4b180SAneesh V /* 48cba4b180SAneesh V * Default implementation of enable_caches() 49cba4b180SAneesh V * Real implementation should be in platform code 50cba4b180SAneesh V */ 51fcfddfd5SJeroen Hofstee __weak void enable_caches(void) 52cba4b180SAneesh V { 53cba4b180SAneesh V puts("WARNING: Caches not enabled\n"); 54cba4b180SAneesh V } 551dfdd9baSThierry Reding 56*387871a1SWu, Josh __weak void invalidate_dcache_range(unsigned long start, unsigned long stop) 57*387871a1SWu, Josh { 58*387871a1SWu, Josh /* An empty stub, real implementation should be in platform code */ 59*387871a1SWu, Josh } 60*387871a1SWu, Josh __weak void flush_dcache_range(unsigned long start, unsigned long stop) 61*387871a1SWu, Josh { 62*387871a1SWu, Josh /* An empty stub, real implementation should be in platform code */ 63*387871a1SWu, Josh } 64*387871a1SWu, Josh 651dfdd9baSThierry Reding #ifdef CONFIG_SYS_NONCACHED_MEMORY 661dfdd9baSThierry Reding /* 671dfdd9baSThierry Reding * Reserve one MMU section worth of address space below the malloc() area that 681dfdd9baSThierry Reding * will be mapped uncached. 691dfdd9baSThierry Reding */ 701dfdd9baSThierry Reding static unsigned long noncached_start; 711dfdd9baSThierry Reding static unsigned long noncached_end; 721dfdd9baSThierry Reding static unsigned long noncached_next; 731dfdd9baSThierry Reding 741dfdd9baSThierry Reding void noncached_init(void) 751dfdd9baSThierry Reding { 761dfdd9baSThierry Reding phys_addr_t start, end; 771dfdd9baSThierry Reding size_t size; 781dfdd9baSThierry Reding 791dfdd9baSThierry Reding end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; 801dfdd9baSThierry Reding size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); 811dfdd9baSThierry Reding start = end - size; 821dfdd9baSThierry Reding 831dfdd9baSThierry Reding debug("mapping memory %pa-%pa non-cached\n", &start, &end); 841dfdd9baSThierry Reding 851dfdd9baSThierry Reding noncached_start = start; 861dfdd9baSThierry Reding noncached_end = end; 871dfdd9baSThierry Reding noncached_next = start; 881dfdd9baSThierry Reding 891dfdd9baSThierry Reding #ifndef CONFIG_SYS_DCACHE_OFF 901dfdd9baSThierry Reding mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF); 911dfdd9baSThierry Reding #endif 921dfdd9baSThierry Reding } 931dfdd9baSThierry Reding 941dfdd9baSThierry Reding phys_addr_t noncached_alloc(size_t size, size_t align) 951dfdd9baSThierry Reding { 961dfdd9baSThierry Reding phys_addr_t next = ALIGN(noncached_next, align); 971dfdd9baSThierry Reding 981dfdd9baSThierry Reding if (next >= noncached_end || (noncached_end - next) < size) 991dfdd9baSThierry Reding return 0; 1001dfdd9baSThierry Reding 1011dfdd9baSThierry Reding debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); 1021dfdd9baSThierry Reding noncached_next = next + size; 1031dfdd9baSThierry Reding 1041dfdd9baSThierry Reding return next; 1051dfdd9baSThierry Reding } 1061dfdd9baSThierry Reding #endif /* CONFIG_SYS_NONCACHED_MEMORY */ 107