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
|
#include "arch.h"
#include "kern/mpu/mpu_manager.h"
#include "arch/arm/cortex-m4/mpu.h"
#include "kern/common.h"
#include "kern/log.h"
#include "kern/panic.h"
memory_region_opts_t memory_regions[8];
void mpu_set_enabled(bool enabled)
{
if (enabled) {
regset(MPU.ctrl_r, mpu_en, 1);
__isb();
__dsb();
} else {
regset(MPU.ctrl_r, mpu_en, 0);
}
}
void mpu_configure_region(int region_number, memory_region_opts_t* opts)
{
if (region_number >= 8) {
panic("MPU can only handle 8 regions.");
}
memory_regions[region_number] = *opts;
uint32_t region = ptr2reg(opts->region);
if (opts->size == REGION_SIZE_4Gb && region != 0) {
panic("Region pointer must be 0 for region size of 4Gb");
} else if ((region & region_size_mask(opts->size))) {
panic("Memory region MUST be aligned with given size.");
}
MPU.rn_r = region_number;
uint32_t rbar = region;
regset(rbar, mpu_region, region_number);
regset(rbar, mpu_valid, 1);
klogf("Writing RBAR: %p\n", rbar);
uint32_t rasr = 0;
regset(rasr, mpu_en, opts->enable);
regset(rasr, mpu_size, opts->size);
regset(rasr, mpu_srd, opts->subregion_disable);
regset(rasr, mpu_b, opts->bufferable);
regset(rasr, mpu_c, opts->cacheable);
regset(rasr, mpu_s, opts->sharable);
regset(rasr, mpu_tex, opts->tex);
regset(rasr, mpu_ap, opts->perms);
regset(rasr, mpu_xn, !opts->executable);
klogf("Writing RASR: %p\n", rasr);
MPU.rba_r = rbar;
MPU.ras_r = rasr;
}
|