18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_BOOK3S_64_HASH_4K_H 38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_BOOK3S_64_HASH_4K_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#define H_PTE_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 4KB = 2MB 68c2ecf20Sopenharmony_ci#define H_PMD_INDEX_SIZE 7 // size: 8B << 7 = 1KB, maps: 2^7 x 2MB = 256MB 78c2ecf20Sopenharmony_ci#define H_PUD_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 256MB = 128GB 88c2ecf20Sopenharmony_ci#define H_PGD_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 128GB = 64TB 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * Each context is 512TB. But on 4k we restrict our max TASK size to 64TB 128c2ecf20Sopenharmony_ci * Hence also limit max EA bits to 64TB. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#define MAX_EA_BITS_PER_CONTEXT 46 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * Our page table limit us to 64TB. For 64TB physical memory, we only need 64GB 198c2ecf20Sopenharmony_ci * of vmemmap space. To better support sparse memory layout, we use 61TB 208c2ecf20Sopenharmony_ci * linear map range, 1TB of vmalloc, 1TB of I/O and 1TB of vmememmap. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci#define REGION_SHIFT (40) 238c2ecf20Sopenharmony_ci#define H_KERN_MAP_SIZE (ASM_CONST(1) << REGION_SHIFT) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * Limits the linear mapping range 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci#define H_MAX_PHYSMEM_BITS 46 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Define the address range of the kernel non-linear virtual area (61TB) 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci#define H_KERN_VIRT_START ASM_CONST(0xc0003d0000000000) 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 368c2ecf20Sopenharmony_ci#define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE) 378c2ecf20Sopenharmony_ci#define H_PMD_TABLE_SIZE (sizeof(pmd_t) << H_PMD_INDEX_SIZE) 388c2ecf20Sopenharmony_ci#define H_PUD_TABLE_SIZE (sizeof(pud_t) << H_PUD_INDEX_SIZE) 398c2ecf20Sopenharmony_ci#define H_PGD_TABLE_SIZE (sizeof(pgd_t) << H_PGD_INDEX_SIZE) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define H_PAGE_F_GIX_SHIFT _PAGE_PA_MAX 428c2ecf20Sopenharmony_ci#define H_PAGE_F_SECOND _RPAGE_PKEY_BIT0 /* HPTE is in 2ndary HPTEG */ 438c2ecf20Sopenharmony_ci#define H_PAGE_F_GIX (_RPAGE_RPN43 | _RPAGE_RPN42 | _RPAGE_RPN41) 448c2ecf20Sopenharmony_ci#define H_PAGE_BUSY _RPAGE_RSV1 458c2ecf20Sopenharmony_ci#define H_PAGE_HASHPTE _RPAGE_PKEY_BIT4 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* PTE flags to conserve for HPTE identification */ 488c2ecf20Sopenharmony_ci#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \ 498c2ecf20Sopenharmony_ci H_PAGE_F_SECOND | H_PAGE_F_GIX) 508c2ecf20Sopenharmony_ci/* 518c2ecf20Sopenharmony_ci * Not supported by 4k linux page size 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_ci#define H_PAGE_4K_PFN 0x0 548c2ecf20Sopenharmony_ci#define H_PAGE_THP_HUGE 0x0 558c2ecf20Sopenharmony_ci#define H_PAGE_COMBO 0x0 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 8 bytes per each pte entry */ 588c2ecf20Sopenharmony_ci#define H_PTE_FRAG_SIZE_SHIFT (H_PTE_INDEX_SIZE + 3) 598c2ecf20Sopenharmony_ci#define H_PTE_FRAG_NR (PAGE_SIZE >> H_PTE_FRAG_SIZE_SHIFT) 608c2ecf20Sopenharmony_ci#define H_PMD_FRAG_SIZE_SHIFT (H_PMD_INDEX_SIZE + 3) 618c2ecf20Sopenharmony_ci#define H_PMD_FRAG_NR (PAGE_SIZE >> H_PMD_FRAG_SIZE_SHIFT) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/* memory key bits, only 8 keys supported */ 648c2ecf20Sopenharmony_ci#define H_PTE_PKEY_BIT4 0 658c2ecf20Sopenharmony_ci#define H_PTE_PKEY_BIT3 0 668c2ecf20Sopenharmony_ci#define H_PTE_PKEY_BIT2 _RPAGE_PKEY_BIT3 678c2ecf20Sopenharmony_ci#define H_PTE_PKEY_BIT1 _RPAGE_PKEY_BIT2 688c2ecf20Sopenharmony_ci#define H_PTE_PKEY_BIT0 _RPAGE_PKEY_BIT1 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci#define remap_4k_pfn(vma, addr, pfn, prot) \ 758c2ecf20Sopenharmony_ci remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#ifdef CONFIG_HUGETLB_PAGE 788c2ecf20Sopenharmony_cistatic inline int hash__hugepd_ok(hugepd_t hpd) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci unsigned long hpdval = hpd_val(hpd); 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * if it is not a pte and have hugepd shift mask 838c2ecf20Sopenharmony_ci * set, then it is a hugepd directory pointer 848c2ecf20Sopenharmony_ci */ 858c2ecf20Sopenharmony_ci if (!(hpdval & _PAGE_PTE) && (hpdval & _PAGE_PRESENT) && 868c2ecf20Sopenharmony_ci ((hpdval & HUGEPD_SHIFT_MASK) != 0)) 878c2ecf20Sopenharmony_ci return true; 888c2ecf20Sopenharmony_ci return false; 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci#endif 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/* 938c2ecf20Sopenharmony_ci * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just 948c2ecf20Sopenharmony_ci * a matter of returning the PTE bits that need to be modified. On 64K PTE, 958c2ecf20Sopenharmony_ci * things are a little more involved and hence needs many more parameters to 968c2ecf20Sopenharmony_ci * accomplish the same. However we want to abstract this out from the caller by 978c2ecf20Sopenharmony_ci * keeping the prototype consistent across the two formats. 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_cistatic inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte, 1008c2ecf20Sopenharmony_ci unsigned int subpg_index, unsigned long hidx, 1018c2ecf20Sopenharmony_ci int offset) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci return (hidx << H_PAGE_F_GIX_SHIFT) & 1048c2ecf20Sopenharmony_ci (H_PAGE_F_SECOND | H_PAGE_F_GIX); 1058c2ecf20Sopenharmony_ci} 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci#ifdef CONFIG_TRANSPARENT_HUGEPAGE 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic inline char *get_hpte_slot_array(pmd_t *pmdp) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci BUG(); 1128c2ecf20Sopenharmony_ci return NULL; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci BUG(); 1188c2ecf20Sopenharmony_ci return 0; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, 1228c2ecf20Sopenharmony_ci int index) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci BUG(); 1258c2ecf20Sopenharmony_ci return 0; 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, 1298c2ecf20Sopenharmony_ci unsigned int index, unsigned int hidx) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci BUG(); 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic inline int hash__pmd_trans_huge(pmd_t pmd) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci return 0; 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic inline int hash__pmd_same(pmd_t pmd_a, pmd_t pmd_b) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci BUG(); 1428c2ecf20Sopenharmony_ci return 0; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic inline pmd_t hash__pmd_mkhuge(pmd_t pmd) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci BUG(); 1488c2ecf20Sopenharmony_ci return pmd; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciextern unsigned long hash__pmd_hugepage_update(struct mm_struct *mm, 1528c2ecf20Sopenharmony_ci unsigned long addr, pmd_t *pmdp, 1538c2ecf20Sopenharmony_ci unsigned long clr, unsigned long set); 1548c2ecf20Sopenharmony_ciextern pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, 1558c2ecf20Sopenharmony_ci unsigned long address, pmd_t *pmdp); 1568c2ecf20Sopenharmony_ciextern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, 1578c2ecf20Sopenharmony_ci pgtable_t pgtable); 1588c2ecf20Sopenharmony_ciextern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); 1598c2ecf20Sopenharmony_ciextern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, 1608c2ecf20Sopenharmony_ci unsigned long addr, pmd_t *pmdp); 1618c2ecf20Sopenharmony_ciextern int hash__has_transparent_hugepage(void); 1628c2ecf20Sopenharmony_ci#endif 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic inline pmd_t hash__pmd_mkdevmap(pmd_t pmd) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci BUG(); 1678c2ecf20Sopenharmony_ci return pmd; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ 173