162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_IA64_PAGE_H 362306a36Sopenharmony_ci#define _ASM_IA64_PAGE_H 462306a36Sopenharmony_ci/* 562306a36Sopenharmony_ci * Pagetable related stuff. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co 862306a36Sopenharmony_ci * David Mosberger-Tang <davidm@hpl.hp.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm/intrinsics.h> 1262306a36Sopenharmony_ci#include <asm/types.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * The top three bits of an IA64 address are its Region Number. 1662306a36Sopenharmony_ci * Different regions are assigned to different purposes. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci#define RGN_SHIFT (61) 1962306a36Sopenharmony_ci#define RGN_BASE(r) (__IA64_UL_CONST(r)<<RGN_SHIFT) 2062306a36Sopenharmony_ci#define RGN_BITS (RGN_BASE(-1)) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define RGN_KERNEL 7 /* Identity mapped region */ 2362306a36Sopenharmony_ci#define RGN_UNCACHED 6 /* Identity mapped I/O region */ 2462306a36Sopenharmony_ci#define RGN_GATE 5 /* Gate page, Kernel text, etc */ 2562306a36Sopenharmony_ci#define RGN_HPAGE 4 /* For Huge TLB pages */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * PAGE_SHIFT determines the actual kernel page size. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ci#if defined(CONFIG_IA64_PAGE_SIZE_4KB) 3162306a36Sopenharmony_ci# define PAGE_SHIFT 12 3262306a36Sopenharmony_ci#elif defined(CONFIG_IA64_PAGE_SIZE_8KB) 3362306a36Sopenharmony_ci# define PAGE_SHIFT 13 3462306a36Sopenharmony_ci#elif defined(CONFIG_IA64_PAGE_SIZE_16KB) 3562306a36Sopenharmony_ci# define PAGE_SHIFT 14 3662306a36Sopenharmony_ci#elif defined(CONFIG_IA64_PAGE_SIZE_64KB) 3762306a36Sopenharmony_ci# define PAGE_SHIFT 16 3862306a36Sopenharmony_ci#else 3962306a36Sopenharmony_ci# error Unsupported page size! 4062306a36Sopenharmony_ci#endif 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT) 4362306a36Sopenharmony_ci#define PAGE_MASK (~(PAGE_SIZE - 1)) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define PERCPU_PAGE_SHIFT 18 /* log2() of max. size of per-CPU area */ 4662306a36Sopenharmony_ci#define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#ifdef CONFIG_HUGETLB_PAGE 5062306a36Sopenharmony_ci# define HPAGE_REGION_BASE RGN_BASE(RGN_HPAGE) 5162306a36Sopenharmony_ci# define HPAGE_SHIFT hpage_shift 5262306a36Sopenharmony_ci# define HPAGE_SHIFT_DEFAULT 28 /* check ia64 SDM for architecture supported size */ 5362306a36Sopenharmony_ci# define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT) 5462306a36Sopenharmony_ci# define HPAGE_MASK (~(HPAGE_SIZE - 1)) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci# define HAVE_ARCH_HUGETLB_UNMAPPED_AREA 5762306a36Sopenharmony_ci#endif /* CONFIG_HUGETLB_PAGE */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 6062306a36Sopenharmony_ci# define __pa(x) ((x) - PAGE_OFFSET) 6162306a36Sopenharmony_ci# define __va(x) ((x) + PAGE_OFFSET) 6262306a36Sopenharmony_ci#else /* !__ASSEMBLY */ 6362306a36Sopenharmony_ci# define STRICT_MM_TYPECHECKS 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciextern void clear_page (void *page); 6662306a36Sopenharmony_ciextern void copy_page (void *to, void *from); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* 6962306a36Sopenharmony_ci * clear_user_page() and copy_user_page() can't be inline functions because 7062306a36Sopenharmony_ci * flush_dcache_page() can't be defined until later... 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_ci#define clear_user_page(addr, vaddr, page) \ 7362306a36Sopenharmony_cido { \ 7462306a36Sopenharmony_ci clear_page(addr); \ 7562306a36Sopenharmony_ci flush_dcache_page(page); \ 7662306a36Sopenharmony_ci} while (0) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define copy_user_page(to, from, vaddr, page) \ 7962306a36Sopenharmony_cido { \ 8062306a36Sopenharmony_ci copy_page((to), (from)); \ 8162306a36Sopenharmony_ci flush_dcache_page(page); \ 8262306a36Sopenharmony_ci} while (0) 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define vma_alloc_zeroed_movable_folio(vma, vaddr) \ 8662306a36Sopenharmony_ci({ \ 8762306a36Sopenharmony_ci struct folio *folio = vma_alloc_folio( \ 8862306a36Sopenharmony_ci GFP_HIGHUSER_MOVABLE | __GFP_ZERO, 0, vma, vaddr, false); \ 8962306a36Sopenharmony_ci if (folio) \ 9062306a36Sopenharmony_ci flush_dcache_folio(folio); \ 9162306a36Sopenharmony_ci folio; \ 9262306a36Sopenharmony_ci}) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#include <asm-generic/memory_model.h> 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 9962306a36Sopenharmony_ci#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 10062306a36Sopenharmony_ci#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_citypedef union ia64_va { 10362306a36Sopenharmony_ci struct { 10462306a36Sopenharmony_ci unsigned long off : 61; /* intra-region offset */ 10562306a36Sopenharmony_ci unsigned long reg : 3; /* region number */ 10662306a36Sopenharmony_ci } f; 10762306a36Sopenharmony_ci unsigned long l; 10862306a36Sopenharmony_ci void *p; 10962306a36Sopenharmony_ci} ia64_va; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* 11262306a36Sopenharmony_ci * Note: These macros depend on the fact that PAGE_OFFSET has all 11362306a36Sopenharmony_ci * region bits set to 1 and all other bits set to zero. They are 11462306a36Sopenharmony_ci * expressed in this way to ensure they result in a single "dep" 11562306a36Sopenharmony_ci * instruction. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci#define __pa(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;}) 11862306a36Sopenharmony_ci#define __va(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;}) 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#define REGION_NUMBER(x) ({ia64_va _v; _v.l = (long) (x); _v.f.reg;}) 12162306a36Sopenharmony_ci#define REGION_OFFSET(x) ({ia64_va _v; _v.l = (long) (x); _v.f.off;}) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#ifdef CONFIG_HUGETLB_PAGE 12462306a36Sopenharmony_ci# define htlbpage_to_page(x) (((unsigned long) REGION_NUMBER(x) << 61) \ 12562306a36Sopenharmony_ci | (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT))) 12662306a36Sopenharmony_ci# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 12762306a36Sopenharmony_ciextern unsigned int hpage_shift; 12862306a36Sopenharmony_ci#endif 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistatic __inline__ int 13162306a36Sopenharmony_ciget_order (unsigned long size) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci long double d = size - 1; 13462306a36Sopenharmony_ci long order; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci order = ia64_getf_exp(d); 13762306a36Sopenharmony_ci order = order - PAGE_SHIFT - 0xffff + 1; 13862306a36Sopenharmony_ci if (order < 0) 13962306a36Sopenharmony_ci order = 0; 14062306a36Sopenharmony_ci return order; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci#ifdef STRICT_MM_TYPECHECKS 14662306a36Sopenharmony_ci /* 14762306a36Sopenharmony_ci * These are used to make use of C type-checking.. 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_ci typedef struct { unsigned long pte; } pte_t; 15062306a36Sopenharmony_ci typedef struct { unsigned long pmd; } pmd_t; 15162306a36Sopenharmony_ci#if CONFIG_PGTABLE_LEVELS == 4 15262306a36Sopenharmony_ci typedef struct { unsigned long pud; } pud_t; 15362306a36Sopenharmony_ci#endif 15462306a36Sopenharmony_ci typedef struct { unsigned long pgd; } pgd_t; 15562306a36Sopenharmony_ci typedef struct { unsigned long pgprot; } pgprot_t; 15662306a36Sopenharmony_ci typedef struct page *pgtable_t; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci# define pte_val(x) ((x).pte) 15962306a36Sopenharmony_ci# define pmd_val(x) ((x).pmd) 16062306a36Sopenharmony_ci#if CONFIG_PGTABLE_LEVELS == 4 16162306a36Sopenharmony_ci# define pud_val(x) ((x).pud) 16262306a36Sopenharmony_ci#endif 16362306a36Sopenharmony_ci# define pgd_val(x) ((x).pgd) 16462306a36Sopenharmony_ci# define pgprot_val(x) ((x).pgprot) 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci# define __pte(x) ((pte_t) { (x) } ) 16762306a36Sopenharmony_ci# define __pmd(x) ((pmd_t) { (x) } ) 16862306a36Sopenharmony_ci# define __pgprot(x) ((pgprot_t) { (x) } ) 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci#else /* !STRICT_MM_TYPECHECKS */ 17162306a36Sopenharmony_ci /* 17262306a36Sopenharmony_ci * .. while these make it easier on the compiler 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_ci# ifndef __ASSEMBLY__ 17562306a36Sopenharmony_ci typedef unsigned long pte_t; 17662306a36Sopenharmony_ci typedef unsigned long pmd_t; 17762306a36Sopenharmony_ci typedef unsigned long pgd_t; 17862306a36Sopenharmony_ci typedef unsigned long pgprot_t; 17962306a36Sopenharmony_ci typedef struct page *pgtable_t; 18062306a36Sopenharmony_ci# endif 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci# define pte_val(x) (x) 18362306a36Sopenharmony_ci# define pmd_val(x) (x) 18462306a36Sopenharmony_ci# define pgd_val(x) (x) 18562306a36Sopenharmony_ci# define pgprot_val(x) (x) 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci# define __pte(x) (x) 18862306a36Sopenharmony_ci# define __pgd(x) (x) 18962306a36Sopenharmony_ci# define __pgprot(x) (x) 19062306a36Sopenharmony_ci#endif /* !STRICT_MM_TYPECHECKS */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci#define PAGE_OFFSET RGN_BASE(RGN_KERNEL) 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#define GATE_ADDR RGN_BASE(RGN_GATE) 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* 19962306a36Sopenharmony_ci * 0xa000000000000000+2*PERCPU_PAGE_SIZE 20062306a36Sopenharmony_ci * - 0xa000000000000000+3*PERCPU_PAGE_SIZE remain unmapped (guard page) 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_ci#define KERNEL_START (GATE_ADDR+__IA64_UL_CONST(0x100000000)) 20362306a36Sopenharmony_ci#define PERCPU_ADDR (-PERCPU_PAGE_SIZE) 20462306a36Sopenharmony_ci#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE) 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci#define __HAVE_ARCH_GATE_AREA 1 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci#endif /* _ASM_IA64_PAGE_H */ 209