18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * OpenRISC Linux
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Linux architectural port borrowing liberally from similar works of
68c2ecf20Sopenharmony_ci * others.  All original copyrights apply as per the original source
78c2ecf20Sopenharmony_ci * declaration.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * OpenRISC implementation:
108c2ecf20Sopenharmony_ci * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
118c2ecf20Sopenharmony_ci * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
128c2ecf20Sopenharmony_ci * et al.
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#ifndef __ASM_OPENRISC_PGALLOC_H
168c2ecf20Sopenharmony_ci#define __ASM_OPENRISC_PGALLOC_H
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <asm/page.h>
198c2ecf20Sopenharmony_ci#include <linux/threads.h>
208c2ecf20Sopenharmony_ci#include <linux/mm.h>
218c2ecf20Sopenharmony_ci#include <linux/memblock.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
248c2ecf20Sopenharmony_ci#include <asm-generic/pgalloc.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciextern int mem_init_done;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#define pmd_populate_kernel(mm, pmd, pte) \
298c2ecf20Sopenharmony_ci	set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
328c2ecf20Sopenharmony_ci				struct page *pte)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	set_pmd(pmd, __pmd(_KERNPG_TABLE +
358c2ecf20Sopenharmony_ci		     ((unsigned long)page_to_pfn(pte) <<
368c2ecf20Sopenharmony_ci		     (unsigned long) PAGE_SHIFT)));
378c2ecf20Sopenharmony_ci}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/*
408c2ecf20Sopenharmony_ci * Allocate and free page tables.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_cistatic inline pgd_t *pgd_alloc(struct mm_struct *mm)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	if (ret) {
478c2ecf20Sopenharmony_ci		memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
488c2ecf20Sopenharmony_ci		memcpy(ret + USER_PTRS_PER_PGD,
498c2ecf20Sopenharmony_ci		       swapper_pg_dir + USER_PTRS_PER_PGD,
508c2ecf20Sopenharmony_ci		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	}
538c2ecf20Sopenharmony_ci	return ret;
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#if 0
578c2ecf20Sopenharmony_ci/* FIXME: This seems to be the preferred style, but we are using
588c2ecf20Sopenharmony_ci * current_pgd (from mm->pgd) to load kernel pages so we need it
598c2ecf20Sopenharmony_ci * initialized.  This needs to be looked into.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ciextern inline pgd_t *pgd_alloc(struct mm_struct *mm)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	return (pgd_t *)get_zeroed_page(GFP_KERNEL);
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci#endif
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciextern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#define __pte_free_tlb(tlb, pte, addr)	\
708c2ecf20Sopenharmony_cido {					\
718c2ecf20Sopenharmony_ci	pgtable_pte_page_dtor(pte);	\
728c2ecf20Sopenharmony_ci	tlb_remove_page((tlb), (pte));	\
738c2ecf20Sopenharmony_ci} while (0)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#define pmd_pgtable(pmd) pmd_page(pmd)
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#endif
78