Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163453
b: refs/heads/master
c: f26b2a5
h: refs/heads/master
i:
  163451: cad10d1
v: v3
  • Loading branch information
Paul Mundt committed Aug 21, 2009
1 parent 30edb61 commit e2df05a
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 161 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f9bd71f255b4349c4f9f596863161fd5182f67fa
refs/heads/master: f26b2a562b46ab186c8383993ab1332673ac4a47
41 changes: 29 additions & 12 deletions trunk/arch/sh/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,40 @@
* - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
* - flush_cache_sigtramp(vaddr) flushes the signal trampoline
*/
extern void (*flush_cache_all)(void);
extern void (*flush_cache_mm)(struct mm_struct *mm);
extern void (*flush_cache_dup_mm)(struct mm_struct *mm);
extern void (*flush_cache_page)(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn);
extern void (*flush_cache_range)(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void (*flush_dcache_page)(struct page *page);
extern void (*flush_icache_range)(unsigned long start, unsigned long end);
extern void (*flush_icache_page)(struct vm_area_struct *vma,
struct page *page);
extern void (*flush_cache_sigtramp)(unsigned long address);
extern void (*local_flush_cache_all)(void *args);
extern void (*local_flush_cache_mm)(void *args);
extern void (*local_flush_cache_dup_mm)(void *args);
extern void (*local_flush_cache_page)(void *args);
extern void (*local_flush_cache_range)(void *args);
extern void (*local_flush_dcache_page)(void *args);
extern void (*local_flush_icache_range)(void *args);
extern void (*local_flush_icache_page)(void *args);
extern void (*local_flush_cache_sigtramp)(void *args);

static inline void cache_noop(void *args) { }

extern void (*__flush_wback_region)(void *start, int size);
extern void (*__flush_purge_region)(void *start, int size);
extern void (*__flush_invalidate_region)(void *start, int size);

extern void flush_cache_all(void);
extern void flush_cache_mm(struct mm_struct *mm);
extern void flush_cache_dup_mm(struct mm_struct *mm);
extern void flush_cache_page(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn);
extern void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void flush_dcache_page(struct page *page);
extern void flush_icache_range(unsigned long start, unsigned long end);
extern void flush_icache_page(struct vm_area_struct *vma,
struct page *page);
extern void flush_cache_sigtramp(unsigned long address);

struct flusher_data {
struct vm_area_struct *vma;
unsigned long addr1, addr2;
};

#define ARCH_HAS_FLUSH_ANON_PAGE
extern void __flush_anon_page(struct page *page, unsigned long);

Expand Down
10 changes: 6 additions & 4 deletions trunk/arch/sh/mm/cache-sh2a.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ static void sh2a__flush_invalidate_region(void *start, int size)
}

/* WBack O-Cache and flush I-Cache */
static void sh2a_flush_icache_range(unsigned long start, unsigned long end)
static void sh2a_flush_icache_range(void *args)
{
struct flusher_data *data = args;
unsigned long start, end;
unsigned long v;
unsigned long flags;

start = start & ~(L1_CACHE_BYTES-1);
end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
start = data->addr1 & ~(L1_CACHE_BYTES-1);
end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);

local_irq_save(flags);
jump_to_uncached();
Expand All @@ -130,7 +132,7 @@ static void sh2a_flush_icache_range(unsigned long start, unsigned long end)

void __init sh2a_cache_init(void)
{
flush_icache_range = sh2a_flush_icache_range;
local_flush_icache_range = sh2a_flush_icache_range;

__flush_wback_region = sh2a__flush_wback_region;
__flush_purge_region = sh2a__flush_purge_region;
Expand Down
54 changes: 37 additions & 17 deletions trunk/arch/sh/mm/cache-sh4.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,20 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
* Called from kernel/module.c:sys_init_module and routine for a.out format,
* signal handler code and kprobes code
*/
static void sh4_flush_icache_range(unsigned long start, unsigned long end)
static void sh4_flush_icache_range(void *args)
{
struct flusher_data *data = args;
int icacheaddr;
unsigned long start, end;
unsigned long flags, v;
int i;

start = data->addr1;
end = data->addr2;

/* If there are too many pages then just blow the caches */
if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
flush_cache_all();
local_flush_cache_all(args);
} else {
/* selectively flush d-cache then invalidate the i-cache */
/* this is inefficient, so only use for small ranges */
Expand Down Expand Up @@ -104,7 +109,7 @@ static inline void flush_cache_4096(unsigned long start,
* Write back & invalidate the D-cache of the page.
* (To avoid "alias" issues)
*/
static void sh4_flush_dcache_page(struct page *page)
static void sh4_flush_dcache_page(void *page)
{
#ifndef CONFIG_SMP
struct address_space *mapping = page_mapping(page);
Expand Down Expand Up @@ -155,7 +160,7 @@ static inline void flush_dcache_all(void)
wmb();
}

static void sh4_flush_cache_all(void)
static void sh4_flush_cache_all(void *unused)
{
flush_dcache_all();
flush_icache_all();
Expand Down Expand Up @@ -247,8 +252,10 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
*
* Caller takes mm->mmap_sem.
*/
static void sh4_flush_cache_mm(struct mm_struct *mm)
static void sh4_flush_cache_mm(void *arg)
{
struct mm_struct *mm = arg;

if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
return;

Expand Down Expand Up @@ -287,12 +294,18 @@ static void sh4_flush_cache_mm(struct mm_struct *mm)
* ADDR: Virtual Address (U0 address)
* PFN: Physical page number
*/
static void sh4_flush_cache_page(struct vm_area_struct *vma,
unsigned long address, unsigned long pfn)
static void sh4_flush_cache_page(void *args)
{
unsigned long phys = pfn << PAGE_SHIFT;
struct flusher_data *data = args;
struct vm_area_struct *vma;
unsigned long address, pfn, phys;
unsigned int alias_mask;

vma = data->vma;
address = data->addr1;
pfn = data->addr2;
phys = pfn << PAGE_SHIFT;

if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
return;

Expand Down Expand Up @@ -335,9 +348,16 @@ static void sh4_flush_cache_page(struct vm_area_struct *vma,
* Flushing the cache lines for U0 only isn't enough.
* We need to flush for P1 too, which may contain aliases.
*/
static void sh4_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
static void sh4_flush_cache_range(void *args)
{
struct flusher_data *data = args;
struct vm_area_struct *vma;
unsigned long start, end;

vma = data->vma;
start = data->addr1;
end = data->addr2;

if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
return;

Expand Down Expand Up @@ -663,13 +683,13 @@ void __init sh4_cache_init(void)
break;
}

flush_icache_range = sh4_flush_icache_range;
flush_dcache_page = sh4_flush_dcache_page;
flush_cache_all = sh4_flush_cache_all;
flush_cache_mm = sh4_flush_cache_mm;
flush_cache_dup_mm = sh4_flush_cache_mm;
flush_cache_page = sh4_flush_cache_page;
flush_cache_range = sh4_flush_cache_range;
local_flush_icache_range = sh4_flush_icache_range;
local_flush_dcache_page = sh4_flush_dcache_page;
local_flush_cache_all = sh4_flush_cache_all;
local_flush_cache_mm = sh4_flush_cache_mm;
local_flush_cache_dup_mm = sh4_flush_cache_mm;
local_flush_cache_page = sh4_flush_cache_page;
local_flush_cache_range = sh4_flush_cache_range;

sh4__flush_region_init();
}
64 changes: 41 additions & 23 deletions trunk/arch/sh/mm/cache-sh5.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
* Invalidate the entire contents of both caches, after writing back to
* memory any dirty data from the D-cache.
*/
static void sh5_flush_cache_all(void)
static void sh5_flush_cache_all(void *unused)
{
sh64_dcache_purge_all();
sh64_icache_inv_all();
Expand All @@ -510,7 +510,7 @@ static void sh5_flush_cache_all(void)
* I-cache. This is similar to the lack of action needed in
* flush_tlb_mm - see fault.c.
*/
static void sh5_flush_cache_mm(struct mm_struct *mm)
static void sh5_flush_cache_mm(void *unused)
{
sh64_dcache_purge_all();
}
Expand All @@ -522,13 +522,18 @@ static void sh5_flush_cache_mm(struct mm_struct *mm)
*
* Note, 'end' is 1 byte beyond the end of the range to flush.
*/
static void sh5_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
static void sh5_flush_cache_range(void *args)
{
struct mm_struct *mm = vma->vm_mm;
struct flusher_data *data = args;
struct vm_area_struct *vma;
unsigned long start, end;

sh64_dcache_purge_user_range(mm, start, end);
sh64_icache_inv_user_page_range(mm, start, end);
vma = data->vma;
start = data->addr1;
end = data->addr2;

sh64_dcache_purge_user_range(vma->vm_mm, start, end);
sh64_icache_inv_user_page_range(vma->vm_mm, start, end);
}

/*
Expand All @@ -540,16 +545,23 @@ static void sh5_flush_cache_range(struct vm_area_struct *vma,
*
* Note, this is called with pte lock held.
*/
static void sh5_flush_cache_page(struct vm_area_struct *vma,
unsigned long eaddr, unsigned long pfn)
static void sh5_flush_cache_page(void *args)
{
struct flusher_data *data = args;
struct vm_area_struct *vma;
unsigned long eaddr, pfn;

vma = data->vma;
eaddr = data->addr1;
pfn = data->addr2;

sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);

if (vma->vm_flags & VM_EXEC)
sh64_icache_inv_user_page(vma, eaddr);
}

static void sh5_flush_dcache_page(struct page *page)
static void sh5_flush_dcache_page(void *page)
{
sh64_dcache_purge_phy_page(page_to_phys(page));
wmb();
Expand All @@ -563,8 +575,14 @@ static void sh5_flush_dcache_page(struct page *page)
* mapping, therefore it's guaranteed that there no cache entries for
* the range in cache sets of the wrong colour.
*/
static void sh5_flush_icache_range(unsigned long start, unsigned long end)
static void sh5_flush_icache_range(void *args)
{
struct flusher_data *data = args;
unsigned long start, end;

start = data->addr1;
end = data->addr2;

__flush_purge_region((void *)start, end);
wmb();
sh64_icache_inv_kernel_range(start, end);
Expand All @@ -576,25 +594,25 @@ static void sh5_flush_icache_range(unsigned long start, unsigned long end)
* current process. Used to flush signal trampolines on the stack to
* make them executable.
*/
static void sh5_flush_cache_sigtramp(unsigned long vaddr)
static void sh5_flush_cache_sigtramp(void *vaddr)
{
unsigned long end = vaddr + L1_CACHE_BYTES;
unsigned long end = (unsigned long)vaddr + L1_CACHE_BYTES;

__flush_wback_region((void *)vaddr, L1_CACHE_BYTES);
__flush_wback_region(vaddr, L1_CACHE_BYTES);
wmb();
sh64_icache_inv_current_user_range(vaddr, end);
sh64_icache_inv_current_user_range((unsigned long)vaddr, end);
}

void __init sh5_cache_init(void)
{
flush_cache_all = sh5_flush_cache_all;
flush_cache_mm = sh5_flush_cache_mm;
flush_cache_dup_mm = sh5_flush_cache_mm;
flush_cache_page = sh5_flush_cache_page;
flush_cache_range = sh5_flush_cache_range;
flush_dcache_page = sh5_flush_dcache_page;
flush_icache_range = sh5_flush_icache_range;
flush_cache_sigtramp = sh5_flush_cache_sigtramp;
local_flush_cache_all = sh5_flush_cache_all;
local_flush_cache_mm = sh5_flush_cache_mm;
local_flush_cache_dup_mm = sh5_flush_cache_mm;
local_flush_cache_page = sh5_flush_cache_page;
local_flush_cache_range = sh5_flush_cache_range;
local_flush_dcache_page = sh5_flush_dcache_page;
local_flush_icache_range = sh5_flush_icache_range;
local_flush_cache_sigtramp = sh5_flush_cache_sigtramp;

/* Reserve a slot for dcache colouring in the DTLB */
dtlb_cache_slot = sh64_get_wired_dtlb_entry();
Expand Down
Loading

0 comments on commit e2df05a

Please sign in to comment.