QEMU总线模拟

1 Abstract

设备之间通过总线互联通信,如果将所有设备都挂在到sysbus(即所谓的内部总线:连接cpu、内存、pic总线控制器等设备的总线)将会增加主板的布线难度,而且cpu并不需要实时与外围设备通信。因此没必要每个设备都直接与cpu连接。

现代cpu通过sysbus直接连接一个控制芯片,这个控制芯片再管理外围设备。控制芯片将数据汇总后再与cpu通信。

这个过程对应到QEMU中的就是:

  • cpu通过sysbus找到pcihost
  • pcihost通过pcibus找到pci设备完成cpu的指令

本文主要说明QEMU的怎么模拟实现这个过程的

2 Preface

PCI设备有如下三种不同内存:

  • MMIO
  • PCI IO space
  • PCI configuration space

其中pci configuration space 是用来配置pci设备的,其中也包含了关于pci设备的特定信息。而config空间中的BAR: Base address register可以用来确定设备需要使用的内存或I/O空间的大小,也可以用来存放设备寄存器的地址。

与pci设备通信,先会通过pcihost找到对应的pci设备,修改其config空间、传递指令信息。之后会调用pci_update_mappings更新pci设备的内存映射,因为可能接下来就要通过mmio/pio与pci设备通信了。如: gdb追踪pci_host_config_write、pci_host_data_write、pci_update_mappings的执行。

会发现pci_host_config_write传递指令信息保存到config_reg,pci_host_data_write根据config_reg修改config空间,之后会调用pci_update_mappings。pci_update_mappings会根据修改的config空间的信息更新内存映射。

下文将对其进行详细说明

3 模拟方法

pcihost模拟是主要功能是:根据cpu的指令找到pci设备,然后”转发”指令给pci设备

pcibus模拟的主要功能是:维护pci设备信息,为pcihost索引目标设备提供依据

pci设备模拟的主要功能是:维护自己的config空间和操作对应的回调函数,设备的内存空间映射将会根据config空间的内容完成

要了解pci总线模拟应该搞清楚以下问题:

  • 如何给设备编号:初始化程序扫描总线上每个插槽并编号
    • 对应规范文档:
      • 设备编号:pci-pci-bridge specifiation: 13.2. Device Number and Slot Number Assignment Rules,约138页
    • 对应qemu: qemu/hw/pci/pci.c:do_pci_register_device,当指定devfn=-1时自动扫描可用设备号
  • cpu如何知道设备编号:初始化时初始化程序从IRQ Routing Table获取设备号信息
    • 对应规范文档:
      • 设备号信息初始化:pci-pci-bridge specifiation: 13.6. Run-Time Algorithm for Determining Chassis and Slot Number。约145页
    • 对应qemu: TODO,没有找到,可能是操作系统中完成的?
  • pcihost如何找到pci设备
    • 对应规范文档:
      • 3.2.2.3.2. Software Generation of Configuration Transactions。约33页
    • 对应本文章节:
    • 对应qemu:
      • qemu/hw/pci/pci_host.c:pci_dev_find_by_addr()
  • pci总线规范中几个比较重要的协议内容
    • 对应规范文档:
      • config space的编码规范:Figure 6-1,约191页
      • 设备控制:6.2.2. Device Control,约193页
      • 设备状态控制:6.2.3. Device Status,约196页
      • BAR寄存器:6.2.5. Base Addresses,约201页
    • 对应本文章节:
      • 设备控制(对应Figure 6-1的command register)和状态控制(对应Figure 6-1的status register)等:bus transaction中举例的接口根据addr参数读写各个寄存器
      • BAR寄存器功能:设备IO空间
    • 对应qemu:
      • 设备控制和状态控制等:qemu/pci/pci.c:pci_default_write_config,根据addr参数修改对应寄存器内容
  • 如何给设备分配IO空间
    • 对应规范文档:
      • BAR寄存器:6.2.5. Base Addresses,约201页
    • 对应本文章节:
    • 对应qemu:
      • 设备BAR:qemu/pci/pci.c:pci_register_bar
      • 根据BAR进程内存空间映射:qemu/pci/pci.c:pci_update_mappings
  • cpu与pci设备通信的流程:中途经过什么设备,做了什么操作,如何读写设备等
    • 对应规范文档:
      • 整体流程概述:3.2.2.3.2. Software Generation of Configuration Transactions。约33页
    • 对应本文章节:
    • 对应qemu:
      • 修改config空间的接口:qemu/pci/pci.c:pci_default_write_config
      • CONFIG_ADDRESS阶段:qemu/pci/pci_host.c:pci_host_config_read,qemu/pci/pci_host.c:pci_host_config_write
      • CONFIG_DATA阶段:qemu/pci/pci_host.c:pci_host_data_read,qemu/pci/pci_host.c:pci_host_data_write

3.1 pcihost

3.1.1 控制流程

pcihost对pci设备控制流程可以分为两阶段

  • CONFIG_ADDRESS
    • cpu访问CONFIG_ADDRESS对应的端口时触发,将命令保存到pcihost的config寄存器中
  • CONFIG_DATA
    • cpu访问CONFIG_DATA对应的端口时触发,根据config寄存器中内容进行相应的操作

3.1.1.1 CONFIG_ADDRESS

以i440fx北桥芯片这个pcihost为例,他使用两个pio来接收,cpu的指令信息。CF8h处的地址空间称为CONFIG_ADDRESS,CFCh处的地址空间称为CONFIG_DATA

参考i440fx规范文档,其pci相关的核心内容如下:

  • i440fx设备的IO端口:3.1. I/O Mapped Registers,约17页
    • 主要内容:CONFIG_ADDRESS寄存器在CF8h端口,CONFIG_DATA寄存器在CFCh端口
    • 对应qemu的模拟:qemu/hw/pci-host/i440fx.c:i440fx_pcihost_realize
  • pci config空间与各寄存器的功能:3.2. PCI Configuration Space Mapped Registers
    • 主要内容:说明了config空格各个字段的内容,访问config空间的格式(TYPE0和TYPE1)
    • 对应qemu的模拟:qemu/hw/pci-host/i440fx.c:pci_host_conf_le_ops和qemu/hw/pci-host/i440fx.c:pci_host_data_le_ops

static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
{
    PCIHostState *s = PCI_HOST_BRIDGE(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
    sysbus_init_ioports(sbd, 0xcf8, 4);

    sysbus_add_io(sbd, 0xcfc, &s->data_mem);
    sysbus_init_ioports(sbd, 0xcfc, 4);

    /* register i440fx 0xcf8 port as coalesced pio */
    memory_region_set_flush_coalesced(&s->data_mem);
    memory_region_add_coalescing(&s->conf_mem, 0, 4);
}

当对CH8h端口写时,pcihost会将数据用锁存器(latch)保存起来。当对CH8h端口读时,pcihost就会返回CONFIG_ADDRESS中的数据。pci规范文档中说明如下(约在32页, 3.2.2.3.2. Software Generation of Configuration Transactions):

qemu中的模拟如下,qemu中用s->config_reg做锁存器,向对CONFIG_ADDRESS写入的数据。读时就直接返回s->config_reg

stati
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值