diff options
Diffstat (limited to 'include/asm-sparc64/pgalloc.h')
-rw-r--r-- | include/asm-sparc64/pgalloc.h | 88 |
1 files changed, 38 insertions, 50 deletions
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index 45e1f1828..a0a93cbfa 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -1,4 +1,4 @@ -/* $Id: pgalloc.h,v 1.14 2000/12/09 04:15:24 anton Exp $ */ +/* $Id: pgalloc.h,v 1.18 2001/03/24 09:36:01 davem Exp $ */ #ifndef _SPARC64_PGALLOC_H #define _SPARC64_PGALLOC_H @@ -22,18 +22,22 @@ #define flush_page_to_ram(page) do { } while (0) /* - * icache doesnt snoop local stores and we don't use block commit stores - * (which invalidate icache lines) during module load, so we need this. + * On spitfire, the icache doesn't snoop local stores and we don't + * use block commit stores (which invalidate icache lines) during + * module load, so we need this. */ extern void flush_icache_range(unsigned long start, unsigned long end); extern void __flush_dcache_page(void *addr, int flush_icache); #define flush_dcache_page(page) \ -do { if ((page)->mapping && !(page)->mapping->i_mmap && !(page)->mapping->i_mmap_shared) \ +do { if ((page)->mapping && \ + !((page)->mapping->i_mmap) && \ + !((page)->mapping->i_mmap_shared)) \ set_bit(PG_dcache_dirty, &(page)->flags); \ else \ __flush_dcache_page((page)->virtual, \ - (page)->mapping != NULL); \ + ((tlb_type == spitfire) && \ + (page)->mapping != NULL)); \ } while(0) extern void __flush_dcache_range(unsigned long start, unsigned long end); @@ -93,14 +97,18 @@ extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page); #endif /* ! CONFIG_SMP */ -/* This will change for Cheetah and later chips. */ -#define VPTE_BASE 0xfffffffe00000000 +#define VPTE_BASE_SPITFIRE 0xfffffffe00000000 +#if 1 +#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE +#else +#define VPTE_BASE_CHEETAH 0xffe0000000000000 +#endif extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) { /* Note the signed type. */ - long s = start, e = end; + long s = start, e = end, vpte_base; if (s > e) /* Nobody should call us with start below VM hole and end above. See if it is really true. */ @@ -110,10 +118,15 @@ extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long st s &= PMD_MASK; e = (e + PMD_SIZE - 1) & PMD_MASK; #endif + vpte_base = (tlb_type == spitfire ? + VPTE_BASE_SPITFIRE : + VPTE_BASE_CHEETAH); flush_tlb_range(mm, - VPTE_BASE + (s >> (PAGE_SHIFT - 3)), - VPTE_BASE + (e >> (PAGE_SHIFT - 3))); + vpte_base + (s >> (PAGE_SHIFT - 3)), + vpte_base + (e >> (PAGE_SHIFT - 3))); } +#undef VPTE_BASE_SPITFIRE +#undef VPTE_BASE_CHEETAH /* Page table allocation/freeing. */ #ifdef CONFIG_SMP @@ -214,9 +227,17 @@ extern __inline__ void free_pgd_slow(pgd_t *pgd) #endif /* CONFIG_SMP */ -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked); +#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) + +extern __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL); + if (pmd) + memset(pmd, 0, PAGE_SIZE); + return pmd; +} -extern __inline__ pmd_t *get_pmd_fast(void) +extern __inline__ pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address) { unsigned long *ret; int color = 0; @@ -246,11 +267,13 @@ extern __inline__ void free_pmd_slow(pmd_t *pmd) free_page((unsigned long)pmd); } -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted, - unsigned long color); +#define pmd_populate(MM, PMD, PTE) pmd_set(PMD, PTE) + +extern pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address); -extern __inline__ pte_t *get_pte_fast(unsigned long color) +extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) { + unsigned long color = (address >> (PAGE_SHIFT + 10)) & 0x1UL; unsigned long *ret; if((ret = (unsigned long *)pte_quicklist[color]) != NULL) { @@ -274,46 +297,11 @@ extern __inline__ void free_pte_slow(pte_t *pte) free_page((unsigned long)pte); } -#define pte_free_kernel(pte) free_pte_fast(pte) #define pte_free(pte) free_pte_fast(pte) -#define pmd_free_kernel(pmd) free_pmd_fast(pmd) #define pmd_free(pmd) free_pmd_fast(pmd) #define pgd_free(pgd) free_pgd_fast(pgd) #define pgd_alloc() get_pgd_fast() -extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address) -{ - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); - if (pmd_none(*pmd)) { - /* Be careful, address can be just about anything... */ - unsigned long color = (((unsigned long)pmd)>>2UL) & 0x1UL; - pte_t *page = get_pte_fast(color); - - if (!page) - return get_pte_slow(pmd, address, color); - pmd_set(pmd, page); - return page + address; - } - return (pte_t *) pmd_page(*pmd) + address; -} - -extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) -{ - address = (address >> PMD_SHIFT) & (REAL_PTRS_PER_PMD - 1); - if (pgd_none(*pgd)) { - pmd_t *page = get_pmd_fast(); - - if (!page) - return get_pmd_slow(pgd, address); - pgd_set(pgd, page); - return page + address; - } - return (pmd_t *) pgd_page(*pgd) + address; -} - -#define pte_alloc_kernel(pmd, addr) pte_alloc(pmd, addr) -#define pmd_alloc_kernel(pgd, addr) pmd_alloc(pgd, addr) - extern int do_check_pgt_cache(int, int); #endif /* _SPARC64_PGALLOC_H */ |