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

📄 c-r4k.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		c->options |= MIPS_CPU_CACHE_CDEX_P;		break;	case CPU_R4000PC:	case CPU_R4000SC:	case CPU_R4000MC:	case CPU_R4400PC:	case CPU_R4400SC:	case CPU_R4400MC:	case CPU_R4300:		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);		c->icache.ways = 1;		c->icache.waybit = 0; 	/* doesn't matter */		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);		c->dcache.ways = 1;		c->dcache.waybit = 0;	/* does not matter */		c->options |= MIPS_CPU_CACHE_CDEX_P;		break;	case CPU_R10000:	case CPU_R12000:		icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));		c->icache.linesz = 64;		c->icache.ways = 2;		c->icache.waybit = 0;		dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26));		c->dcache.linesz = 32;		c->dcache.ways = 2;		c->dcache.waybit = 0;		c->options |= MIPS_CPU_PREFETCH;		break;	case CPU_VR4133:		write_c0_config(config & ~CONF_EB);	case CPU_VR4131:		/* Workaround for cache instruction bug of VR4131 */		if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U ||		    c->processor_id == 0x0c82U) {			config &= ~0x00000030U;			config |= 0x00410000U;			write_c0_config(config);		}		icache_size = 1 << (10 + ((config & CONF_IC) >> 9));		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);		c->icache.ways = 2;		c->icache.waybit = ffs(icache_size/2) - 1;		dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);		c->dcache.ways = 2;		c->dcache.waybit = ffs(dcache_size/2) - 1;		c->options |= MIPS_CPU_CACHE_CDEX_P;		break;	case CPU_VR41XX:	case CPU_VR4111:	case CPU_VR4121:	case CPU_VR4122:	case CPU_VR4181:	case CPU_VR4181A:		icache_size = 1 << (10 + ((config & CONF_IC) >> 9));		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);		c->icache.ways = 1;		c->icache.waybit = 0; 	/* doesn't matter */		dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);		c->dcache.ways = 1;		c->dcache.waybit = 0;	/* does not matter */		c->options |= MIPS_CPU_CACHE_CDEX_P;		break;	case CPU_RM7000:		rm7k_erratum31();	case CPU_RM9000:		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);		c->icache.ways = 4;		c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);		c->dcache.ways = 4;		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)		c->options |= MIPS_CPU_CACHE_CDEX_P;#endif		c->options |= MIPS_CPU_PREFETCH;		break;	default:		if (!(config & MIPS_CONF_M))			panic("Don't know how to probe P-caches on this cpu.");		/*		 * So we seem to be a MIPS32 or MIPS64 CPU		 * So let's probe the I-cache ...		 */		config1 = read_c0_config1();		if ((lsize = ((config1 >> 19) & 7)))			c->icache.linesz = 2 << lsize;		else			c->icache.linesz = lsize;		c->icache.sets = 64 << ((config1 >> 22) & 7);		c->icache.ways = 1 + ((config1 >> 16) & 7);		icache_size = c->icache.sets *		              c->icache.ways *		              c->icache.linesz;		c->icache.waybit = ffs(icache_size/c->icache.ways) - 1;		if (config & 0x8)		/* VI bit */			c->icache.flags |= MIPS_CACHE_VTAG;		/*		 * Now probe the MIPS32 / MIPS64 data cache.		 */		c->dcache.flags = 0;		if ((lsize = ((config1 >> 10) & 7)))			c->dcache.linesz = 2 << lsize;		else			c->dcache.linesz= lsize;		c->dcache.sets = 64 << ((config1 >> 13) & 7);		c->dcache.ways = 1 + ((config1 >> 7) & 7);		dcache_size = c->dcache.sets *		              c->dcache.ways *		              c->dcache.linesz;		c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1;		c->options |= MIPS_CPU_PREFETCH;		break;	}	/*	 * Processor configuration sanity check for the R4000SC erratum	 * #5.  With page sizes larger than 32kB there is no possibility	 * to get a VCE exception anymore so we don't care about this	 * misconfiguration.  The case is rather theoretical anyway;	 * presumably no vendor is shipping his hardware in the "bad"	 * configuration.	 */	if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 &&	    !(config & CONF_SC) && c->icache.linesz != 16 &&	    PAGE_SIZE <= 0x8000)		panic("Improper R4000SC processor configuration detected");	/* compute a couple of other cache variables */	c->icache.waysize = icache_size / c->icache.ways;	c->dcache.waysize = dcache_size / c->dcache.ways;	c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways);	c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways);	/*	 * R10000 and R12000 P-caches are odd in a positive way.  They're 32kB	 * 2-way virtually indexed so normally would suffer from aliases.  So	 * normally they'd suffer from aliases but magic in the hardware deals	 * with that for us so we don't need to take care ourselves.	 */	switch (c->cputype) {	case CPU_20KC:	case CPU_25KF:	case CPU_R10000:	case CPU_R12000:	case CPU_SB1:		break;	case CPU_24K:		if (!(read_c0_config7() & (1 << 16)))	default:			if (c->dcache.waysize > PAGE_SIZE)				c->dcache.flags |= MIPS_CACHE_ALIASES;	}	switch (c->cputype) {	case CPU_20KC:		/*		 * Some older 20Kc chips doesn't have the 'VI' bit in		 * the config register.		 */		c->icache.flags |= MIPS_CACHE_VTAG;		break;	case CPU_AU1000:	case CPU_AU1500:	case CPU_AU1100:	case CPU_AU1550:	case CPU_AU1200:		c->icache.flags |= MIPS_CACHE_IC_F_DC;		break;	}	printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",	       icache_size >> 10,	       cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",	       way_string[c->icache.ways], c->icache.linesz);	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",	       dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);}/* * If you even _breathe_ on this function, look at the gcc output and make sure * it does not pop things on and off the stack for the cache sizing loop that * executes in KSEG1 space or else you will crash and burn badly.  You have * been warned. */static int __init probe_scache(void){	extern unsigned long stext;	unsigned long flags, addr, begin, end, pow2;	unsigned int config = read_c0_config();	struct cpuinfo_mips *c = &current_cpu_data;	int tmp;	if (config & CONF_SC)		return 0;	begin = (unsigned long) &stext;	begin &= ~((4 * 1024 * 1024) - 1);	end = begin + (4 * 1024 * 1024);	/*	 * This is such a bitch, you'd think they would make it easy to do	 * this.  Away you daemons of stupidity!	 */	local_irq_save(flags);	/* Fill each size-multiple cache line with a valid tag. */	pow2 = (64 * 1024);	for (addr = begin; addr < end; addr = (begin + pow2)) {		unsigned long *p = (unsigned long *) addr;		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */		pow2 <<= 1;	}	/* Load first line with zero (therefore invalid) tag. */	write_c0_taglo(0);	write_c0_taghi(0);	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */	cache_op(Index_Store_Tag_I, begin);	cache_op(Index_Store_Tag_D, begin);	cache_op(Index_Store_Tag_SD, begin);	/* Now search for the wrap around point. */	pow2 = (128 * 1024);	tmp = 0;	for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) {		cache_op(Index_Load_Tag_SD, addr);		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */		if (!read_c0_taglo())			break;		pow2 <<= 1;	}	local_irq_restore(flags);	addr -= begin;	scache_size = addr;	c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22);	c->scache.ways = 1;	c->dcache.waybit = 0;		/* does not matter */	return 1;}extern int r5k_sc_init(void);extern int rm7k_sc_init(void);static void __init setup_scache(void){	struct cpuinfo_mips *c = &current_cpu_data;	unsigned int config = read_c0_config();	int sc_present = 0;	/*	 * Do the probing thing on R4000SC and R4400SC processors.  Other	 * processors don't have a S-cache that would be relevant to the	 * Linux memory managment.	 */	switch (c->cputype) {	case CPU_R4000SC:	case CPU_R4000MC:	case CPU_R4400SC:	case CPU_R4400MC:		sc_present = run_uncached(probe_scache);		if (sc_present)			c->options |= MIPS_CPU_CACHE_CDEX_S;		break;	case CPU_R10000:	case CPU_R12000:		scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);		c->scache.linesz = 64 << ((config >> 13) & 1);		c->scache.ways = 2;		c->scache.waybit= 0;		sc_present = 1;		break;	case CPU_R5000:	case CPU_NEVADA:#ifdef CONFIG_R5000_CPU_SCACHE		r5k_sc_init();#endif                return;	case CPU_RM7000:	case CPU_RM9000:#ifdef CONFIG_RM7000_CPU_SCACHE		rm7k_sc_init();#endif		return;	default:		sc_present = 0;	}	if (!sc_present)		return;	if ((c->isa_level == MIPS_CPU_ISA_M32 ||	     c->isa_level == MIPS_CPU_ISA_M64) &&	    !(c->scache.flags & MIPS_CACHE_NOT_PRESENT))		panic("Dunno how to handle MIPS32 / MIPS64 second level cache");	/* compute a couple of other cache variables */	c->scache.waysize = scache_size / c->scache.ways;	c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);	printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n",	       scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);	c->options |= MIPS_CPU_SUBSET_CACHES;}static inline void coherency_setup(void){	change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);	/*	 * c0_status.cu=0 specifies that updates by the sc instruction use	 * the coherency mode specified by the TLB; 1 means cachable	 * coherent update on write will be used.  Not all processors have	 * this bit and; some wire it to zero, others like Toshiba had the	 * silly idea of putting something else there ...	 */	switch (current_cpu_data.cputype) {	case CPU_R4000PC:	case CPU_R4000SC:	case CPU_R4000MC:	case CPU_R4400PC:	case CPU_R4400SC:	case CPU_R4400MC:		clear_c0_config(CONF_CU);		break;	}}void __init r4k_cache_init(void){	extern void build_clear_page(void);	extern void build_copy_page(void);	extern char except_vec2_generic;	struct cpuinfo_mips *c = &current_cpu_data;	/* Default cache error handler for R4000 and R5000 family */	set_uncached_handler (0x100, &except_vec2_generic, 0x80);	probe_pcache();	setup_scache();	r4k_blast_dcache_page_setup();	r4k_blast_dcache_page_indexed_setup();	r4k_blast_dcache_setup();	r4k_blast_icache_page_setup();	r4k_blast_icache_page_indexed_setup();	r4k_blast_icache_setup();	r4k_blast_scache_page_setup();	r4k_blast_scache_page_indexed_setup();	r4k_blast_scache_setup();	/*	 * Some MIPS32 and MIPS64 processors have physically indexed caches.	 * This code supports virtually indexed processors and will be	 * unnecessarily inefficient on physically indexed processors.	 */	shm_align_mask = max_t( unsigned long,				c->dcache.sets * c->dcache.linesz - 1,				PAGE_SIZE - 1);	flush_cache_all		= r4k_flush_cache_all;	__flush_cache_all	= r4k___flush_cache_all;	flush_cache_mm		= r4k_flush_cache_mm;	flush_cache_page	= r4k_flush_cache_page;	flush_icache_page	= r4k_flush_icache_page;	flush_cache_range	= r4k_flush_cache_range;	flush_cache_sigtramp	= r4k_flush_cache_sigtramp;	flush_icache_all	= r4k_flush_icache_all;	flush_data_cache_page	= r4k_flush_data_cache_page;	flush_icache_range	= r4k_flush_icache_range;#ifdef CONFIG_DMA_NONCOHERENT	_dma_cache_wback_inv	= r4k_dma_cache_wback_inv;	_dma_cache_wback	= r4k_dma_cache_wback_inv;	_dma_cache_inv		= r4k_dma_cache_inv;#endif	build_clear_page();	build_copy_page();	local_r4k___flush_cache_all(NULL);	coherency_setup();}

⌨️ 快捷键说明

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