xref: /kernel/linux/linux-6.6/arch/mips/mm/pgtable-32.c (revision 62306a36)
162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2003 by Ralf Baechle
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/mm.h>
1062306a36Sopenharmony_ci#include <linux/memblock.h>
1162306a36Sopenharmony_ci#include <linux/highmem.h>
1262306a36Sopenharmony_ci#include <asm/fixmap.h>
1362306a36Sopenharmony_ci#include <asm/pgalloc.h>
1462306a36Sopenharmony_ci#include <asm/tlbflush.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_civoid pgd_init(void *addr)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	unsigned long *p = (unsigned long *)addr;
1962306a36Sopenharmony_ci	int i;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
2262306a36Sopenharmony_ci		p[i + 0] = (unsigned long) invalid_pte_table;
2362306a36Sopenharmony_ci		p[i + 1] = (unsigned long) invalid_pte_table;
2462306a36Sopenharmony_ci		p[i + 2] = (unsigned long) invalid_pte_table;
2562306a36Sopenharmony_ci		p[i + 3] = (unsigned long) invalid_pte_table;
2662306a36Sopenharmony_ci		p[i + 4] = (unsigned long) invalid_pte_table;
2762306a36Sopenharmony_ci		p[i + 5] = (unsigned long) invalid_pte_table;
2862306a36Sopenharmony_ci		p[i + 6] = (unsigned long) invalid_pte_table;
2962306a36Sopenharmony_ci		p[i + 7] = (unsigned long) invalid_pte_table;
3062306a36Sopenharmony_ci	}
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#if defined(CONFIG_TRANSPARENT_HUGEPAGE)
3462306a36Sopenharmony_cipmd_t mk_pmd(struct page *page, pgprot_t prot)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	pmd_t pmd;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	pmd_val(pmd) = (page_to_pfn(page) << PFN_PTE_SHIFT) | pgprot_val(prot);
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	return pmd;
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_civoid set_pmd_at(struct mm_struct *mm, unsigned long addr,
4562306a36Sopenharmony_ci		pmd_t *pmdp, pmd_t pmd)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	*pmdp = pmd;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci#endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_civoid __init pagetable_init(void)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	unsigned long vaddr;
5462306a36Sopenharmony_ci	pgd_t *pgd_base;
5562306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM
5662306a36Sopenharmony_ci	pgd_t *pgd;
5762306a36Sopenharmony_ci	p4d_t *p4d;
5862306a36Sopenharmony_ci	pud_t *pud;
5962306a36Sopenharmony_ci	pmd_t *pmd;
6062306a36Sopenharmony_ci	pte_t *pte;
6162306a36Sopenharmony_ci#endif
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	/* Initialize the entire pgd.  */
6462306a36Sopenharmony_ci	pgd_init(swapper_pg_dir);
6562306a36Sopenharmony_ci	pgd_init(&swapper_pg_dir[USER_PTRS_PER_PGD]);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	pgd_base = swapper_pg_dir;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	/*
7062306a36Sopenharmony_ci	 * Fixed mappings:
7162306a36Sopenharmony_ci	 */
7262306a36Sopenharmony_ci	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
7362306a36Sopenharmony_ci	fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM
7662306a36Sopenharmony_ci	/*
7762306a36Sopenharmony_ci	 * Permanent kmaps:
7862306a36Sopenharmony_ci	 */
7962306a36Sopenharmony_ci	vaddr = PKMAP_BASE;
8062306a36Sopenharmony_ci	fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	pgd = swapper_pg_dir + pgd_index(vaddr);
8362306a36Sopenharmony_ci	p4d = p4d_offset(pgd, vaddr);
8462306a36Sopenharmony_ci	pud = pud_offset(p4d, vaddr);
8562306a36Sopenharmony_ci	pmd = pmd_offset(pud, vaddr);
8662306a36Sopenharmony_ci	pte = pte_offset_kernel(pmd, vaddr);
8762306a36Sopenharmony_ci	pkmap_page_table = pte;
8862306a36Sopenharmony_ci#endif
8962306a36Sopenharmony_ci}
90