2、中断系统原理:龙芯中断控制器介绍、中断向量与优先级、中断使能与屏蔽机制

在龙芯HDMI调试中,中断丢失是导致显示异常、画面撕裂或驱动无响应的常见根因。要准确排查中断丢失问题,首先必须理解龙芯中断控制器的硬件架构、中断向量的分配规则、优先级仲裁逻辑以及使能与屏蔽机制。本节将从这四个维度展开,为后续的调试实战奠定理论基础。

2.1 龙芯中断控制器架构

龙芯系列处理器(如龙芯3A5000/3A6000)内部集成了一套多级中断控制器系统,通常包含以下层次:

  • 核心级中断控制器(INTC):位于CPU核内部,负责接收来自片内外设和外部中断控制器的中断请求,并映射到CPU的异常处理入口。
  • 系统级中断控制器(LIOINTC/HTINTC):位于CPU核外,通过HT(HyperTransport)或LIO(Local I/O)总线与核心连接,负责汇聚多个外设中断源,进行优先级裁决后统一上报给核心级控制器。
  • MSI中断控制器:用于处理PCIe MSI/MSI-X中断,在HDMI场景中,GPU或显示控制器通常通过MSI中断通知驱动帧完成或错误状态。
调试要点: 龙芯HDMI驱动中,中断丢失往往发生在系统级控制器到核心级控制器的传递路径上,或者MSI中断在PCIe桥片处的转发环节。排查时应优先检查中断控制器的状态寄存器。
龙芯中断控制器层级架构 龙芯中断控制器层级架构 CPU核心 (Core) 核心级INTC 系统级中断控制器 LIOINTC / HTINTC MSI中断控制器 PCIe MSI/MSI-X 外设 (HDMI/GPU/显示控制器) 中断丢失高发区 ① 系统级→核心级传递 ② MSI在桥片转发 ③ 外设中断信号毛刺

2.2 中断向量与优先级

龙芯中断控制器为每个中断源分配一个唯一的中断向量号,CPU根据向量号跳转到对应的中断服务程序(ISR)。中断优先级决定了当多个中断同时到达时,哪个中断被优先响应。

中断类型 向量号范围 优先级 典型用途
核内异常 0 - 15 最高(固定) TLB缺失、地址错误、算术溢出
核间中断(IPI) 16 - 23 高 多核通信、调度
定时器中断 24 - 31 中高 时钟滴答、调度时钟
外设中断(含HDMI) 32 - 127 可编程(默认中低) 显示控制器、GPU、音频、网络
MSI中断 128 - 255 可编程(默认低) PCIe设备、HDMI帧完成
HDMI调试提示: 龙芯HDMI驱动通常将显示控制器中断配置为外设中断(向量号32-63),而GPU的帧完成中断通过MSI(向量号128+)上报。如果MSI中断优先级低于其他外设中断,在高负载下可能被长时间屏蔽,导致帧完成中断丢失,表现为画面卡顿或撕裂。
中断向量与优先级映射 中断向量与优先级映射 优先级 高 低 核内异常 (0-15) 核间中断 (16-23) 定时器 (24-31) 外设中断 (32-127) MSI中断 (128-255) HDMI中断分布 显示控制器 → 外设中断 GPU帧完成 → MSI中断 优先级差异可能导致丢失

2.3 中断使能与屏蔽机制

龙芯中断控制器提供多级使能与屏蔽控制,驱动开发者必须理解每一级的作用,否则极易导致中断丢失。

2.3.1 三级屏蔽路径

  1. 全局中断使能(CPU级):通过CPU的SR(Status Register)中的IE位控制。IE=0时,CPU不响应任何中断。
  2. 中断控制器级屏蔽:系统级中断控制器(LIOINTC/HTINTC)提供IMR(Interrupt Mask Register),可单独屏蔽每个中断源。
  3. 外设级中断使能:HDMI控制器或GPU内部的中断使能寄存器,控制具体事件(如帧开始、帧结束、错误)是否产生中断请求。
常见陷阱: 在龙芯HDMI调试中,驱动初始化时如果只配置了外设级中断使能,却忘记设置中断控制器级的IMR寄存器,中断请求会被系统级控制器屏蔽,导致CPU永远收不到中断。这是中断丢失问题中最容易被忽略的原因之一。

2.3.2 中断使能配置示例(伪代码)

/* 龙芯HDMI中断使能配置流程 */
void hdmi_irq_enable(struct hdmi_device *dev)
{
    unsigned long flags;
    
    /* 1. 保存中断状态并关闭全局中断 */
    local_irq_save(flags);
    
    /* 2. 配置外设级中断使能:HDMI控制器内部寄存器 */
    writel(HDMI_IRQ_VSYNC | HDMI_IRQ_HSYNC | HDMI_IRQ_ERROR,
           dev->regs + HDMI_INT_EN);
    
    /* 3. 配置中断控制器级屏蔽:清除对应IMR位 */
    writel(readl(dev->intc_base + INTC_IMR) & ~(1 << dev->irq_pin),
           dev->intc_base + INTC_IMR);
    
    /* 4. 使能CPU全局中断 */
    local_irq_restore(flags);
}

2.3.3 中断屏蔽与丢失的关系

屏蔽层级 屏蔽方式 对中断丢失的影响 调试检查方法
CPU全局 SR.IE = 0 所有中断丢失 读取SR寄存器
中断控制器 IMR对应位置1 特定中断源丢失 读取INTC_IMR寄存器
外设内部 INT_EN对应位清0 特定事件中断丢失 读取HDMI_INT_EN寄存器
中断嵌套 ISR中未重新使能 后续中断丢失 检查ISR末尾是否调用unmask
中断使能与屏蔽三级路径 中断使能与屏蔽三级路径 HDMI外设 外设级屏蔽 INT_EN寄存器 控制器级屏蔽 IMR寄存器 CPU全局屏蔽 SR.IE位 CPU 中断丢失排查路径 ① 检查CPU SR.IE是否为1 → ② 检查INTC_IMR对应位是否为0 ③ 检查HDMI_INT_EN对应位是否为1 → ④ 检查ISR中是否重新使能

2.4 中断丢失的典型场景与排查思路

基于上述中断系统原理,在龙芯HDMI调试中,中断丢失通常表现为以下几种模式:

  • 模式A:中断完全不触发 — 检查三级屏蔽路径是否全部开放,重点排查IMR寄存器和外设INT_EN寄存器。
  • 模式B:中断偶尔丢失 — 检查优先级配置,确认MSI中断是否被更高优先级的中断长时间阻塞。
  • 模式C:中断触发但CPU未响应 — 检查中断向量号是否配置正确,以及中断控制器到CPU核的物理连线是否正常。
  • 模式D:中断响应后丢失后续中断 — 检查ISR中是否在退出前重新使能了中断,以及是否清除了中断挂起位。
调试命令速查: 在龙芯平台下,可以通过以下方式快速检查中断状态:
cat /proc/interrupts — 查看各中断号触发次数,判断HDMI中断是否递增。
devmem2 0x1fe00000 — 直接读取中断控制器寄存器(地址需根据平台调整)。
echo 1 > /sys/irq/xxx/debug — 开启指定中断的调试日志。