xref: /openbmc/linux/arch/mips/mm/pgtable-64.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * This file is subject to the terms and conditions of the GNU General Public
31da177e4SLinus Torvalds  * License.  See the file "COPYING" in the main directory of this archive
41da177e4SLinus Torvalds  * for more details.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Copyright (C) 1999, 2000 by Silicon Graphics
71da177e4SLinus Torvalds  * Copyright (C) 2003 by Ralf Baechle
81da177e4SLinus Torvalds  */
9ccf01516SJames Hogan #include <linux/export.h>
101da177e4SLinus Torvalds #include <linux/init.h>
111da177e4SLinus Torvalds #include <linux/mm.h>
12f8829caeSRalf Baechle #include <asm/fixmap.h>
136a1e5529SAtsushi Nemoto #include <asm/pgalloc.h>
14970d032fSRalf Baechle #include <asm/tlbflush.h>
151da177e4SLinus Torvalds 
pgd_init(void * addr)1622c4e804SFeiyang Chen void pgd_init(void *addr)
171da177e4SLinus Torvalds {
181da177e4SLinus Torvalds 	unsigned long *p, *end;
19325f8a0aSDavid Daney 	unsigned long entry;
20325f8a0aSDavid Daney 
213377e227SAlex Belits #if !defined(__PAGETABLE_PUD_FOLDED)
223377e227SAlex Belits 	entry = (unsigned long)invalid_pud_table;
233377e227SAlex Belits #elif !defined(__PAGETABLE_PMD_FOLDED)
24325f8a0aSDavid Daney 	entry = (unsigned long)invalid_pmd_table;
253377e227SAlex Belits #else
263377e227SAlex Belits 	entry = (unsigned long)invalid_pte_table;
27325f8a0aSDavid Daney #endif
281da177e4SLinus Torvalds 
2922c4e804SFeiyang Chen 	p = (unsigned long *) addr;
301da177e4SLinus Torvalds 	end = p + PTRS_PER_PGD;
311da177e4SLinus Torvalds 
32f59a2d22SDavid Daney 	do {
33325f8a0aSDavid Daney 		p[0] = entry;
34325f8a0aSDavid Daney 		p[1] = entry;
35325f8a0aSDavid Daney 		p[2] = entry;
36325f8a0aSDavid Daney 		p[3] = entry;
37325f8a0aSDavid Daney 		p[4] = entry;
381da177e4SLinus Torvalds 		p += 8;
39f59a2d22SDavid Daney 		p[-3] = entry;
40f59a2d22SDavid Daney 		p[-2] = entry;
41f59a2d22SDavid Daney 		p[-1] = entry;
42f59a2d22SDavid Daney 	} while (p != end);
431da177e4SLinus Torvalds }
441da177e4SLinus Torvalds 
45325f8a0aSDavid Daney #ifndef __PAGETABLE_PMD_FOLDED
pmd_init(void * addr)4622c4e804SFeiyang Chen void pmd_init(void *addr)
471da177e4SLinus Torvalds {
481da177e4SLinus Torvalds 	unsigned long *p, *end;
4922c4e804SFeiyang Chen 	unsigned long pagetable = (unsigned long)invalid_pte_table;
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds 	p = (unsigned long *)addr;
521da177e4SLinus Torvalds 	end = p + PTRS_PER_PMD;
531da177e4SLinus Torvalds 
54f59a2d22SDavid Daney 	do {
55325f8a0aSDavid Daney 		p[0] = pagetable;
56325f8a0aSDavid Daney 		p[1] = pagetable;
57325f8a0aSDavid Daney 		p[2] = pagetable;
58325f8a0aSDavid Daney 		p[3] = pagetable;
59325f8a0aSDavid Daney 		p[4] = pagetable;
601da177e4SLinus Torvalds 		p += 8;
61f59a2d22SDavid Daney 		p[-3] = pagetable;
62f59a2d22SDavid Daney 		p[-2] = pagetable;
63f59a2d22SDavid Daney 		p[-1] = pagetable;
64f59a2d22SDavid Daney 	} while (p != end);
651da177e4SLinus Torvalds }
66ccf01516SJames Hogan EXPORT_SYMBOL_GPL(pmd_init);
67325f8a0aSDavid Daney #endif
681da177e4SLinus Torvalds 
693377e227SAlex Belits #ifndef __PAGETABLE_PUD_FOLDED
pud_init(void * addr)7022c4e804SFeiyang Chen void pud_init(void *addr)
713377e227SAlex Belits {
723377e227SAlex Belits 	unsigned long *p, *end;
7322c4e804SFeiyang Chen 	unsigned long pagetable = (unsigned long)invalid_pmd_table;
743377e227SAlex Belits 
753377e227SAlex Belits 	p = (unsigned long *)addr;
763377e227SAlex Belits 	end = p + PTRS_PER_PUD;
773377e227SAlex Belits 
783377e227SAlex Belits 	do {
793377e227SAlex Belits 		p[0] = pagetable;
803377e227SAlex Belits 		p[1] = pagetable;
813377e227SAlex Belits 		p[2] = pagetable;
823377e227SAlex Belits 		p[3] = pagetable;
833377e227SAlex Belits 		p[4] = pagetable;
843377e227SAlex Belits 		p += 8;
853377e227SAlex Belits 		p[-3] = pagetable;
863377e227SAlex Belits 		p[-2] = pagetable;
873377e227SAlex Belits 		p[-1] = pagetable;
883377e227SAlex Belits 	} while (p != end);
893377e227SAlex Belits }
903377e227SAlex Belits #endif
913377e227SAlex Belits 
mk_pmd(struct page * page,pgprot_t prot)92970d032fSRalf Baechle pmd_t mk_pmd(struct page *page, pgprot_t prot)
93970d032fSRalf Baechle {
94970d032fSRalf Baechle 	pmd_t pmd;
95970d032fSRalf Baechle 
96*15fa3e8eSMatthew Wilcox (Oracle) 	pmd_val(pmd) = (page_to_pfn(page) << PFN_PTE_SHIFT) | pgprot_val(prot);
97970d032fSRalf Baechle 
98970d032fSRalf Baechle 	return pmd;
99970d032fSRalf Baechle }
100970d032fSRalf Baechle 
set_pmd_at(struct mm_struct * mm,unsigned long addr,pmd_t * pmdp,pmd_t pmd)101970d032fSRalf Baechle void set_pmd_at(struct mm_struct *mm, unsigned long addr,
102970d032fSRalf Baechle 		pmd_t *pmdp, pmd_t pmd)
103970d032fSRalf Baechle {
104970d032fSRalf Baechle 	*pmdp = pmd;
105970d032fSRalf Baechle }
106970d032fSRalf Baechle 
pagetable_init(void)1071da177e4SLinus Torvalds void __init pagetable_init(void)
1081da177e4SLinus Torvalds {
109f8829caeSRalf Baechle 	unsigned long vaddr;
110f8829caeSRalf Baechle 	pgd_t *pgd_base;
111f8829caeSRalf Baechle 
1121da177e4SLinus Torvalds 	/* Initialize the entire pgd.  */
11322c4e804SFeiyang Chen 	pgd_init(swapper_pg_dir);
1143377e227SAlex Belits #ifndef __PAGETABLE_PUD_FOLDED
11522c4e804SFeiyang Chen 	pud_init(invalid_pud_table);
1163377e227SAlex Belits #endif
117325f8a0aSDavid Daney #ifndef __PAGETABLE_PMD_FOLDED
11822c4e804SFeiyang Chen 	pmd_init(invalid_pmd_table);
119325f8a0aSDavid Daney #endif
120f8829caeSRalf Baechle 	pgd_base = swapper_pg_dir;
121f8829caeSRalf Baechle 	/*
122f8829caeSRalf Baechle 	 * Fixed mappings:
123f8829caeSRalf Baechle 	 */
124f8829caeSRalf Baechle 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
125464fd83eSKevin Cernekee 	fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
1261da177e4SLinus Torvalds }
127