中断体系相关

☆ 中断体系的建立
中断体系的建立对应的函数是在 arch/arm/mach-s5pv210/mach-x210.c 中结构体struct machine_desc
的元素 .init_irq = s5pv210_init_irq
开机如何被调用可以参考前面博客的 静态映射表的建立
而且中断体系用到了静态映射表的内容;查看struct map_desc结构体数组得出映射关系
虚拟地址       硬件地址              映射长度
VA_VIC(0)      0xF2000000            0x00004000
VA_VIC(1)      0xF2100000            0x00004000
VA_VIC(2)      0xF2200000            0x00004000
VA_VIC(3)      0xF2300000            0x00004000
VA_VIC(0) ==> S3C_VA_IRQ ==> S3C_ADDR(0x00000000) ==> S3C_ADDR_BASE ==> 0xF6000000
VA_VIC(1) ==> S3C_VA_IRQ + 0x10000
VA_VIC(2) ==> S3C_VA_IRQ + 0x20000
VA_VIC(3) ==> S3C_VA_IRQ + 0x30000
下面主要来分析s5pv210_init_irq如何建立中断体系的


☆ s5pv210_init_irq的分析:
s5pv210_init_irq 函数中定义了 u32 vic[4];  然后通过vic[0/1/2/3] = ~0; 的方式把vic的四个元素的所有位全部置1;
首先vic[0] 是一个int型,有32位,分别代表了32个中断,vic数组4个元素就可以表示 4 X 32=128个中断号,
如果某一位为1说明有此中断号,如果某一位为0说明没有此中断号;x210这里vic数组的四个元素全为1,说明有128个连续的中断号
然后调用s5p_init_irq函数
       ↓
s5p_init_irq 函数中对vic数组的四个元素调用了 vic_init
传入的参数(虚拟地址,物理地址,数组元素,中断掩码),
vic_init调用四次,每次操作一组(32个)中断号
        ↓
vic_init 函数主要调用了vic_set_irq_sources(虚拟地址,物理地址,数组元素)
        ↓
vic_set_irq_sources 针对每一组(32个)中断号做以下处理
==> set_irq_chip(irq, &vic_chip);
    vic_chip结构体定义了某些中断操作,irq_chip_set_defaults()函数定了剩余的操作为默认操作,这样每个中断号都有对应的设置操作函数
(操作时通过irq可以找到irq_desc结构体,irq_desc结构体中的chip就包含了操作函数)
==> set_irq_chip_data(irq, base);
    把irq 和基地址对应起来了
(操作时通过irq可以找到irq_desc结构体,irq_desc结构体中的chip_data就是基地址)
==> set_irq_handler(irq, handle_level_irq);
    看样子应该是设置 中断对应的中断函数
==> set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
    设置某些标志位,暂不清楚作用


通过上面分析,发现有个关键点是 通过irq可以找到irq_desc结构体,也就是肯定在其他地方定义了irq_desc结构体数组,我们这里才可以这样找
查看代码获知:set_irq_handler(irq)  是从irq_desc数组查找irq 对应的irq_desc结构体
irq_desc数组被定义在kernel/irq/handle.c文件中
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {           //这个用法比较高级呀
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
}
};
这个结构体会被early_irq_init进行第一次初始化先,调用关系是 start_kernel-->early_irq_init()
第一次初始化先初始一些特定的东西


然后根据不同的板级函数进行第二次初始化,x210也就是s5pv210_init_irq,调用关系是 start_kernel-->init_IRQ()
第二次初始化设置和板级芯片有关的东西


这样内核启动之后start_kernel通过调用early_irq_init() + init_IRQ()就成功的搭建起来了中断体系~~~




我们真正调用的时候
request_irq(....) 像内核申请irq,内核有一套管理系统告诉你,申请是否成功


enable_irq(unsigned int irq)
    desc = irq_to_desc(irq);
    __enable_irq(desc, irq, false)
   check_irq_resend(desc, irq);
   desc->chip->enable(irq);  这里调用到了我们真正的设置函数

disable_irq(unsigned int irq)
    desc = irq_to_desc(irq);
   disable_irq_nosync(irq);
   desc = irq_to_desc(irq);
__disable_irq(desc, irq, false);
   desc->chip->disable(irq); 这里调用到了我们真正的设置函数
最终的调用其实会调用到上面分析的 set_irq_chip(irq, &vic_chip); 的vic_chip结构体,
这里面才是真正的操作硬件的函数,关键就是实现下面三个函数
.ack = vic_ack_irq,
.mask = vic_mask_irq,
.unmask = vic_unmask_irq,
里面肯定是通过irq 找到base地址 然后做真正的硬件操作~~~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值