免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1299 | 回复: 0
打印 上一主题 下一主题

1.2 8259A的登记过程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-15 15:36 |只看该作者 |倒序浏览

下面我们以8259A为例,看看系统是如何为其注册中断源的,即注册INTSRC(0)~INTSRC(15)。 描述8259A中断控制器的数据结构是struct atpic_intsrc,其第一个成员是一个中断源结构,这种类型定义方法是BSD中常用的方法,起到了面向对象编程中继承的作用。
由于两个级连的8259A中断控制器可以控制16个中断,因此系统注册16个struct atpic_intsrc。这些中断响应程序的的入口地址是IDTVEC(atpic_intr ## irq )。IDTVEC在.c文件中将扩展成Xatpic_intr0 至Xatpic_intr15,即为函数名的引用。而在.s文件中将扩展成
代码:
ALIGN_TEXT;
  .globl Xatpic_intr0;
  .type Xatpic_intr0,@function;
Xatpic_intr0:
等等,即定义一个全局的函数,也就是说在.c文件中只是引用该函数,真正定义该函数的是
在sys/i386/isa/atpic_vector.s中,该函数实际上就是一个对atpic_handle_intr()
函数的包装,我们后面还将看到该函数。
代码:
struct atpic_intsrc {
  struct intsrc at_intsrc;
  int at_irq; /* Relative to PIC base. */
  inthand_t *at_intr;
  u_long at_count;
  u_long at_straycount;
};
static struct atpic_intsrc atintrs[] = {
  INTSRC(0),
  INTSRC(1),
  INTSRC(2),
  INTSRC(3),
  INTSRC(4),
  INTSRC(5),
  INTSRC(6),
  INTSRC(7),
  INTSRC(8),
  INTSRC(9),
  INTSRC(10),
  INTSRC(11),
  INTSRC(12),
  INTSRC(13),
  INTSRC(14),
  INTSRC(15),
};
#define INTSRC(irq) \
  { { &atpics[(irq) / 8].at_pic }, (irq) % 8, \
    IDTVEC(atpic_intr ## irq ) }
系统启动时,调用8259A的初始化函数atpic_init(),为非SLAVE IRQ号注册中断源。并在i386初始化时调用atpic_startup()函数,注册中断向量IDTVEC(atpic_intr ## irq ),注意,这只是注册总的包装函数,具体IRQ号的中断处理函数将由设备驱动通过intr_add_handler()函数来注册。
代码:
SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
static void
atpic_init(void *dummy __unused)
{
  int i;
  /* Loop through all interrupt sources and add them. */
  for (i = 0; i  sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) {
    if (i == ICU_SLAVEID)
      continue;
    intr_register_source(&atintrs.at_intsrc);
  }
}
void
init386(first)
  int first;
{
  ......
#ifdef DEV_ISA
  atpic_startup();
#endif
  ......
}
void
atpic_startup(void)
{
  struct atpic_intsrc *ai;
  int i;
  /* Start off with all interrupts disabled. */
  imen = 0xffff;
  i8259_init(&atpics[MASTER], 0);
  i8259_init(&atpics[SLAVE], 1);
  atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
  /* Install low-level interrupt handlers for all of our IRQs. */
  for (i = 0; i  sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) {
    if (i == ICU_SLAVEID)
      continue;
    ai = &atintrs;
    ai->at_intsrc.is_count = &ai->at_count;
    ai->at_intsrc.is_straycount = &ai->at_straycount;
    setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
      ai->at_irq, ai->at_intr, SDT_SYS386IGT, SEL_KPL,
      GSEL(GCODE_SEL, SEL_KPL));
  }
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/38079/showart_301986.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP