1 /**
2 * \file
3 *
4 * \brief SAMV70/SAMV71/SAME70/SAMS70-XULTRA board mpu config.
5 *
6 * Copyright (c) 2015 Atmel Corporation. All rights reserved.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 * \asf_license_stop
41 *
42 */
43 /*
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45 */
46
47 #include "mpu.h"
48
49 /** \file */
50
51 /**
52 * \addtogroup mmu MMU Initialization
53 *
54 * \section Usage
55 *
56 * Translation Look-aside Buffers (TLBs) are an implementation technique that
57 * caches translations or translation table entries. TLBs avoid the requirement
58 * for every memory access to perform a translation table lookup.
59 * The ARM architecture does not specify the exact form of the TLB structures
60 * for any design. In a similar way to the requirements for caches, the
61 * architecture only defines certain principles for TLBs:
62 *
63 * The MMU supports memory accesses based on memory sections or pages:
64 * Super-sections Consist of 16MB blocks of memory. Support for Super sections
65 * is optional.
66 * -# Sections Consist of 1MB blocks of memory.
67 * -# Large pages Consist of 64KB blocks of memory.
68 * -# Small pages Consist of 4KB blocks of memory.
69 *
70 * Access to a memory region is controlled by the access permission bits and
71 * the domain field in the TLB entry.
72 * Memory region attributes
73 * Each TLB entry has an associated set of memory region attributes. These
74 * control accesses to the caches,
75 * how the write buffer is used, and if the memory region is Shareable and
76 * therefore must be kept coherent.
77 *
78 * Related files:\n
79 * \ref mmu.c\n
80 * \ref mmu.h \n
81 */
82
83 /*----------------------------------------------------------------------------
84 * Exported functions
85
86 *----------------------------------------------------------------------------*/
87 /**
88 * \brief Enables the MPU module.
89 *
90 * \param dwMPUEnable Enable/Disable the memory region.
91 */
mpu_enable(uint32_t dw_mpu_enable)92 void mpu_enable(uint32_t dw_mpu_enable)
93 {
94 MPU->CTRL = dw_mpu_enable ;
95 }
96
97 /**
98 * \brief Set active memory region.
99 *
100 * \param dwRegionNum The memory region to be active.
101 */
mpu_set_region_num(uint32_t dw_region_num)102 void mpu_set_region_num(uint32_t dw_region_num)
103 {
104 MPU->RNR = dw_region_num;
105 }
106
107 /**
108 * \brief Disable the current active region.
109 */
mpu_disable_region(void)110 void mpu_disable_region(void)
111 {
112 MPU->RASR &= 0xfffffffe;
113 }
114
115 /**
116 * \brief Setup a memory region.
117 *
118 * \param dwRegionBaseAddr Memory region base address.
119 * \param dwRegionAttr Memory region attributes.
120 */
mpu_set_region(uint32_t dw_region_base_addr,uint32_t dw_region_attr)121 void mpu_set_region(uint32_t dw_region_base_addr, uint32_t dw_region_attr)
122 {
123 MPU->RBAR = dw_region_base_addr;
124 MPU->RASR = dw_region_attr;
125 }
126
127
128 /**
129 * \brief Calculate region size for the RASR.
130 */
mpu_cal_mpu_region_size(uint32_t dw_actual_size_in_bytes)131 uint32_t mpu_cal_mpu_region_size(uint32_t dw_actual_size_in_bytes)
132 {
133 uint32_t dwRegionSize = 32;
134 uint32_t dwReturnValue = 4;
135
136 while( dwReturnValue < 31 ) {
137 if( dw_actual_size_in_bytes <= dwRegionSize ) {
138 break;
139 } else {
140 dwReturnValue++;
141 }
142 dwRegionSize <<= 1;
143 }
144
145 return ( dwReturnValue << 1 );
146 }
147
148
149 /**
150 * \brief Update MPU regions.
151 *
152 * \return Unused (ANSI-C compatibility).
153 */
mpu_update_regions(uint32_t dw_region_num,uint32_t dw_region_base_addr,uint32_t dw_region_attr)154 void mpu_update_regions(uint32_t dw_region_num, uint32_t dw_region_base_addr, uint32_t dw_region_attr)
155 {
156
157 /* Disable interrupt */
158 __disable_irq();
159
160 /* Clean up data and instruction buffer */
161 __DSB();
162 __ISB();
163
164 /* Set active region */
165 mpu_set_region_num(dw_region_num);
166
167 /* Disable region */
168 mpu_disable_region();
169
170 /* Update region attribute */
171 mpu_set_region( dw_region_base_addr, dw_region_attr);
172
173 /* Clean up data and instruction buffer to make the new region taking
174 effect at once */
175 __DSB();
176 __ISB();
177
178 /* Enable the interrupt */
179 __enable_irq();
180 }