3

我有点卡在编程设备MSI(消息信号中断)上,欢迎任何指针...... (我的环境是 Watcom C + DOS/32a - dos 扩展器,在平面模式下......)

@ PIC(8259) 模式对我来说没问题...

我在下面列出了我所做的事情,也许有人可以帮助澄清这些......谢谢!

(1)多消息启用 = 0(对于单个 MSI 设置此字段 = 0;MMC = 100b)

(2) MSI能力中的MSI消息地址寄存器

  • 位[31:20] = 0xFEE
  • bit[19:12] = 0(目标 ID,并找到本地 APIC ID = 0...)
  • bit3 = 0(重定向提示 = 0)
  • bit2 = 0(目标模式,不关心,因为 RH = 0)

(3) MSI能力中的MSI消息数据寄存器

  • bit15 = 0(触发模式 = 边沿)
  • bit14 = 0(触发电平,如果触发模式 = 边沿则忽略)
  • 位[10:8] = 000(传送模式 = 固定)
  • bit[7:0] = 0x20(向量,我选择使用0x20)

(4)最后通过设置 MSICAP.MC.MSIE = 1 来启用 MSI

  1. 我已经大致阅读了文档(第 10 章)http://download.intel.com/products/processor/manual/253668.pdf
  2. 我认为没有必要对 IO APIC 和本地 APIC 寄存器进行编程,因为 MSI 不会路由到 APIC 系统......!

当前状态:启用 MSIE = 1 后发现系统挂起,设备通过 MSI 产生中断!

注意:在上面的序列中,没有安装服务例程,因为我不知道该怎么做......(这是我的应用程序挂起的原因吗?)

谢谢 !

[20120822 更新]将Message Data字段 中的向量设置为 0x20 时,app 挂起...但如果设置为 0x76,我发现 app 没有挂起,然后我可以检查设备是否产生中断,Local APIC 收到此中断消息如下:

  1. 对于 PCI 设备(AHCI 控制器):

    • ID(中断禁用)= 0
    • IS(中断状态)= 0
    • MSI 上限 = 09,FEE00000,00000076
  2. 对于 AHCI HBA 寄存器:

    • PxIS = 00000023
    • PxIE = 7DC0007F
    • IS = 00000001
    • IE 位 1 = 1

通过 1 和 2,我认为设备成功发送消息以请求服务,因为:

  • IS bit0 = 1(端口 0 有挂起的中断状态)
  • IE(中断启用)= 1
  • PCI 命令寄存器 bit10(ID) = 0
  • MSICAP.MC.MSIE = 1(至 MSI 引擎)

我还发现 LAPIC 收到了这个中断消息,因为:

  • 本地 APIC IRR(中断请求寄存器) bit118(=0x76) = 1
  • 本地 APIC ISR(In-Service register) bit118(=0x76) = 1

因此,设备似乎产生了中断,而本地 APIC 接收到了这个;即便如此,我的服务程序也没有被调用!

4

1 回答 1

2

要在 DOS 模式下实现 MSI 功能,您可以参考以下序列:

检查是否启用了本地 APIC

  1. 读取 CPU MSR 0x1B 并检查本地 APIC 全局启用/禁用位是否 = 1
  2. 读取本地 APIC 寄存器 杂散中断向量寄存器 bit8(APIC SW enable/disable)=1

初始化 MSI 能力寄存器

  1. 配置消息控制寄存器(例如 MME...)
  2. 配置消息地址寄存器(例如目标 ID、DM 和 RH)
  3. 配置消息数据寄存器(例如触发模式、断言、传递模式和向量)

安装您自己的服务程序

  • 这取决于您使用的编译器/编程语言...
  • 以 (Watcom C+Dos32a) 为例,您可以使用下面来声明和安装服务例程
  • 使用 __interrupt __far 来声明和创建 YourISR
  • 使用 DPMI 调用 0x204/0x205 来获取(旧)和设置(新)中断向量!

笔记:

  1. Message Data 寄存器中的中断向量可以是 Ex. 0x70,0x71,..., 或 0x76
  2. 在 ISR 结束和返回之前,请“写入”本地 APIC 寄存器(EOI)“然后 LAPIC 将清除 In-Service Register 中的位,然后准备服务另一个中断!

使设备能够通过 MSI 请求服务

  1. PCI 命令寄存器 bit10(ID) = 0
  2. 设备的中断允许位 = 1(设备特定)
  3. MSICAP.MC.MSIE = 1(中断路由到 MSI 引擎)

您可以检查设备是否生成请求并且 LAPIC 是否收到此请求

  • 设备将发出 PCI DWORD 写入事务以将 32 位数据写入 32 位内存地址,因此您可以探测 LA 是否发生这种情况,或者您可以检查是否 (ID = 0 && 中断状态!= 0 && MSIE = 1)
  • 检查 LAPIC 寄存器 IRR 和 ISR 以查看请求是否被 LAPIC 接收和服务!

@ 参考:

Intel 64 和 IA-32 架构软件开发人员手册

APIC

PCI 本地总线规范 v2.2

访问 CPU MSR

DOS/32 高级

于 2012-08-23T03:05:24.743 回答