在DOS模式下实现消息信号中断

3

我在编程设备MSI(消息信号中断)方面遇到了一些困难,欢迎任何指针...(我的环境是Watcom C + DOS/32a - dos扩展器,在flat模式下...)

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

我列出了我所做的事情,希望有人可以帮助澄清这些...谢谢!

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

(2)对于MSI功能中的MSI消息地址寄存器

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

(3)对于MSI功能中的MSI消息数据寄存器

  • bit15 = 0(触发模式= edge)
  • bit14 = 0(触发电平,如果触发模式= edge,则忽略)
  • bit [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和Local APIC寄存器,因为MSI不路由到APIC系统...!

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

注意:在上述序列中,由于我不知道如何执行服务例程(这是我的应用程序挂起的原因吗?),所以未安装服务程序

谢谢!

[20120822更新]
当将Message Data字段中的向量设置为0x20时,应用程序会挂起...但如果设置为0x76,则发现应用程序没有挂起,然后我可以检查设备是否生成中断以及本地APIC是否收到此中断消息,如下所示:

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

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

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

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

  • IS位0 = 1(端口0具有待处理的中断状态)
  • IE(中断使能)= 1
  • PCI命令寄存器位10(ID)= 0
  • MSICAP.MC.MSIE = 1(对于MSI引擎)

此外,我发现LAPIC接收了此中断消息,因为:

  • 本地APIC IRR(中断请求寄存器)位118(=0x76)= 1
  • 本地APIC ISR(正在服务寄存器)位118(=0x76)= 1

因此,似乎是设备生成了中断并且本地APIC接收到了中断,即使如此,我的服务例程仍未被调用!


在将向量设置为0x70并使用DPMI调用0x204/0x205安装ISR后,我的自定义例程成功调用,并且在MSI模式下读写访问似乎正常! - liaoo
1个回答

2
要在DOS模式下实现MSI功能,您可以参考以下步骤:

检查本地APIC是否启用

  1. 读取CPU MSR 0x1B并检查Local APIC全局启用/禁用位=1
  2. 读取本地APIC寄存器Spurious Interrupt Vector Register bit8(APIC SW enable/disable)=1

初始化MSI功能寄存器

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

安装您自己的服务例程

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

注意事项:

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

通过以下方式启用设备请求MSI服务

  1. PCI Command寄存器bit10(ID)=0
  2. 设备的中断使能位=1(特定于设备)
  3. MSICAP.MC.MSIE=1(中断路由到MSI引擎)

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

  • 设备将发出PCI DWORD写事务以将32位数据写入32位内存地址,因此您可以通过LA来探测是否发生这种情况,或者您可以检查(ID=0&&Interrupt status!=0&&MSIE=1)
  • 检查LAPIC寄存器IRR和ISR,以查看是否已接收并由LAPIC提供服务!

@参考文献:

Intel 64 and IA-32 Architectures Software Developer Manuals

APIC

PCI Local Bus Specification v2.2

Access CPU MSR

DOS/32 Advanced


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接