nds32: Cache and TLB routines
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>
This commit is contained in:
12
arch/nds32/include/asm/cache.h
Normal file
12
arch/nds32/include/asm/cache.h
Normal file
@@ -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__ */
|
13
arch/nds32/include/asm/cache_info.h
Normal file
13
arch/nds32/include/asm/cache_info.h
Normal file
@@ -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
|
||||
};
|
44
arch/nds32/include/asm/cacheflush.h
Normal file
44
arch/nds32/include/asm/cacheflush.h
Normal file
@@ -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__ */
|
68
arch/nds32/include/asm/mmu_context.h
Normal file
68
arch/nds32/include/asm/mmu_context.h
Normal file
@@ -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
|
44
arch/nds32/include/asm/proc-fns.h
Normal file
44
arch/nds32/include/asm/proc-fns.h
Normal file
@@ -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__ */
|
28
arch/nds32/include/asm/tlb.h
Normal file
28
arch/nds32/include/asm/tlb.h
Normal file
@@ -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
|
47
arch/nds32/include/asm/tlbflush.h
Normal file
47
arch/nds32/include/asm/tlbflush.h
Normal file
@@ -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
|
Viittaa uudesa ongelmassa
Block a user