fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc / mm / srmmu.c
index c18475e..0df7121 100644 (file)
@@ -8,7 +8,6 @@
  * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org)
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -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
@@ -1341,9 +1348,8 @@ void __init srmmu_paging_init(void)
                zones_size[ZONE_HIGHMEM] = npages;
                zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
 
-               free_area_init_node(0, &contig_page_data, NULL, zones_size,
+               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);