]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained_IAR_Keil/libchip_samv7/source/mpu.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained_IAR_Keil / libchip_samv7 / source / mpu.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2014, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\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
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\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
16  *\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
28  */\r
29 \r
30 /** \file */\r
31 \r
32 /** \r
33  * \addtogroup mmu MMU Initialization\r
34  *\r
35  * \section Usage\r
36  *\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
41  * \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
47  *\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
52  *\r
53  * Related files:\n\r
54  * \ref mmu.c\n\r
55  * \ref mmu.h \n\r
56  */\r
57 \r
58 /*------------------------------------------------------------------------------ */\r
59 /*         Headers                                                               */\r
60 /*------------------------------------------------------------------------------ */\r
61 #include <chip.h>\r
62 \r
63 /*----------------------------------------------------------------------------\r
64  *        Exported functions\r
65 \r
66  *----------------------------------------------------------------------------*/\r
67 /**\r
68  * \brief Enables the MPU module.\r
69  *\r
70  * \param dwMPUEnable  Enable/Disable the memory region.\r
71  */\r
72 void MPU_Enable( uint32_t dwMPUEnable )\r
73 {\r
74     MPU->CTRL = dwMPUEnable ;\r
75 }\r
76 \r
77 /**\r
78  * \brief Set active memory region.\r
79  *\r
80  * \param dwRegionNum  The memory region to be active.\r
81  */\r
82 void MPU_SetRegionNum( uint32_t dwRegionNum )\r
83 {\r
84     MPU->RNR = dwRegionNum;\r
85 }\r
86 \r
87 /**\r
88  * \brief Disable the current active region.\r
89  */\r
90 extern void MPU_DisableRegion( void )\r
91 {\r
92     MPU->RASR &= 0xfffffffe;\r
93 }\r
94 \r
95 /**\r
96  * \brief Setup a memory region.\r
97  *\r
98  * \param dwRegionBaseAddr  Memory region base address.\r
99  * \param dwRegionAttr  Memory region attributes.  \r
100  */\r
101 void MPU_SetRegion( uint32_t dwRegionBaseAddr, uint32_t dwRegionAttr )\r
102 {\r
103     MPU->RBAR = dwRegionBaseAddr;\r
104     MPU->RASR = dwRegionAttr;\r
105 }\r
106 \r
107 \r
108 /**\r
109  * \brief Calculate region size for the RASR.\r
110  */\r
111 uint32_t MPU_CalMPURegionSize( uint32_t dwActualSizeInBytes )\r
112 {\r
113     uint32_t dwRegionSize = 32;\r
114     uint32_t dwReturnValue = 4;\r
115 \r
116     while( dwReturnValue < 31 )\r
117     {\r
118         if( dwActualSizeInBytes <= dwRegionSize )\r
119         {\r
120             break;\r
121         }\r
122         else\r
123         {\r
124             dwReturnValue++;\r
125         }\r
126 \r
127         dwRegionSize <<= 1;\r
128     }\r
129 \r
130     return ( dwReturnValue << 1 );\r
131 }\r
132 \r
133 \r
134 /**\r
135  *  \brief Update MPU regions.\r
136  *\r
137  *  \return Unused (ANSI-C compatibility).\r
138  */\r
139 void MPU_UpdateRegions( uint32_t dwRegionNum, uint32_t dwRegionBaseAddr,\r
140         uint32_t dwRegionAttr)\r
141 {\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
146 \r
147     /* Disable interrupt */\r
148     __disable_irq();\r
149 \r
150     /* Clean up data and instruction buffer */\r
151     __DSB();\r
152     __ISB();\r
153 \r
154     /* Set active region */\r
155     MPU_SetRegionNum(dwRegionNum);\r
156 \r
157     /* Disable region */\r
158     MPU_DisableRegion();\r
159 \r
160     /* Update region attribute */\r
161     MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);\r
162 \r
163     /* Clean up data and instruction buffer to make the new region taking \r
164        effect at once */\r
165     __DSB();\r
166     __ISB();\r
167 \r
168     /* Enable the interrupt */\r
169     __enable_irq();\r
170 \r
171     /* Reset to thread mode */\r
172     __set_CONTROL(USER_MODE);\r
173 }\r
174 \r