1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 */ 15 16/** 17 * @file 18 * 19 * Support for invalidating bytes in the instruction cache. 20 */ 21 22#ifndef __ARCH_ICACHE_H__ 23#define __ARCH_ICACHE_H__ 24 25#include <arch/chip.h> 26 27 28/** 29 * Invalidate the instruction cache for the given range of memory. 30 * 31 * @param addr The start of memory to be invalidated. 32 * @param size The number of bytes to be invalidated. 33 * @param page_size The system's page size, e.g. getpagesize() in userspace. 34 * This value must be a power of two no larger than the page containing 35 * the code to be invalidated. If the value is smaller than the actual page 36 * size, this function will still work, but may run slower than necessary. 37 */ 38static __inline void 39invalidate_icache(const void* addr, unsigned long size, 40 unsigned long page_size) 41{ 42 const unsigned long cache_way_size = 43 CHIP_L1I_CACHE_SIZE() / CHIP_L1I_ASSOC(); 44 unsigned long max_useful_size; 45 const char* start, *end; 46 long num_passes; 47 48 if (__builtin_expect(size == 0, 0)) 49 return; 50 51#ifdef __tilegx__ 52 /* Limit the number of bytes visited to avoid redundant iterations. */ 53 max_useful_size = (page_size < cache_way_size) ? page_size : cache_way_size; 54 55 /* No PA aliasing is possible, so one pass always suffices. */ 56 num_passes = 1; 57#else 58 /* Limit the number of bytes visited to avoid redundant iterations. */ 59 max_useful_size = cache_way_size; 60 61 /* 62 * Compute how many passes we need (we'll treat 0 as if it were 1). 63 * This works because we know the page size is a power of two. 64 */ 65 num_passes = cache_way_size >> __builtin_ctzl(page_size); 66#endif 67 68 if (__builtin_expect(size > max_useful_size, 0)) 69 size = max_useful_size; 70 71 /* Locate the first and last bytes to be invalidated. */ 72 start = (const char *)((unsigned long)addr & -CHIP_L1I_LINE_SIZE()); 73 end = (const char*)addr + size - 1; 74 75 __insn_mf(); 76 77 do 78 { 79 const char* p; 80 81 for (p = start; p <= end; p += CHIP_L1I_LINE_SIZE()) 82 __insn_icoh(p); 83 84 start += page_size; 85 end += page_size; 86 } 87 while (--num_passes > 0); 88 89 __insn_drain(); 90} 91 92 93#endif /* __ARCH_ICACHE_H__ */ 94