MPU (Memory Protection Unit) driver module for AVR32 devices.
Definition in file mpu.c.
#include <avr32/io.h>
#include "compiler.h"
#include "mpu.h"
Go to the source code of this file.
Functions | |
void | disable_mpu (void) |
Disable the memory protection unit. MPU address checking is disabled, no exceptions will be generated by the MPU. | |
void | disable_mpu_entry (unsigned int region_number, unsigned int register_select) |
void | enable_mpu (void) |
Enable the memory protection unit. MPU address checking is enabled. | |
Bool | mpu_convert_kbsize_to_eregionsize (eRegionSize *peRegionSizeValue, U32 kBSizeValue) |
Converts an input region size expressed in kBytes to the corresponding eRegionSize type value. | |
void | select_subregion (unsigned int region_number, unsigned int pattern_select) |
void | set_access_permissions (unsigned int region_number, unsigned int register_select, unsigned int right_access) |
char | set_mpu_entry (const mpu_entry_t *mpu_entry, unsigned int region_number) |
void disable_mpu | ( | void | ) |
Disable the memory protection unit. MPU address checking is disabled, no exceptions will be generated by the MPU.
Control of the MPU control register MPUCR: disable MPUCR
Definition at line 65 of file mpu.c.
Referenced by handle_exception().
void disable_mpu_entry | ( | unsigned int | region_number, | |
unsigned int | register_select | |||
) |
Disable a MPU entry
region_number,: | MPU entry region number (0..7). | |
register_select,: | register A: '0' -- B: '1' |
Definition at line 182 of file mpu.c.
00183 { 00184 /* Set Address Register. */ 00185 avr32_mpuar0_t ar; 00186 00187 ar.base = 0; 00188 ar.size = 0; 00189 ar.v = 0; 00190 00191 /* Region entry */ 00192 switch ( region_number & 0x7 ) 00193 { 00194 default: 00195 case 0: 00196 Set_system_register(AVR32_MPUAR0, *((unsigned int *)&ar)); 00197 break; 00198 case 1: 00199 Set_system_register(AVR32_MPUAR1, *((unsigned int *)&ar)); 00200 break; 00201 case 2: 00202 Set_system_register(AVR32_MPUAR2, *((unsigned int *)&ar)); 00203 break; 00204 case 3: 00205 Set_system_register(AVR32_MPUAR3, *((unsigned int *)&ar)); 00206 break; 00207 case 4: 00208 Set_system_register(AVR32_MPUAR4, *((unsigned int *)&ar)); 00209 break; 00210 case 5: 00211 Set_system_register(AVR32_MPUAR5, *((unsigned int *)&ar)); 00212 break; 00213 case 6: 00214 Set_system_register(AVR32_MPUAR6, *((unsigned int *)&ar)); 00215 break; 00216 case 7: 00217 Set_system_register(AVR32_MPUAR7, *((unsigned int *)&ar)); 00218 break; 00219 } 00220 }
void enable_mpu | ( | void | ) |
Enable the memory protection unit. MPU address checking is enabled.
Control of the MPU control register MPUCR: enable MPUCR
Definition at line 56 of file mpu.c.
Referenced by test_memory_area().
Bool mpu_convert_kbsize_to_eregionsize | ( | eRegionSize * | peRegionSizeValue, | |
U32 | kBSizeValue | |||
) |
Converts an input region size expressed in kBytes to the corresponding eRegionSize type value.
kBSizeValue,: | input region size expressed in kBytes | |
peRegionSizeValue,: | output region size in the eRegionSize type |
Definition at line 81 of file mpu.c.
References MPU_REGION_SIZE_HIGHLIMIT_FORBIDDEN, and MPU_REGION_SIZE_LOWLIMIT_FORBIDDEN.
Referenced by test_memory_area().
00082 { 00083 U32 Log2kBSize; 00084 eRegionSize RegVal; 00085 00086 // The size must be non-zero. 00087 if (!kBSizeValue) 00088 return KO; 00089 00090 // Compute the logarithm to base 2 of the size expressed in kB. 00091 Log2kBSize = 32 - (clz(kBSizeValue) + 1); 00092 00093 // The size must be a power of 2. 00094 if (kBSizeValue != 1 << Log2kBSize) 00095 return KO; 00096 00097 // MPUARx.SIZE is (the logarithm to base 2 of the size expressed in bytes) - 1. 00098 RegVal = (eRegionSize)(10 + Log2kBSize - 1); 00099 00100 // The size must be in the allowed range. 00101 if (RegVal <= MPU_REGION_SIZE_LOWLIMIT_FORBIDDEN || 00102 RegVal >= MPU_REGION_SIZE_HIGHLIMIT_FORBIDDEN) 00103 return KO; 00104 00105 *peRegionSizeValue = RegVal; 00106 return OK; 00107 }
void select_subregion | ( | unsigned int | region_number, | |
unsigned int | pattern_select | |||
) |
Setup a Subregion
region_number,: | MPU entry region number (0..7). | |
pattern_select,: | bit-field for the 16 subregions: register A: '0' -- B: '1' |
Definition at line 312 of file mpu.c.
Referenced by test_memory_area().
00313 { 00314 /* Region entry */ 00315 switch ( region_number & 0x7 ) 00316 { 00317 default: 00318 case 0: Set_system_register(AVR32_MPUPSR0, pattern_select );break; 00319 case 1: Set_system_register(AVR32_MPUPSR1, pattern_select );break; 00320 case 2: Set_system_register(AVR32_MPUPSR2, pattern_select );break; 00321 case 3: Set_system_register(AVR32_MPUPSR3, pattern_select );break; 00322 case 4: Set_system_register(AVR32_MPUPSR4, pattern_select );break; 00323 case 5: Set_system_register(AVR32_MPUPSR5, pattern_select );break; 00324 case 6: Set_system_register(AVR32_MPUPSR6, pattern_select );break; 00325 case 7: Set_system_register(AVR32_MPUPSR7, pattern_select );break; 00326 } 00327 }
void set_access_permissions | ( | unsigned int | region_number, | |
unsigned int | register_select, | |||
unsigned int | right_access | |||
) |
Setup a register A and B
region_number,: | MPU entry region number (0..7). | |
register_select,: | register A: '0' -- B: '1' | |
right_access,: | R/W/X see doc32002.pdf (Table 5-3. Access permissions implied by the APn bits) |
Definition at line 229 of file mpu.c.
Referenced by test_memory_area().
00230 { 00231 avr32_mpuapra_t mpu_regA; 00232 avr32_mpuaprb_t mpu_regB; 00233 00234 *(U32 *)&mpu_regA = (U32) Get_system_register(AVR32_MPUAPRA); 00235 *(U32 *)&mpu_regB = (U32) Get_system_register(AVR32_MPUAPRB); 00236 00237 /* Region entry */ 00238 if (register_select==0) //Register A 00239 { 00240 switch ( region_number & 0x7 ) 00241 { 00242 default: 00243 case 0: 00244 mpu_regA.ap0 = (right_access); 00245 break; 00246 case 1: 00247 mpu_regA.ap1 = (right_access); 00248 break; 00249 case 2: 00250 mpu_regA.ap2 = (right_access); 00251 break; 00252 case 3: 00253 mpu_regA.ap3 = (right_access); 00254 break; 00255 case 4: 00256 mpu_regA.ap4 = (right_access); 00257 break; 00258 case 5: 00259 mpu_regA.ap5 = (right_access); 00260 break; 00261 case 6: 00262 mpu_regA.ap6 = (right_access); 00263 break; 00264 case 7: 00265 mpu_regA.ap7 = (right_access); 00266 break; 00267 } 00268 /* Set permissions */ 00269 Set_system_register(AVR32_MPUAPRA, *((unsigned int *)&mpu_regA)); 00270 } 00271 else //Register B 00272 { 00273 switch ( region_number & 0x7 ) 00274 { 00275 default: 00276 case 0: 00277 mpu_regB.ap0 = (right_access); 00278 break; 00279 case 1: 00280 mpu_regB.ap1 = (right_access); 00281 break; 00282 case 2: 00283 mpu_regB.ap2 = (right_access); 00284 break; 00285 case 3: 00286 mpu_regB.ap3 = (right_access); 00287 break; 00288 case 4: 00289 mpu_regB.ap4 = (right_access); 00290 break; 00291 case 5: 00292 mpu_regB.ap5 = (right_access); 00293 break; 00294 case 6: 00295 mpu_regB.ap6 = (right_access); 00296 break; 00297 case 7: 00298 mpu_regB.ap7 = (right_access); 00299 break; 00300 } 00301 /* Set permissions */ 00302 Set_system_register(AVR32_MPUAPRB, *((unsigned int *)&mpu_regB)); 00303 } 00304 }
char set_mpu_entry | ( | const mpu_entry_t * | mpu_entry, | |
unsigned int | region_number | |||
) |
Setup a MPU entry
mpu_entry,: | pointer to mpu_entry_t with the MPU settings (base address, size, validity). | |
region_number,: | MPU entry region number (0..7). |
Definition at line 118 of file mpu.c.
References mpu_entry_t::addr, MPU_REGION_SIZE_HIGHLIMIT_FORBIDDEN, MPU_REGION_SIZE_LOWLIMIT_FORBIDDEN, MPU_SETUP_ENTRY_INVALIDBASEADDR, MPU_SETUP_ENTRY_INVALIDSIZE, MPU_SETUP_ENTRY_OK, mpu_entry_t::size, and mpu_entry_t::valid.
Referenced by test_memory_area().
00119 { 00120 /* Set Address Register. */ 00121 avr32_mpuar0_t ar; 00122 00123 // Check the size: it must (be a power of 2) and (greater than or equal to 4kB) and (less than or equal to 4GB). 00124 // Based on Table 6.1 in doc32002 "AVR32UC Technical Reference Manual Complete". 00125 if( ( mpu_entry->size <= MPU_REGION_SIZE_LOWLIMIT_FORBIDDEN ) 00126 ||( mpu_entry->size >= MPU_REGION_SIZE_HIGHLIMIT_FORBIDDEN ) ) 00127 // ERROR: the input size is not of the type eRegionSize. 00128 return(MPU_SETUP_ENTRY_INVALIDSIZE); 00129 00130 // Check the base address: it must be aligned to the size of the region. 00131 // This test is written carefully to also work for the 4-GB case. 00132 if(!Test_align(mpu_entry->addr, 2 << (U32)mpu_entry->size)) 00133 // ERROR: the input base address is not aligned to the size of the region. 00134 return(MPU_SETUP_ENTRY_INVALIDBASEADDR); 00135 00136 // Specify the 20 most significant bits of the start address. 00137 ar.base = mpu_entry->addr >> 12; 00138 // Size of this protected region; based on Table 5.1 in doc32000 (AVR32 00139 // Architecture Manual Complete). 00140 ar.size = mpu_entry->size; 00141 ar.v = mpu_entry->valid; 00142 00143 /* Region entry */ 00144 switch ( region_number & 0x7 ) 00145 { 00146 default: 00147 case 0: 00148 Set_system_register(AVR32_MPUAR0, *((unsigned int *)&ar)); 00149 break; 00150 case 1: 00151 Set_system_register(AVR32_MPUAR1, *((unsigned int *)&ar)); 00152 break; 00153 case 2: 00154 Set_system_register(AVR32_MPUAR2, *((unsigned int *)&ar)); 00155 break; 00156 case 3: 00157 Set_system_register(AVR32_MPUAR3, *((unsigned int *)&ar)); 00158 break; 00159 case 4: 00160 Set_system_register(AVR32_MPUAR4, *((unsigned int *)&ar)); 00161 break; 00162 case 5: 00163 Set_system_register(AVR32_MPUAR5, *((unsigned int *)&ar)); 00164 break; 00165 case 6: 00166 Set_system_register(AVR32_MPUAR6, *((unsigned int *)&ar)); 00167 break; 00168 case 7: 00169 Set_system_register(AVR32_MPUAR7, *((unsigned int *)&ar)); 00170 break; 00171 } 00172 00173 return(MPU_SETUP_ENTRY_OK); 00174 }