]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/sparc/mm/srmmu.c
sparc32: Un-btfixup pte_{write,dirty,young}i
[mirror_ubuntu-bionic-kernel.git] / arch / sparc / mm / srmmu.c
index 85d7f82e57856db58c4df2a378adb57feb332e81..b01c735b581550c68510cd9ff016528adc0c9035 100644 (file)
@@ -55,12 +55,14 @@ static unsigned int hwbug_bitmask;
 int vac_cache_size;
 int vac_line_size;
 
+struct ctx_list *ctx_list_pool;
+struct ctx_list ctx_free;
+struct ctx_list ctx_used;
+
 extern struct resource sparc_iomap;
 
 extern unsigned long last_valid_pfn;
 
-extern unsigned long page_kernel;
-
 static pgd_t *srmmu_swapper_pg_dir;
 
 #ifdef CONFIG_SMP
@@ -91,28 +93,6 @@ static DEFINE_SPINLOCK(srmmu_context_spinlock);
 
 static int is_hypersparc;
 
-/*
- * In general all page table modifications should use the V8 atomic
- * swap instruction.  This insures the mmu and the cpu are in sync
- * with respect to ref/mod bits in the page tables.
- */
-static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value)
-{
-       __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr));
-       return value;
-}
-
-static inline void srmmu_set_pte(pte_t *ptep, pte_t pteval)
-{
-       srmmu_swap((unsigned long *)ptep, pte_val(pteval));
-}
-
-/* The very generic SRMMU page table operations. */
-static inline int srmmu_device_memory(unsigned long x)
-{
-       return ((x & 0xF0000000) != 0);
-}
-
 static int srmmu_cache_pagetables;
 
 /* these will be initialized in srmmu_nocache_calcsize() */
@@ -129,27 +109,6 @@ void *srmmu_nocache_pool;
 void *srmmu_nocache_bitmap;
 static struct bit_map srmmu_nocache_map;
 
-static unsigned long srmmu_pte_pfn(pte_t pte)
-{
-       if (srmmu_device_memory(pte_val(pte))) {
-               /* Just return something that will cause
-                * pfn_valid() to return false.  This makes
-                * copy_one_pte() to just directly copy to
-                * PTE over.
-                */
-               return ~0UL;
-       }
-       return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4);
-}
-
-static struct page *srmmu_pmd_page(pmd_t pmd)
-{
-
-       if (srmmu_device_memory(pmd_val(pmd)))
-               BUG();
-       return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
-}
-
 static inline unsigned long srmmu_pgd_page(pgd_t pgd)
 { return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); }
 
@@ -157,39 +116,9 @@ static inline unsigned long srmmu_pgd_page(pgd_t pgd)
 static inline int srmmu_pte_none(pte_t pte)
 { return !(pte_val(pte) & 0xFFFFFFF); }
 
-static inline int srmmu_pte_present(pte_t pte)
-{ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); }
-
-static inline void srmmu_pte_clear(pte_t *ptep)
-{ srmmu_set_pte(ptep, __pte(0)); }
-
 static inline int srmmu_pmd_none(pmd_t pmd)
 { return !(pmd_val(pmd) & 0xFFFFFFF); }
 
-static inline int srmmu_pmd_bad(pmd_t pmd)
-{ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; }
-
-static inline int srmmu_pmd_present(pmd_t pmd)
-{ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-
-static inline void srmmu_pmd_clear(pmd_t *pmdp) {
-       int i;
-       for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++)
-               srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
-}
-
-static inline int srmmu_pgd_none(pgd_t pgd)          
-{ return !(pgd_val(pgd) & 0xFFFFFFF); }
-
-static inline int srmmu_pgd_bad(pgd_t pgd)
-{ return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; }
-
-static inline int srmmu_pgd_present(pgd_t pgd)
-{ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-
-static inline void srmmu_pgd_clear(pgd_t * pgdp)
-{ srmmu_set_pte((pte_t *)pgdp, __pte(0)); }
-
 static inline pte_t srmmu_pte_wrprotect(pte_t pte)
 { return __pte(pte_val(pte) & ~SRMMU_WRITE);}
 
@@ -208,25 +137,12 @@ static inline pte_t srmmu_pte_mkdirty(pte_t pte)
 static inline pte_t srmmu_pte_mkyoung(pte_t pte)
 { return __pte(pte_val(pte) | SRMMU_REF);}
 
-/*
- * 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 srmmu_mk_pte(struct page *page, pgprot_t pgprot)
-{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
-
-static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
-{ return __pte(((page) >> 4) | pgprot_val(pgprot)); }
-
-static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
-{ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); }
-
 /* XXX should we hyper_flush_whole_icache here - Anton */
 static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
-{ srmmu_set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); }
+{ set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); }
 
 static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); }
+{ set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); }
 
 static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep)
 {
@@ -235,7 +151,7 @@ static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep)
 
        ptp = __nocache_pa((unsigned long) ptep) >> 4;
        for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
-               srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
+               set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
                ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
        }
 }
@@ -247,7 +163,7 @@ static void srmmu_pmd_populate(pmd_t *pmdp, struct page *ptep)
 
        ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4);      /* watch for overflow */
        for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
-               srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
+               set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
                ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
        }
 }
@@ -437,7 +353,7 @@ static void __init srmmu_nocache_init(void)
                if (srmmu_cache_pagetables)
                        pteval |= SRMMU_CACHE;
 
-               srmmu_set_pte(__nocache_fix(pte), __pte(pteval));
+               set_pte(__nocache_fix(pte), __pte(pteval));
 
                vaddr += PAGE_SIZE;
                paddr += PAGE_SIZE;
@@ -602,7 +518,7 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
        tmp |= (bus_type << 28);
        tmp |= SRMMU_PRIV;
        __flush_page_to_ram(virt_addr);
-       srmmu_set_pte(ptep, __pte(tmp));
+       set_pte(ptep, __pte(tmp));
 }
 
 static void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
@@ -628,7 +544,7 @@ static inline void srmmu_unmapioaddr(unsigned long virt_addr)
        ptep = srmmu_pte_offset(pmdp, virt_addr);
 
        /* No need to flush uncacheable page. */
-       srmmu_pte_clear(ptep);
+       __pte_clear(ptep);
 }
 
 static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
@@ -1064,7 +980,7 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
 
        while(start < end) {
                pgdp = pgd_offset_k(start);
-               if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+               if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
                        pmdp = (pmd_t *) __srmmu_get_nocache(
                            SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
@@ -1095,7 +1011,7 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
 
        while(start < end) {
                pgdp = pgd_offset_k(start);
-               if(srmmu_pgd_none(*pgdp)) {
+               if (pgd_none(*pgdp)) {
                        pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
                                early_pgtable_allocfail("pmd");
@@ -1161,7 +1077,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
                        start += SRMMU_PGDIR_SIZE;
                        continue;
                }
-               if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+               if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
                        pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
                        if (pmdp == NULL)
                                early_pgtable_allocfail("pmd");
@@ -1248,8 +1164,6 @@ static inline void map_kernel(void)
        for (i = 0; sp_banks[i].num_bytes != 0; i++) {
                map_spbank((unsigned long)__va(sp_banks[i].base_addr), i);
        }
-
-       BTFIXUPSET_SIMM13(user_ptrs_per_pgd, PAGE_OFFSET / SRMMU_PGDIR_SIZE);
 }
 
 /* Paging initialization on the Sparc Reference MMU. */
@@ -1482,9 +1396,6 @@ static void __init init_hypersparc(void)
 
        is_hypersparc = 1;
 
-       BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_all, hypersparc_flush_cache_all, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM);
@@ -1548,9 +1459,6 @@ static void __init init_cypress_common(void)
 {
        init_vac_layout();
 
-       BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_all, cypress_flush_cache_all, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_mm, cypress_flush_cache_mm, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(flush_cache_range, cypress_flush_cache_range, BTFIXUPCALL_NORM);
@@ -1932,10 +1840,6 @@ static void __init init_viking(void)
                viking_mxcc_present = 0;
                msi_set_sync();
 
-               BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
-               BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
-               BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
-
                /*
                 * We need this to make sure old viking takes no hits
                 * on it's cache for dma snoops to workaround the
@@ -2122,11 +2026,6 @@ static void __init get_srmmu_type(void)
        srmmu_is_bad();
 }
 
-/* don't laugh, static pagetables */
-static void srmmu_check_pgt_cache(int low, int high)
-{
-}
-
 extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme,
        tsetup_mmu_patchme, rtrap_mmu_patchme;
 
@@ -2144,53 +2043,19 @@ static void smp_flush_page_for_dma(unsigned long page)
 #endif
 
 /* Load up routines and constants for sun4m and sun4d mmu */
-void __init ld_mmu_srmmu(void)
+void __init load_mmu(void)
 {
        extern void ld_mmu_iommu(void);
        extern void ld_mmu_iounit(void);
        extern void ___xchg32_sun4md(void);
 
-       BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT);
-       BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE);
-       BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK);
-
-       BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD);
-       BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD);
-
-       BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE));
-       PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
-       BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
-       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);
-
        /* Functions */
 #ifndef CONFIG_SMP     
        BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2);
 #endif
-       BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NOP);
-
-       BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1);
 
-       BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM);
 
-       BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
-
-       BTFIXUPSET_CALL(pmd_bad, srmmu_pmd_bad, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pmd_present, srmmu_pmd_present, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_SWAPO0G0);
-
-       BTFIXUPSET_CALL(pgd_none, srmmu_pgd_none, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pgd_bad, srmmu_pgd_bad, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pgd_present, srmmu_pgd_present, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_SWAPO0G0);
-
-       BTFIXUPSET_CALL(mk_pte, srmmu_mk_pte, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(mk_pte_phys, srmmu_mk_pte_phys, BTFIXUPCALL_NORM);
-       BTFIXUPSET_CALL(mk_pte_io, srmmu_mk_pte_io, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(pgd_set, srmmu_pgd_set, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(pmd_populate, srmmu_pmd_populate, BTFIXUPCALL_NORM);
@@ -2208,9 +2073,6 @@ void __init ld_mmu_srmmu(void)
        BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM);
        BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM);
 
-       BTFIXUPSET_HALF(pte_writei, SRMMU_WRITE);
-       BTFIXUPSET_HALF(pte_dirtyi, SRMMU_DIRTY);
-       BTFIXUPSET_HALF(pte_youngi, SRMMU_REF);
        BTFIXUPSET_HALF(pte_filei, SRMMU_FILE);
        BTFIXUPSET_HALF(pte_wrprotecti, SRMMU_WRITE);
        BTFIXUPSET_HALF(pte_mkcleani, SRMMU_DIRTY);
@@ -2286,4 +2148,5 @@ void __init ld_mmu_srmmu(void)
        else
                sun4m_init_smp();
 #endif
+       btfixup();
 }