extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2]; 
static void inherit_prom_mappings(void){	struct linux_prom_translation *trans;	unsigned long phys_page, tte_vaddr, tte_data;	void (*remap_func)(unsigned long, unsigned long, int);	pmd_t *pmdp;	pte_t *ptep;	int node, n, i, tsz;	extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2];	node = prom_finddevice("/virtual-memory");	n = prom_getproplen(node, "translations");	if (n == 0 || n == -1) {		prom_printf("Couldn't get translation property\n");		prom_halt();	}	n += 5 * sizeof(struct linux_prom_translation);	for (tsz = 1; tsz < n; tsz <<= 1)		/* empty */;	trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base);	if (trans == NULL) {		prom_printf("inherit_prom_mappings: Cannot alloc translations.\n");		prom_halt();	}	memset(trans, 0, tsz);	if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {		prom_printf("Couldn't get translation property\n");		prom_halt();	}	n = n / sizeof(*trans);	/*	 * The obp translations are saved based on 8k pagesize, since obp can	 * use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000,	 * ie obp range, are handled in entry.S and do not use the vpte scheme	 * (see rant in inherit_locked_prom_mappings()).	 */#define OBP_PMD_SIZE 2048	prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base);	if (prompmd == NULL)		early_pgtable_allocfail("pmd");	memset(prompmd, 0, OBP_PMD_SIZE);	for (i = 0; i < n; i++) {		unsigned long vaddr;		if (trans[i].virt >= LOW_OBP_ADDRESS && trans[i].virt < HI_OBP_ADDRESS) {			for (vaddr = trans[i].virt;			     ((vaddr < trans[i].virt + trans[i].size) && 			     (vaddr < HI_OBP_ADDRESS));			     vaddr += BASE_PAGE_SIZE) {				unsigned long val;				pmdp = prompmd + ((vaddr >> 23) & 0x7ff);				if (pmd_none(*pmdp)) {					ptep = __alloc_bootmem(BASE_PAGE_SIZE,							       BASE_PAGE_SIZE,							       bootmap_base);					if (ptep == NULL)						early_pgtable_allocfail("pte");					memset(ptep, 0, BASE_PAGE_SIZE);					pmd_set(pmdp, ptep);				}				ptep = (pte_t *)__pmd_page(*pmdp) +						((vaddr >> 13) & 0x3ff);				val = trans[i].data;				/* Clear diag TTE bits. */				if (tlb_type == spitfire)					val &= ~0x0003fe0000000000UL;				set_pte_at(&init_mm, vaddr,					   ptep, __pte(val | _PAGE_MODIFIED));				trans[i].data += BASE_PAGE_SIZE;			}		}	}	phys_page = __pa(prompmd);	obp_iaddr_patch[0] |= (phys_page >> 10);	obp_iaddr_patch[1] |= (phys_page & 0x3ff);	flushi((long)&obp_iaddr_patch[0]);	obp_daddr_patch[0] |= (phys_page >> 10);	obp_daddr_patch[1] |= (phys_page & 0x3ff);	flushi((long)&obp_daddr_patch[0]);	/* Now fixup OBP's idea about where we really are mapped. */	prom_printf("Remapping the kernel... ");	/* Spitfire Errata #32 workaround */	/* NOTE: Using plain zero for the context value is	 *       correct here, we are not using the Linux trap	 *       tables yet so we should not use the special	 *       UltraSPARC-III+ page size encodings yet.	 */	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"			     "flush	%%g6"			     : /* No outputs */			     : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));	switch (tlb_type) {	default:	case spitfire:		phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());		break;	case cheetah:	case cheetah_plus:		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 || tlb_type == cheetah_plus) {		/* 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 */	/* NOTE: Using plain zero for the context value is	 *       correct here, we are not using the Linux trap	 *       tables yet so we should not use the special	 *       UltraSPARC-III+ page size encodings yet.	 */	__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 */	/* NOTE: Using plain zero for the context value is	 *       correct here, we are not using the Linux trap	 *       tables yet so we should not use the special	 *       UltraSPARC-III+ page size encodings yet.	 */	__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();}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/1ac4f5ebaa496a23ab4a148c9864d7e30a6c6cd3/init.c/buggy/arch/sparc64/mm/init.c