2005-04-17 02:20:36 +04:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 1999 , 2000 by Silicon Graphics
* Copyright ( C ) 2003 by Ralf Baechle
*/
# include <linux/init.h>
# include <linux/mm.h>
2006-10-22 02:17:35 +04:00
# include <asm/fixmap.h>
2005-04-17 02:20:36 +04:00
# include <asm/pgtable.h>
2007-02-18 19:27:34 +03:00
# include <asm/pgalloc.h>
2012-10-18 15:54:15 +04:00
# include <asm/tlbflush.h>
2005-04-17 02:20:36 +04:00
void pgd_init ( unsigned long page )
{
unsigned long * p , * end ;
2009-12-05 00:52:36 +03:00
unsigned long entry ;
# ifdef __PAGETABLE_PMD_FOLDED
entry = ( unsigned long ) invalid_pte_table ;
# else
entry = ( unsigned long ) invalid_pmd_table ;
# endif
2005-04-17 02:20:36 +04:00
2013-01-22 15:59:30 +04:00
p = ( unsigned long * ) page ;
2005-04-17 02:20:36 +04:00
end = p + PTRS_PER_PGD ;
2012-08-16 22:15:22 +04:00
do {
2009-12-05 00:52:36 +03:00
p [ 0 ] = entry ;
p [ 1 ] = entry ;
p [ 2 ] = entry ;
p [ 3 ] = entry ;
p [ 4 ] = entry ;
2005-04-17 02:20:36 +04:00
p + = 8 ;
2012-08-16 22:15:22 +04:00
p [ - 3 ] = entry ;
p [ - 2 ] = entry ;
p [ - 1 ] = entry ;
} while ( p ! = end ) ;
2005-04-17 02:20:36 +04:00
}
2009-12-05 00:52:36 +03:00
# ifndef __PAGETABLE_PMD_FOLDED
2005-04-17 02:20:36 +04:00
void pmd_init ( unsigned long addr , unsigned long pagetable )
{
unsigned long * p , * end ;
2013-01-22 15:59:30 +04:00
p = ( unsigned long * ) addr ;
2005-04-17 02:20:36 +04:00
end = p + PTRS_PER_PMD ;
2012-08-16 22:15:22 +04:00
do {
2009-12-05 00:52:36 +03:00
p [ 0 ] = pagetable ;
p [ 1 ] = pagetable ;
p [ 2 ] = pagetable ;
p [ 3 ] = pagetable ;
p [ 4 ] = pagetable ;
2005-04-17 02:20:36 +04:00
p + = 8 ;
2012-08-16 22:15:22 +04:00
p [ - 3 ] = pagetable ;
p [ - 2 ] = pagetable ;
p [ - 1 ] = pagetable ;
} while ( p ! = end ) ;
2005-04-17 02:20:36 +04:00
}
2009-12-05 00:52:36 +03:00
# endif
2005-04-17 02:20:36 +04:00
2012-10-18 15:54:15 +04:00
# ifdef CONFIG_TRANSPARENT_HUGEPAGE
void pmdp_splitting_flush ( struct vm_area_struct * vma ,
unsigned long address ,
pmd_t * pmdp )
{
if ( ! pmd_trans_splitting ( * pmdp ) ) {
pmd_t pmd = pmd_mksplitting ( * pmdp ) ;
set_pmd_at ( vma - > vm_mm , address , pmdp , pmd ) ;
}
}
# endif
pmd_t mk_pmd ( struct page * page , pgprot_t prot )
{
pmd_t pmd ;
pmd_val ( pmd ) = ( page_to_pfn ( page ) < < _PFN_SHIFT ) | pgprot_val ( prot ) ;
return pmd ;
}
void set_pmd_at ( struct mm_struct * mm , unsigned long addr ,
pmd_t * pmdp , pmd_t pmd )
{
* pmdp = pmd ;
flush_tlb_all ( ) ;
}
2005-04-17 02:20:36 +04:00
void __init pagetable_init ( void )
{
2006-10-22 02:17:35 +04:00
unsigned long vaddr ;
pgd_t * pgd_base ;
2005-04-17 02:20:36 +04:00
/* Initialize the entire pgd. */
pgd_init ( ( unsigned long ) swapper_pg_dir ) ;
2009-12-05 00:52:36 +03:00
# ifndef __PAGETABLE_PMD_FOLDED
2005-04-17 02:20:36 +04:00
pmd_init ( ( unsigned long ) invalid_pmd_table , ( unsigned long ) invalid_pte_table ) ;
2009-12-05 00:52:36 +03:00
# endif
2006-10-22 02:17:35 +04:00
pgd_base = swapper_pg_dir ;
/*
* Fixed mappings :
*/
vaddr = __fix_to_virt ( __end_of_fixed_addresses - 1 ) & PMD_MASK ;
2011-01-06 10:31:30 +03:00
fixrange_init ( vaddr , vaddr + FIXADDR_SIZE , pgd_base ) ;
2005-04-17 02:20:36 +04:00
}