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

📄 sun4c.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
{	pte = __pte(pte_val(pte) | _SUN4C_PAGE_MODIFIED);	if (pte_val(pte) & _SUN4C_PAGE_WRITE)		pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE);	return pte;}static pte_t sun4c_pte_mkyoung(pte_t pte){	pte = __pte(pte_val(pte) | _SUN4C_PAGE_ACCESSED);	if (pte_val(pte) & _SUN4C_PAGE_READ)		pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_READ);	return pte;}/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */static pte_t sun4c_mk_pte(struct page *page, pgprot_t pgprot){	return __pte((page - mem_map) | pgprot_val(pgprot));}static pte_t sun4c_mk_pte_phys(unsigned long phys_page, pgprot_t pgprot){	return __pte((phys_page >> PAGE_SHIFT) | pgprot_val(pgprot));}static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space){	return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot));}static struct page *sun4c_pte_page(pte_t pte){	return (mem_map + (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK));}static inline unsigned long sun4c_pmd_page(pmd_t pmd){	return (pmd_val(pmd) & PAGE_MASK);}static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; }/* to find an entry in a page-table-directory */static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address){	return mm->pgd + (address >> SUN4C_PGDIR_SHIFT);}/* Find an entry in the second-level page table.. */static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address){	return (pmd_t *) dir;}/* Find an entry in the third-level page table.. */ pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address){	return (pte_t *) sun4c_pmd_page(*dir) +	((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1));}static void sun4c_free_pte_slow(pte_t *pte){	free_page((unsigned long)pte);}static void sun4c_free_pgd_slow(pgd_t *pgd){	free_page((unsigned long)pgd);}static pgd_t *sun4c_get_pgd_fast(void){	unsigned long *ret;	if ((ret = pgd_quicklist) != NULL) {		pgd_quicklist = (unsigned long *)(*ret);		ret[0] = ret[1];		pgtable_cache_size--;	} else {		pgd_t *init;				ret = (unsigned long *)__get_free_page(GFP_KERNEL);		memset (ret, 0, (KERNBASE / SUN4C_PGDIR_SIZE) * sizeof(pgd_t));		init = sun4c_pgd_offset(&init_mm, 0);		memcpy (((pgd_t *)ret) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));	}	return (pgd_t *)ret;}static void sun4c_free_pgd_fast(pgd_t *pgd){	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;	pgd_quicklist = (unsigned long *) pgd;	pgtable_cache_size++;}static pte_t *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address){	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL);	if (pte)		memset(pte, 0, PAGE_SIZE);	return pte;}pte_t *sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address){	unsigned long *ret;	if ((ret = (unsigned long *)pte_quicklist) != NULL) {		pte_quicklist = (unsigned long *)(*ret);		ret[0] = ret[1];		pgtable_cache_size--;	}	return (pte_t *)ret;}static __inline__ void sun4c_free_pte_fast(pte_t *pte){	*(unsigned long *)pte = (unsigned long) pte_quicklist;	pte_quicklist = (unsigned long *) pte;	pgtable_cache_size++;}/* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */static pmd_t *sun4c_pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address){	BUG();	return NULL;}static void sun4c_free_pmd_fast(pmd_t * pmd) { }static int sun4c_check_pgt_cache(int low, int high){	int freed = 0;	if (pgtable_cache_size > high) {		do {			if (pgd_quicklist)				sun4c_free_pgd_slow(sun4c_get_pgd_fast()), freed++;			if (pte_quicklist)				sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0)), freed++;		} while (pgtable_cache_size > low);	}	return freed;}/* An experiment, turn off by default for now... -DaveM */#define SUN4C_PRELOAD_PSEGvoid sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte){	unsigned long flags;	int pseg;	save_and_cli(flags);	address &= PAGE_MASK;	if ((pseg = sun4c_get_segmap(address)) == invalid_segment) {		struct sun4c_mmu_entry *entry = sun4c_user_strategy();		struct mm_struct *mm = vma->vm_mm;		unsigned long start, end;		entry->vaddr = start = (address & SUN4C_REAL_PGDIR_MASK);		entry->ctx = mm->context;		add_ring_ordered(sun4c_context_ring + mm->context, entry);		sun4c_put_segmap(entry->vaddr, entry->pseg);		end = start + SUN4C_REAL_PGDIR_SIZE;		while (start < end) {#ifdef SUN4C_PRELOAD_PSEG			pgd_t *pgdp = sun4c_pgd_offset(mm, start);			pte_t *ptep;			if (!pgdp)				goto no_mapping;			ptep = sun4c_pte_offset((pmd_t *) pgdp, start);			if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT))				goto no_mapping;			sun4c_put_pte(start, pte_val(*ptep));			goto next;		no_mapping:#endif			sun4c_put_pte(start, 0);#ifdef SUN4C_PRELOAD_PSEG		next:#endif			start += PAGE_SIZE;		}#ifndef SUN4C_PRELOAD_PSEG		sun4c_put_pte(address, pte_val(pte));#endif		restore_flags(flags);		return;	} else {		struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg];		remove_lru(entry);		add_lru(entry);	}	sun4c_put_pte(address, pte_val(pte));	restore_flags(flags);}extern void sparc_context_init(int);extern unsigned long end;extern unsigned long bootmem_init(unsigned long *pages_avail);extern unsigned long last_valid_pfn;extern void sun_serial_setup(void);extern unsigned long fix_kmap_begin;extern unsigned long fix_kmap_end;void __init sun4c_paging_init(void){	int i, cnt;	unsigned long kernel_end, vaddr;	extern struct resource sparc_iomap;	unsigned long end_pfn, pages_avail;	fix_kmap_begin = KERNBASE + SRMMU_MAXMEM; /* Why bother with SRMMU_MAXMEM? */	fix_kmap_end = fix_kmap_begin + ((KM_TYPE_NR*NR_CPUS)-1)*PAGE_SIZE;	kernel_end = (unsigned long) &end;	kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);	kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);	pages_avail = 0;	last_valid_pfn = bootmem_init(&pages_avail);	end_pfn = last_valid_pfn;	/* This does not logically belong here, but we need to	 * call it at the moment we are able to use the bootmem	 * allocator.	 */	sun_serial_setup();	sun4c_probe_mmu();	invalid_segment = (num_segmaps - 1);	sun4c_init_mmu_entry_pool();	sun4c_init_rings();	sun4c_init_map_kernelprom(kernel_end);	sun4c_init_clean_mmu(kernel_end);	sun4c_init_fill_kernel_ring(SUN4C_KERNEL_BUCKETS);	sun4c_init_lock_area(sparc_iomap.start, IOBASE_END);	sun4c_init_lock_area(DVMA_VADDR, DVMA_END);	sun4c_init_lock_areas();	sun4c_init_fill_user_ring();	sun4c_set_context(0);	memset(swapper_pg_dir, 0, PAGE_SIZE);	memset(pg0, 0, PAGE_SIZE);	memset(pg1, 0, PAGE_SIZE);	memset(pg2, 0, PAGE_SIZE);	memset(pg3, 0, PAGE_SIZE);	/* Save work later. */	vaddr = VMALLOC_START;	swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0);	vaddr += SUN4C_PGDIR_SIZE;	swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1);	vaddr += SUN4C_PGDIR_SIZE;	swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg2);	vaddr += SUN4C_PGDIR_SIZE;	swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg3);	sun4c_init_ss2_cache_bug();	sparc_context_init(num_contexts);	{		unsigned long zones_size[MAX_NR_ZONES];		unsigned long zholes_size[MAX_NR_ZONES];		unsigned long npages;		int znum;		for (znum = 0; znum < MAX_NR_ZONES; znum++)			zones_size[znum] = zholes_size[znum] = 0;		npages = max_low_pfn - (phys_base >> PAGE_SHIFT);		zones_size[ZONE_DMA] = npages;		zholes_size[ZONE_DMA] = npages - pages_avail;		npages = highend_pfn - max_low_pfn;		zones_size[ZONE_HIGHMEM] = npages;		zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();		free_area_init_node(0, NULL, NULL, zones_size,				    phys_base, zholes_size);	}	cnt = 0;	for (i = 0; i < num_segmaps; i++)		if (mmu_entry_pool[i].locked)			cnt++;	max_user_taken_entries = num_segmaps - cnt - 40 - 1;	printk("SUN4C: %d mmu entries for the kernel\n", cnt);}/* Load up routines and constants for sun4c mmu */void __init ld_mmu_sun4c(void){	extern void ___xchg32_sun4c(void);		printk("Loading sun4c MMU routines\n");	/* First the constants */	BTFIXUPSET_SIMM13(pmd_shift, SUN4C_PMD_SHIFT);	BTFIXUPSET_SETHI(pmd_size, SUN4C_PMD_SIZE);	BTFIXUPSET_SETHI(pmd_mask, SUN4C_PMD_MASK);	BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT);	BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE);	BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK);	BTFIXUPSET_SIMM13(ptrs_per_pte, SUN4C_PTRS_PER_PTE);	BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD);	BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD);	BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);	BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE));	BTFIXUPSET_INT(page_shared, pgprot_val(SUN4C_PAGE_SHARED));	BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY));	BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY));	BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL));	page_kernel = pgprot_val(SUN4C_PAGE_KERNEL);	pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE |		    _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE;		/* Functions */	BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM);		BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM);	if (sun4c_vacinfo.do_hwflushes) {		BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_hw, BTFIXUPCALL_NORM);		BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_hw, BTFIXUPCALL_NORM);		BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_hw, BTFIXUPCALL_NORM);	} else {		BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_sw, BTFIXUPCALL_NORM);		BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_sw, BTFIXUPCALL_NORM);		BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_sw, BTFIXUPCALL_NORM);	}	BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(destroy_context, sun4c_destroy_context, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(switch_mm, sun4c_switch_mm, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(free_task_struct, sun4c_free_task_struct, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(flush_sig_insns, sun4c_flush_sig_insns, BTFIXUPCALL_NOP);	BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);	BTFIXUPSET_CALL(pte_page, sun4c_pte_page, BTFIXUPCALL_NORM);#if PAGE_SHIFT <= 12		BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));#else	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM);#endif	BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0);	BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pmd_clear, sun4c_pmd_clear, BTFIXUPCALL_STG0O0);	BTFIXUPSET_CALL(pgd_none, sun4c_pgd_none, BTFIXUPCALL_RETINT(0));	BTFIXUPSET_CALL(pgd_bad, sun4c_pgd_bad, BTFIXUPCALL_RETINT(0));	BTFIXUPSET_CALL(pgd_present, sun4c_pgd_present, BTFIXUPCALL_RETINT(1));	BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP);	BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM);		BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK);	BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_offset, sun4c_pte_offset, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_alloc_one_fast, sun4c_pte_alloc_one_fast, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP);	BTFIXUPSET_CALL(pmd_alloc_one_fast, sun4c_pmd_alloc_one_fast, BTFIXUPCALL_RETO0);	BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM);	BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE);	BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED);	BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED);	BTFIXUPSET_HALF(pte_wrprotecti, _SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE);	BTFIXUPSET_HALF(pte_mkcleani, _SUN4C_PAGE_MODIFIED|_SUN4C_PAGE_SILENT_WRITE);	BTFIXUPSET_HALF(pte_mkoldi, _SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_SILENT_READ);	BTFIXUPSET_CALL(pte_mkwrite, sun4c_pte_mkwrite, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_mkdirty, sun4c_pte_mkdirty, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(pte_mkyoung, sun4c_pte_mkyoung, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(update_mmu_cache, sun4c_update_mmu_cache, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_lockarea, sun4c_lockarea, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_unlockarea, sun4c_unlockarea, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_get_scsi_one, sun4c_get_scsi_one, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_get_scsi_sgl, sun4c_get_scsi_sgl, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_release_scsi_one, sun4c_release_scsi_one, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_release_scsi_sgl, sun4c_release_scsi_sgl, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);	/* Task struct and kernel stack allocating/freeing. */	BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM);	BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);	/* These should _never_ get called with two level tables. */	BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);	BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0);}

⌨️ 快捷键说明

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