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

📄 rm7k.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				set_entryhi(KSEG0);				BARRIER;				if(idx < 0)					continue;				tlb_write_indexed();				BARRIER;			}			set_entryhi(oldpid);		} else {			get_new_mmu_context(mm, asid_cache);			if(mm == current->mm)				set_entryhi(mm->context & 0xff);		}		__restore_flags(flags);	}}void flush_tlb_page(struct vm_area_struct *vma, unsigned long page){	if(vma->vm_mm->context != 0) {		unsigned long flags;		int oldpid, newpid, idx;		newpid = (vma->vm_mm->context & 0xff);		page &= (PAGE_MASK << 1);		__save_and_cli(flags);		oldpid = (get_entryhi() & 0xff);		set_entryhi(page | newpid);		BARRIER;		tlb_probe();		BARRIER;		idx = get_index();		set_entrylo0(0);		set_entrylo1(0);		set_entryhi(KSEG0);		if(idx < 0)			goto finish;		BARRIER;		tlb_write_indexed();	finish:		BARRIER;		set_entryhi(oldpid);		__restore_flags(flags);	}}void pgd_init(unsigned long page){	unsigned long *p = (unsigned long *) page;	int i;	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {		p[i + 0] = (unsigned long) invalid_pte_table;		p[i + 1] = (unsigned long) invalid_pte_table;		p[i + 2] = (unsigned long) invalid_pte_table;		p[i + 3] = (unsigned long) invalid_pte_table;		p[i + 4] = (unsigned long) invalid_pte_table;		p[i + 5] = (unsigned long) invalid_pte_table;		p[i + 6] = (unsigned long) invalid_pte_table;		p[i + 7] = (unsigned long) invalid_pte_table;	}}/* * We will need multiple versions of update_mmu_cache(), one that just * updates the TLB with the new pte(s), and another which also checks * for the R4k "end of page" hardware bug and does the needy. */void update_mmu_cache(struct vm_area_struct * vma,				 unsigned long address, pte_t pte){	unsigned long flags;	pgd_t *pgdp;	pmd_t *pmdp;	pte_t *ptep;	int idx, pid;	/*	 * Handle debugger faulting in for debugee.	 */	if (current->active_mm != vma->vm_mm)		return;	pid = get_entryhi() & 0xff;	__save_and_cli(flags);	address &= (PAGE_MASK << 1);	set_entryhi(address | (pid));	pgdp = pgd_offset(vma->vm_mm, address);	BARRIER;	tlb_probe();	BARRIER;	pmdp = pmd_offset(pgdp, address);	idx = get_index();	ptep = pte_offset(pmdp, address);	BARRIER;	set_entrylo0(pte_val(*ptep++) >> 6);	set_entrylo1(pte_val(*ptep) >> 6);	set_entryhi(address | (pid));	BARRIER;	if (idx < 0) {		tlb_write_random();	} else {		tlb_write_indexed();	}	BARRIER;	set_entryhi(pid);	BARRIER;	__restore_flags(flags);}void show_regs(struct pt_regs * regs){	/* Saved main processor registers. */	printk(KERN_INFO "$0 : %08lx %08lx %08lx %08lx\n",	       0UL, regs->regs[1], regs->regs[2], regs->regs[3]);	printk(KERN_INFO "$4 : %08lx %08lx %08lx %08lx\n",               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);	printk(KERN_INFO "$8 : %08lx %08lx %08lx %08lx\n",	       regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);	printk(KERN_INFO "$12: %08lx %08lx %08lx %08lx\n",               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);	printk(KERN_INFO "$16: %08lx %08lx %08lx %08lx\n",	       regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);	printk(KERN_INFO "$20: %08lx %08lx %08lx %08lx\n",               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);	printk(KERN_INFO "$24: %08lx %08lx\n",	       regs->regs[24], regs->regs[25]);	printk(KERN_INFO "$28: %08lx %08lx %08lx %08lx\n",	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);	/* Saved cp0 registers. */	printk(KERN_INFO "epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);}void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,                     unsigned long entryhi, unsigned long pagemask){        unsigned long flags;        unsigned long wired;        unsigned long old_pagemask;        unsigned long old_ctx;        __save_and_cli(flags);        /* Save old context and create impossible VPN2 value */        old_ctx = (get_entryhi() & 0xff);        old_pagemask = get_pagemask();        wired = get_wired();        set_wired (wired + 1);        set_index (wired);        BARRIER;            set_pagemask (pagemask);        set_entryhi(entryhi);        set_entrylo0(entrylo0);        set_entrylo1(entrylo1);        BARRIER;            tlb_write_indexed();        BARRIER;                set_entryhi(old_ctx);        BARRIER;            set_pagemask (old_pagemask);        flush_tlb_all();            __restore_flags(flags);}/* Used for loading TLB entries before trap_init() has started, when we   don't actually want to add a wired entry which remains throughout the   lifetime of the system */static int temp_tlb_entry __initdata;__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,                               unsigned long entryhi, unsigned long pagemask){	int ret = 0;        unsigned long flags;        unsigned long wired;        unsigned long old_pagemask;        unsigned long old_ctx;        __save_and_cli(flags);        /* Save old context and create impossible VPN2 value */        old_ctx = (get_entryhi() & 0xff);        old_pagemask = get_pagemask();        wired = get_wired();        if (--temp_tlb_entry < wired) {		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");		ret = -ENOSPC;		goto out;	}        set_index (temp_tlb_entry);        BARRIER;            set_pagemask (pagemask);        set_entryhi(entryhi);        set_entrylo0(entrylo0);        set_entrylo1(entrylo1);        BARRIER;            tlb_write_indexed();        BARRIER;                set_entryhi(old_ctx);        BARRIER;            set_pagemask (old_pagemask); out:        __restore_flags(flags);	return ret;}/* Detect and size the caches. */static inline void probe_icache(unsigned long config){	icache_size = 1 << (12 + ((config >> 9) & 7));	printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10);}static inline void probe_dcache(unsigned long config){	dcache_size = 1 << (12 + ((config >> 6) & 7));	printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10);}/*  * This function is executed in the uncached segment KSEG1. * It must not touch the stack, because the stack pointer still points * into KSEG0.  * * Three options: *	- Write it in assembly and guarantee that we don't use the stack. *	- Disable caching for KSEG0 before calling it. *	- Pray that GCC doesn't randomly start using the stack. * * This being Linux, we obviously take the least sane of those options - * following DaveM's lead in r4xx0.c * * It seems we get our kicks from relying on unguaranteed behaviour in GCC */static __init void setup_scache(void){	int register i;		set_cp0_config(1<<3 /* CONF_SE */);	set_taglo(0);	set_taghi(0);		for (i=0; i<scache_size; i+=sc_lsize) {		__asm__ __volatile__ (		      ".set noreorder\n\t"		      ".set mips3\n\t"		      "cache %1, (%0)\n\t"		      ".set mips0\n\t"		      ".set reorder"		      :		      : "r" (KSEG0ADDR(i)),		        "i" (Index_Store_Tag_SD));	}}static inline void probe_scache(unsigned long config){	void (*func)(void) = KSEG1ADDR(&setup_scache);	if ((config >> 31) & 1)		return;	printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n",	       (scache_size >> 10), sc_lsize);	if ((config >> 3) & 1)		return;	printk(KERN_INFO "Enabling secondary cache...");	func();	printk("Done\n");} static inline void probe_tcache(unsigned long config){	if ((config >> 17) & 1)		return;	/* We can't enable the L3 cache yet. There may be board-specific	 * magic necessary to turn it on, and blindly asking the CPU to	 * start using it would may give cache errors.	 *	 * Also, board-specific knowledge may allow us to use the 	 * CACHE Flash_Invalidate_T instruction if the tag RAM supports	 * it, and may specify the size of the L3 cache so we don't have	 * to probe it. 	 */	printk(KERN_INFO "Tertiary cache present, %s enabled\n",	       config&(1<<12) ? "already" : "not (yet)");	if ((config >> 12) & 1)		rm7k_tcache_enabled = 1;}void __init ld_mmu_rm7k(void){	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);	unsigned long addr;	printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));        change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);	/* RM7000 erratum #31. The icache is screwed at startup. */	set_taglo(0);	set_taghi(0);	for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) {		__asm__ __volatile__ (			".set noreorder\n\t"			".set mips3\n\t"			"cache\t%1, 0(%0)\n\t"			"cache\t%1, 0x1000(%0)\n\t"			"cache\t%1, 0x2000(%0)\n\t"			"cache\t%1, 0x3000(%0)\n\t"			"cache\t%2, 0(%0)\n\t"			"cache\t%2, 0x1000(%0)\n\t"			"cache\t%2, 0x2000(%0)\n\t"			"cache\t%2, 0x3000(%0)\n\t"			"cache\t%1, 0(%0)\n\t"			"cache\t%1, 0x1000(%0)\n\t"			"cache\t%1, 0x2000(%0)\n\t"			"cache\t%1, 0x3000(%0)\n\t"			".set\tmips0\n\t"			".set\treorder\n\t"			:			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));	}#ifndef CONFIG_MIPS_UNCACHED	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);#endif	probe_icache(config);	probe_dcache(config);	probe_scache(config);	probe_tcache(config);	printk("TLB has %d entries.\n", ntlb_entries());	_clear_page = rm7k_clear_page;	_copy_page = rm7k_copy_page;	_flush_cache_all = rm7k_flush_cache_all_d32i32;	___flush_cache_all = __flush_cache_all_d32i32;	_flush_cache_mm = rm7k_flush_cache_mm_d32i32;	_flush_cache_range = rm7k_flush_cache_range_d32i32;	_flush_cache_page = rm7k_flush_cache_page_d32i32;	_flush_page_to_ram = rm7k_flush_page_to_ram_d32i32;	_flush_cache_sigtramp = rm7k_flush_cache_sigtramp;	_flush_icache_range = rm7k_flush_icache_range;	_flush_icache_page = rm7k_flush_icache_page;	_dma_cache_wback_inv = rm7k_dma_cache_wback_inv;	_dma_cache_wback = rm7k_dma_cache_wback;	_dma_cache_inv = rm7k_dma_cache_inv;	__flush_cache_all_d32i32();	write_32bit_cp0_register(CP0_WIRED, 0);	temp_tlb_entry = ntlb_entries() - 1;	write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);	flush_tlb_all();}

⌨️ 快捷键说明

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