1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef M68K_MCF_PGALLOC_H
3*4882a593Smuzhiyun #define M68K_MCF_PGALLOC_H
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun #include <asm/tlb.h>
6*4882a593Smuzhiyun #include <asm/tlbflush.h>
7*4882a593Smuzhiyun
pte_free_kernel(struct mm_struct * mm,pte_t * pte)8*4882a593Smuzhiyun extern inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
9*4882a593Smuzhiyun {
10*4882a593Smuzhiyun free_page((unsigned long) pte);
11*4882a593Smuzhiyun }
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun extern const char bad_pmd_string[];
14*4882a593Smuzhiyun
pte_alloc_one_kernel(struct mm_struct * mm)15*4882a593Smuzhiyun extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun unsigned long page = __get_free_page(GFP_DMA);
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun if (!page)
20*4882a593Smuzhiyun return NULL;
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun memset((void *)page, 0, PAGE_SIZE);
23*4882a593Smuzhiyun return (pte_t *) (page);
24*4882a593Smuzhiyun }
25*4882a593Smuzhiyun
pmd_alloc_kernel(pgd_t * pgd,unsigned long address)26*4882a593Smuzhiyun extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun return (pmd_t *) pgd;
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #define pmd_populate(mm, pmd, pte) (pmd_val(*pmd) = (unsigned long)(pte))
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define pmd_populate_kernel pmd_populate
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define pmd_pgtable(pmd) pfn_to_virt(pmd_val(pmd) >> PAGE_SHIFT)
36*4882a593Smuzhiyun
__pte_free_tlb(struct mmu_gather * tlb,pgtable_t pgtable,unsigned long address)37*4882a593Smuzhiyun static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pgtable,
38*4882a593Smuzhiyun unsigned long address)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun struct page *page = virt_to_page(pgtable);
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun pgtable_pte_page_dtor(page);
43*4882a593Smuzhiyun __free_page(page);
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun
pte_alloc_one(struct mm_struct * mm)46*4882a593Smuzhiyun static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun struct page *page = alloc_pages(GFP_DMA, 0);
49*4882a593Smuzhiyun pte_t *pte;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun if (!page)
52*4882a593Smuzhiyun return NULL;
53*4882a593Smuzhiyun if (!pgtable_pte_page_ctor(page)) {
54*4882a593Smuzhiyun __free_page(page);
55*4882a593Smuzhiyun return NULL;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun pte = page_address(page);
59*4882a593Smuzhiyun clear_page(pte);
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun return pte;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
pte_free(struct mm_struct * mm,pgtable_t pgtable)64*4882a593Smuzhiyun static inline void pte_free(struct mm_struct *mm, pgtable_t pgtable)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun struct page *page = virt_to_page(pgtable);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun pgtable_pte_page_dtor(page);
69*4882a593Smuzhiyun __free_page(page);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * In our implementation, each pgd entry contains 1 pmd that is never allocated
74*4882a593Smuzhiyun * or freed. pgd_present is always 1, so this should never be called. -NL
75*4882a593Smuzhiyun */
76*4882a593Smuzhiyun #define pmd_free(mm, pmd) BUG()
77*4882a593Smuzhiyun
pgd_free(struct mm_struct * mm,pgd_t * pgd)78*4882a593Smuzhiyun static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun free_page((unsigned long) pgd);
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
pgd_alloc(struct mm_struct * mm)83*4882a593Smuzhiyun static inline pgd_t *pgd_alloc(struct mm_struct *mm)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun pgd_t *new_pgd;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
88*4882a593Smuzhiyun if (!new_pgd)
89*4882a593Smuzhiyun return NULL;
90*4882a593Smuzhiyun memcpy(new_pgd, swapper_pg_dir, PTRS_PER_PGD * sizeof(pgd_t));
91*4882a593Smuzhiyun memset(new_pgd, 0, PAGE_OFFSET >> PGDIR_SHIFT);
92*4882a593Smuzhiyun return new_pgd;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #endif /* M68K_MCF_PGALLOC_H */
96