X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fmm%2Fsrmmu.c;h=0df7121cef07b768d8fe0090609f994edcca3ac5;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=d5593b5d2e53db5940107e9947763b85bb2f0be1;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index d5593b5d2..0df7121ce 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -8,7 +8,6 @@ * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org) */ -#include #include #include #include @@ -88,7 +87,7 @@ ctxd_t *srmmu_ctx_table_phys; ctxd_t *srmmu_context_table; int viking_mxcc_present; -static spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(srmmu_context_spinlock); int is_hypersparc; @@ -133,11 +132,12 @@ static struct bit_map srmmu_nocache_map; static unsigned long srmmu_pte_pfn(pte_t pte) { if (srmmu_device_memory(pte_val(pte))) { - /* XXX Anton obviously had something in mind when he did this. - * But what? + /* Just return something that will cause + * pfn_valid() to return false. This makes + * copy_one_pte() to just directly copy to + * PTE over. */ - /* return (struct page *)~0; */ - BUG(); + return ~0UL; } return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4); } @@ -160,6 +160,9 @@ static inline int srmmu_pte_none(pte_t pte) static inline int srmmu_pte_present(pte_t pte) { return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); } +static inline int srmmu_pte_read(pte_t pte) +{ return !(pte_val(pte) & SRMMU_NOREAD); } + static inline void srmmu_pte_clear(pte_t *ptep) { srmmu_set_pte(ptep, __pte(0)); } @@ -256,7 +259,7 @@ static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot) { return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); } /* to find an entry in a top-level page table... */ -extern inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) +static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address) { return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); } /* Find an entry in the second-level page table.. */ @@ -399,7 +402,7 @@ void srmmu_nocache_calcsize(void) srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size; } -void srmmu_nocache_init(void) +void __init srmmu_nocache_init(void) { unsigned int bitmap_bits; pgd_t *pgd; @@ -1002,8 +1005,7 @@ extern void viking_flush_cache_all(void); extern void viking_flush_cache_mm(struct mm_struct *mm); extern void viking_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern void viking_flush_cache_page(struct vm_area_struct *vma, - unsigned long page); +extern void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page); extern void viking_flush_page_to_ram(unsigned long page); extern void viking_flush_page_for_dma(unsigned long page); extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr); @@ -1299,7 +1301,12 @@ void __init srmmu_paging_init(void) flush_cache_all(); srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys); +#ifdef CONFIG_SMP + /* Stop from hanging here... */ + local_flush_tlb_all(); +#else flush_tlb_all(); +#endif poke_srmmu(); #ifdef CONFIG_SUN_IO @@ -1343,7 +1350,6 @@ void __init srmmu_paging_init(void) free_area_init_node(0, &contig_page_data, zones_size, pfn_base, zholes_size); - mem_map = contig_page_data.node_mem_map; } } @@ -1417,6 +1423,7 @@ static void __init init_vac_layout(void) max_size = vac_cache_size; if(vac_line_size < min_line_size) min_line_size = vac_line_size; + //FIXME: cpus not contiguous!! cpu++; if (cpu >= NR_CPUS || !cpu_online(cpu)) break; @@ -1463,6 +1470,7 @@ static void __init poke_hypersparc(void) static void __init init_hypersparc(void) { srmmu_name = "ROSS HyperSparc"; + srmmu_modtype = HyperSparc; init_vac_layout(); @@ -2127,6 +2135,13 @@ static unsigned long srmmu_pte_to_pgoff(pte_t pte) return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT; } +static pgprot_t srmmu_pgprot_noncached(pgprot_t prot) +{ + prot &= ~__pgprot(SRMMU_CACHE); + + return prot; +} + /* Load up routines and constants for sun4m and sun4d mmu */ void __init ld_mmu_srmmu(void) { @@ -2147,9 +2162,9 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); - pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; /* Functions */ + BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM); #ifndef CONFIG_SMP BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2); #endif @@ -2160,12 +2175,13 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM); BTFIXUPSET_SETHI(none_mask, 0xF0000000); BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0); + BTFIXUPSET_CALL(pte_read, srmmu_pte_read, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_bad, srmmu_pmd_bad, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_present, srmmu_pmd_present, BTFIXUPCALL_NORM);