mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 08:54:44 +08:00
NIOS2: Add MPU support functions
This commit is contained in:
@@ -37,6 +37,7 @@ libscorecpu_a_SOURCES += nios2-isr-install-raw-handler.c
|
||||
libscorecpu_a_SOURCES += nios2-isr-install-vector.c
|
||||
libscorecpu_a_SOURCES += nios2-isr-is-in-progress.c
|
||||
libscorecpu_a_SOURCES += nios2-isr-set-level.c
|
||||
libscorecpu_a_SOURCES += nios2-mpu-add-region.c
|
||||
libscorecpu_a_SOURCES += nios2-mpu-configuration.c
|
||||
libscorecpu_a_SOURCES += nios2-mpu-descriptor.c
|
||||
libscorecpu_a_SOURCES += nios2-mpu-disable-protected.c
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/score/nios2-utility.h>
|
||||
|
||||
static bool _Nios2_MPU_Is_region_disabled(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
uint32_t mpubase,
|
||||
uint32_t mpuacc
|
||||
)
|
||||
{
|
||||
bool disabled = false;
|
||||
|
||||
if ( config->region_uses_limit ) {
|
||||
disabled = (mpubase & NIOS2_MPUBASE_BASE_MASK)
|
||||
> (mpuacc & NIOS2_MPUACC_LIMIT_MASK);
|
||||
} else {
|
||||
disabled = (mpuacc & NIOS2_MPUACC_MASK_MASK) == 0;
|
||||
}
|
||||
|
||||
return disabled;
|
||||
}
|
||||
|
||||
int _Nios2_MPU_Get_disabled_region_index(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
bool data,
|
||||
int begin,
|
||||
int end
|
||||
)
|
||||
{
|
||||
int index = -1;
|
||||
int count = _Nios2_MPU_Get_region_count( config, data );
|
||||
|
||||
if ( end < 0 || count < end ) {
|
||||
end = count;
|
||||
}
|
||||
|
||||
if ( begin >= 0 ) {
|
||||
int i = 0;
|
||||
|
||||
for ( i = begin; i < end && index < 0; ++i ) {
|
||||
uint32_t mpubase = 0;
|
||||
uint32_t mpuacc = 0;
|
||||
|
||||
_Nios2_MPU_Get_region_registers( i, data, &mpubase, &mpuacc );
|
||||
|
||||
if ( _Nios2_MPU_Is_region_disabled( config, mpubase, mpuacc ) ) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
bool _Nios2_MPU_Add_region(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
const Nios2_MPU_Region_descriptor *desc,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
bool ok = true;
|
||||
int index = desc->index;
|
||||
bool data = desc->data;
|
||||
uint32_t mpubase = 0;
|
||||
uint32_t mpuacc = 0;
|
||||
|
||||
if ( _Nios2_MPU_Is_valid_index( config, data, index ) ) {
|
||||
if ( !force ) {
|
||||
_Nios2_MPU_Get_region_registers( index, data, &mpubase, &mpuacc );
|
||||
ok = _Nios2_MPU_Is_region_disabled( config, mpubase, mpuacc );
|
||||
}
|
||||
|
||||
if ( ok ) {
|
||||
ok = _Nios2_MPU_Setup_region_registers(
|
||||
config,
|
||||
desc,
|
||||
&mpubase,
|
||||
&mpuacc
|
||||
);
|
||||
if ( ok ) {
|
||||
_Nios2_Set_ctlreg_mpubase(mpubase);
|
||||
_Nios2_Set_ctlreg_mpuacc(mpuacc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -60,19 +60,6 @@ static bool _Nios2_Is_valid_base_and_end(
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool _Nios2_Is_valid_index(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
bool data,
|
||||
int index
|
||||
)
|
||||
{
|
||||
int count = data ?
|
||||
config->data_region_count
|
||||
: config->instruction_region_count;
|
||||
|
||||
return 0 <= index && index < count;
|
||||
}
|
||||
|
||||
static bool _Nios2_Is_valid_permission(
|
||||
bool data,
|
||||
int perm
|
||||
@@ -101,7 +88,7 @@ bool _Nios2_MPU_Setup_region_registers(
|
||||
&mask_or_limit
|
||||
);
|
||||
bool ok = is_valid_base_and_end
|
||||
&& _Nios2_Is_valid_index( config, desc->data, desc->index )
|
||||
&& _Nios2_MPU_Is_valid_index( config, desc->data, desc->index )
|
||||
&& _Nios2_Is_valid_permission( desc->data, desc->perm )
|
||||
&& !(!desc->data && desc->cacheable)
|
||||
&& !(desc->read && desc->write);
|
||||
|
||||
@@ -169,13 +169,10 @@ extern char _Nios2_ISR_Status_mask [];
|
||||
*/
|
||||
extern char _Nios2_ISR_Status_bits [];
|
||||
|
||||
/**
|
||||
* @brief This global variable indicates that the Nios2 MPU is active
|
||||
*
|
||||
* This global variable is set to 1 when the board support package
|
||||
* initializes the MPU during startup.
|
||||
*/
|
||||
extern uint32_t _Nios2_Mpu_active;
|
||||
static inline void _Nios2_Flush_pipeline( void )
|
||||
{
|
||||
__asm__ volatile ("flushp");
|
||||
}
|
||||
|
||||
static inline uint32_t _Nios2_Get_ctlreg_status( void )
|
||||
{
|
||||
@@ -377,6 +374,26 @@ typedef struct {
|
||||
true, false, false, true \
|
||||
}
|
||||
|
||||
static inline int _Nios2_MPU_Get_region_count(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
bool data
|
||||
)
|
||||
{
|
||||
return data ?
|
||||
config->data_region_count
|
||||
: config->instruction_region_count;
|
||||
}
|
||||
|
||||
static inline bool _Nios2_MPU_Is_valid_index(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
bool data,
|
||||
int index
|
||||
)
|
||||
{
|
||||
return 0 <= index
|
||||
&& index < _Nios2_MPU_Get_region_count( config, data );
|
||||
}
|
||||
|
||||
bool _Nios2_MPU_Setup_region_registers(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
const Nios2_MPU_Region_descriptor *desc,
|
||||
@@ -384,6 +401,38 @@ bool _Nios2_MPU_Setup_region_registers(
|
||||
uint32_t *mpuacc
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Seaches the region table part for a disabled region.
|
||||
*
|
||||
* The table will be searched between indices @a begin and @a end. The @a end
|
||||
* index is not part of the search range. If @a end is negative, then the
|
||||
* region count will be used. Thus a @a begin of 0 and a @a end of -1 will
|
||||
* specifiy the complete table.
|
||||
*
|
||||
* @retval -1 No disabled region is available.
|
||||
* @retval other Index of disabled region.
|
||||
*/
|
||||
int _Nios2_MPU_Get_disabled_region_index(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
bool data,
|
||||
int begin,
|
||||
int end
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Adds a region according to region descriptor @a desc.
|
||||
*
|
||||
* If @a force is true, then an enabled region will be overwritten.
|
||||
*
|
||||
* @retval true Successful operation.
|
||||
* @retval false Invalid region descriptor or region already in use.
|
||||
*/
|
||||
bool _Nios2_MPU_Add_region(
|
||||
const Nios2_MPU_Configuration *config,
|
||||
const Nios2_MPU_Region_descriptor *desc,
|
||||
bool force
|
||||
);
|
||||
|
||||
static inline void _Nios2_MPU_Get_region_registers(
|
||||
int index,
|
||||
bool data,
|
||||
@@ -397,6 +446,7 @@ static inline void _Nios2_MPU_Get_region_registers(
|
||||
|
||||
_Nios2_Set_ctlreg_mpubase( base );
|
||||
_Nios2_Set_ctlreg_mpuacc( NIOS2_MPUACC_RD );
|
||||
_Nios2_Flush_pipeline();
|
||||
*mpubase = _Nios2_Get_ctlreg_mpubase() | base;
|
||||
*mpuacc = _Nios2_Get_ctlreg_mpuacc();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user