summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/mmu.h
blob: c911ee209f51b86aab9003069635172304694064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef __ARM_MMU_H
#define __ARM_MMU_H

#include <asm/pgtable.h>
#include <linux/sizes.h>
#include <asm/system_info.h>

#include "mmu-common.h"

#define PGDIR_SHIFT	20
#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)

#define pgd_index(addr)		((addr) >> PGDIR_SHIFT)

#ifdef CONFIG_MMU
void __mmu_cache_on(void);
void __mmu_cache_off(void);
void __mmu_cache_flush(void);
#else
static inline void __mmu_cache_on(void) {}
static inline void __mmu_cache_off(void) {}
static inline void __mmu_cache_flush(void) {}
#endif

static inline unsigned long get_ttbr(void)
{
	unsigned long ttb;

	asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));

	return ttb;
}

static inline void set_ttbr(void *ttb)
{
	asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb) /*:*/);
}

#define DOMAIN_MANAGER	3

static inline void set_domain(unsigned val)
{
	/* Set the Domain Access Control Register */
	asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(val) /*:*/);
}

static inline void
create_sections(uint32_t *ttb, unsigned long first,
		unsigned long last, unsigned int flags)
{
	unsigned long ttb_start = pgd_index(first);
	unsigned long ttb_end = pgd_index(last) + 1;
	unsigned int i, addr = first;

	for (i = ttb_start; i < ttb_end; i++) {
		ttb[i] = addr | flags;
		addr += PGDIR_SIZE;
	}
}

#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT)
#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED)

static inline void create_flat_mapping(uint32_t *ttb)
{
	unsigned int flags = PMD_SECT_DEF_UNCACHED;

	if (cpu_architecture() >= CPU_ARCH_ARMv7)
		flags |= PMD_SECT_XN;

	/* create a flat mapping using 1MiB sections */
	create_sections(ttb, 0, 0xffffffff, flags);
}

#endif /* __ARM_MMU_H */