mpu.h
4.38 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* Copyright (C) 2016 Loci Controls Inc.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_cortexm_common
* @{
*
* @file mpu.h
* @brief Cortex-M Memory Protection Unit (MPU) Driver Header File
*
* @author Ian Martin <ian@locicontrols.com>
*
* @}
*/
#ifndef MPU_H_
#define MPU_H_
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Number of MPU regions available (will vary depending on the Cortex-M version)
*/
#define MPU_NUM_REGIONS ( (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos )
/**
* @brief Access Permission words
*/
enum {
AP_NO_NO = 0, /**< no access for all levels */
AP_RW_NO = 1, /**< read/write for privileged level, no access from user level */
AP_RW_RO = 2, /**< read/write for privileged level, read-only for user level */
AP_RW_RW = 3, /**< read/write for all levels */
AP_RO_NO = 5, /**< read-only for privileged level, no access from user level */
AP_RO_RO = 6, /**< read-only for all levels */
};
/**
* @brief MPU region sizes
*/
enum {
MPU_SIZE_32B = 4, /**< 32 bytes */
MPU_SIZE_64B = 5, /**< 64 bytes */
MPU_SIZE_128B = 6, /**< 128 bytes */
MPU_SIZE_256B = 7, /**< 256 bytes */
MPU_SIZE_512B = 8, /**< 512 bytes */
MPU_SIZE_1K = 9, /**< 1 kilobytes */
MPU_SIZE_2K = 10, /**< 2 kilobytes */
MPU_SIZE_4K = 11, /**< 4 kilobytes */
MPU_SIZE_8K = 12, /**< 8 kilobytes */
MPU_SIZE_16K = 13, /**< 16 kilobytes */
MPU_SIZE_32K = 14, /**< 32 kilobytes */
MPU_SIZE_64K = 15, /**< 64 kilobytes */
MPU_SIZE_128K = 16, /**< 128 kilobytes */
MPU_SIZE_256K = 17, /**< 256 kilobytes */
MPU_SIZE_512K = 18, /**< 512 kilobytes */
MPU_SIZE_1M = 19, /**< 1 megabytes */
MPU_SIZE_2M = 20, /**< 2 megabytes */
MPU_SIZE_4M = 21, /**< 4 megabytes */
MPU_SIZE_8M = 22, /**< 8 megabytes */
MPU_SIZE_16M = 23, /**< 16 megabytes */
MPU_SIZE_32M = 24, /**< 32 megabytes */
MPU_SIZE_64M = 25, /**< 64 megabytes */
MPU_SIZE_128M = 26, /**< 128 megabytes */
MPU_SIZE_256M = 27, /**< 256 megabytes */
MPU_SIZE_512M = 28, /**< 512 megabytes */
MPU_SIZE_1G = 29, /**< 1 gigabytes */
MPU_SIZE_2G = 30, /**< 2 gigabytes */
MPU_SIZE_4G = 31, /**< 4 gigabytes */
};
/**
* @brief convert a region size code to a size in bytes
*
* @param[in] size region size code, e.g. MPU_SIZE_32B
*
* @return region size in bytes
*/
#define MPU_SIZE_TO_BYTES(size) ( (uintptr_t)1 << ((size) + 1) )
/**
* @brief generate an MPU attribute word suitable for writing to the RASR register
*
* @param[in] xn eXecute Never flag (forbids instruction fetches)
* @param[in] ap Access Permission word, e.g. AP_RO_RO
* @param[in] tex Type Extension Field
* @param[in] c Cacheable bit
* @param[in] b Bufferable bit
* @param[in] s Sub-Region Disable (SRD) field
* @param[in] size region size code, e.g. MPU_SIZE_32B
*
* @return combined region attribute word
*/
static inline uint32_t MPU_ATTR(
uint32_t xn,
uint32_t ap,
uint32_t tex,
uint32_t c,
uint32_t b,
uint32_t s,
uint32_t size)
{
return
(xn << 28) |
(ap << 24) |
(tex << 19) |
(s << 18) |
(c << 17) |
(b << 16) |
(size << 1);
}
/**
* @brief disable the MPU
*
* @return 0 on success
* @return <0 on failure or no MPU present
*/
int mpu_disable(void);
/**
* @brief enable the MPU
*
* @return 0 on success
* @return <0 on failure or no MPU present
*/
int mpu_enable(void);
/**
* @brief test if the MPU is enabled
*
* @return true if enabled
* @return false if disabled
*/
bool mpu_enabled(void);
/**
* @brief configure the base address and attributes for an MPU region
*
* @param[in] region MPU region to configure (0 <= @p region < MPU_NUM_REGIONS)
* @param[in] base base address in RAM (aligned to the size specified within @p attr)
* @param[in] attr attribute word generated by MPU_ATTR()
*
* @return 0 on success
* @return <0 on failure or no MPU present
*/
int mpu_configure(uint_fast8_t region, uintptr_t base, uint_fast32_t attr);
#ifdef __cplusplus
}
#endif
#endif /* MPU_H_ */