Ejemplo n.º 1
0
rtems_task Test_task(
  rtems_task_argument unused
)
{
  rtems_id          tid;
  rtems_time_of_day time;
  uint32_t    task_index;
  rtems_status_code status;
  int               cpu_num;
  char              name[5];
  char             *p;

  /* Get the task name */
  p = rtems_object_get_name( RTEMS_SELF, 5, name );
  rtems_test_assert( p != NULL );

  status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid );
  task_index = task_number( tid );
  for ( ; ; ) {

    /* Get the CPU Number */
    cpu_num = bsp_smp_processor_id();

    status = rtems_clock_get_tod( &time );
    if ( time.second >= 35 ) {
      locked_printf( "*** END OF SMP08 TEST ***" );
      rtems_test_exit( 0 );
    }

    PrintTaskInfo( p, &time );
    status = rtems_task_wake_after(
      task_index * 5 * rtems_clock_get_ticks_per_second() );
  }
}
Ejemplo n.º 2
0
void _SMP_lock_spinlock_nested_Release(
  SMP_lock_spinlock_nested_Control *lock,
  ISR_Level                        level
)
{
  #if defined (RTEMS_DEBUG) || defined(SMPLOCK_DEBUG)
    if ( lock->count == 0 ) {
      printk(
        "\ncpu %d lock %d Releasing spinlock when count is already "
        "zero (%p from %p,%p)?!?!\n",
        bsp_smp_processor_id(),  
        lock->cpu_id,
        lock,
        __builtin_return_address(0),
        __builtin_return_address(1)
      );
      debug_dump_log();
      return;
    }
  #endif

  /* assume we actually have it */
  if (lock->count == 1) {
    lock->cpu_id = -1;
    debug_logit( 'U', lock );
    lock->count  = 0;
    RTEMS_COMPILER_MEMORY_BARRIER();
    lock->lock = 0;
  } else {
    debug_logit( 'u', lock );
    lock->count--;
  }

  _ISR_Enable_on_this_core( level ); 
}
Ejemplo n.º 3
0
void _SMP_Request_other_cores_to_shutdown(void)
{
  bool   allDown;
  int    ncpus;
  int    n;
  int    cpu;

  cpu   = bsp_smp_processor_id();
  ncpus = _SMP_Processor_count;

  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );

  allDown = true;
  for (n=0 ; n<ncpus ; n++ ) {
     if ( n == cpu ) 
       continue;
     bsp_smp_wait_for(
       (unsigned int *)&_Per_CPU_Information[n].state,
       RTEMS_BSP_SMP_CPU_SHUTDOWN,
       10000
    );
    if ( _Per_CPU_Information[n].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
      allDown = false;
  }
  if ( !allDown )
    printk( "not all down -- timed out\n" );
  #if defined(RTEMS_DEBUG)
    else
      printk( "All CPUs shutdown successfully\n" );
  #endif
}
Ejemplo n.º 4
0
rtems_task Test_task(
  rtems_task_argument argument
)
{
  locked_printf( "Shut down from CPU %d\n", bsp_smp_processor_id() );
  locked_printf( "*** END OF TEST SMP05 ***\n" );
  rtems_test_exit(0);
}
Ejemplo n.º 5
0
void PrintTaskInfo(
  const char *task_name
)
{
  int               cpu_num;

  cpu_num = bsp_smp_processor_id();

  locked_printf("  CPU %d running task %s\n", cpu_num, task_name );
}
Ejemplo n.º 6
0
  static void debug_logit(
    char                             act,
    SMP_lock_spinlock_nested_Control *lock
  )
  { 
    debug_debug_spinlog_t *sp;
    if ( DEBUG_SPINLOG_INDEX == DEBUG_SPINLOG_MAX )
      #if defined (ENABLE_LOOPED_DEBUG_LOGGING)
        DEBUG_SPINLOG_INDEX = 0;
      #else
        return;
      #endif

    sp = &DEBUG_SPINLOG[ DEBUG_SPINLOG_INDEX++ ];
    sp->action = act;

    #if 0
      if ( lock == &_ISR_SMP_Lock )
        sp->lock = 'I';
      else 
    #endif
    if ( lock == &_Thread_Dispatch_disable_level_lock )
      sp->lock   = 'D';
    sp->cpu    = bsp_smp_processor_id() + '0';
    sp->count  = lock->count;
    #if 0
      if ( sp->lock == 'I' ) {
        if ( _Thread_Dispatch_smp_spin_lock.id == 0 )
          printk( "not nested %p from %p %p %p %p\n", sp,
          __builtin_return_address(0), __builtin_return_address(1),
          __builtin_return_address(2), __builtin_return_address(3) 
        );
      }
    #endif
    sp->nest_level =  _ISR_Nest_level; 
    sp->ret1 = 0;
    sp->ret2 = 0;
    sp->ret3 = 0;
    sp->ret4 = 0;
    sp->ret1 = __builtin_return_address(0);
    if ( sp->ret1 >= start && sp->ret1 <= _fini ) {
      sp->ret2   = __builtin_return_address(1);
      if ( sp->ret2 >= start && sp->ret2 <= _fini ) {
        sp->ret3   = __builtin_return_address(2);
        if ( sp->ret3 >= start && sp->ret3 <= _fini ) {
          sp->ret4   = __builtin_return_address(3);
        }
      }
    }
  }
Ejemplo n.º 7
0
rtems_task Init(
  rtems_task_argument argument
)
{
  int                i;
  char               ch;
  int                cpu_num;
  rtems_id           id;
  rtems_status_code  status;

  locked_print_initialize();
  locked_printf( "\n\n*** TEST SMP09 ***\n" );

  for ( killtime=0; killtime<1000000; killtime++ )
    ;
  
  for ( i=0; i<rtems_smp_get_number_of_processors() -1; i++ ) {
    ch = '1' + i;

    status = rtems_task_create(
      rtems_build_name( 'T', 'A', ch, ' ' ),
      1,
      RTEMS_MINIMUM_STACK_SIZE,
      RTEMS_DEFAULT_MODES,
      RTEMS_DEFAULT_ATTRIBUTES,
      &id
    );
    directive_failed( status, "task create" );

    cpu_num = bsp_smp_processor_id();
    locked_printf(" CPU %d start task TA%c\n", cpu_num, ch);

    status = rtems_task_start( id, Test_task, i+1 );
    directive_failed( status, "task start" );
  }

  locked_printf(" kill 10 clock ticks\n" );
  while ( rtems_clock_get_ticks_since_boot() < 10 )
    ;

  rtems_cpu_usage_report();

  locked_printf( "*** END OF TEST SMP09 ***" );
  rtems_test_exit(0);
}
Ejemplo n.º 8
0
void rtems_smp_secondary_cpu_initialize(void)
{
  int       cpu;
  ISR_Level level;

  cpu = bsp_smp_processor_id();

  _ISR_Disable_on_this_core( level );
  bsp_smp_secondary_cpu_initialize(cpu);

  /*
   *  Inform the primary CPU that this secondary CPU is initialized
   *  and ready to dispatch to the first thread it is supposed to
   *  execute when the primary CPU is ready.
   */
  _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;

  #if defined(RTEMS_DEBUG)
    printk( "Made it to %d -- ", cpu );
  #endif

  /*
   *  With this secondary core out of reset, we can wait for the
   *  request to switch to the first task.
   */
  while(1) {
    uint32_t   message;

    bsp_smp_wait_for(
      (volatile unsigned int *)&_Per_CPU_Information[cpu].message,
      RTEMS_BSP_SMP_FIRST_TASK,
      10000
    );

    level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
      message = _Per_CPU_Information[cpu].message;
      if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
	_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
        _ISR_Set_level( 0 );
      }
     
    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
  }
}
Ejemplo n.º 9
0
void _SMP_Request_other_cores_to_dispatch(void)
{
  int i;
  int cpu;

  cpu = bsp_smp_processor_id();

  if ( !_System_state_Is_up (_System_state_Current) )
    return;
  for (i=1 ; i < _SMP_Processor_count ; i++ ) {
    if ( cpu == i )
      continue;
    if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP )
      continue;
    if ( !_Per_CPU_Information[i].dispatch_necessary )
      continue;
    _SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
  }
}
Ejemplo n.º 10
0
void _SMP_Broadcast_message(
  uint32_t  message
)
{
  int        dest_cpu;
  int        cpu;
  ISR_Level  level;

  cpu = bsp_smp_processor_id();

  for ( dest_cpu=0 ; dest_cpu <  _SMP_Processor_count; dest_cpu++ ) {
    if ( cpu == dest_cpu )
      continue;
    level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
      _Per_CPU_Information[dest_cpu].message |= message;
    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
  }
  bsp_smp_broadcast_interrupt();
}
Ejemplo n.º 11
0
ISR_Level _SMP_lock_spinlock_nested_Obtain(
  SMP_lock_spinlock_nested_Control *lock
)
{
  ISR_Level  level = 0;
  uint32_t   value = 1;
  uint32_t   previous;
  int        cpu_id;

  /* Note: Disable provides an implicit memory barrier. */
  _ISR_Disable_on_this_core( level ); 

  cpu_id = bsp_smp_processor_id();

  /*
   *  Attempt to obtain the lock.  If we do not get it immediately, then
   *  do a single "monitor" iteration.  This should allow the loop to back
   *  off the bus a bit and allow the other core to finish sooner.
   */
  while (1) {
    RTEMS_COMPILER_MEMORY_BARRIER();
    SMP_CPU_SWAP( &lock->lock, value, previous );
    RTEMS_COMPILER_MEMORY_BARRIER();
    if ( previous == 0 ) {
      /* was not locked */
      break;
    }

    /* Deal with nested calls from one cpu */
    if (cpu_id == lock->cpu_id) {
      lock->count++;
      debug_logit( 'l', lock );
      return level;
    }
  }

  lock->cpu_id = cpu_id;
  lock->count = 1;
  debug_logit( 'L', lock );

  return level;
}
Ejemplo n.º 12
0
rtems_task Test_task(
  rtems_task_argument do_exit
)
{
  int               cpu_num;
  char              name[5];
  char             *p;

  p = rtems_object_get_name( RTEMS_SELF, 5, name );
  rtems_test_assert( p != NULL );

  cpu_num = bsp_smp_processor_id();
  locked_printf(" CPU %d running Task %s\n", cpu_num, name);

  Ran = true;

  if ( do_exit ) {
    locked_printf( "*** END OF TEST SMP06 ***\n" );
    rtems_test_exit(0);
  }
  while(1)
    ;
}
Ejemplo n.º 13
0
rtems_task Init(
  rtems_task_argument argument
)
{
  int                i;
  char               ch;
  int                cpu_num;
  rtems_id           id;
  rtems_status_code  status;

  locked_print_initialize();
  locked_printf( "\n\n*** TEST SMP05 ***\n" );

  for ( i=0; i<rtems_smp_get_number_of_processors() ; i++ ) {
    ch = '1' + i;

    status = rtems_task_create(
      rtems_build_name( 'T', 'A', ch, ' ' ),
      1,
      RTEMS_MINIMUM_STACK_SIZE,
      RTEMS_DEFAULT_MODES,
      RTEMS_DEFAULT_ATTRIBUTES,
      &id
    );
    directive_failed( status, "task create" );

    cpu_num = bsp_smp_processor_id();
    locked_printf(" CPU %d start task TA%c\n", cpu_num, ch);

    status = rtems_task_start( id, Test_task, i+1 );
    directive_failed( status, "task start" );
  }

  while (1)
    ;
}
Ejemplo n.º 14
0
void rtems_smp_process_interrupt(void)
{
  int        cpu;
  uint32_t   message;
  ISR_Level  level;

  cpu = bsp_smp_processor_id();

  level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
  message = _Per_CPU_Information[cpu].message;

  #if defined(RTEMS_DEBUG)
    {
      void *sp = __builtin_frame_address(0);
      if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
	if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY )
	  printk( "context switch necessary\n" );
	if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
	  printk( "signal to self\n" );
	if ( message & RTEMS_BSP_SMP_SHUTDOWN )
	  printk( "shutdown\n" );
	if ( message & RTEMS_BSP_SMP_FIRST_TASK )
	  printk( "switch to first task\n" );
      }
 
      printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
    }
  #endif

  if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
    _Per_CPU_Information[cpu].isr_nest_level = 0;
    _Per_CPU_Information[cpu].message &= ~message;
    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;

    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );

    rtems_smp_run_first_task(cpu);
    /* does not return */
  }

  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
    _Per_CPU_Information[cpu].message &= ~message;

    _Per_CPU_Information[cpu].isr_nest_level = 0;
    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );

    _Thread_Enable_dispatch();       /* undo ISR code */
    _ISR_Disable_on_this_core( level );
    while(1)
      ;
    /* does not continue past here */
  }

  if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
    #if defined(RTEMS_DEBUG)
      printk( "switch needed\n" );
    #endif
    _Per_CPU_Information[cpu].message &= ~message;
    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
  }
}
Ejemplo n.º 15
0
rtems_task Init(
  rtems_task_argument argument
)
{
  int                cpu_num;
  rtems_id           id;
  rtems_status_code  status;

  locked_print_initialize();
  locked_printf( "\n\n*** TEST SMP06 ***\n" );
  locked_printf( "rtems_clock_tick - so this task has run longer\n" );
  status = rtems_clock_tick();
  directive_failed( status, "clock tick" );

  rtems_test_assert( rtems_smp_get_number_of_processors()  > 1 );

  cpu_num = bsp_smp_processor_id();

  /*
   * Create a task at equal priority.
   */
  Ran = false;
  status = rtems_task_create(
    rtems_build_name( 'T', 'A', '1', ' ' ),
    2,
    RTEMS_MINIMUM_STACK_SIZE,
    RTEMS_PREEMPT,
    RTEMS_DEFAULT_ATTRIBUTES,
    &id
  );
  directive_failed( status, "task create" );

  locked_printf(" CPU %d start task TA1\n", cpu_num );

  status = rtems_task_start( id, Test_task, 0 );
  directive_failed( status, "task start" );

  while ( Ran == false )
    ;

  /*
   * Create a task at greater priority.
   */
  Ran = false;
  status = rtems_task_create(
    rtems_build_name( 'T', 'A', '2', ' ' ),
    1,
    RTEMS_MINIMUM_STACK_SIZE,
    RTEMS_PREEMPT,
    RTEMS_DEFAULT_ATTRIBUTES,
    &id
  );
  directive_failed( status, "task create" );

  cpu_num = bsp_smp_processor_id();
  locked_printf(" CPU %d start task TA2\n", cpu_num );

  status = rtems_task_start( id, Test_task, 1 );
  directive_failed( status, "task start" );

  while ( 1 )
    ;
}
Ejemplo n.º 16
0
rtems_task Init(
  rtems_task_argument argument
)
{
  int               i;
  char              ch;
  int               cpu_num;
  rtems_id          id;
  rtems_status_code status;
  char              str[80];

  locked_print_initialize();
  locked_printf( "\n\n***  SMP02 TEST ***\n" );

  /* Create/verify synchronisation semaphore */
  status = rtems_semaphore_create(
    rtems_build_name ('S', 'E', 'M', '1'),
    1,                                             
    RTEMS_LOCAL                   |
    RTEMS_SIMPLE_BINARY_SEMAPHORE |
    RTEMS_PRIORITY,
    1,
    &Semaphore);
  directive_failed( status, "rtems_semaphore_create" );

  /* Lock semaphore */
  status = rtems_semaphore_obtain( Semaphore, RTEMS_WAIT, 0);
  directive_failed( status,"rtems_semaphore_obtain of SEM1\n");

  for ( i=1; i < rtems_smp_get_number_of_processors(); i++ ){

    /* Create and start tasks for each CPU */
    ch = '0' + i;

    status = rtems_task_create(
      rtems_build_name( 'T', 'A', ch, ' ' ),
      1,
      RTEMS_MINIMUM_STACK_SIZE,
      RTEMS_DEFAULT_MODES,
      RTEMS_DEFAULT_ATTRIBUTES,
      &id
    );

    cpu_num = bsp_smp_processor_id();
    locked_printf(" CPU %d start task TA%c\n", cpu_num, ch);
    status = rtems_task_start( id, Test_task, i+1 );
    directive_failed( status, str );
  }

  /*
   * Release the semaphore, allowing the blocked tasks to start.
   */
  status = rtems_semaphore_release( Semaphore );
  directive_failed( status,"rtems_semaphore_release of SEM1\n");
  

  /* 
   * Wait for log full. print the log and end the program.
   */  
  while (Log_index < LOG_SIZE)
    ;
 
  for (i=0; i< LOG_SIZE; i++) {
    if ( Log[i].IsLocked ) {
      locked_printf(
        " CPU %d Task TA%" PRIu32 " Obtain\n", 
        Log[i].cpu_num,
        Log[i].task_index
      );
    } else {
      locked_printf(
        " CPU %d Task TA%" PRIu32 " Release\n", 
        Log[i].cpu_num,
        Log[i].task_index
      );
    }
  }

  locked_printf( "*** END OF TEST SMP02 ***\n" );
  rtems_test_exit( 0 );
}