mpu.c File Reference


Detailed Description

MPU driver.

MPU (Memory Protection Unit) driver module for AVR32 devices.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

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)


Function Documentation

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().

00066 {
00067   Set_system_register(AVR32_MPUCR, 0);
00068 }

void disable_mpu_entry ( unsigned int  region_number,
unsigned int  register_select 
)

Disable a MPU entry

Parameters:
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().

00057 {
00058   Set_system_register(AVR32_MPUCR, AVR32_MPUCR_E_MASK);
00059 }

Bool mpu_convert_kbsize_to_eregionsize ( eRegionSize peRegionSizeValue,
U32  kBSizeValue 
)

Converts an input region size expressed in kBytes to the corresponding eRegionSize type value.

Parameters:
kBSizeValue,: input region size expressed in kBytes
peRegionSizeValue,: output region size in the eRegionSize type
Returns:
Bool OK if the conversion succeeded KO if the conversion failed (the input is not a possible protected region size).

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

Parameters:
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

Parameters:
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

Parameters:
mpu_entry,: pointer to mpu_entry_t with the MPU settings (base address, size, validity).
region_number,: MPU entry region number (0..7).
Returns:
int MPU_SETUP_ENTRY_OK if the setup succeeded MPU_SETUP_ENTRY_INVALIDBASEADDR if the setup failed because the input base address is not aligned to the size of the region. MPU_SETUP_ENTRY_INVALIDSIZE if the setup failed because the input size is not one of the type eRegionSize.

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 }


Generated on Fri Feb 19 02:24:28 2010 for AVR32 - Memory Protection Unit Driver by  doxygen 1.5.5