首页 > 系统相关 >3.3.2 IPIPE对Linux中断使能与屏蔽的改造

3.3.2 IPIPE对Linux中断使能与屏蔽的改造

时间:2024-09-01 21:57:26浏览次数:13  
标签:__ 使能 中断 irq hard 3.3 Linux local

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客

        3.3 第一行之hard_local_irq_disable() 

                3.3.1 Linux中断的使能与屏蔽

                        3.3.1.1 中断使能与屏蔽的三重关卡
                        3.3.1.2 第一重关卡IMR
                        3.3.1.3 第二重关卡中断控制器的使能bit
                        3.3.1.4 第三重关卡CPU core异常掩码标志

                3.3.2 IPIPE对Linux中断使能与屏蔽的改造

                        3.3.2.1 第一重关卡IMR的改造
                        3.3.2.2 第二重关卡中断控制器的使能bit的改造
                        3.3.2.3 第三重关卡的改造

3.3.2 IPIPE对Linux中断使能与屏蔽的改造

3.3.2.1 第一重关卡IMR的改造

        如上文分析,设备的Interrupt Mask Register(IMR)是由各个设备的驱动自行控制的,IPIPE patch不会做任何修改。

        如果想把某个设备交给Head域的实时内核(例如Cobalt)来使用,那么需要使用RTDM来重写设备的驱动程序。内核打上了Xenomai3 patch之后,在drivers/xenomai/目录下有很多在RTDM框架下写好的驱动。以/drivers/xenomai/spi/spi-bcm2835.c为例,它依然是直接读写IMR寄存器来控制自身的中断。

static int do_transfer_irq(struct rtdm_spi_remote_slave *slave)
{
	struct spi_master_bcm2835 *spim = to_master_bcm2835(slave);
	int ret;
	u32 cs;
	
	cs = bcm2835_rd(spim, BCM2835_SPI_CS);

    ……

	/* Enable interrupts last, wait for transfer completion. */
	cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD;
	bcm2835_wr(spim, BCM2835_SPI_CS, cs);

    ……

	return 0;
}
3.3.2.2 第二重关卡中断控制器的使能bit的改造

        如上文分析,默认情况下,disable_irq工作在UNLAZY模式。但是IPIPE是无法在UNLAZY模式下工作的,必须设置为DISABLE_UNLAZY模式。这个修正是通过__fixup_irq_handler函数来完成的。

kernel/irq/chip.c:

irq_flow_handler_t
__fixup_irq_handler(struct irq_desc *desc, irq_flow_handler_t handle, int is_chained)
{
	……

	/*
	 * We don't cope well with lazy disabling simply because we
	 * neither track nor update the descriptor state bits, which
	 * is badly wrong.
	 */
	irq_settings_clr_and_set(desc, 0, _IRQ_DISABLE_UNLAZY);

    ……

	return handle;
}

        那么__fixup_irq_handler函数是在什么时机被调用呢?是在中断分配过程中,对中断描述符irq_desc直接进行修正。具体内核的中断子系统初始化的过程,以后再详细分析。

3.3.2.3 第三重关卡的改造

       如第一章的《1.2.1.2 虚拟中断标志Virtual interrupt flag》所阐述,为了保证头域中的out-of-band代码的实时性,根域中的in-band代码一定不能关闭CPU的物理中断。所以,运行在root域(根域)中的Linux只能管理和使用虚拟中断标志。当根域中的Linux调用local_irq_save/local_irq_disable/spin_lock_irqsave等函数关闭中断时,实际上是对虚拟中断标志进行关闭操作,并没有真正的关闭物理中断标志。此时,头域中的Cobalt依然能够接收物理中断,保证实时性。

       具体是怎么做到的呢?以local_irq_disable为例说明一下。

        local_irq_disable它最终调用的是arch_local_irq_disable,而arch_local_irq_disable定义在头文件<asm/irqflags.h>。在<asm/irqflags.h>,IPIPE patch为它多增加了一个头文件<asm/ipipe_hwirq.h>,正是这个新的头文件抢先定义了local_irq_disable最终调用的arch_local_irq_disable,把原先对DAIF寄存器的操作变成了对虚拟中断标志的操作ipipe_stall_root<kernel/ipipe/core.c>。来看一下它的代码。 

        它里面最核心的是第395行__set_bit(IPIPE_STALL_FLAG, &__ipipe_root_status),将虚拟中断标志位进行置位操作(stall操作),即关闭虚拟中断。

       既然Linux不再操作物理中断,那IPIPE是如何接手的呢?回顾一下咱们第3.3章节的主题,大家就能猜出来了。是的,IPIPE重新定义一套函数来操作物理中断标志位DAIF,前缀是hard_local_irq_xxx,同样是两对函数。

        这两对函数定义在<arch/arm64/include/asm/hwirq.h>,为简化分析,默认没有定义CONFIG_IPIPE_TRACE_IRQSOFF。

arch/arm64/include/asm/hwirq.h:
#define hard_local_irq_disable    hard_local_irq_disable_notrace
#define hard_local_irq_enable     hard_local_irq_enable_notrace
#define hard_local_irq_save       hard_local_irq_save_notrace
#define hard_local_irq_restore    hard_local_irq_restore_notrace

arch/arm64/include/asm/hwirq.h:
static inline void hard_local_irq_disable_notrace(void)
{
	__asm__ __volatile__("msr daifset, #2" : : : "memory", "cc");
}

static inline void hard_local_irq_enable_notrace(void)
{
	__asm__ __volatile__("msr daifclr, #2" : : : "memory", "cc");
}

#define hard_local_irq_restore_notrace(x)				\
	__asm__ __volatile__(						\
	"msr	daif, %0"	\
	:								\
	: "r" (x)							\
	: "memory", "cc")

static inline unsigned long hard_local_irq_save_notrace(void)
{
	unsigned long res;
	__asm__ __volatile__(
		"mrs	%0, daif\n"
		"msr daifset, #2"
		: "=r" (res) : : "memory", "cc");
	return res;
}

        最后,呼应一下第3.3章节的主题哈。原先start_kernel调用local_irq_disable是为了屏蔽物理中断的。因为local_irq_disable已经变成了对虚拟中断标志位的操作,所以需要替换为IPIPE自己定义的hard_local_irq_disable。

       说起来挺简单的,但是追寻背后的细节还是花费了不少功夫。接下来分析下一行初始化代码。

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

标签:__,使能,中断,irq,hard,3.3,Linux,local
From: https://blog.csdn.net/aspirestro/article/details/141790495

相关文章

  • GNU与Linux 的关系
    问题1:GNOME是什么?GNOME是一个自由且开放源代码的桌面环境,广泛用于基于Linux和其他类Unix操作系统的计算机上。GNOME(GNUNetworkObjectModelEnvironment)的设计目标是提供一个简单、易于使用且现代化的用户界面,让用户能够轻松管理和操作系统资源。主要特性:用户友好:GNOM......
  • 使用公钥登录 Linux 服务器
    使用公钥登录Linux服务器‍Linux上使用公钥登录在客户端上通过ssh-copy_id​将公钥写入到服务器的authorized_keys:[root@VM-4-11-centos~]#[email protected]/usr/bin/ssh-copy-id:INFO:Sourceofkey(s)tobeinstalled:"/root/.ssh/id_rsa.pub"/usr......
  • linux nginx 配置连接时间
    在Nginx中配置连接时间主要涉及到几个不同的参数,通常是指与客户端连接、请求和响应相关的时间设置。以下是一些关键配置项,适用于Nginx的nginx.conf文件或相应的虚拟主机配置文件。1.keepalive_timeout设置保持连接的时间。这个时间是指在客户端和服务器之间保持连接的超时时......
  • 使用公钥登录 Linux 服务器
    使用公钥登录Linux服务器‍Linux上使用公钥登录在客户端上通过ssh-copy_id​将公钥写入到服务器的authorized_keys:[root@VM-4-11-centos~]#[email protected]/usr/bin/ssh-copy-id:INFO:Sourceofkey(s)tobeinstalled:"/root/.ssh/id_rsa.pub"/usr......
  • 使用公钥登录 Linux 服务器
    使用公钥登录Linux服务器‍Linux上使用公钥登录在客户端上通过ssh-copy_id​将公钥写入到服务器的authorized_keys:[root@VM-4-11-centos~]#[email protected]/usr/bin/ssh-copy-id:INFO:Sourceofkey(s)tobeinstalled:"/root/.ssh/id_rsa.pub"/usr......
  • Linux目录详解
     一.树状目录结构图:二.树状目录结构介绍: 1./bin目录 /bin目录包含了引导启动所需的命令或普通用户可能用的命令(可能在引导启动后)。这些命令都是二进制文件的可执行程序(bin是binary--二进制的简称),多是系统中重要的系统文件。2./sbin目录 /sbin目......
  • Linux性能调优大作战:从零到英雄,手把手教你打造极速系统!让你的服务器快如闪电!
    第一章引言Linux系统性能调优在信息技术领域具有不可忽视的重要性。随着Linux操作系统的广泛应用,从桌面环境到大型服务器集群,其性能优化变得尤为关键。调优不仅可以提升系统的响应速度和吞吐量,还能降低资源消耗,从而延长硬件使用寿命,减少总体拥有成本。本文研究旨在深入探讨Li......
  • 正点原子Linux C应用编程:移植tslib并使其适配7寸LCD1024*600的GT911触摸驱动
    正点原子LinuxC应用编程:移植tslib并使其适配7寸LCD1024*600的GT911触摸驱动作者在学习【正点原子】I.MX6U嵌入式LinuxC应用编程指南V1.4时,发现移植tslib后,触摸事件触发不正常。使用的硬件版本:正点原子I.MX6UALPHAV2.4版本底板,LCD:正点原子7寸1024*600,型号ATK-MD0700R-102460......
  • unidac在fpc 3.3.1安装要注意的事项
    fpc3.3.1比3.2.2,字段类型增加了7种字段类型(红字部分):TFieldType=(ftUnknown,ftString,ftSmallint,ftInteger,ftWord,ftBoolean,ftFloat,ftCurrency,ftBCD,ftDate,ftTime,ftDateTime,ftBytes,ftVarBytes,ftAutoInc,ftBlob,ftMemo,ftGraphic,ftFmt......
  • 正点原子Linux Framebuffer编程:解决示例程序在开发板上LCD显示错位和颜色异常
    正点原子LinuxFramebuffer编程:解决示例程序在开发板上运行7寸LCD显示错位和颜色异常作者在学习【正点原子】I.MX6U嵌入式LinuxC应用编程指南V1.4时,发现其配套的程序在开发板上运行不正常。使用的硬件版本:正点原子I.MX6UALPHAV2.4版本底板,LCD:正点原子7寸1024*600,型号ATK-MD0......