tlbflush.h

来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 229 行

H
229
字号
#ifndef _M68K_TLBFLUSH_H#define _M68K_TLBFLUSH_H#ifndef CONFIG_SUN3#include <asm/current.h>static inline void flush_tlb_kernel_page(void *addr){	if (CPU_IS_040_OR_060) {		mm_segment_t old_fs = get_fs();		set_fs(KERNEL_DS);		__asm__ __volatile__(".chip 68040\n\t"				     "pflush (%0)\n\t"				     ".chip 68k"				     : : "a" (addr));		set_fs(old_fs);	} else		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));}/* * flush all user-space atc entries. */static inline void __flush_tlb(void){	if (CPU_IS_040_OR_060)		__asm__ __volatile__(".chip 68040\n\t"				     "pflushan\n\t"				     ".chip 68k");	else		__asm__ __volatile__("pflush #0,#4");}static inline void __flush_tlb040_one(unsigned long addr){	__asm__ __volatile__(".chip 68040\n\t"			     "pflush (%0)\n\t"			     ".chip 68k"			     : : "a" (addr));}static inline void __flush_tlb_one(unsigned long addr){	if (CPU_IS_040_OR_060)		__flush_tlb040_one(addr);	else		__asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));}#define flush_tlb() __flush_tlb()/* * flush all atc entries (both kernel and user-space entries). */static inline void flush_tlb_all(void){	if (CPU_IS_040_OR_060)		__asm__ __volatile__(".chip 68040\n\t"				     "pflusha\n\t"				     ".chip 68k");	else		__asm__ __volatile__("pflusha");}static inline void flush_tlb_mm(struct mm_struct *mm){	if (mm == current->active_mm)		__flush_tlb();}static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr){	if (vma->vm_mm == current->active_mm) {		mm_segment_t old_fs = get_fs();		set_fs(USER_DS);		__flush_tlb_one(addr);		set_fs(old_fs);	}}static inline void flush_tlb_range(struct vm_area_struct *vma,				   unsigned long start, unsigned long end){	if (vma->vm_mm == current->active_mm)		__flush_tlb();}static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end){	flush_tlb_all();}static inline void flush_tlb_pgtables(struct mm_struct *mm,				      unsigned long start, unsigned long end){}#else/* Reserved PMEGs. */extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];/* Flush all userspace mappings one by one...  (why no flush command,   sun?) */static inline void flush_tlb_all(void){       unsigned long addr;       unsigned char ctx, oldctx;       oldctx = sun3_get_context();       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {	       for(ctx = 0; ctx < 8; ctx++) {		       sun3_put_context(ctx);		       sun3_put_segmap(addr, SUN3_INVALID_PMEG);	       }       }       sun3_put_context(oldctx);       /* erase all of the userspace pmeg maps, we've clobbered them	  all anyway */       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {	       if(pmeg_alloc[addr] == 1) {		       pmeg_alloc[addr] = 0;		       pmeg_ctx[addr] = 0;		       pmeg_vaddr[addr] = 0;	       }       }}/* Clear user TLB entries within the context named in mm */static inline void flush_tlb_mm (struct mm_struct *mm){     unsigned char oldctx;     unsigned char seg;     unsigned long i;     oldctx = sun3_get_context();     sun3_put_context(mm->context);     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {	     seg = sun3_get_segmap(i);	     if(seg == SUN3_INVALID_PMEG)		     continue;	     sun3_put_segmap(i, SUN3_INVALID_PMEG);	     pmeg_alloc[seg] = 0;	     pmeg_ctx[seg] = 0;	     pmeg_vaddr[seg] = 0;     }     sun3_put_context(oldctx);}/* Flush a single TLB page. In this case, we're limited to flushing a   single PMEG */static inline void flush_tlb_page (struct vm_area_struct *vma,				   unsigned long addr){	unsigned char oldctx;	unsigned char i;	oldctx = sun3_get_context();	sun3_put_context(vma->vm_mm->context);	addr &= ~SUN3_PMEG_MASK;	if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)	{		pmeg_alloc[i] = 0;		pmeg_ctx[i] = 0;		pmeg_vaddr[i] = 0;		sun3_put_segmap (addr,  SUN3_INVALID_PMEG);	}	sun3_put_context(oldctx);}/* Flush a range of pages from TLB. */static inline void flush_tlb_range (struct vm_area_struct *vma,		      unsigned long start, unsigned long end){	struct mm_struct *mm = vma->vm_mm;	unsigned char seg, oldctx;	start &= ~SUN3_PMEG_MASK;	oldctx = sun3_get_context();	sun3_put_context(mm->context);	while(start < end)	{		if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)		     goto next;		if(pmeg_ctx[seg] == mm->context) {			pmeg_alloc[seg] = 0;			pmeg_ctx[seg] = 0;			pmeg_vaddr[seg] = 0;		}		sun3_put_segmap(start, SUN3_INVALID_PMEG);	next:		start += SUN3_PMEG_SIZE;	}}static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end){	flush_tlb_all();}/* Flush kernel page from TLB. */static inline void flush_tlb_kernel_page (unsigned long addr){	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);}static inline void flush_tlb_pgtables(struct mm_struct *mm,				      unsigned long start, unsigned long end){}#endif#endif /* _M68K_TLBFLUSH_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?