1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2007 Michal Simek 4 * 5 * Michal SIMEK <monstr@monstr.eu> 6 */ 7 8#include <cpu_func.h> 9#include <asm/asm.h> 10#include <asm/cache.h> 11#include <asm/cpuinfo.h> 12#include <asm/global_data.h> 13 14DECLARE_GLOBAL_DATA_PTR; 15 16static void __invalidate_icache(ulong addr, ulong size) 17{ 18 if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { 19 for (int i = 0; i < size; 20 i += gd_cpuinfo()->icache_line_length) { 21 asm volatile ( 22 "wic %0, r0;" 23 "nop;" 24 : 25 : "r" (addr + i) 26 : "memory"); 27 } 28 } 29} 30 31void invalidate_icache_all(void) 32{ 33 __invalidate_icache(0, gd_cpuinfo()->icache_size); 34} 35 36static void __flush_dcache(ulong addr, ulong size) 37{ 38 if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { 39 for (int i = 0; i < size; 40 i += gd_cpuinfo()->dcache_line_length) { 41 asm volatile ( 42 "wdc.flush %0, r0;" 43 "nop;" 44 : 45 : "r" (addr + i) 46 : "memory"); 47 } 48 } 49} 50 51void flush_dcache_range(unsigned long start, unsigned long end) 52{ 53 if (start >= end) { 54 debug("Invalid dcache range - start: 0x%08lx end: 0x%08lx\n", 55 start, end); 56 return; 57 } 58 59 __flush_dcache(start, end - start); 60} 61 62void flush_dcache_all(void) 63{ 64 __flush_dcache(0, gd_cpuinfo()->dcache_size); 65} 66 67int dcache_status(void) 68{ 69 int i = 0; 70 int mask = 0x80; 71 __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); 72 /* i&=0x80 */ 73 __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); 74 return i; 75} 76 77int icache_status(void) 78{ 79 int i = 0; 80 int mask = 0x20; 81 __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory"); 82 /* i&=0x20 */ 83 __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); 84 return i; 85} 86 87void icache_enable(void) 88{ 89 MSRSET(0x20); 90} 91 92void icache_disable(void) 93{ 94 invalidate_icache_all(); 95 96 MSRCLR(0x20); 97} 98 99void dcache_enable(void) 100{ 101 MSRSET(0x80); 102} 103 104void dcache_disable(void) 105{ 106 flush_dcache_all(); 107 108 MSRCLR(0x80); 109} 110 111void flush_cache(ulong addr, ulong size) 112{ 113 __invalidate_icache(addr, size); 114 __flush_dcache(addr, size); 115} 116 117void flush_cache_all(void) 118{ 119 invalidate_icache_all(); 120 flush_dcache_all(); 121} 122