patch-2.1.97 linux/include/asm-sparc64/pgtable.h
Next file: linux/include/asm-sparc64/processor.h
Previous file: linux/include/asm-sparc64/pbm.h
Back to the patch index
Back to the overall index
- Lines: 251
- Date:
Tue Apr 14 17:44:25 1998
- Orig file:
v2.1.96/linux/include/asm-sparc64/pgtable.h
- Orig date:
Mon Jan 12 15:15:58 1998
diff -u --recursive --new-file v2.1.96/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
@@ -1,7 +1,8 @@
-/* $Id: pgtable.h,v 1.59 1997/10/12 06:20:43 davem Exp $
+/* $Id: pgtable.h,v 1.64 1998/02/16 14:06:44 jj Exp $
* pgtable.h: SpitFire page table operations.
*
* Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
#ifndef _SPARC64_PGTABLE_H
@@ -34,18 +35,20 @@
#define PMD_MASK (~(PMD_SIZE-1))
/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PAGE_SHIFT + 2*(PAGE_SHIFT-3))
+#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + (PAGE_SHIFT-2))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* Entries per page directory level. */
-#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
-#define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3))
-#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PMD (1UL << (PAGE_SHIFT-2))
+/* We cannot use the top 16G because a half of mm/ would break, so why to check it */
+#define PTRS_PER_PGD ((1UL << (PAGE_SHIFT-3))-1)
+#define USER_PTRS_PER_PGD PTRS_PER_PGD /* Kernel has a separate 44bit address space */
#define PTE_TABLE_SIZE 0x2000 /* 1024 entries 8 bytes each */
-#define PMD_TABLE_SIZE 0x2000 /* 1024 entries 8 bytes each */
-#define PGD_TABLE_SIZE 0x2000 /* 1024 entries 8 bytes each */
+#define PMD_TABLE_SIZE 0x2000 /* 2048 entries 4 bytes each */
+#define PGD_TABLE_SIZE 0x1000 /* 1024 entries 4 bytes each */
/* the no. of pointers that fit on a page */
#define PTRS_PER_PAGE (1UL << (PAGE_SHIFT-3))
@@ -141,7 +144,7 @@
#define BAD_PTE __bad_pte()
#define BAD_PAGE __bad_page()
-/* First phsical page can be anywhere, the following is needed so that
+/* First physical page can be anywhere, the following is needed so that
* va-->pa and vice versa conversions work properly without performance
* hit for all __pa()/__va() operations.
*/
@@ -149,8 +152,8 @@
#define ZERO_PAGE ((unsigned long)__va(phys_base))
/* This is for making TLB miss faster to process. */
-extern unsigned long null_pmd_table;
-extern unsigned long null_pte_table;
+#define null_pmd_table (null_pte_table - PAGE_SIZE)
+extern unsigned int null_pte_table;
/* Allocate a block of RAM which is aligned to its size.
This procedure can be used until the call to mem_init(). */
@@ -198,7 +201,7 @@
struct mm_struct *mm = vma->vm_mm;
if(mm->context != NO_CONTEXT)
- __flush_tlb_page(mm->context & 0x1fff, page);
+ __flush_tlb_page(mm->context & 0x1fff, page & PAGE_MASK);
}
#else /* __SMP__ */
@@ -260,7 +263,7 @@
extern inline unsigned long pgd_page(pgd_t pgd)
{ return (unsigned long) __va(pgd_val(pgd)); }
-#define PMD_NONE_MAGIC 0x80
+#define PMD_NONE_MAGIC 0x40
#define PGD_NONE_MAGIC 0x40
extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
@@ -323,18 +326,18 @@
/* to find an entry in a page-table-directory. */
extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
-{ return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); }
+{ return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD)); }
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
/* Find an entry in the second-level page table.. */
extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
-{ return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); }
+{ return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); }
/* Find an entry in the third-level page table.. */
extern inline pte_t *pte_offset(pmd_t *dir, unsigned long address)
-{ return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); }
+{ return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); }
/* Very stupidly, we used to get new pgd's and pmd's, init their contents
* to point to the NULL versions of the next level page table, later on
@@ -345,79 +348,97 @@
#ifdef __SMP__
/* Sliiiicck */
-#define pgd_quicklist (cpu_data[smp_processor_id()].pgd_cache)
-#define pmd_quicklist (cpu_data[smp_processor_id()].pmd_cache)
-#define pte_quicklist (cpu_data[smp_processor_id()].pte_cache)
-#define pgtable_cache_size (cpu_data[smp_processor_id()].pgcache_size)
+#define pgt_quicklists cpu_data[smp_processor_id()]
#else
-extern unsigned long *pgd_quicklist;
-extern unsigned long *pmd_quicklist;
-extern unsigned long *pte_quicklist;
-extern unsigned long pgtable_cache_size;
+extern struct pgtable_cache_struct {
+ unsigned long *pgd_cache;
+ unsigned long *pmd_cache;
+ unsigned long *pte_cache;
+ unsigned long pgcache_size;
+} pgt_quicklists;
#endif
+#define pgd_quicklist (pgt_quicklists.pgd_cache)
+#define pmd_quicklist (pgt_quicklists.pmd_cache)
+#define pte_quicklist (pgt_quicklists.pte_cache)
+#define pgtable_cache_size (pgt_quicklists.pgcache_size)
extern pgd_t *get_pgd_slow(void);
extern __inline__ pgd_t *get_pgd_fast(void)
{
- pgd_t *ret;
+ unsigned long *ret;
- if((ret = (pgd_t *)pgd_quicklist) != NULL) {
- pgd_quicklist = (unsigned long *)pgd_val(*ret);
- pgd_val(ret[0]) = pgd_val(ret[1]);
- (pgtable_cache_size)--;
+ if((ret = pgd_quicklist) != NULL) {
+ pgd_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
} else
- ret = get_pgd_slow();
- return ret;
+ ret = (unsigned long *)get_pgd_slow();
+ return (pgd_t *)ret;
}
extern __inline__ void free_pgd_fast(pgd_t *pgd)
{
- pgd_val(*pgd) = (unsigned long) pgd_quicklist;
+ *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
pgd_quicklist = (unsigned long *) pgd;
- (pgtable_cache_size)++;
+ pgtable_cache_size++;
+}
+
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
+{
+ free_page((unsigned long)pgd);
}
extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked);
extern __inline__ pmd_t *get_pmd_fast(void)
{
- pmd_t *ret;
+ unsigned long *ret;
- if((ret = (pmd_t *)pmd_quicklist) != NULL) {
- pmd_quicklist = (unsigned long *)pmd_val(*ret);
- pmd_val(ret[0]) = pmd_val(ret[1]);
- (pgtable_cache_size)--;
+ if((ret = (unsigned long *)pmd_quicklist) != NULL) {
+ pmd_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
}
- return ret;
+ return (pmd_t *)ret;
}
extern __inline__ void free_pmd_fast(pgd_t *pmd)
{
- pmd_val(*pmd) = (unsigned long) pmd_quicklist;
+ *(unsigned long *)pmd = (unsigned long) pmd_quicklist;
pmd_quicklist = (unsigned long *) pmd;
- (pgtable_cache_size)++;
+ pgtable_cache_size++;
+}
+
+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);
extern __inline__ pte_t *get_pte_fast(void)
{
- pte_t *ret;
+ unsigned long *ret;
- if((ret = (pte_t *)pte_quicklist) != NULL) {
- pte_quicklist = (unsigned long *)pte_val(*ret);
- pte_val(ret[0]) = pte_val(ret[1]);
- (pgtable_cache_size)--;
+ if((ret = (unsigned long *)pte_quicklist) != NULL) {
+ pte_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
}
- return ret;
+ return (pte_t *)ret;
}
extern __inline__ void free_pte_fast(pte_t *pte)
{
- pte_val(*pte) = (unsigned long) pte_quicklist;
+ *(unsigned long *)pte = (unsigned long) pte_quicklist;
pte_quicklist = (unsigned long *) pte;
- (pgtable_cache_size)++;
+ pgtable_cache_size++;
+}
+
+extern __inline__ void free_pte_slow(pte_t *pte)
+{
+ free_page((unsigned long)pte);
}
#define pte_free_kernel(pte) free_pte_fast(pte)
@@ -458,6 +479,11 @@
#define pte_alloc_kernel(pmd, addr) pte_alloc(pmd, addr)
#define pmd_alloc_kernel(pgd, addr) pmd_alloc(pgd, addr)
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+ /* Nothing to do on sparc64 :) */
+}
+
extern pgd_t swapper_pg_dir[1024];
extern inline void SET_PAGE_DIR(struct task_struct *tsk, pgd_t *pgdir)
@@ -570,6 +596,10 @@
extern void * module_map (unsigned long size);
extern void module_unmap (void *addr);
+extern void module_shrink (void *addr, unsigned long size);
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page) (test_bit(PG_skip, &(page)->flags))
#endif /* !(__ASSEMBLY__) */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov