linux powerpc e500内核外部中断,PIC,PPC,设备驱动

来源:互联网 发布:周扬青的淘宝店 编辑:程序博客网 时间:2024/05/18 04:51

http://blog.chinaunix.net/u2/71164/showart_2038214.html

 

powerpc e500内核中断系统有两部分组成一个是e500的内核,一个是中断异常控制器programmable interrupt controller (PIC) interrupt protocol

e500内核有些特殊之处是:在e500内核进入中断和异常处理程序时不能关闭mmu也就是说e500内核所看到的是虚拟地址。E500内核的解决办法是利用IVPR  IVOR寄存器来共同决定中断程序的入口地址,IVPR保存中断入口程序的0~15 IVOR保存16~27 28~31位为0;(每一个IVOR对应一种中断,如:IVOR4 对应着外部中断)。此外PIC控制器还有Interrupt Source Configuration Registers用来区分是具体的中断如外部中断一有EIVPR1 EIDR1共同决定

0---------------------------------------------------------------------------------à31

MSK          A      RSV1    P      S            PRIORITY    VECTIOR

0              1        2~7    8      9              12~`15       16~`31

其中vector位为硬件中断号(不同于datasheet种的中断号)。其他个相关位见datasheet

e500 int信号有效是期铜外部中断处理,外部中断处理根据具体的硬件中断号执行具体本中断的处理程序。俺也不知道处于啥原因linux又弄了个软中断号这样你在申请中断(request_irq是应该使用的是软中断号)。为此系统必须建立软中断号与硬中断号之间的联系。建立联系之后你就可以通过硬件中断号向系统要软件中断号了然后request_irq了。参见irq_of_parse_and_map函数或者干脆就直接调用irq_create_mapping(不知道会不会有问题)

与之相关的中断调用如下(arch/powerpc/kernel/head_fsl_booke.S)

      

#define SET_IVOR(vector_number, vector_label)             /

             li      r26,vector_label@l;              /

             mtspr      SPRN_IVOR##vector_number,r26;     /

             sync

 

SET_IVOR(0, CriticalInput);

      SET_IVOR(1,  MachineCheck);

      SET_IVOR(2,  DataStorage);

      SET_IVOR(3,  InstructionStorage);

      SET_IVOR(4,  ExternalInput);

      SET_IVOR(5,  Alignment);

      SET_IVOR(6,  Program);

      SET_IVOR(7,  FloatingPointUnavailable);

      SET_IVOR(8,  SystemCall);

      SET_IVOR(9,  AuxillaryProcessorUnavailable);

      SET_IVOR(10, Decrementer);

      SET_IVOR(11, FixedIntervalTimer);

      SET_IVOR(12, WatchdogTimer);

      SET_IVOR(13, DataTLBError);

      SET_IVOR(14, InstructionTLBError);

      SET_IVOR(15, DebugCrit);

以外部中断处理为例:SET_IVOR(4, ExternalInput);

当外部中断发生时根据 IVOR4 IVPR中的地址会导致调用ExternalInput

arch/powerpc/kernel/head_fs_booke.S-à

/* External Input Interrupt */

      EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)

 

#define EXCEPTION(n, label, hdlr, xfer)                         /

      START_EXCEPTION(label);                             /

      NORMAL_EXCEPTION_PROLOG;                         /

      addi r3,r1,STACK_FRAME_OVERHEAD;                 /

      xfer(n, hdlr)

 

#define EXC_XFER_LITE(n, hdlr)             /

      EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, /

                      ret_from_except)

 

#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)   /

      li      r10,trap;                              /

      stw  r10,_TRAP(r11);                                /

      lis    r10,msr@h;                                /

      ori   r10,r10,msr@l;                                  /

      copyee(r10, r9);                                 /

      bl     tfer;                                 /

      .long       hdlr;                                    /

      .long       ret

 

 

首先,trap加载到寄存器r10中。在接下来的一行中,那个值存储在由TRAP(r11)给出的地址中。TRAP(r11)以及接下来两行去做一些硬件相关的位操作。然后,我们调用tfer函数(transfer_to_handler函数),它会处理更多内部事务并将控制转交给hdlrdo_IRQ)。注意,transfer_to_handler通过链接寄存器加载处理程序的地址,因此您看到的是.longdo_IRQ,而不是bldo_IRQ

这个宏完成一些必要的设置后导致do_IRQ的调用!

 (transfer_to_handler 参见arch/powerpc/kernel/entry_32.S )

void do_IRQ(struct pt_regs *regs)

{

      struct pt_regs *old_regs = set_irq_regs(regs);

      unsigned int irq;

 

      irq_enter();

 

      check_stack_overflow();

 

      irq = ppc_md.get_irq();/*这个东西返回传说中的软件中断号,可见申请中断要用   软件中断号而你在寄存器EIPVRn里读出来的是硬件中断号,呵呵,终于给irq_create_mapping   找个说法了*/

 

      if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)

             handle_one_irq(irq);

      else if (irq != NO_IRQ_IGNORE)

             /* That's not SMP safe ... but who cares ? */

             ppc_spurious_interrupts++;

 

      irq_exit();

      set_irq_regs(old_regs);

 

#ifdef CONFIG_PPC_ISERIES

      if (firmware_has_feature(FW_FEATURE_ISERIES) &&

                    get_lppaca()->int_dword.fields.decr_int) {

             get_lppaca()->int_dword.fields.decr_int = 0;

             /* Signal a fake decrementer interrupt */

             timer_interrupt(regs);

      }

#endif

}

暂时写这么多,有新发现在继续添加(呵呵, 有点晕!)

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5岁宝宝学习太皮怎么办 2岁宝宝太皮了怎么办 身上的皮肤很干怎么办 小孩子挑食厌食不吃饭怎么办 1岁宝宝特别淘气怎么办 4岁宝宝有多动症怎么办 3岁宝宝有多动症怎么办 6个月婴儿睡眠少怎么办 7个月婴儿睡眠少怎么办 孩子好动注意力不集中怎么办 学生在课堂上爱讲话怎么办? 幼儿园老师圢小孩脸怎么办 宝宝上幼儿园坐不住怎么办 宝宝在幼儿园总是坐不住怎么办 早教课上宝宝坐不住怎么办? 孩子在幼儿园上课坐不住怎么办 小孩不会写拼音a怎么办 小朋友上课注意力不集中怎么办 一年级孩子上课爱说话怎么办 一年级小孩不听老师话怎么办 大班幼儿规则意识差怎么办 幼儿大班《打雷了怎么办》的教案 小孩上课不听讲到处乱跑怎么办 小孩子经常咬人好动怎么办 6个月宝宝好动怎么办 新生调皮被幼儿园退学怎么办 孩子在幼儿园太调皮怎么办 幼儿上课注意力不集中怎么办 幼儿上课一半要离开怎么办 八个月宝宝消化不良拉肚子怎么办 8个月的宝宝拉肚子怎么办 孕8个月拉稀怎么办 孩子调皮好动爱说话怎么办 宝宝8个月不会爬怎么办 怀孕8个月不想要了怎么办 8个月宝宝发烧怎么办 八个月的小孩发烧怎么办 孩子8个月发烧38怎么办 8个宝宝发烧38度怎么办 怀孕八个月不想要怎么办 怀孕八个月不想要了怎么办