187d1587bSSuzuki K. Poulose /* 287d1587bSSuzuki K. Poulose * Kernel page table mapping 387d1587bSSuzuki K. Poulose * 487d1587bSSuzuki K. Poulose * Copyright (C) 2015 ARM Ltd. 587d1587bSSuzuki K. Poulose * 687d1587bSSuzuki K. Poulose * This program is free software; you can redistribute it and/or modify 787d1587bSSuzuki K. Poulose * it under the terms of the GNU General Public License version 2 as 887d1587bSSuzuki K. Poulose * published by the Free Software Foundation. 987d1587bSSuzuki K. Poulose * 1087d1587bSSuzuki K. Poulose * This program is distributed in the hope that it will be useful, 1187d1587bSSuzuki K. Poulose * but WITHOUT ANY WARRANTY; without even the implied warranty of 1287d1587bSSuzuki K. Poulose * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1387d1587bSSuzuki K. Poulose * GNU General Public License for more details. 1487d1587bSSuzuki K. Poulose * 1587d1587bSSuzuki K. Poulose * You should have received a copy of the GNU General Public License 1687d1587bSSuzuki K. Poulose * along with this program. If not, see <http://www.gnu.org/licenses/>. 1787d1587bSSuzuki K. Poulose */ 1887d1587bSSuzuki K. Poulose 1987d1587bSSuzuki K. Poulose #ifndef __ASM_KERNEL_PGTABLE_H 2087d1587bSSuzuki K. Poulose #define __ASM_KERNEL_PGTABLE_H 2187d1587bSSuzuki K. Poulose 22*4b65a5dbSCatalin Marinas #include <asm/pgtable.h> 2306e9bf2fSArd Biesheuvel #include <asm/sparsemem.h> 24b433dce0SSuzuki K. Poulose 25b433dce0SSuzuki K. Poulose /* 26b433dce0SSuzuki K. Poulose * The linear mapping and the start of memory are both 2M aligned (per 27b433dce0SSuzuki K. Poulose * the arm64 booting.txt requirements). Hence we can use section mapping 28b433dce0SSuzuki K. Poulose * with 4K (section size = 2M) but not with 16K (section size = 32M) or 29b433dce0SSuzuki K. Poulose * 64K (section size = 512M). 30b433dce0SSuzuki K. Poulose */ 31b433dce0SSuzuki K. Poulose #ifdef CONFIG_ARM64_4K_PAGES 32b433dce0SSuzuki K. Poulose #define ARM64_SWAPPER_USES_SECTION_MAPS 1 33b433dce0SSuzuki K. Poulose #else 34b433dce0SSuzuki K. Poulose #define ARM64_SWAPPER_USES_SECTION_MAPS 0 35b433dce0SSuzuki K. Poulose #endif 36b433dce0SSuzuki K. Poulose 3787d1587bSSuzuki K. Poulose /* 3887d1587bSSuzuki K. Poulose * The idmap and swapper page tables need some space reserved in the kernel 3987d1587bSSuzuki K. Poulose * image. Both require pgd, pud (4 levels only) and pmd tables to (section) 4087d1587bSSuzuki K. Poulose * map the kernel. With the 64K page configuration, swapper and idmap need to 4187d1587bSSuzuki K. Poulose * map to pte level. The swapper also maps the FDT (see __create_page_tables 4287d1587bSSuzuki K. Poulose * for more information). Note that the number of ID map translation levels 4387d1587bSSuzuki K. Poulose * could be increased on the fly if system RAM is out of reach for the default 44c265af51SSuzuki K. Poulose * VA range, so pages required to map highest possible PA are reserved in all 45c265af51SSuzuki K. Poulose * cases. 4687d1587bSSuzuki K. Poulose */ 47b433dce0SSuzuki K. Poulose #if ARM64_SWAPPER_USES_SECTION_MAPS 4887d1587bSSuzuki K. Poulose #define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1) 49c265af51SSuzuki K. Poulose #define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1) 50b433dce0SSuzuki K. Poulose #else 51b433dce0SSuzuki K. Poulose #define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS) 52c265af51SSuzuki K. Poulose #define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT)) 5387d1587bSSuzuki K. Poulose #endif 5487d1587bSSuzuki K. Poulose 5587d1587bSSuzuki K. Poulose #define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE) 56c265af51SSuzuki K. Poulose #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) 5787d1587bSSuzuki K. Poulose 58*4b65a5dbSCatalin Marinas #ifdef CONFIG_ARM64_SW_TTBR0_PAN 59*4b65a5dbSCatalin Marinas #define RESERVED_TTBR0_SIZE (PAGE_SIZE) 60*4b65a5dbSCatalin Marinas #else 61*4b65a5dbSCatalin Marinas #define RESERVED_TTBR0_SIZE (0) 62*4b65a5dbSCatalin Marinas #endif 63*4b65a5dbSCatalin Marinas 6487d1587bSSuzuki K. Poulose /* Initial memory map size */ 65b433dce0SSuzuki K. Poulose #if ARM64_SWAPPER_USES_SECTION_MAPS 6687d1587bSSuzuki K. Poulose #define SWAPPER_BLOCK_SHIFT SECTION_SHIFT 6787d1587bSSuzuki K. Poulose #define SWAPPER_BLOCK_SIZE SECTION_SIZE 6887d1587bSSuzuki K. Poulose #define SWAPPER_TABLE_SHIFT PUD_SHIFT 69b433dce0SSuzuki K. Poulose #else 70b433dce0SSuzuki K. Poulose #define SWAPPER_BLOCK_SHIFT PAGE_SHIFT 71b433dce0SSuzuki K. Poulose #define SWAPPER_BLOCK_SIZE PAGE_SIZE 72b433dce0SSuzuki K. Poulose #define SWAPPER_TABLE_SHIFT PMD_SHIFT 7387d1587bSSuzuki K. Poulose #endif 7487d1587bSSuzuki K. Poulose 75b433dce0SSuzuki K. Poulose /* The size of the initial kernel direct mapping */ 76b433dce0SSuzuki K. Poulose #define SWAPPER_INIT_MAP_SIZE (_AC(1, UL) << SWAPPER_TABLE_SHIFT) 7787d1587bSSuzuki K. Poulose 7887d1587bSSuzuki K. Poulose /* 7987d1587bSSuzuki K. Poulose * Initial memory map attributes. 8087d1587bSSuzuki K. Poulose */ 8187d1587bSSuzuki K. Poulose #define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) 8287d1587bSSuzuki K. Poulose #define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) 8387d1587bSSuzuki K. Poulose 84b433dce0SSuzuki K. Poulose #if ARM64_SWAPPER_USES_SECTION_MAPS 8587d1587bSSuzuki K. Poulose #define SWAPPER_MM_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS) 86b433dce0SSuzuki K. Poulose #else 87b433dce0SSuzuki K. Poulose #define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS) 8887d1587bSSuzuki K. Poulose #endif 8987d1587bSSuzuki K. Poulose 90a7f8de16SArd Biesheuvel /* 91a7f8de16SArd Biesheuvel * To make optimal use of block mappings when laying out the linear 92a7f8de16SArd Biesheuvel * mapping, round down the base of physical memory to a size that can 93a7f8de16SArd Biesheuvel * be mapped efficiently, i.e., either PUD_SIZE (4k granule) or PMD_SIZE 94a7f8de16SArd Biesheuvel * (64k granule), or a multiple that can be mapped using contiguous bits 95a7f8de16SArd Biesheuvel * in the page tables: 32 * PMD_SIZE (16k granule) 96a7f8de16SArd Biesheuvel */ 9706e9bf2fSArd Biesheuvel #if defined(CONFIG_ARM64_4K_PAGES) 9806e9bf2fSArd Biesheuvel #define ARM64_MEMSTART_SHIFT PUD_SHIFT 9906e9bf2fSArd Biesheuvel #elif defined(CONFIG_ARM64_16K_PAGES) 10006e9bf2fSArd Biesheuvel #define ARM64_MEMSTART_SHIFT (PMD_SHIFT + 5) 101a7f8de16SArd Biesheuvel #else 10206e9bf2fSArd Biesheuvel #define ARM64_MEMSTART_SHIFT PMD_SHIFT 10306e9bf2fSArd Biesheuvel #endif 10406e9bf2fSArd Biesheuvel 10506e9bf2fSArd Biesheuvel /* 10606e9bf2fSArd Biesheuvel * sparsemem vmemmap imposes an additional requirement on the alignment of 10706e9bf2fSArd Biesheuvel * memstart_addr, due to the fact that the base of the vmemmap region 10806e9bf2fSArd Biesheuvel * has a direct correspondence, and needs to appear sufficiently aligned 10906e9bf2fSArd Biesheuvel * in the virtual address space. 11006e9bf2fSArd Biesheuvel */ 11106e9bf2fSArd Biesheuvel #if defined(CONFIG_SPARSEMEM_VMEMMAP) && ARM64_MEMSTART_SHIFT < SECTION_SIZE_BITS 11206e9bf2fSArd Biesheuvel #define ARM64_MEMSTART_ALIGN (1UL << SECTION_SIZE_BITS) 11306e9bf2fSArd Biesheuvel #else 11406e9bf2fSArd Biesheuvel #define ARM64_MEMSTART_ALIGN (1UL << ARM64_MEMSTART_SHIFT) 115a7f8de16SArd Biesheuvel #endif 11687d1587bSSuzuki K. Poulose 11787d1587bSSuzuki K. Poulose #endif /* __ASM_KERNEL_PGTABLE_H */ 118