-
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.
This patch contains cache and TLB maintenance functions. Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
- Loading branch information
Greentime Hu
committed
Feb 22, 2018
1 parent
664eec4
commit 7de9cf4
Showing
12 changed files
with
1,224 additions
and
0 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,12 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __NDS32_CACHE_H__ | ||
#define __NDS32_CACHE_H__ | ||
|
||
#define L1_CACHE_BYTES 32 | ||
#define L1_CACHE_SHIFT 5 | ||
|
||
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES | ||
|
||
#endif /* __NDS32_CACHE_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
struct cache_info { | ||
unsigned char ways; | ||
unsigned char line_size; | ||
unsigned short sets; | ||
unsigned short size; | ||
#if defined(CONFIG_CPU_CACHE_ALIASING) | ||
unsigned short aliasing_num; | ||
unsigned int aliasing_mask; | ||
#endif | ||
}; |
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,44 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __NDS32_CACHEFLUSH_H__ | ||
#define __NDS32_CACHEFLUSH_H__ | ||
|
||
#include <linux/mm.h> | ||
|
||
#define PG_dcache_dirty PG_arch_1 | ||
|
||
#ifdef CONFIG_CPU_CACHE_ALIASING | ||
void flush_cache_mm(struct mm_struct *mm); | ||
void flush_cache_dup_mm(struct mm_struct *mm); | ||
void flush_cache_range(struct vm_area_struct *vma, | ||
unsigned long start, unsigned long end); | ||
void flush_cache_page(struct vm_area_struct *vma, | ||
unsigned long addr, unsigned long pfn); | ||
void flush_cache_kmaps(void); | ||
void flush_cache_vmap(unsigned long start, unsigned long end); | ||
void flush_cache_vunmap(unsigned long start, unsigned long end); | ||
|
||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||
void flush_dcache_page(struct page *page); | ||
void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | ||
unsigned long vaddr, void *dst, void *src, int len); | ||
void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | ||
unsigned long vaddr, void *dst, void *src, int len); | ||
|
||
#define ARCH_HAS_FLUSH_ANON_PAGE | ||
void flush_anon_page(struct vm_area_struct *vma, | ||
struct page *page, unsigned long vaddr); | ||
|
||
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE | ||
void flush_kernel_dcache_page(struct page *page); | ||
void flush_icache_range(unsigned long start, unsigned long end); | ||
void flush_icache_page(struct vm_area_struct *vma, struct page *page); | ||
#define flush_dcache_mmap_lock(mapping) spin_lock_irq(&(mapping)->tree_lock) | ||
#define flush_dcache_mmap_unlock(mapping) spin_unlock_irq(&(mapping)->tree_lock) | ||
|
||
#else | ||
#include <asm-generic/cacheflush.h> | ||
#endif | ||
|
||
#endif /* __NDS32_CACHEFLUSH_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __ASM_NDS32_MMU_CONTEXT_H | ||
#define __ASM_NDS32_MMU_CONTEXT_H | ||
|
||
#include <linux/spinlock.h> | ||
#include <asm/tlbflush.h> | ||
#include <asm/proc-fns.h> | ||
#include <asm-generic/mm_hooks.h> | ||
|
||
static inline int | ||
init_new_context(struct task_struct *tsk, struct mm_struct *mm) | ||
{ | ||
mm->context.id = 0; | ||
return 0; | ||
} | ||
|
||
#define destroy_context(mm) do { } while(0) | ||
|
||
#define CID_BITS 9 | ||
extern spinlock_t cid_lock; | ||
extern unsigned int cpu_last_cid; | ||
|
||
static inline void __new_context(struct mm_struct *mm) | ||
{ | ||
unsigned int cid; | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&cid_lock, flags); | ||
cid = cpu_last_cid; | ||
cpu_last_cid += 1 << TLB_MISC_offCID; | ||
if (cpu_last_cid == 0) | ||
cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS; | ||
|
||
if ((cid & TLB_MISC_mskCID) == 0) | ||
flush_tlb_all(); | ||
spin_unlock_irqrestore(&cid_lock, flags); | ||
|
||
mm->context.id = cid; | ||
} | ||
|
||
static inline void check_context(struct mm_struct *mm) | ||
{ | ||
if (unlikely | ||
((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS)) | ||
__new_context(mm); | ||
} | ||
|
||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | ||
{ | ||
} | ||
|
||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
struct task_struct *tsk) | ||
{ | ||
unsigned int cpu = smp_processor_id(); | ||
|
||
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { | ||
check_context(next); | ||
cpu_switch_mm(next); | ||
} | ||
} | ||
|
||
#define deactivate_mm(tsk,mm) do { } while (0) | ||
#define activate_mm(prev,next) switch_mm(prev, next, NULL) | ||
|
||
#endif |
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,44 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __NDS32_PROCFNS_H__ | ||
#define __NDS32_PROCFNS_H__ | ||
|
||
#ifdef __KERNEL__ | ||
#include <asm/page.h> | ||
|
||
struct mm_struct; | ||
struct vm_area_struct; | ||
extern void cpu_proc_init(void); | ||
extern void cpu_proc_fin(void); | ||
extern void cpu_do_idle(void); | ||
extern void cpu_reset(unsigned long reset); | ||
extern void cpu_switch_mm(struct mm_struct *mm); | ||
|
||
extern void cpu_dcache_inval_all(void); | ||
extern void cpu_dcache_wbinval_all(void); | ||
extern void cpu_dcache_inval_page(unsigned long page); | ||
extern void cpu_dcache_wb_page(unsigned long page); | ||
extern void cpu_dcache_wbinval_page(unsigned long page); | ||
extern void cpu_dcache_inval_range(unsigned long start, unsigned long end); | ||
extern void cpu_dcache_wb_range(unsigned long start, unsigned long end); | ||
extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end); | ||
|
||
extern void cpu_icache_inval_all(void); | ||
extern void cpu_icache_inval_page(unsigned long page); | ||
extern void cpu_icache_inval_range(unsigned long start, unsigned long end); | ||
|
||
extern void cpu_cache_wbinval_page(unsigned long page, int flushi); | ||
extern void cpu_cache_wbinval_range(unsigned long start, | ||
unsigned long end, int flushi); | ||
extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma, | ||
unsigned long start, | ||
unsigned long end, bool flushi, | ||
bool wbd); | ||
|
||
extern void cpu_dma_wb_range(unsigned long start, unsigned long end); | ||
extern void cpu_dma_inval_range(unsigned long start, unsigned long end); | ||
extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end); | ||
|
||
#endif /* __KERNEL__ */ | ||
#endif /* __NDS32_PROCFNS_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __ASMNDS32_TLB_H | ||
#define __ASMNDS32_TLB_H | ||
|
||
#define tlb_start_vma(tlb,vma) \ | ||
do { \ | ||
if (!tlb->fullmm) \ | ||
flush_cache_range(vma, vma->vm_start, vma->vm_end); \ | ||
} while (0) | ||
|
||
#define tlb_end_vma(tlb,vma) \ | ||
do { \ | ||
if(!tlb->fullmm) \ | ||
flush_tlb_range(vma, vma->vm_start, vma->vm_end); \ | ||
} while (0) | ||
|
||
#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0) | ||
|
||
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) | ||
|
||
#include <asm-generic/tlb.h> | ||
|
||
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) | ||
#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tln)->mm, pmd) | ||
|
||
#endif |
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,47 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef _ASMNDS32_TLBFLUSH_H | ||
#define _ASMNDS32_TLBFLUSH_H | ||
|
||
#include <linux/spinlock.h> | ||
#include <linux/mm.h> | ||
#include <nds32_intrinsic.h> | ||
|
||
static inline void local_flush_tlb_all(void) | ||
{ | ||
__nds32__tlbop_flua(); | ||
__nds32__isb(); | ||
} | ||
|
||
static inline void local_flush_tlb_mm(struct mm_struct *mm) | ||
{ | ||
__nds32__tlbop_flua(); | ||
__nds32__isb(); | ||
} | ||
|
||
static inline void local_flush_tlb_kernel_range(unsigned long start, | ||
unsigned long end) | ||
{ | ||
while (start < end) { | ||
__nds32__tlbop_inv(start); | ||
__nds32__isb(); | ||
start += PAGE_SIZE; | ||
} | ||
} | ||
|
||
void local_flush_tlb_range(struct vm_area_struct *vma, | ||
unsigned long start, unsigned long end); | ||
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); | ||
|
||
#define flush_tlb_all local_flush_tlb_all | ||
#define flush_tlb_mm local_flush_tlb_mm | ||
#define flush_tlb_range local_flush_tlb_range | ||
#define flush_tlb_page local_flush_tlb_page | ||
#define flush_tlb_kernel_range local_flush_tlb_kernel_range | ||
|
||
void update_mmu_cache(struct vm_area_struct *vma, | ||
unsigned long address, pte_t * pte); | ||
void tlb_migrate_finish(struct mm_struct *mm); | ||
|
||
#endif |
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,14 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 1994, 1995, 1996 by Ralf Baechle | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
#ifndef _ASM_CACHECTL | ||
#define _ASM_CACHECTL | ||
|
||
/* | ||
* Options for cacheflush system call | ||
*/ | ||
#define ICACHE 0 /* flush instruction cache */ | ||
#define DCACHE 1 /* writeback and flush data cache */ | ||
#define BCACHE 2 /* flush instruction cache + writeback and flush data cache */ | ||
|
||
#endif /* _ASM_CACHECTL */ |
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,49 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#include <linux/bitops.h> | ||
#include <linux/cacheinfo.h> | ||
#include <linux/cpu.h> | ||
|
||
static void ci_leaf_init(struct cacheinfo *this_leaf, | ||
enum cache_type type, unsigned int level) | ||
{ | ||
char cache_type = (type & CACHE_TYPE_INST ? ICACHE : DCACHE); | ||
|
||
this_leaf->level = level; | ||
this_leaf->type = type; | ||
this_leaf->coherency_line_size = CACHE_LINE_SIZE(cache_type); | ||
this_leaf->number_of_sets = CACHE_SET(cache_type);; | ||
this_leaf->ways_of_associativity = CACHE_WAY(cache_type); | ||
this_leaf->size = this_leaf->number_of_sets * | ||
this_leaf->coherency_line_size * this_leaf->ways_of_associativity; | ||
#if defined(CONFIG_CPU_DCACHE_WRITETHROUGH) | ||
this_leaf->attributes = CACHE_WRITE_THROUGH; | ||
#else | ||
this_leaf->attributes = CACHE_WRITE_BACK; | ||
#endif | ||
} | ||
|
||
int init_cache_level(unsigned int cpu) | ||
{ | ||
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
|
||
/* Only 1 level and I/D cache seperate. */ | ||
this_cpu_ci->num_levels = 1; | ||
this_cpu_ci->num_leaves = 2; | ||
return 0; | ||
} | ||
|
||
int populate_cache_leaves(unsigned int cpu) | ||
{ | ||
unsigned int level, idx; | ||
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
struct cacheinfo *this_leaf = this_cpu_ci->info_list; | ||
|
||
for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && | ||
idx < this_cpu_ci->num_leaves; idx++, level++) { | ||
ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); | ||
ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); | ||
} | ||
return 0; | ||
} |
Oops, something went wrong.