uehtml 网站源码,html5企业网站带后台,济南网络推广,平面广告创意作品接上文#xff0c;本文继续介绍Linux软件部分逻辑。
参考内核版本#xff1a;kernel-4.19
目录
1.中断信号在各级中断控制器中的应答
2.supports_deactivate_key意义
3.中断嵌套 1.中断信号在各级中断控制器中的应答 本章主要从内核软件层面来看各中断控制器对中断信号处…接上文本文继续介绍Linux软件部分逻辑。
参考内核版本kernel-4.19
目录
1.中断信号在各级中断控制器中的应答
2.supports_deactivate_key意义
3.中断嵌套 1.中断信号在各级中断控制器中的应答 本章主要从内核软件层面来看各中断控制器对中断信号处理应答关于硬件层面的处理硬件过程可以参考前文。同样使用前文中GICv3 PIO 中断控制器为硬件框架介绍PIO接受到外部中断时软件层各控制器的应答文中设定supports_deactivate_key 为false。 如下图触发中断(EL1 、SPI类型)后软件通过操作硬件中断控制器对中断应答操作(卷尺框图) #1.读取GICv3中断控制器的IAR中断应答寄存器获取GIC的硬件中断号 #2.通过PIO中断控制器maskack对应中断 #3.通过PIO中断控制器unmask对应中断 #4.操作GICv3中断控制器EOI寄存器标记该GIC中断为deactivted并回退GIC的中优先级
从 #2、#3代码上逻辑上看一推出 a.因在执行该中断的处理handle时PIO中断控制器上mask该中断故认为该中断在该CPU不 能实现中断嵌套 b.对于GIC已经通过IAR寄存器响应了来自PIO的中断则处理该中断的CPU不能相应低于PIO 中断优先级的中断 2.supports_deactivate_key意义 supports_deactivate_key 是用指示GIC采用 ICC_CTLR_ELn.EOImode的形式mode0或者mode1值为true时表示采用mode1即EOI寄存器被置位时只是回退到该中断处理的前的优先级、需要再操作DIR寄存器将当前中断状态切换到非激活状态值为false时表示采用mode0即操作EOI寄存器就会完成优先级回退和切换该中断到非激活状态。GICv3的驱动代码可以明确体现上述逻辑
static void gic_cpu_sys_reg_init(void)
{…if (static_branch_likely(supports_deactivate_key)) {/*当supports_deactivate_key使能时配置为EOI为mode1形式*/gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);} else {/*当supports_deactivate_key使能时配置为EOI为mode0形式*/gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);}…
} supports_deactivate_key的值与hyp modeArm的虚拟化模式默认值为ture当判定hyp mode未使能时则设置该置为false。代码逻辑如下
static int __init gic_init_bases(void __iomem *dist_base,struct redist_region *rdist_regs,u32 nr_redist_regions,u64 redist_stride,struct fwnode_handle *handle)
{…/*hyp mode未使能设置supports_deactivate_key为false*/if (!is_hyp_mode_available())static_branch_disable(supports_deactivate_key);/*supports_deactivate_key值为true时表示EOL Deactivate 分开处理*/if (static_branch_likely(supports_deactivate_key))pr_info(GIC: Using split EOI/Deactivate mode\n);…
}
3.中断嵌套 据说是从kernel-2.6.34开始不支持。其实内核中有很多代码都可以证明不支持中断嵌套处理逻辑如下便是一例作证
static int __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
{/** request_irq() - __setup_irq()* 如下当irq设置 IRQ_NESTED_THREAD 支持嵌套中断属性时如果注册的中断处理无thread_fn* 函数时支持返回中断注册EINVAL错误.* 如果有注册thread_fn则将中断handle处理函数设置为irq_nested_primary_handler* 因为irq_nested_primary_handler函数直接返回IRQ_NONE则thread_fn也无法得到执行。* 故支持中断嵌套处理的函数不能得到处理所以Linu内核不支持嵌套中断。*//** Check whether the interrupt nests into another interrupt* thread.*/nested irq_settings_is_nested_thread(desc);if (nested) {if (!new-thread_fn) {ret -EINVAL;goto out_mput;}/** Replace the primary handler which was provided from* the driver for non nested interrupt handling by the* dummy function which warns when called.*/new-handler irq_nested_primary_handler;...
} 另外从处理器硬件层面也限制了中断嵌套处理的可能。如下ARM异常处理的文档中描述当处理器捕获到异常并进入异常处理状态时该处理器的PSTATE.DAIF中断掩码被自动设置也是说该处理不能再响应对应的异常处理。当完成异常处理时系统通过调用eret指令完成PSTATE状态和被中断指令地址的恢复即同时恢复了PSTATE.DAIF状态可能把当前处理器从异常中断状态恢复出来。 在系统进行IRQ异常处理的过程中可能有局部使能或者关闭local_irq_enable/local_irq_disable当前CPU IRQ的行为如bottom half处理的softirq tasklet处理过程会使能当前CPU的IRQ但也会进行成对的关闭行为这点符合局部对称的设计要要求但因为softirq阶段有短暂的使能本地中断行为所以在中断的bottom half阶段可能有高优先级的中断被路由到当前CPU导致中断嵌套。 总结当前内核不支持top half阶段的中断的嵌套支持bottom half阶段的中断嵌套。