Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7de9cf47 authored by Greentime Hu's avatar Greentime Hu
Browse files

nds32: Cache and TLB routines



This patch contains cache and TLB maintenance functions.

Signed-off-by: default avatarVincent Chen <vincentc@andestech.com>
Signed-off-by: default avatarGreentime Hu <greentime@andestech.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 664eec40
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
// 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 −0
Original line number Diff line number Diff line
// 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 −0
Original line number Diff line number Diff line
// 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 −0
Original line number Diff line number Diff line
// 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 −0
Original line number Diff line number Diff line
// 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__ */
Loading