xref: /kvm-unit-tests/lib/arm/mmu.c (revision 39ac3f8494beb048a121f44bf626275b18c66da5)
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