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

时间:2012-08-21 08:15:08

标签: c dos interrupt pci apic

我有点困在编程设备 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(触发电平,如果触发模式=边沿则忽略)
  • 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和本地APIC寄存器,因为MSI不会路由到APIC系统......!
  3. 当前状态: 我在启用MSIE = 1后发现系统挂起,设备通过MSI生成中断!

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

    谢谢!

    [20120822已更新] 当将 消息数据 字段中的向量设置为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 bit1 = 1
    3. 我认为设备成功地将消息发送到请求服务,因为:

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

检查是否已启用本地APIC

  1. 读取CPU MSR 0x1B并检查本地APIC全局启用/禁用位= 1
  2. 读取本地APIC寄存器寄生中断向量寄存器bit8(APIC SW启用/禁用)= 1
  3. 初始化MSI功能寄存器

    1. 配置消息控制寄存器(例如MME ...)
    2. 配置消息地址寄存器(例如目的地ID,DM和RH)
    3. 配置消息数据寄存器(例如触发模式,断言,传送模式和向量)
    4. 安装您自己的服务例程

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

      注意:

      1. 消息数据寄存器中的中断向量可以是Ex。 0x70,0x71,...或0x76
      2. 在ISR结束时和返回之前请“写入”本地APIC寄存器(EOI)“然后LAPIC将清除服务中寄存器中的位,然后准备再服务另一个中断!
      3. 允许设备通过

        通过MSI请求服务
        1. PCI命令寄存器bit10(ID)= 0
        2. 设备的中断使能位= 1(特定于器件)
        3. MSICAP.MC.MSIE = 1(中断路由到MSI引擎)
        4. 您可以检查设备是否生成请求,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