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