コード例 #1
0
ファイル: isrsmp.c プロジェクト: cotodevel/rtems-gsoc2012
ISR_Level _ISR_SMP_Disable(void)
{
  ISR_Level level;

  _ISR_Disable_on_this_core( level );
  return level;
}
コード例 #2
0
uint32_t _Thread_Dispatch_decrement_disable_level(void)
{
  ISR_Level  isr_level;
  uint32_t   level;

  /*  First we must disable ISRs in order to protect
   *  accesses to the dispatch disable level.
   */
  _ISR_Disable_on_this_core( isr_level );

  _Thread_Dispatch_disable_level--;
  level = _Thread_Dispatch_disable_level;


  /* 
   * Note: _SMP_lock_spinlock_nested_Obtain returns with
   *        ISR's disabled and _SMP_lock_spinlock_nested_Release
   *        is responsable for re-enabling interrupts.
   */
  _SMP_lock_spinlock_nested_Release( 
    &_Thread_Dispatch_disable_level_lock,
    isr_level
  ); 

  return level;
}
コード例 #3
0
ファイル: isrsmp.c プロジェクト: cotodevel/rtems-gsoc2012
int _ISR_SMP_Enter(void)
{
  uint32_t isr_nest_level;
  ISR_Level level;

  _ISR_Disable_on_this_core( level );

  isr_nest_level = _ISR_Nest_level++;

  _Thread_Disable_dispatch();

  return isr_nest_level;
}
コード例 #4
0
ファイル: smp.c プロジェクト: cotodevel/rtems-gsoc2012
/*
 *  Process request to switch to the first task on a secondary core.
 */
void rtems_smp_run_first_task(int cpu)
{
  Thread_Control *heir;
  ISR_Level       level;

  _ISR_Disable_on_this_core( level );

  /*
   *  The Scheduler will have selected the heir thread for each CPU core.
   *  Now we have been requested to perform the first context switch.  So
   *  force a switch to the designated heir and make it executing on 
   *  THIS core.
   */
  heir              = _Thread_Heir;
  _Thread_Executing = heir;

  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
}
コード例 #5
0
ファイル: smplock.c プロジェクト: yangxi/omap4m3
ISR_Level _SMP_lock_spinlock_simple_Obtain(
  SMP_lock_spinlock_simple_Control *lock
)
{
   ISR_Level  level = 0;
   uint32_t   value = 1;
   uint32_t   previous;

   /* Note: Disable provides an implicit memory barrier. */
  _ISR_Disable_on_this_core( level );
   do {
     RTEMS_COMPILER_MEMORY_BARRIER();
     SMP_CPU_SWAP( lock, value, previous );
     RTEMS_COMPILER_MEMORY_BARRIER();
   } while (previous == 1);

  return level;
}
コード例 #6
0
ファイル: smp.c プロジェクト: cotodevel/rtems-gsoc2012
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 );
  }
}
コード例 #7
0
ファイル: smplock.c プロジェクト: yangxi/omap4m3
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;
}
コード例 #8
0
ファイル: isrsmp.c プロジェクト: cotodevel/rtems-gsoc2012
int _ISR_SMP_Exit(void)
{
  ISR_Level level;
  int       retval;

  retval = 0;

  _ISR_Disable_on_this_core( level );

  _ISR_Nest_level--;

  if ( _ISR_Nest_level == 0 ) {
    if ( _Thread_Dispatch_necessary ) {
      if ( _Thread_Dispatch_get_disable_level() == 1 ) {
        retval = 1;
      }
    } 
  }

  /*
   *  SPARC has special support to avoid some nasty recursive type behaviour.
   *  When dispatching in a thread and we want to return to it then it needs
   *  to finish.
   */
  #if defined(__sparc__)
    if ( _CPU_ISR_Dispatch_disable )
      retval = 0;
  #endif

  _ISR_Enable_on_this_core( level );

  _Thread_Dispatch_decrement_disable_level();

   if ( retval == 0 )
    _SMP_Request_other_cores_to_dispatch();

  return retval;
}
コード例 #9
0
ファイル: smp.c プロジェクト: cotodevel/rtems-gsoc2012
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 );
  }
}