18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/include/asm/pgtable-2level.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1995-2002 Russell King 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef _ASM_PGTABLE_2LEVEL_H 88c2ecf20Sopenharmony_ci#define _ASM_PGTABLE_2LEVEL_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define __PAGETABLE_PMD_FOLDED 1 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* 138c2ecf20Sopenharmony_ci * Hardware-wise, we have a two level page table structure, where the first 148c2ecf20Sopenharmony_ci * level has 4096 entries, and the second level has 256 entries. Each entry 158c2ecf20Sopenharmony_ci * is one 32-bit word. Most of the bits in the second level entry are used 168c2ecf20Sopenharmony_ci * by hardware, and there aren't any "accessed" and "dirty" bits. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Linux on the other hand has a three level page table structure, which can 198c2ecf20Sopenharmony_ci * be wrapped to fit a two level page table structure easily - using the PGD 208c2ecf20Sopenharmony_ci * and PTE only. However, Linux also expects one "PTE" table per page, and 218c2ecf20Sopenharmony_ci * at least a "dirty" bit. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Therefore, we tweak the implementation slightly - we tell Linux that we 248c2ecf20Sopenharmony_ci * have 2048 entries in the first level, each of which is 8 bytes (iow, two 258c2ecf20Sopenharmony_ci * hardware pointers to the second level.) The second level contains two 268c2ecf20Sopenharmony_ci * hardware PTE tables arranged contiguously, preceded by Linux versions 278c2ecf20Sopenharmony_ci * which contain the state information Linux needs. We, therefore, end up 288c2ecf20Sopenharmony_ci * with 512 entries in the "PTE" level. 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * This leads to the page tables having the following layout: 318c2ecf20Sopenharmony_ci * 328c2ecf20Sopenharmony_ci * pgd pte 338c2ecf20Sopenharmony_ci * | | 348c2ecf20Sopenharmony_ci * +--------+ 358c2ecf20Sopenharmony_ci * | | +------------+ +0 368c2ecf20Sopenharmony_ci * +- - - - + | Linux pt 0 | 378c2ecf20Sopenharmony_ci * | | +------------+ +1024 388c2ecf20Sopenharmony_ci * +--------+ +0 | Linux pt 1 | 398c2ecf20Sopenharmony_ci * | |-----> +------------+ +2048 408c2ecf20Sopenharmony_ci * +- - - - + +4 | h/w pt 0 | 418c2ecf20Sopenharmony_ci * | |-----> +------------+ +3072 428c2ecf20Sopenharmony_ci * +--------+ +8 | h/w pt 1 | 438c2ecf20Sopenharmony_ci * | | +------------+ +4096 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * See L_PTE_xxx below for definitions of bits in the "Linux pt", and 468c2ecf20Sopenharmony_ci * PTE_xxx for definitions of bits appearing in the "h/w pt". 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * PMD_xxx definitions refer to bits in the first level page table. 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * The "dirty" bit is emulated by only granting hardware write permission 518c2ecf20Sopenharmony_ci * iff the page is marked "writable" and "dirty" in the Linux PTE. This 528c2ecf20Sopenharmony_ci * means that a write to a clean page will cause a permission fault, and 538c2ecf20Sopenharmony_ci * the Linux MM layer will mark the page dirty via handle_pte_fault(). 548c2ecf20Sopenharmony_ci * For the hardware to notice the permission change, the TLB entry must 558c2ecf20Sopenharmony_ci * be flushed, and ptep_set_access_flags() does that for us. 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * The "accessed" or "young" bit is emulated by a similar method; we only 588c2ecf20Sopenharmony_ci * allow accesses to the page if the "young" bit is set. Accesses to the 598c2ecf20Sopenharmony_ci * page will cause a fault, and handle_pte_fault() will set the young bit 608c2ecf20Sopenharmony_ci * for us as long as the page is marked present in the corresponding Linux 618c2ecf20Sopenharmony_ci * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is 628c2ecf20Sopenharmony_ci * up to date. 638c2ecf20Sopenharmony_ci * 648c2ecf20Sopenharmony_ci * However, when the "young" bit is cleared, we deny access to the page 658c2ecf20Sopenharmony_ci * by clearing the hardware PTE. Currently Linux does not flush the TLB 668c2ecf20Sopenharmony_ci * for us in this case, which means the TLB will retain the transation 678c2ecf20Sopenharmony_ci * until either the TLB entry is evicted under pressure, or a context 688c2ecf20Sopenharmony_ci * switch which changes the user space mapping occurs. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci#define PTRS_PER_PTE 512 718c2ecf20Sopenharmony_ci#define PTRS_PER_PMD 1 728c2ecf20Sopenharmony_ci#define PTRS_PER_PGD 2048 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#define PTE_HWTABLE_PTRS (PTRS_PER_PTE) 758c2ecf20Sopenharmony_ci#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t)) 768c2ecf20Sopenharmony_ci#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32)) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci#define MAX_POSSIBLE_PHYSMEM_BITS 32 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* 818c2ecf20Sopenharmony_ci * PMD_SHIFT determines the size of the area a second-level page table can map 828c2ecf20Sopenharmony_ci * PGDIR_SHIFT determines what a third-level page table entry can map 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci#define PMD_SHIFT 21 858c2ecf20Sopenharmony_ci#define PGDIR_SHIFT 21 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define PMD_SIZE (1UL << PMD_SHIFT) 888c2ecf20Sopenharmony_ci#define PMD_MASK (~(PMD_SIZE-1)) 898c2ecf20Sopenharmony_ci#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 908c2ecf20Sopenharmony_ci#define PGDIR_MASK (~(PGDIR_SIZE-1)) 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/* 938c2ecf20Sopenharmony_ci * section address mask and size definitions. 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_ci#define SECTION_SHIFT 20 968c2ecf20Sopenharmony_ci#define SECTION_SIZE (1UL << SECTION_SHIFT) 978c2ecf20Sopenharmony_ci#define SECTION_MASK (~(SECTION_SIZE-1)) 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* 1008c2ecf20Sopenharmony_ci * ARMv6 supersection address mask and size definitions. 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci#define SUPERSECTION_SHIFT 24 1038c2ecf20Sopenharmony_ci#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT) 1048c2ecf20Sopenharmony_ci#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1)) 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* 1098c2ecf20Sopenharmony_ci * "Linux" PTE definitions. 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * We keep two sets of PTEs - the hardware and the linux version. 1128c2ecf20Sopenharmony_ci * This allows greater flexibility in the way we map the Linux bits 1138c2ecf20Sopenharmony_ci * onto the hardware tables, and allows us to have YOUNG and DIRTY 1148c2ecf20Sopenharmony_ci * bits. 1158c2ecf20Sopenharmony_ci * 1168c2ecf20Sopenharmony_ci * The PTE table pointer refers to the hardware entries; the "Linux" 1178c2ecf20Sopenharmony_ci * entries are stored 1024 bytes below. 1188c2ecf20Sopenharmony_ci */ 1198c2ecf20Sopenharmony_ci#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */ 1208c2ecf20Sopenharmony_ci#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0) 1218c2ecf20Sopenharmony_ci#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1) 1228c2ecf20Sopenharmony_ci#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6) 1238c2ecf20Sopenharmony_ci#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) 1248c2ecf20Sopenharmony_ci#define L_PTE_USER (_AT(pteval_t, 1) << 8) 1258c2ecf20Sopenharmony_ci#define L_PTE_XN (_AT(pteval_t, 1) << 9) 1268c2ecf20Sopenharmony_ci#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */ 1278c2ecf20Sopenharmony_ci#define L_PTE_NONE (_AT(pteval_t, 1) << 11) 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* 1308c2ecf20Sopenharmony_ci * These are the memory types, defined to be compatible with 1318c2ecf20Sopenharmony_ci * pre-ARMv6 CPUs cacheable and bufferable bits: n/a,n/a,C,B 1328c2ecf20Sopenharmony_ci * ARMv6+ without TEX remapping, they are a table index. 1338c2ecf20Sopenharmony_ci * ARMv6+ with TEX remapping, they correspond to n/a,TEX(0),C,B 1348c2ecf20Sopenharmony_ci * 1358c2ecf20Sopenharmony_ci * MT type Pre-ARMv6 ARMv6+ type / cacheable status 1368c2ecf20Sopenharmony_ci * UNCACHED Uncached Strongly ordered 1378c2ecf20Sopenharmony_ci * BUFFERABLE Bufferable Normal memory / non-cacheable 1388c2ecf20Sopenharmony_ci * WRITETHROUGH Writethrough Normal memory / write through 1398c2ecf20Sopenharmony_ci * WRITEBACK Writeback Normal memory / write back, read alloc 1408c2ecf20Sopenharmony_ci * MINICACHE Minicache N/A 1418c2ecf20Sopenharmony_ci * WRITEALLOC Writeback Normal memory / write back, write alloc 1428c2ecf20Sopenharmony_ci * DEV_SHARED Uncached Device memory (shared) 1438c2ecf20Sopenharmony_ci * DEV_NONSHARED Uncached Device memory (non-shared) 1448c2ecf20Sopenharmony_ci * DEV_WC Bufferable Normal memory / non-cacheable 1458c2ecf20Sopenharmony_ci * DEV_CACHED Writeback Normal memory / write back, read alloc 1468c2ecf20Sopenharmony_ci * VECTORS Variable Normal memory / variable 1478c2ecf20Sopenharmony_ci * 1488c2ecf20Sopenharmony_ci * All normal memory mappings have the following properties: 1498c2ecf20Sopenharmony_ci * - reads can be repeated with no side effects 1508c2ecf20Sopenharmony_ci * - repeated reads return the last value written 1518c2ecf20Sopenharmony_ci * - reads can fetch additional locations without side effects 1528c2ecf20Sopenharmony_ci * - writes can be repeated (in certain cases) with no side effects 1538c2ecf20Sopenharmony_ci * - writes can be merged before accessing the target 1548c2ecf20Sopenharmony_ci * - unaligned accesses can be supported 1558c2ecf20Sopenharmony_ci * 1568c2ecf20Sopenharmony_ci * All device mappings have the following properties: 1578c2ecf20Sopenharmony_ci * - no access speculation 1588c2ecf20Sopenharmony_ci * - no repetition (eg, on return from an exception) 1598c2ecf20Sopenharmony_ci * - number, order and size of accesses are maintained 1608c2ecf20Sopenharmony_ci * - unaligned accesses are "unpredictable" 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */ 1638c2ecf20Sopenharmony_ci#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */ 1648c2ecf20Sopenharmony_ci#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */ 1658c2ecf20Sopenharmony_ci#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */ 1668c2ecf20Sopenharmony_ci#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */ 1678c2ecf20Sopenharmony_ci#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */ 1688c2ecf20Sopenharmony_ci#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */ 1698c2ecf20Sopenharmony_ci#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */ 1708c2ecf20Sopenharmony_ci#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */ 1718c2ecf20Sopenharmony_ci#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ 1728c2ecf20Sopenharmony_ci#define L_PTE_MT_VECTORS (_AT(pteval_t, 0x0f) << 2) /* 1111 */ 1738c2ecf20Sopenharmony_ci#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci/* 1788c2ecf20Sopenharmony_ci * The "pud_xxx()" functions here are trivial when the pmd is folded into 1798c2ecf20Sopenharmony_ci * the pud: the pud entry is never bad, always exists, and can't be set or 1808c2ecf20Sopenharmony_ci * cleared. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_ci#define pud_none(pud) (0) 1838c2ecf20Sopenharmony_ci#define pud_bad(pud) (0) 1848c2ecf20Sopenharmony_ci#define pud_present(pud) (1) 1858c2ecf20Sopenharmony_ci#define pud_clear(pudp) do { } while (0) 1868c2ecf20Sopenharmony_ci#define set_pud(pud,pudp) do { } while (0) 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci return (pmd_t *)pud; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci#define pmd_offset pmd_offset 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#define pmd_large(pmd) (pmd_val(pmd) & 2) 1958c2ecf20Sopenharmony_ci#define pmd_leaf(pmd) (pmd_val(pmd) & 2) 1968c2ecf20Sopenharmony_ci#define pmd_bad(pmd) (pmd_val(pmd) & 2) 1978c2ecf20Sopenharmony_ci#define pmd_present(pmd) (pmd_val(pmd)) 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#define copy_pmd(pmdpd,pmdps) \ 2008c2ecf20Sopenharmony_ci do { \ 2018c2ecf20Sopenharmony_ci pmdpd[0] = pmdps[0]; \ 2028c2ecf20Sopenharmony_ci pmdpd[1] = pmdps[1]; \ 2038c2ecf20Sopenharmony_ci flush_pmd_entry(pmdpd); \ 2048c2ecf20Sopenharmony_ci } while (0) 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci#define pmd_clear(pmdp) \ 2078c2ecf20Sopenharmony_ci do { \ 2088c2ecf20Sopenharmony_ci pmdp[0] = __pmd(0); \ 2098c2ecf20Sopenharmony_ci pmdp[1] = __pmd(0); \ 2108c2ecf20Sopenharmony_ci clean_pmd_entry(pmdp); \ 2118c2ecf20Sopenharmony_ci } while (0) 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci/* we don't need complex calculations here as the pmd is folded into the pgd */ 2148c2ecf20Sopenharmony_ci#define pmd_addr_end(addr,end) (end) 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci/* 2198c2ecf20Sopenharmony_ci * We don't have huge page support for short descriptors, for the moment 2208c2ecf20Sopenharmony_ci * define empty stubs for use by pin_page_for_write. 2218c2ecf20Sopenharmony_ci */ 2228c2ecf20Sopenharmony_ci#define pmd_hugewillfault(pmd) (0) 2238c2ecf20Sopenharmony_ci#define pmd_thp_or_huge(pmd) (0) 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci#endif /* _ASM_PGTABLE_2LEVEL_H */ 228