forked from Imagelibrary/rtems
score: Use <sys/bitset.h> for Processor_mask
Implement the Processor_mask via <sys/bitset.h>. Provide _Processor_mask_To_uint32_t() to enable its use in device specific routines, e.g. interrupt affinity register in an interrupt controller. Update #3059.
This commit is contained in:
@@ -133,7 +133,10 @@ static void qoriq_clock_cleanup(void)
|
|||||||
qoriq_clock_handler_install(&old_isr)
|
qoriq_clock_handler_install(&old_isr)
|
||||||
|
|
||||||
#define Clock_driver_support_set_interrupt_affinity(online_processors) \
|
#define Clock_driver_support_set_interrupt_affinity(online_processors) \
|
||||||
qoriq_pic_set_affinities(CLOCK_INTERRUPT, online_processors[0])
|
qoriq_pic_set_affinities( \
|
||||||
|
CLOCK_INTERRUPT, \
|
||||||
|
_Processor_mask_To_uint32_t(online_processors, 0) \
|
||||||
|
)
|
||||||
|
|
||||||
#define Clock_driver_support_shutdown_hardware() \
|
#define Clock_driver_support_shutdown_hardware() \
|
||||||
qoriq_clock_cleanup()
|
qoriq_clock_cleanup()
|
||||||
|
|||||||
@@ -99,7 +99,8 @@ static void restart_interrupt(void *arg)
|
|||||||
|
|
||||||
static void raise_restart_interrupt(void)
|
static void raise_restart_interrupt(void)
|
||||||
{
|
{
|
||||||
qoriq.pic.ipidr[RESTART_IPI_INDEX].reg = _SMP_Online_processors[0];
|
qoriq.pic.ipidr[RESTART_IPI_INDEX].reg =
|
||||||
|
_Processor_mask_To_uint32_t(&_SMP_Online_processors, 0);
|
||||||
ppc_synchronize_data();
|
ppc_synchronize_data();
|
||||||
ppc_synchronize_instructions();
|
ppc_synchronize_instructions();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ static void Clock_driver_timecounter_tick( void )
|
|||||||
|
|
||||||
if ( _Per_CPU_Is_boot_processor( cpu ) ) {
|
if ( _Per_CPU_Is_boot_processor( cpu ) ) {
|
||||||
rtems_timecounter_tick();
|
rtems_timecounter_tick();
|
||||||
} else if ( _Processor_mask_Is_set( _SMP_Online_processors, cpu_index ) ) {
|
} else if ( _Processor_mask_Is_set( &_SMP_Online_processors, cpu_index ) ) {
|
||||||
_Watchdog_Tick( cpu );
|
_Watchdog_Tick( cpu );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ rtems_device_driver Clock_initialize(
|
|||||||
Clock_driver_support_install_isr( Clock_isr, Old_ticker );
|
Clock_driver_support_install_isr( Clock_isr, Old_ticker );
|
||||||
|
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
Clock_driver_support_set_interrupt_affinity( _SMP_Online_processors );
|
Clock_driver_support_set_interrupt_affinity( &_SMP_Online_processors );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void ambapp_dev_info(struct drvmgr_dev *, void (*print)(void *p, char *str), voi
|
|||||||
int ambapp_int_set_affinity(
|
int ambapp_int_set_affinity(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
int index,
|
int index,
|
||||||
Processor_mask cpus);
|
const Processor_mask *cpus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct drvmgr_bus_ops ambapp_bus_ops =
|
struct drvmgr_bus_ops ambapp_bus_ops =
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ int ambapp_grlib_int_unmask(
|
|||||||
int ambapp_grlib_int_set_affinity(
|
int ambapp_grlib_int_set_affinity(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
int irq,
|
int irq,
|
||||||
Processor_mask cpus);
|
const Processor_mask *cpus);
|
||||||
#endif
|
#endif
|
||||||
int ambapp_grlib_get_params(
|
int ambapp_grlib_get_params(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
@@ -233,7 +233,7 @@ int ambapp_grlib_int_set_affinity
|
|||||||
(
|
(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
int irq,
|
int irq,
|
||||||
Processor_mask cpus
|
const Processor_mask *cpus
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t cpu_count = rtems_get_processor_count();
|
uint32_t cpu_count = rtems_get_processor_count();
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ struct ambapp_ops {
|
|||||||
int (*int_unmask)(struct drvmgr_dev *dev, int index);
|
int (*int_unmask)(struct drvmgr_dev *dev, int index);
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
int (*int_set_affinity)(struct drvmgr_dev *dev, int index,
|
int (*int_set_affinity)(struct drvmgr_dev *dev, int index,
|
||||||
Processor_mask cpus);
|
const Processor_mask *cpus);
|
||||||
#endif
|
#endif
|
||||||
int (*get_params)
|
int (*get_params)
|
||||||
(struct drvmgr_dev *, struct drvmgr_bus_params *);
|
(struct drvmgr_dev *, struct drvmgr_bus_params *);
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ struct drvmgr_bus_ops {
|
|||||||
int (*int_unmask)(struct drvmgr_dev *, int index);
|
int (*int_unmask)(struct drvmgr_dev *, int index);
|
||||||
#ifdef RTEMS_SMP
|
#ifdef RTEMS_SMP
|
||||||
int (*int_set_affinity)(struct drvmgr_dev *, int index,
|
int (*int_set_affinity)(struct drvmgr_dev *, int index,
|
||||||
Processor_mask cpus);
|
const Processor_mask *cpus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get Parameters */
|
/* Get Parameters */
|
||||||
@@ -645,7 +645,7 @@ extern int drvmgr_interrupt_mask(
|
|||||||
extern int drvmgr_interrupt_set_affinity(
|
extern int drvmgr_interrupt_set_affinity(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
int index,
|
int index,
|
||||||
Processor_mask cpus);
|
const Processor_mask *cpus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! drvmgr_translate() translation options */
|
/*! drvmgr_translate() translation options */
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ int drvmgr_interrupt_mask(
|
|||||||
int drvmgr_interrupt_set_affinity(
|
int drvmgr_interrupt_set_affinity(
|
||||||
struct drvmgr_dev *dev,
|
struct drvmgr_dev *dev,
|
||||||
int index,
|
int index,
|
||||||
Processor_mask cpus)
|
const Processor_mask *cpus)
|
||||||
{
|
{
|
||||||
if (!dev || !dev->parent || !dev->parent->ops->int_set_affinity)
|
if (!dev || !dev->parent || !dev->parent->ops->int_set_affinity)
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2016, 2017 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Dornierstr. 4
|
* Dornierstr. 4
|
||||||
@@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
#include <rtems/score/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
|
|
||||||
|
#include <sys/_bitset.h>
|
||||||
|
#include <sys/bitset.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
@@ -41,75 +44,65 @@ extern "C" {
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROCESSOR_MASK_BITS_PER_FIELD 32
|
|
||||||
|
|
||||||
#define PROCESSOR_MASK_FIELD_COUNT \
|
|
||||||
( ( CPU_MAXIMUM_PROCESSORS + PROCESSOR_MASK_BITS_PER_FIELD - 1 ) \
|
|
||||||
/ PROCESSOR_MASK_BITS_PER_FIELD )
|
|
||||||
|
|
||||||
#define PROCESSOR_MASK_BIT( index ) \
|
|
||||||
(1UL << ( ( index ) % PROCESSOR_MASK_BITS_PER_FIELD ) )
|
|
||||||
|
|
||||||
#define PROCESSOR_MASK_FIELD( index ) \
|
|
||||||
( ( index ) / PROCESSOR_MASK_BITS_PER_FIELD )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A bit map consisting of 32-bit integer fields which is large enough
|
* @brief A bit map which is large enough to provide one bit for each processor
|
||||||
* to provide one bit for each processor in the system.
|
* in the system.
|
||||||
*
|
|
||||||
* Processor 0 corresponds to the bit 0 (least-significant) of the field 0 in
|
|
||||||
* the array, and so on.
|
|
||||||
*/
|
*/
|
||||||
typedef uint32_t Processor_mask[ PROCESSOR_MASK_FIELD_COUNT ];
|
typedef BITSET_DEFINE( Processor_mask, CPU_MAXIMUM_PROCESSORS ) Processor_mask;
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE void _Processor_mask_Zero( Processor_mask mask )
|
RTEMS_INLINE_ROUTINE void _Processor_mask_Zero( Processor_mask *mask )
|
||||||
{
|
{
|
||||||
size_t i;
|
BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask );
|
||||||
|
|
||||||
for ( i = 0; i < PROCESSOR_MASK_FIELD_COUNT; ++i ) {
|
|
||||||
mask[ i ] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_zero( const Processor_mask mask )
|
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_zero( const Processor_mask *mask )
|
||||||
{
|
{
|
||||||
size_t i;
|
return BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask );
|
||||||
|
|
||||||
for ( i = 0; i < PROCESSOR_MASK_FIELD_COUNT; ++i ) {
|
|
||||||
if ( mask[ i ] != 0 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
RTEMS_INLINE_ROUTINE void _Processor_mask_Assign(
|
||||||
}
|
Processor_mask *dst, const Processor_mask *src
|
||||||
|
)
|
||||||
RTEMS_INLINE_ROUTINE void _Processor_mask_Assign( Processor_mask dst, const Processor_mask src )
|
|
||||||
{
|
{
|
||||||
size_t i;
|
BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst );
|
||||||
|
|
||||||
for ( i = 0; i < PROCESSOR_MASK_FIELD_COUNT; ++i ) {
|
|
||||||
dst[ i ] = src[ i ];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE void _Processor_mask_Set( Processor_mask mask, uint32_t index )
|
RTEMS_INLINE_ROUTINE void _Processor_mask_Set(
|
||||||
{
|
Processor_mask *mask,
|
||||||
mask[ PROCESSOR_MASK_FIELD( index ) ] |= PROCESSOR_MASK_BIT( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE void _Processor_mask_Clear( Processor_mask mask, uint32_t index )
|
|
||||||
{
|
|
||||||
mask[ PROCESSOR_MASK_FIELD( index ) ] &= ~PROCESSOR_MASK_BIT( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_set(
|
|
||||||
const Processor_mask mask,
|
|
||||||
uint32_t index
|
uint32_t index
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ( mask[ PROCESSOR_MASK_FIELD( index ) ]
|
BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask );
|
||||||
& PROCESSOR_MASK_BIT( index ) ) != 0;
|
}
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE void _Processor_mask_Clear(
|
||||||
|
Processor_mask *mask,
|
||||||
|
uint32_t index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_set(
|
||||||
|
const Processor_mask *mask,
|
||||||
|
uint32_t index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the subset of 32 processors containing the specified index as
|
||||||
|
* an unsigned 32-bit integer.
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_To_uint32_t(
|
||||||
|
const Processor_mask *mask,
|
||||||
|
uint32_t index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
long bits = mask->__bits[ __bitset_words( index ) ];
|
||||||
|
|
||||||
|
return (uint32_t) (bits >> (32 * (index % _BITSET_BITS) / 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ void _SMP_Send_message_broadcast(
|
|||||||
* @param[in] message The message.
|
* @param[in] message The message.
|
||||||
*/
|
*/
|
||||||
void _SMP_Send_message_multicast(
|
void _SMP_Send_message_multicast(
|
||||||
const Processor_mask targets,
|
const Processor_mask *targets,
|
||||||
unsigned long message
|
unsigned long message
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ static void _SMP_Start_processors( uint32_t cpu_count )
|
|||||||
cpu->Scheduler.control = scheduler;
|
cpu->Scheduler.control = scheduler;
|
||||||
cpu->Scheduler.context = context;
|
cpu->Scheduler.context = context;
|
||||||
|
|
||||||
_Processor_mask_Set( _SMP_Online_processors, cpu_index );
|
_Processor_mask_Set( &_SMP_Online_processors, cpu_index );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ void _SMP_Send_message_broadcast( unsigned long message )
|
|||||||
for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
|
for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
|
||||||
if (
|
if (
|
||||||
cpu_index != cpu_index_self
|
cpu_index != cpu_index_self
|
||||||
&& _Processor_mask_Is_set( _SMP_Online_processors, cpu_index )
|
&& _Processor_mask_Is_set( &_SMP_Online_processors, cpu_index )
|
||||||
) {
|
) {
|
||||||
_SMP_Send_message( cpu_index, message );
|
_SMP_Send_message( cpu_index, message );
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ void _SMP_Send_message_broadcast( unsigned long message )
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _SMP_Send_message_multicast(
|
void _SMP_Send_message_multicast(
|
||||||
const Processor_mask targets,
|
const Processor_mask *targets,
|
||||||
unsigned long message
|
unsigned long message
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ void _SMP_Multicast_actions_process( void )
|
|||||||
while ( !_Chain_Is_tail( &_SMP_Multicast.Actions, &node->Node ) ) {
|
while ( !_Chain_Is_tail( &_SMP_Multicast.Actions, &node->Node ) ) {
|
||||||
next = (SMP_Multicast_action *) _Chain_Next( &node->Node );
|
next = (SMP_Multicast_action *) _Chain_Next( &node->Node );
|
||||||
|
|
||||||
if ( _Processor_mask_Is_set( node->targets, cpu_self_index ) ) {
|
if ( _Processor_mask_Is_set( &node->targets, cpu_self_index ) ) {
|
||||||
_Processor_mask_Clear( node->targets, cpu_self_index );
|
_Processor_mask_Clear( &node->targets, cpu_self_index );
|
||||||
|
|
||||||
( *node->handler )( node->arg );
|
( *node->handler )( node->arg );
|
||||||
|
|
||||||
if ( _Processor_mask_Is_zero( node->targets ) ) {
|
if ( _Processor_mask_Is_zero( &node->targets ) ) {
|
||||||
_Chain_Extract_unprotected( &node->Node );
|
_Chain_Extract_unprotected( &node->Node );
|
||||||
_Atomic_Store_ulong( &node->done, 1, ATOMIC_ORDER_RELEASE );
|
_Atomic_Store_ulong( &node->done, 1, ATOMIC_ORDER_RELEASE );
|
||||||
}
|
}
|
||||||
@@ -106,13 +106,13 @@ void _SMP_Multicast_action(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( cpus == NULL ) {
|
if( cpus == NULL ) {
|
||||||
_Processor_mask_Assign( targets, _SMP_Online_processors );
|
_Processor_mask_Assign( &targets, &_SMP_Online_processors );
|
||||||
} else {
|
} else {
|
||||||
_Processor_mask_Zero( targets );
|
_Processor_mask_Zero( &targets );
|
||||||
|
|
||||||
for ( i = 0; i < _SMP_Get_processor_count(); ++i ) {
|
for ( i = 0; i < _SMP_Get_processor_count(); ++i ) {
|
||||||
if ( CPU_ISSET_S( i, setsize, cpus ) ) {
|
if ( CPU_ISSET_S( i, setsize, cpus ) ) {
|
||||||
_Processor_mask_Set( targets, i );
|
_Processor_mask_Set( &targets, i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,14 +120,14 @@ void _SMP_Multicast_action(
|
|||||||
_Chain_Initialize_node( &node.Node );
|
_Chain_Initialize_node( &node.Node );
|
||||||
node.handler = handler;
|
node.handler = handler;
|
||||||
node.arg = arg;
|
node.arg = arg;
|
||||||
_Processor_mask_Assign( node.targets, targets );
|
_Processor_mask_Assign( &node.targets, &targets );
|
||||||
_Atomic_Store_ulong( &node.done, 0, ATOMIC_ORDER_RELAXED );
|
_Atomic_Store_ulong( &node.done, 0, ATOMIC_ORDER_RELAXED );
|
||||||
|
|
||||||
_SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context );
|
_SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context );
|
||||||
_Chain_Prepend_unprotected( &_SMP_Multicast.Actions, &node.Node );
|
_Chain_Prepend_unprotected( &_SMP_Multicast.Actions, &node.Node );
|
||||||
_SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context );
|
_SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context );
|
||||||
|
|
||||||
_SMP_Send_message_multicast( targets, SMP_MESSAGE_MULTICAST_ACTION );
|
_SMP_Send_message_multicast( &targets, SMP_MESSAGE_MULTICAST_ACTION );
|
||||||
_SMP_Multicasts_try_process();
|
_SMP_Multicasts_try_process();
|
||||||
|
|
||||||
while ( _Atomic_Load_ulong( &node.done, ATOMIC_ORDER_ACQUIRE ) == 0 ) {
|
while ( _Atomic_Load_ulong( &node.done, ATOMIC_ORDER_ACQUIRE ) == 0 ) {
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ static void test_send_message_flood(
|
|||||||
|
|
||||||
for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
|
for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
|
||||||
rtems_test_assert(
|
rtems_test_assert(
|
||||||
_Processor_mask_Is_set(_SMP_Online_processors, cpu_index)
|
_Processor_mask_Is_set(&_SMP_Online_processors, cpu_index)
|
||||||
);
|
);
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
@@ -176,7 +176,7 @@ static void test_send_message_flood(
|
|||||||
|
|
||||||
for (; cpu_index < CPU_COUNT; ++cpu_index) {
|
for (; cpu_index < CPU_COUNT; ++cpu_index) {
|
||||||
rtems_test_assert(
|
rtems_test_assert(
|
||||||
!_Processor_mask_Is_set(_SMP_Online_processors, cpu_index)
|
!_Processor_mask_Is_set(&_SMP_Online_processors, cpu_index)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user