QEMU源码全解析 —— PCI设备模拟(12)

88 篇文章 19 订阅
本文详细解析QEMU中PCI设备中断模拟的机制,涵盖中断引脚、中断控制器、PCI链接设备及中断路由。通过示例说明如何在e1000设备中设置中断引脚,并探讨了PCI设备中断负载均衡和中断线到IRQ的映射,揭示了SeaBIOS在配置中断路由中的作用。
摘要由CSDN通过智能技术生成

接前一篇文章:

3. PCI设备中断模拟

上一节介绍了 操作系统 驱动设备的MMIO/PIO基址以及QEMU是如何模拟该机制的。操作系统与设备通信的另一方面则是设备产生了事件,通过中断机制通知操作系统。设备寄存器和I/O端口提供操作系统向设备的通信,而中断机制则提供了设备向操作系统的通信。

前文书介绍了每个PCI设备都有4个引脚,都可以触发中断,单功能设备都用INTA#触发中断,只有多功能设备会用到INTB#、INTC#、INTD#等中断引脚。使用哪个引脚通常体现在 QEMU 在设备具现化的时候写入PCI设备配置空间内0x3d处的一个字节。比如下边的代码显示了e1000设备使用了INTA#引脚。

hw/net/e1000.c中:

  1. static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
  2. {
  3. DeviceState *dev = DEVICE(pci_dev);
  4. E1000State *d = E1000(pci_dev);
  5. uint8_t *pci_conf;
  6. uint8_t *macaddr;
  7. pci_dev->config_write = e1000_write_config;
  8. pci_conf = pci_dev->config;
  9. /* TODO: RST# value should be 0, PCI spec 6.2.4 */
  10. pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
  11. pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
  12. e1000_mmio_setup(d);
  13. pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
  14. pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
  15. qemu_macaddr_default_if_unset(&d->conf.macaddr);
  16. macaddr = d->conf.macaddr.a;
  17. e1000x_core_prepare_eeprom(d->eeprom_data,
  18. e1000_eeprom_template,
  19. sizeof(e1000_eeprom_template),
  20. PCI_DEVICE_GET_CLASS(pci_dev)->device_id,
  21. macaddr);
  22. d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
  23. object_get_typename(OBJECT(d)), dev->id,
  24. &dev->mem_reentrancy_guard, d);
  25. qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
  26. d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
  27. d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
  28. d->flush_queue_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
  29. e1000_flush_queue_timer, d);
  30. }

QEMU中很多地方都定义了PI_INTERRUPT_PIN,但无论是哪一处,都是如下:

#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */

PCI总线上能够挂载多个设备,而通常中断控制器的中断线是有限的,加上一些中断线已经分配给了主板上的设备,所以通常留给PCI设备的中断个数只有4个或者8个,QEMU在i440fx主板上只有4个中断。将PCI设备使用的中断引脚与中断控制器的中断线关联起来,通常叫作PCI设备的中断路由。

PCI设备中断路由器涉及3个概念:一是已经介绍过的PCI设备的中断引脚;二是中断控制器的中断线;三是所谓的PCI链接设备(PCI Linking device,LNK)。 PCI链接设备可以理解成用来将PCI总线与中断线连接在一起的设备 。i440fx主板模拟给PCI设备的中断线有4条,所以通常有LNKA、LNKB、LNKC、LNKD这4个PCI链接设备。

PCI设备中断路由 包括 两个部分 一个是设备INTA连接到LNKA的交错链接 ,这样可以均衡每个LNKA的负载。因为大多数设备都是用INTA触发中断,所以如此连接使每个设备的INTA都链接到了不同的PCI链接设备上;PCI中断路由的 第二个部分包括PCI链接设备路由到具体的IRQ线上 ,这通常是由BIOS设定的。这里需要注意的是, LNK[A-D]路由到的IRQ不一定是一一对应的,可能有两个LNK*链接到同一个IRQ的情况

PCI链接设备到中断控制器上的路由信息是通过SeaBIOS配置完成的。具体细节请看下回。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他