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

📄 init.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	case cheetah:		phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());		break;	};	phys_page &= _PAGE_PADDR;	phys_page += ((unsigned long)&prom_boot_page -		      (unsigned long)KERNBASE);	if (tlb_type == spitfire) {		/* Lock this into i/d tlb entry 59 */		__asm__ __volatile__(			"stxa	%%g0, [%2] %3\n\t"			"stxa	%0, [%1] %4\n\t"			"membar	#Sync\n\t"			"flush	%%g6\n\t"			"stxa	%%g0, [%2] %5\n\t"			"stxa	%0, [%1] %6\n\t"			"membar	#Sync\n\t"			"flush	%%g6"			: : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |				 _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),			"r" (59 << 3), "r" (TLB_TAG_ACCESS),			"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),			"i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)			: "memory");	} else if (tlb_type == cheetah) {		/* Lock this into i/d tlb-0 entry 11 */		__asm__ __volatile__(			"stxa	%%g0, [%2] %3\n\t"			"stxa	%0, [%1] %4\n\t"			"membar	#Sync\n\t"			"flush	%%g6\n\t"			"stxa	%%g0, [%2] %5\n\t"			"stxa	%0, [%1] %6\n\t"			"membar	#Sync\n\t"			"flush	%%g6"			: : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |				 _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),			"r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS),			"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),			"i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)			: "memory");	} else {		/* Implement me :-) */		BUG();	}	tte_vaddr = (unsigned long) KERNBASE;	/* Spitfire Errata #32 workaround */	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"			     "flush	%%g6"			     : /* No outputs */			     : "r" (0),			     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));	if (tlb_type == spitfire)		tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());	else		tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent());	kern_locked_tte_data = tte_data;	remap_func = (void *)  ((unsigned long) &prom_remap -				(unsigned long) &prom_boot_page);	/* Spitfire Errata #32 workaround */	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"			     "flush	%%g6"			     : /* No outputs */			     : "r" (0),			     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));	remap_func((tlb_type == spitfire ?		    (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :		    (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),		   (unsigned long) KERNBASE,		   prom_get_mmu_ihandle());	if (bigkernel)		remap_func(((tte_data + 0x400000) & _PAGE_PADDR),			(unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle());	/* Flush out that temporary mapping. */	spitfire_flush_dtlb_nucleus_page(0x0);	spitfire_flush_itlb_nucleus_page(0x0);	/* Now lock us back into the TLBs via OBP. */	prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);	prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);	if (bigkernel) {		prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 								tte_vaddr + 0x400000);		prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, 								tte_vaddr + 0x400000);	}	/* Re-read translations property. */	if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {		prom_printf("Couldn't get translation property\n");		prom_halt();	}	n = n / sizeof(*trans);	for (i = 0; i < n; i++) {		unsigned long vaddr = trans[i].virt;		unsigned long size = trans[i].size;		if (vaddr < 0xf0000000UL) {			unsigned long avoid_start = (unsigned long) KERNBASE;			unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);			if (bigkernel)				avoid_end += (4 * 1024 * 1024);			if (vaddr < avoid_start) {				unsigned long top = vaddr + size;				if (top > avoid_start)					top = avoid_start;				prom_unmap(top - vaddr, vaddr);			}			if ((vaddr + size) > avoid_end) {				unsigned long bottom = vaddr;				if (bottom < avoid_end)					bottom = avoid_end;				prom_unmap((vaddr + size) - bottom, bottom);			}		}	}	prom_printf("done.\n");	register_prom_callbacks();}/* The OBP specifications for sun4u mark 0xfffffffc00000000 and * upwards as reserved for use by the firmware (I wonder if this * will be the same on Cheetah...).  We use this virtual address * range for the VPTE table mappings of the nucleus so we need * to zap them when we enter the PROM.  -DaveM */static void __flush_nucleus_vptes(void){	unsigned long prom_reserved_base = 0xfffffffc00000000UL;	int i;	/* Only DTLB must be checked for VPTE entries. */	if (tlb_type == spitfire) {		for (i = 0; i < 63; i++) {			unsigned long tag;			/* Spitfire Errata #32 workaround */			__asm__ __volatile__("stxa	%0, [%1] %2\n\t"					     "flush	%%g6"					     : /* No outputs */					     : "r" (0),					     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));			tag = spitfire_get_dtlb_tag(i);			if (((tag & ~(PAGE_MASK)) == 0) &&			    ((tag &  (PAGE_MASK)) >= prom_reserved_base)) {				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : /* no outputs */						     : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));				spitfire_put_dtlb_data(i, 0x0UL);			}		}	} else if (tlb_type == cheetah) {		for (i = 0; i < 512; i++) {			unsigned long tag = cheetah_get_dtlb_tag(i);			if ((tag & ~PAGE_MASK) == 0 &&			    (tag & PAGE_MASK) >= prom_reserved_base) {				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : /* no outputs */						     : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));				cheetah_put_dtlb_data(i, 0x0UL);			}		}	} else {		/* Implement me :-) */		BUG();	}}static int prom_ditlb_set = 0;struct prom_tlb_entry {	int		tlb_ent;	unsigned long	tlb_tag;	unsigned long	tlb_data;};struct prom_tlb_entry prom_itlb[16], prom_dtlb[16];void prom_world(int enter){	unsigned long pstate;	int i;	if (!enter)		set_fs(current->thread.current_ds);	if (!prom_ditlb_set)		return;	/* Make sure the following runs atomically. */	__asm__ __volatile__("flushw\n\t"			     "rdpr	%%pstate, %0\n\t"			     "wrpr	%0, %1, %%pstate"			     : "=r" (pstate)			     : "i" (PSTATE_IE));	if (enter) {		/* Kick out nucleus VPTEs. */		__flush_nucleus_vptes();		/* Install PROM world. */		for (i = 0; i < 16; i++) {			if (prom_dtlb[i].tlb_ent != -1) {				__asm__ __volatile__("stxa %0, [%1] %2\n\t"						     "membar #Sync"					: : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),					"i" (ASI_DMMU));				if (tlb_type == spitfire)					spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,							       prom_dtlb[i].tlb_data);				else if (tlb_type == cheetah)					cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent,							       prom_dtlb[i].tlb_data);			}			if (prom_itlb[i].tlb_ent != -1) {				__asm__ __volatile__("stxa %0, [%1] %2\n\t"						     "membar #Sync"						     : : "r" (prom_itlb[i].tlb_tag),						     "r" (TLB_TAG_ACCESS),						     "i" (ASI_IMMU));				if (tlb_type == spitfire)					spitfire_put_itlb_data(prom_itlb[i].tlb_ent,							       prom_itlb[i].tlb_data);				else if (tlb_type == cheetah)					cheetah_put_litlb_data(prom_itlb[i].tlb_ent,							       prom_itlb[i].tlb_data);			}		}	} else {		for (i = 0; i < 16; i++) {			if (prom_dtlb[i].tlb_ent != -1) {				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"					: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));				if (tlb_type == spitfire)					spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);				else					cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);			}			if (prom_itlb[i].tlb_ent != -1) {				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : : "r" (TLB_TAG_ACCESS),						     "i" (ASI_IMMU));				if (tlb_type == spitfire)					spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL);				else					cheetah_put_litlb_data(prom_itlb[i].tlb_ent, 0x0UL);			}		}	}	__asm__ __volatile__("wrpr	%0, 0, %%pstate"			     : : "r" (pstate));}void inherit_locked_prom_mappings(int save_p){	int i;	int dtlb_seen = 0;	int itlb_seen = 0;	/* Fucking losing PROM has more mappings in the TLB, but	 * it (conveniently) fails to mention any of these in the	 * translations property.  The only ones that matter are	 * the locked PROM tlb entries, so we impose the following	 * irrecovable rule on the PROM, it is allowed 8 locked	 * entries in the ITLB and 8 in the DTLB.	 *	 * Supposedly the upper 16GB of the address space is	 * reserved for OBP, BUT I WISH THIS WAS DOCUMENTED	 * SOMEWHERE!!!!!!!!!!!!!!!!!  Furthermore the entire interface	 * used between the client program and the firmware on sun5	 * systems to coordinate mmu mappings is also COMPLETELY	 * UNDOCUMENTED!!!!!! Thanks S(t)un!	 */	if (save_p) {		for (i = 0; i < 16; i++) {			prom_itlb[i].tlb_ent = -1;			prom_dtlb[i].tlb_ent = -1;		}	}	if (tlb_type == spitfire) {		int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel;		for (i = 0; i < high; i++) {			unsigned long data;			/* Spitfire Errata #32 workaround */			__asm__ __volatile__("stxa	%0, [%1] %2\n\t"					     "flush	%%g6"					     : /* No outputs */					     : "r" (0),					     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));			data = spitfire_get_dtlb_data(i);			if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {				unsigned long tag;				/* Spitfire Errata #32 workaround */				__asm__ __volatile__("stxa	%0, [%1] %2\n\t"						     "flush	%%g6"						     : /* No outputs */						     : "r" (0),						     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));				tag = spitfire_get_dtlb_tag(i);				if (save_p) {					prom_dtlb[dtlb_seen].tlb_ent = i;					prom_dtlb[dtlb_seen].tlb_tag = tag;					prom_dtlb[dtlb_seen].tlb_data = data;				}				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));				spitfire_put_dtlb_data(i, 0x0UL);				dtlb_seen++;				if (dtlb_seen > 15)					break;			}		}		for (i = 0; i < high; i++) {			unsigned long data;			/* Spitfire Errata #32 workaround */			__asm__ __volatile__("stxa	%0, [%1] %2\n\t"					     "flush	%%g6"					     : /* No outputs */					     : "r" (0),					     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));			data = spitfire_get_itlb_data(i);			if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {				unsigned long tag;				/* Spitfire Errata #32 workaround */				__asm__ __volatile__("stxa	%0, [%1] %2\n\t"						     "flush	%%g6"						     : /* No outputs */						     : "r" (0),						     "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));				tag = spitfire_get_itlb_tag(i);				if (save_p) {					prom_itlb[itlb_seen].tlb_ent = i;					prom_itlb[itlb_seen].tlb_tag = tag;					prom_itlb[itlb_seen].tlb_data = data;				}				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));				spitfire_put_itlb_data(i, 0x0UL);				itlb_seen++;				if (itlb_seen > 15)					break;			}		}	} else if (tlb_type == cheetah) {		int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel;		for (i = 0; i < high; i++) {			unsigned long data;			data = cheetah_get_ldtlb_data(i);			if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {				unsigned long tag;				tag = cheetah_get_ldtlb_tag(i);				if (save_p) {					prom_dtlb[dtlb_seen].tlb_ent = i;					prom_dtlb[dtlb_seen].tlb_tag = tag;					prom_dtlb[dtlb_seen].tlb_data = data;				}				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));				cheetah_put_ldtlb_data(i, 0x0UL);				dtlb_seen++;				if (dtlb_seen > 15)					break;			}		}		for (i = 0; i < high; i++) {			unsigned long data;			data = cheetah_get_litlb_data(i);			if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {				unsigned long tag;				tag = cheetah_get_litlb_tag(i);				if (save_p) {					prom_itlb[itlb_seen].tlb_ent = i;					prom_itlb[itlb_seen].tlb_tag = tag;					prom_itlb[itlb_seen].tlb_data = data;				}				__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"						     "membar #Sync"						     : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));				cheetah_put_litlb_data(i, 0x0UL);				itlb_seen++;				if (itlb_seen > 15)					break;

⌨️ 快捷键说明

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