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