-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arch/tile: Split the icache flush code off to a generic <arch> header.
This code is used in other places in our system than in Linux, so to share it we now implement it as an inline function in our low-level <arch> headers, and instantiate it in one file in Linux's arch/tile/lib. The file is now cacheflush.c and is C code rather than the strangely-named and assembler-implemented __invalidate_icache.S. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
- Loading branch information
Chris Metcalf
committed
Jul 6, 2010
1 parent
2db0982
commit c78095b
Showing
5 changed files
with
120 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
* NON INFRINGEMENT. See the GNU General Public License for | ||
* more details. | ||
* | ||
*/ | ||
|
||
/** | ||
* @file | ||
* | ||
* Support for invalidating bytes in the instruction | ||
*/ | ||
|
||
#ifndef __ARCH_ICACHE_H__ | ||
#define __ARCH_ICACHE_H__ | ||
|
||
#include <arch/chip.h> | ||
|
||
|
||
/** | ||
* Invalidate the instruction cache for the given range of memory. | ||
* | ||
* @param addr The start of memory to be invalidated. | ||
* @param size The number of bytes to be invalidated. | ||
* @param page_size The system's page size, typically the PAGE_SIZE constant | ||
* in sys/page.h. This value must be a power of two no larger | ||
* than the page containing the code to be invalidated. If the value | ||
* is smaller than the actual page size, this function will still | ||
* work, but may run slower than necessary. | ||
*/ | ||
static __inline void | ||
invalidate_icache(const void* addr, unsigned long size, | ||
unsigned long page_size) | ||
{ | ||
const unsigned long cache_way_size = | ||
CHIP_L1I_CACHE_SIZE() / CHIP_L1I_ASSOC(); | ||
unsigned long max_useful_size; | ||
const char* start, *end; | ||
long num_passes; | ||
|
||
if (__builtin_expect(size == 0, 0)) | ||
return; | ||
|
||
#ifdef __tilegx__ | ||
/* Limit the number of bytes visited to avoid redundant iterations. */ | ||
max_useful_size = (page_size < cache_way_size) ? page_size : cache_way_size; | ||
|
||
/* No PA aliasing is possible, so one pass always suffices. */ | ||
num_passes = 1; | ||
#else | ||
/* Limit the number of bytes visited to avoid redundant iterations. */ | ||
max_useful_size = cache_way_size; | ||
|
||
/* | ||
* Compute how many passes we need (we'll treat 0 as if it were 1). | ||
* This works because we know the page size is a power of two. | ||
*/ | ||
num_passes = cache_way_size >> __builtin_ctzl(page_size); | ||
#endif | ||
|
||
if (__builtin_expect(size > max_useful_size, 0)) | ||
size = max_useful_size; | ||
|
||
/* Locate the first and last bytes to be invalidated. */ | ||
start = (const char *)((unsigned long)addr & -CHIP_L1I_LINE_SIZE()); | ||
end = (const char*)addr + size - 1; | ||
|
||
__insn_mf(); | ||
|
||
do | ||
{ | ||
const char* p; | ||
|
||
for (p = start; p <= end; p += CHIP_L1I_LINE_SIZE()) | ||
__insn_icoh(p); | ||
|
||
start += page_size; | ||
end += page_size; | ||
} | ||
while (--num_passes > 0); | ||
|
||
__insn_drain(); | ||
} | ||
|
||
|
||
#endif /* __ARCH_ICACHE_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
* NON INFRINGEMENT. See the GNU General Public License for | ||
* more details. | ||
*/ | ||
|
||
#include <asm/page.h> | ||
#include <asm/cacheflush.h> | ||
#include <arch/icache.h> | ||
|
||
|
||
void __flush_icache_range(unsigned long start, unsigned long end) | ||
{ | ||
invalidate_icache((const void *)start, end - start, PAGE_SIZE); | ||
} |