注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

蓝瑟

人生苦短,及时行乐

 
 
 

日志

 
 

SMP中的IPI  

2009-12-22 15:33:58|  分类: 学习心得 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

本文学习基于:Blackfin561-uCLinux

IPI: Inter-Processor Interrupt(处理器之间的中断)(在本平台中用于解决Core A核Core B之间的中断)

用途:中断系统中的任何处理器核,在本平台中主要通过对寄存器SICB_SYSCR(System Reset Configuration Register B)中[9:6]置位来设置中断,对[13:10]清零来清除中断。

在Blackfin-uCLinux中,BF561有两个中断类型来服务于IPI,分别是:supplement_int0和supplement_int1,所以在SICB_SYSCR中分别对A,B两核的两种中断各有一位进行控制。在uCLinux中使用supplement_int0来中断,分别对应寄存器的6.7.10.11位。

在Linux2.6内核中通过这样的方式来注册:

start_kernel->rest_init->kernel_init->smp_prepare_cpus->platform_request_ipi

其中有platform_request_ipi注册的ipi_handler具体处理IPI中断。

static irqreturn_t ipi_handler(int irq, void *dev_instance)
{
 struct ipi_message *msg;

/*ipi_message:

struct ipi_message {
 struct list_head list;
 unsigned long type;
 struct smp_call_struct call_struct;

 smp_call_struct :

struct smp_call_struct {
 void (*func)(void *info);
 void *info;
 int wait;
 cpumask_t pending;
 cpumask_t waitmask;
};
} */
 struct ipi_message_queue *msg_queue;
 unsigned int cpu = smp_processor_id(); //得到当前的blackfin core id

 platform_clear_ipi(cpu); // 设置SICB_SYSCR的相应清零IPI位置

 msg_queue = &__get_cpu_var(ipi_msg_queue);
 msg_queue->count++;

 spin_lock(&msg_queue->lock);
 while (!list_empty(&msg_queue->head)) {
  msg = list_entry(msg_queue->head.next, typeof(*msg), list);
  list_del(&msg->list);
  switch (msg->type) {
  case BFIN_IPI_RESCHEDULE: //收到ipi后重新调度,不做其他任何处理
   /* That's the easiest one; leave it to
    * return_from_int. */
   kfree(msg);
   break;
  case BFIN_IPI_CALL_FUNC://调用某个制定的函数,该函数在msg指定的结构中的call_struct->func
   spin_unlock(&msg_queue->lock);
   ipi_call_function(cpu, msg);
   spin_lock(&msg_queue->lock);
   break;
  case BFIN_IPI_CPU_STOP://停止CPU
   spin_unlock(&msg_queue->lock);
   ipi_cpu_stop(cpu);
   spin_lock(&msg_queue->lock);
   kfree(msg);
   break;
  default:
   printk(KERN_CRIT "CPU%u: Unknown IPI message \
   0x%lx\n", cpu, msg->type);
   kfree(msg);
   break;
  }
 }
 spin_unlock(&msg_queue->lock);
 return IRQ_HANDLED;
}

触发中断的方式:platform_send_ipi

在该函数中同样是通过对寄存器SICB_SYSCR的6,7位置位来进行中断的设置

  评论这张
 
阅读(820)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017