summaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64/pgalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-sparc64/pgalloc.h')
-rw-r--r--include/asm-sparc64/pgalloc.h88
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 */