1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2014, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
33 * \addtogroup mmu MMU Initialization
\r
37 * Translation Lookaside Buffers (TLBs) are an implementation technique that caches translations or
\r
38 * translation table entries. TLBs avoid the requirement for every memory access to perform a translation table
\r
39 * lookup. The ARM architecture does not specify the exact form of the TLB structures for any design. In a
\r
40 * similar way to the requirements for caches, the architecture only defines certain principles for TLBs:
\r
42 * The MMU supports memory accesses based on memory sections or pages:
\r
43 * Supersections Consist of 16MB blocks of memory. Support for Supersections is optional.
\r
44 * -# Sections Consist of 1MB blocks of memory.
\r
45 * -# Large pages Consist of 64KB blocks of memory.
\r
46 * -# Small pages Consist of 4KB blocks of memory.
\r
48 * Access to a memory region is controlled by the access permission bits and the domain field in the TLB entry.
\r
49 * Memory region attributes
\r
50 * Each TLB entry has an associated set of memory region attributes. These control accesses to the caches,
\r
51 * how the write buffer is used, and if the memory region is Shareable and therefore must be kept coherent.
\r
58 /*------------------------------------------------------------------------------ */
\r
60 /*------------------------------------------------------------------------------ */
\r
63 /*----------------------------------------------------------------------------
\r
64 * Exported functions
\r
66 *----------------------------------------------------------------------------*/
\r
68 * \brief Enables the MPU module.
\r
70 * \param dwMPUEnable Enable/Disable the memory region.
\r
72 void MPU_Enable( uint32_t dwMPUEnable )
\r
74 MPU->CTRL = dwMPUEnable ;
\r
78 * \brief Set active memory region.
\r
80 * \param dwRegionNum The memory region to be active.
\r
82 void MPU_SetRegionNum( uint32_t dwRegionNum )
\r
84 MPU->RNR = dwRegionNum;
\r
88 * \brief Disable the current active region.
\r
90 extern void MPU_DisableRegion( void )
\r
92 MPU->RASR &= 0xfffffffe;
\r
96 * \brief Setup a memory region.
\r
98 * \param dwRegionBaseAddr Memory region base address.
\r
99 * \param dwRegionAttr Memory region attributes.
\r
101 void MPU_SetRegion( uint32_t dwRegionBaseAddr, uint32_t dwRegionAttr )
\r
103 MPU->RBAR = dwRegionBaseAddr;
\r
104 MPU->RASR = dwRegionAttr;
\r
109 * \brief Calculate region size for the RASR.
\r
111 uint32_t MPU_CalMPURegionSize( uint32_t dwActualSizeInBytes )
\r
113 uint32_t dwRegionSize = 32;
\r
114 uint32_t dwReturnValue = 4;
\r
116 while( dwReturnValue < 31 )
\r
118 if( dwActualSizeInBytes <= dwRegionSize )
\r
127 dwRegionSize <<= 1;
\r
130 return ( dwReturnValue << 1 );
\r
135 * \brief Update MPU regions.
\r
137 * \return Unused (ANSI-C compatibility).
\r
139 void MPU_UpdateRegions( uint32_t dwRegionNum, uint32_t dwRegionBaseAddr,
\r
140 uint32_t dwRegionAttr)
\r
142 /* Raise privilege, the MPU register could be set only in privilege mode */
\r
143 asm volatile(" swi 0x00 ");
\r
144 while (!dwRaisePriDone);
\r
145 dwRaisePriDone = 0;
\r
147 /* Disable interrupt */
\r
150 /* Clean up data and instruction buffer */
\r
154 /* Set active region */
\r
155 MPU_SetRegionNum(dwRegionNum);
\r
157 /* Disable region */
\r
158 MPU_DisableRegion();
\r
160 /* Update region attribute */
\r
161 MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
\r
163 /* Clean up data and instruction buffer to make the new region taking
\r
168 /* Enable the interrupt */
\r
171 /* Reset to thread mode */
\r
172 __set_CONTROL(USER_MODE);
\r