1 /* 2 * MMU enable and page table manipulation functions 3 * 4 * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8 #include <asm/setup.h> 9 #include <asm/mmu.h> 10 #include <asm/pgtable-hwdef.h> 11 12 static bool mmu_on; 13 static pgd_t idmap[PTRS_PER_PGD] __attribute__((aligned(L1_CACHE_BYTES))); 14 15 bool mmu_enabled(void) 16 { 17 return mmu_on; 18 } 19 20 extern void asm_mmu_enable(phys_addr_t pgtable); 21 void mmu_enable(pgd_t *pgtable) 22 { 23 asm_mmu_enable(__pa(pgtable)); 24 flush_tlb_all(); 25 mmu_on = true; 26 } 27 28 void mmu_init_io_sect(pgd_t *pgtable) 29 { 30 /* 31 * mach-virt reserves the first 1G section for I/O 32 */ 33 pgd_val(pgtable[0]) = PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_USER; 34 pgd_val(pgtable[0]) |= PMD_SECT_UNCACHED; 35 } 36 37 void mmu_enable_idmap(void) 38 { 39 unsigned long sect, end; 40 41 mmu_init_io_sect(idmap); 42 43 end = sizeof(long) == 8 || !(PHYS_END >> 32) ? PHYS_END : 0xfffff000; 44 45 for (sect = PHYS_OFFSET & PGDIR_MASK; sect < end; sect += PGDIR_SIZE) { 46 int i = sect >> PGDIR_SHIFT; 47 pgd_val(idmap[i]) = sect; 48 pgd_val(idmap[i]) |= PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_USER; 49 pgd_val(idmap[i]) |= PMD_SECT_S | PMD_SECT_WBWA; 50 } 51 52 mmu_enable(idmap); 53 } 54