10ae76531SDavid Feng /* 20ae76531SDavid Feng * (C) Copyright 2013 30ae76531SDavid Feng * David Feng <fenghua@phytium.com.cn> 40ae76531SDavid Feng * 50ae76531SDavid Feng * SPDX-License-Identifier: GPL-2.0+ 60ae76531SDavid Feng */ 70ae76531SDavid Feng 80ae76531SDavid Feng #ifndef _ASM_ARMV8_MMU_H_ 90ae76531SDavid Feng #define _ASM_ARMV8_MMU_H_ 100ae76531SDavid Feng 110ae76531SDavid Feng #ifdef __ASSEMBLY__ 120ae76531SDavid Feng #define _AC(X, Y) X 130ae76531SDavid Feng #else 140ae76531SDavid Feng #define _AC(X, Y) (X##Y) 150ae76531SDavid Feng #endif 160ae76531SDavid Feng 170ae76531SDavid Feng #define UL(x) _AC(x, UL) 180ae76531SDavid Feng 190ae76531SDavid Feng /***************************************************************/ 200ae76531SDavid Feng /* 210ae76531SDavid Feng * The following definitions are related each other, shoud be 220ae76531SDavid Feng * calculated specifically. 230ae76531SDavid Feng */ 2494f7ff36SSergey Temerkhanov 2594f7ff36SSergey Temerkhanov #define VA_BITS CONFIG_SYS_VA_BITS 265e2ec773SAlexander Graf #define PTE_BLOCK_BITS CONFIG_SYS_PTL2_BITS 270ae76531SDavid Feng 280ae76531SDavid Feng /* 2994f7ff36SSergey Temerkhanov * block/section address mask and size definitions. 300ae76531SDavid Feng */ 315e2ec773SAlexander Graf 325e2ec773SAlexander Graf /* PAGE_SHIFT determines the page size */ 335e2ec773SAlexander Graf #undef PAGE_SIZE 345e2ec773SAlexander Graf #define PAGE_SHIFT 12 355e2ec773SAlexander Graf #define PAGE_SIZE (1 << PAGE_SHIFT) 365e2ec773SAlexander Graf #define PAGE_MASK (~(PAGE_SIZE-1)) 375e2ec773SAlexander Graf 380ae76531SDavid Feng /***************************************************************/ 390ae76531SDavid Feng 400ae76531SDavid Feng /* 410ae76531SDavid Feng * Memory types 420ae76531SDavid Feng */ 430ae76531SDavid Feng #define MT_DEVICE_NGNRNE 0 440ae76531SDavid Feng #define MT_DEVICE_NGNRE 1 450ae76531SDavid Feng #define MT_DEVICE_GRE 2 460ae76531SDavid Feng #define MT_NORMAL_NC 3 470ae76531SDavid Feng #define MT_NORMAL 4 480ae76531SDavid Feng 490ae76531SDavid Feng #define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE * 8)) | \ 500ae76531SDavid Feng (0x04 << (MT_DEVICE_NGNRE * 8)) | \ 510ae76531SDavid Feng (0x0c << (MT_DEVICE_GRE * 8)) | \ 520ae76531SDavid Feng (0x44 << (MT_NORMAL_NC * 8)) | \ 530ae76531SDavid Feng (UL(0xff) << (MT_NORMAL * 8))) 540ae76531SDavid Feng 550ae76531SDavid Feng /* 560ae76531SDavid Feng * Hardware page table definitions. 570ae76531SDavid Feng * 5894f7ff36SSergey Temerkhanov */ 5994f7ff36SSergey Temerkhanov 605e2ec773SAlexander Graf #define PTE_TYPE_MASK (3 << 0) 615e2ec773SAlexander Graf #define PTE_TYPE_FAULT (0 << 0) 625e2ec773SAlexander Graf #define PTE_TYPE_TABLE (3 << 0) 635e2ec773SAlexander Graf #define PTE_TYPE_BLOCK (1 << 0) 6494f7ff36SSergey Temerkhanov 655e2ec773SAlexander Graf #define PTE_TABLE_PXN (1UL << 59) 665e2ec773SAlexander Graf #define PTE_TABLE_XN (1UL << 60) 675e2ec773SAlexander Graf #define PTE_TABLE_AP (1UL << 61) 685e2ec773SAlexander Graf #define PTE_TABLE_NS (1UL << 63) 6994f7ff36SSergey Temerkhanov 7094f7ff36SSergey Temerkhanov /* 7194f7ff36SSergey Temerkhanov * Block 7294f7ff36SSergey Temerkhanov */ 735e2ec773SAlexander Graf #define PTE_BLOCK_MEMTYPE(x) ((x) << 2) 747985cdf7SAlexander Graf #define PTE_BLOCK_NS (1 << 5) 755e2ec773SAlexander Graf #define PTE_BLOCK_NON_SHARE (0 << 8) 765e2ec773SAlexander Graf #define PTE_BLOCK_OUTER_SHARE (2 << 8) 775e2ec773SAlexander Graf #define PTE_BLOCK_INNER_SHARE (3 << 8) 785e2ec773SAlexander Graf #define PTE_BLOCK_AF (1 << 10) 795e2ec773SAlexander Graf #define PTE_BLOCK_NG (1 << 11) 805e2ec773SAlexander Graf #define PTE_BLOCK_PXN (UL(1) << 53) 815e2ec773SAlexander Graf #define PTE_BLOCK_UXN (UL(1) << 54) 8294f7ff36SSergey Temerkhanov 830ae76531SDavid Feng /* 840ae76531SDavid Feng * AttrIndx[2:0] 850ae76531SDavid Feng */ 860ae76531SDavid Feng #define PMD_ATTRINDX(t) ((t) << 2) 870ae76531SDavid Feng #define PMD_ATTRINDX_MASK (7 << 2) 880ae76531SDavid Feng 890ae76531SDavid Feng /* 900ae76531SDavid Feng * TCR flags. 910ae76531SDavid Feng */ 920ae76531SDavid Feng #define TCR_T0SZ(x) ((64 - (x)) << 0) 930ae76531SDavid Feng #define TCR_IRGN_NC (0 << 8) 940ae76531SDavid Feng #define TCR_IRGN_WBWA (1 << 8) 950ae76531SDavid Feng #define TCR_IRGN_WT (2 << 8) 960ae76531SDavid Feng #define TCR_IRGN_WBNWA (3 << 8) 970ae76531SDavid Feng #define TCR_IRGN_MASK (3 << 8) 980ae76531SDavid Feng #define TCR_ORGN_NC (0 << 10) 990ae76531SDavid Feng #define TCR_ORGN_WBWA (1 << 10) 1000ae76531SDavid Feng #define TCR_ORGN_WT (2 << 10) 1010ae76531SDavid Feng #define TCR_ORGN_WBNWA (3 << 10) 1020ae76531SDavid Feng #define TCR_ORGN_MASK (3 << 10) 1030ae76531SDavid Feng #define TCR_SHARED_NON (0 << 12) 10421a257b9SZhichun Hua #define TCR_SHARED_OUTER (2 << 12) 10521a257b9SZhichun Hua #define TCR_SHARED_INNER (3 << 12) 1060ae76531SDavid Feng #define TCR_TG0_4K (0 << 14) 1070ae76531SDavid Feng #define TCR_TG0_64K (1 << 14) 1080ae76531SDavid Feng #define TCR_TG0_16K (2 << 14) 1099bb367a5SAlexander Graf #define TCR_EPD1_DISABLE (1 << 23) 11094f7ff36SSergey Temerkhanov 111ad3d6e88SThierry Reding #define TCR_EL1_RSVD (1 << 31) 112ad3d6e88SThierry Reding #define TCR_EL2_RSVD (1 << 31 | 1 << 23) 113ad3d6e88SThierry Reding #define TCR_EL3_RSVD (1 << 31 | 1 << 23) 114ad3d6e88SThierry Reding 11522932ffcSYork Sun #ifndef __ASSEMBLY__ 11622932ffcSYork Sun static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr) 11722932ffcSYork Sun { 11822932ffcSYork Sun asm volatile("dsb sy"); 11922932ffcSYork Sun if (el == 1) { 12022932ffcSYork Sun asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory"); 12122932ffcSYork Sun asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory"); 12222932ffcSYork Sun asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory"); 12322932ffcSYork Sun } else if (el == 2) { 12422932ffcSYork Sun asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory"); 12522932ffcSYork Sun asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory"); 12622932ffcSYork Sun asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory"); 12722932ffcSYork Sun } else if (el == 3) { 12822932ffcSYork Sun asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory"); 12922932ffcSYork Sun asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory"); 13022932ffcSYork Sun asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory"); 13122932ffcSYork Sun } else { 13222932ffcSYork Sun hang(); 13322932ffcSYork Sun } 13422932ffcSYork Sun asm volatile("isb"); 13522932ffcSYork Sun } 13694f7ff36SSergey Temerkhanov 13794f7ff36SSergey Temerkhanov struct mm_region { 138*cd4b0c5fSYork Sun u64 virt; 139*cd4b0c5fSYork Sun u64 phys; 14094f7ff36SSergey Temerkhanov u64 size; 14194f7ff36SSergey Temerkhanov u64 attrs; 14294f7ff36SSergey Temerkhanov }; 143d473f0c6SAlexander Graf 144d473f0c6SAlexander Graf extern struct mm_region *mem_map; 145252cdb46SYork Sun void setup_pgtables(void); 146252cdb46SYork Sun u64 get_tcr(int el, u64 *pips, u64 *pva_bits); 14722932ffcSYork Sun #endif 14894f7ff36SSergey Temerkhanov 1490ae76531SDavid Feng #endif /* _ASM_ARMV8_MMU_H_ */ 150