⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 linux 内核源代码
💻 C
字号:
/* * Copyright (C) 2004-2006 Atmel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/highmem.h>#include <linux/unistd.h>#include <asm/cacheflush.h>#include <asm/cachectl.h>#include <asm/processor.h>#include <asm/uaccess.h>/* * If you attempt to flush anything more than this, you need superuser * privileges.  The value is completely arbitrary. */#define CACHEFLUSH_MAX_LEN	1024void invalidate_dcache_region(void *start, size_t size){	unsigned long v, begin, end, linesz, mask;	linesz = boot_cpu_data.dcache.linesz;	mask = linesz - 1;	/* when first and/or last cachelines are shared, flush them	 * instead of invalidating ... never discard valid data!	 */	begin = (unsigned long)start;	end = begin + size;	if (begin & mask) {		flush_dcache_line(start);		begin += linesz;	}	if (end & mask) {		flush_dcache_line((void *)end);		end &= ~mask;	}	/* remaining cachelines only need invalidation */	for (v = begin; v < end; v += linesz)		invalidate_dcache_line((void *)v);	flush_write_buffer();}void clean_dcache_region(void *start, size_t size){	unsigned long v, begin, end, linesz;	linesz = boot_cpu_data.dcache.linesz;	begin = (unsigned long)start & ~(linesz - 1);	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);	for (v = begin; v < end; v += linesz)		clean_dcache_line((void *)v);	flush_write_buffer();}void flush_dcache_region(void *start, size_t size){	unsigned long v, begin, end, linesz;	linesz = boot_cpu_data.dcache.linesz;	begin = (unsigned long)start & ~(linesz - 1);	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);	for (v = begin; v < end; v += linesz)		flush_dcache_line((void *)v);	flush_write_buffer();}void invalidate_icache_region(void *start, size_t size){	unsigned long v, begin, end, linesz;	linesz = boot_cpu_data.icache.linesz;	begin = (unsigned long)start & ~(linesz - 1);	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);	for (v = begin; v < end; v += linesz)		invalidate_icache_line((void *)v);}static inline void __flush_icache_range(unsigned long start, unsigned long end){	unsigned long v, linesz;	linesz = boot_cpu_data.dcache.linesz;	for (v = start; v < end; v += linesz) {		clean_dcache_line((void *)v);		invalidate_icache_line((void *)v);	}	flush_write_buffer();}/* * This one is called after a module has been loaded. */void flush_icache_range(unsigned long start, unsigned long end){	unsigned long linesz;	linesz = boot_cpu_data.dcache.linesz;	__flush_icache_range(start & ~(linesz - 1),			     (end + linesz - 1) & ~(linesz - 1));}/* * This one is called from do_no_page(), do_swap_page() and install_page(). */void flush_icache_page(struct vm_area_struct *vma, struct page *page){	if (vma->vm_flags & VM_EXEC) {		void *v = page_address(page);		__flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);	}}asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len){	int ret;	if (len > CACHEFLUSH_MAX_LEN) {		ret = -EPERM;		if (!capable(CAP_SYS_ADMIN))			goto out;	}	ret = -EFAULT;	if (!access_ok(VERIFY_WRITE, addr, len))		goto out;	switch (operation) {	case CACHE_IFLUSH:		flush_icache_range((unsigned long)addr,				   (unsigned long)addr + len);		ret = 0;		break;	default:		ret = -EINVAL;	}out:	return ret;}void copy_to_user_page(struct vm_area_struct *vma, struct page *page,		unsigned long vaddr, void *dst, const void *src,		unsigned long len){	memcpy(dst, src, len);	if (vma->vm_flags & VM_EXEC)		flush_icache_range((unsigned long)dst,				(unsigned long)dst + len);}

⌨️ 快捷键说明

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