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

📄 cache.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
字号:
/* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1999 Helge Deller (07-13-1999) * Copyright (C) 1999 SuSE GmbH Nuernberg * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org) * * Cache and TLB management * */ #include <linux/init.h>#include <linux/kernel.h>#include <linux/mm.h>#include <asm/pdc.h>#include <asm/cache.h>#include <asm/system.h>#include <asm/page.h>#include <asm/pgalloc.h>struct pdc_cache_info cache_info;#ifndef __LP64__static struct pdc_btlb_info btlb_info;#endifvoid __flush_page_to_ram(unsigned long address){	__flush_dcache_range(address, PAGE_SIZE);	__flush_icache_range(address, PAGE_SIZE);}void flush_data_cache(void){	register unsigned long base   = cache_info.dc_base;	register unsigned long count  = cache_info.dc_count;	register unsigned long loop   = cache_info.dc_loop;	register unsigned long stride = cache_info.dc_stride;	register unsigned long addr;	register long i, j;	for(i=0,addr=base; i<count; i++,addr+=stride)		for(j=0; j<loop; j++)			fdce(addr);}		static inline void flush_data_tlb_space(void){	unsigned long base   = cache_info.dt_off_base;	unsigned long count  = cache_info.dt_off_count;	unsigned long stride = cache_info.dt_off_stride;	unsigned long loop   = cache_info.dt_loop;	unsigned long addr;	long i,j;		for(i=0,addr=base; i<count; i++,addr+=stride)		for(j=0; j<loop; j++)			pdtlbe(addr);}void flush_data_tlb(void){	unsigned long base   = cache_info.dt_sp_base;	unsigned long count  = cache_info.dt_sp_count;	unsigned long stride = cache_info.dt_sp_stride;	unsigned long space;	unsigned long old_sr1;	long i;		old_sr1 = mfsp(1);		for(i=0,space=base; i<count; i++, space+=stride) {		mtsp(space,1);		flush_data_tlb_space();	}	mtsp(old_sr1, 1);}static inline void flush_instruction_tlb_space(void){	unsigned long base   = cache_info.it_off_base;	unsigned long count  = cache_info.it_off_count;	unsigned long stride = cache_info.it_off_stride;	unsigned long loop   = cache_info.it_loop;	unsigned long addr;	long i,j;		for(i=0,addr=base; i<count; i++,addr+=stride)		for(j=0; j<loop; j++)			pitlbe(addr);}void flush_instruction_tlb(void){	unsigned long base   = cache_info.it_sp_base;	unsigned long count  = cache_info.it_sp_count;	unsigned long stride = cache_info.it_sp_stride;	unsigned long space;	unsigned long old_sr1;	unsigned int i;		old_sr1 = mfsp(1);		for(i=0,space=base; i<count; i++, space+=stride) {		mtsp(space,1);		flush_instruction_tlb_space();	}	mtsp(old_sr1, 1);}void __flush_tlb_space(unsigned long space){	unsigned long old_sr1;	old_sr1 = mfsp(1);	mtsp(space, 1);		flush_data_tlb_space();	flush_instruction_tlb_space();	mtsp(old_sr1, 1);}void flush_instruction_cache(void){	register unsigned long base   = cache_info.ic_base;	register unsigned long count  = cache_info.ic_count;	register unsigned long loop   = cache_info.ic_loop;	register unsigned long stride = cache_info.ic_stride;	register unsigned long addr;	register long i, j;	unsigned long old_sr1;		old_sr1 = mfsp(1);	mtsp(0,1);	/*	 * Note: fice instruction has 3 bit space field, so one must	 *       be specified (otherwise you are justing using whatever	 *       happens to be in sr0).	 */	for(i=0,addr=base; i<count; i++,addr+=stride)		for(j=0; j<loop; j++)			fice(addr);	mtsp(old_sr1, 1);}/* not yet ... fdc() needs to be implemented in cache.h !void flush_datacache_range( unsigned int base, unsigned int end ){    register long offset,offset_add;    offset_add = ( (1<<(cache_info.dc_conf.cc_block-1)) * 		    cache_info.dc_conf.cc_line ) << 4;    for (offset=base; offset<=end; offset+=offset_add)	fdc(space,offset);    fdc(space,end);}*//* flushes code and data-cache */void flush_all_caches(void){	flush_instruction_cache();	flush_data_cache();	flush_instruction_tlb();	flush_data_tlb();	asm volatile("sync");	asm volatile("syncdma");	asm volatile("sync");}int get_cache_info(char *buffer){	char *p = buffer;	p += sprintf(p, "I-cache\t\t: %ld KB\n", 		cache_info.ic_size/1024 );	p += sprintf(p, "D-cache\t\t: %ld KB (%s)%s\n", 		cache_info.dc_size/1024,		(cache_info.dc_conf.cc_wt ? "WT":"WB"),		(cache_info.dc_conf.cc_sh ? " - shared I/D":"")	);	p += sprintf(p, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",		cache_info.it_size,		cache_info.dt_size,		cache_info.dt_conf.tc_sh ? " - shared with ITLB":""	);		#ifndef __LP64__	/* BTLB - Block TLB */	if (btlb_info.max_size==0) {		p += sprintf(p, "BTLB\t\t: not supported\n" );	} else {		p += sprintf(p, 		"BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"		"BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"		"BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",		btlb_info.max_size, (int)4096,		btlb_info.max_size>>8,		btlb_info.fixed_range_info.num_i,		btlb_info.fixed_range_info.num_d,		btlb_info.fixed_range_info.num_comb, 		btlb_info.variable_range_info.num_i,		btlb_info.variable_range_info.num_d,		btlb_info.variable_range_info.num_comb		);	}#endif	return p - buffer;}void __init cache_init(void){	if(pdc_cache_info(&cache_info)<0)		panic("cache_init: pdc_cache_info failed");#if 0	printk("ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",	    cache_info.ic_size,	    cache_info.dc_size,	    cache_info.it_size,	    sizeof (struct pdc_cache_info) / sizeof (long),	    sizeof (struct pdc_cache_cf)	);#endif#ifndef __LP64__	if(pdc_btlb_info(&btlb_info)<0) {		memset(&btlb_info, 0, sizeof btlb_info);	}#endif}

⌨️ 快捷键说明

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