谁分配 I/O 地址范围
我们结合着主板ASMB-784 用户手册
https://downloadt.advantech.com.cn/ProductFile/Downloadfile5/1-1AZOJUN/ASMB-784_User_Manual_Ed.2.pdf
1、南桥芯片连接着不同的pcie-x总线,不同的pcie-x 设备
2. 南桥芯片通过DMI/FDI连着cpu
cpu配置寄存器映射到pcie总线配置空间,所以cpu可以通过DMI/FDI等连接到pcie上
下图是实物各种接口及设备位置和主板ASMB-784标注图
下图是具体的CH368提供 pci接口,CH368可以制作各种卡,这些卡就通过pcie的插槽连接上某条pcie总线
CH368是一款连接PCI-Express总线的通用接口芯片,支持I/O端口映射、内存映射、扩展ROM和中断。CH368 将高速PCIE 总线转换成一个易于使用的32 位或8 位主动并行接口,类似于ISA 总线。可用于制作低成本的基于PCIE总线的计算机卡,以及从基于ISA或PCI总线升级到PCIE卡。与其他总线相比,PCIE速度更快、实时性更好、控制性更好,因此CH368适用于高速实时I/O控制卡、通讯接口卡、数据采集卡等
http://www.wch-ic.com/products/CH368.html
现在通过以上我们,直接着来讨论几个问题?
一、who assign I/O address range? 谁来分配I/O设备
我们在系统中或者是驱动程序中经常会看到I/O地址或操作I/O,到底是操作什么。
首先通过上面了解到,I/O是一个地址,也是通过这个地址来操作I/O设备,那么这个地址是来自哪里呢?
引用和修改了维基百科:(下面以PCI为例子,注意PCIE和PCI都有配置空间实现,而且是兼容的,但是他们不是一个东西)
故障要寻址 PCI 设备,必须通过映射到的系统的 I/O 端口地址空间或内存映射地址空间来启用它。系统的固件、设备驱动程序或操作系统对基地址寄存器(通常称为 BAR)进行编程,cpu通过前端总线,连接上PCI系统以通过向 某个总线下的PCI设备里面的PCI 控制器写入配置命令来通知设备其地址映射。我们看CH368芯片内置pci接口控制器,因为所有 PCI 设备在系统重置时都处于非活动状态,所以它们没有分配给它们的地址,BIOS 或操作系统通过 PCI 控制器使用每个插槽 IDSEL(初始化)对 PCI 插槽(例如,第一个 PCI slot、第二个 PCI slot或第三个 PCI slot等)进行地理寻址设备选择、设置)进行初始化。然后操作系统或设备驱动程序可以通过这些地址与它们进行通信。
由于 BIOS 或操作系统没有直接方法来确定哪些 PCI 插槽安装了设备(也无法确定设备实现了哪些功能),因此必须枚举 PCI 总线。总线枚举是通过尝试读取供应商 ID 和设备 ID (VID/DID) 寄存器以获取设备功能 #0 处的总线号和设备号的每个组合来执行的。
当对供应商 ID 寄存器的指定 B/D/F 组合的读取成功时,设备驱动程序知道它存在;它将所有 1 写入其 BAR,并以编码形式读回设备请求的内存大小。该设计意味着所有地址空间大小都是 2 的幂并且自然对齐。
此时,BIOS 或操作系统会将内存映射和 I/O 端口地址编程到设备的 BAR 配置寄存器中。只要系统保持打开状态,这些地址就会保持有效。断电后,所有这些设置都将丢失,下次系统重新启动时将重复该过程。
BAR 位被卡住的故障硬件,因此它被分配了一个 I/O 范围,而您的机器上不可用
用于设置 I/O 范围的 LINUX 命令(因为我发现了 Windows setpci 等效命令)吗?我的供应商 ID 是
15AD
,我的设备 ID 是 0405。实际上我可以执行这个命令:setpci -d 15AD:0405 device_id
但我不知道如何添加参数来修改我的 I/O 范围。为了简化,我只想输入0000
错误的 I/O 范围我们看下linux pci的布局情况
[root@aozhejin ~]$lspci -k 00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01) Subsystem: VMware Virtual Machine Chipset Kernel driver in use: agpgart-intel 00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01) 00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 08) Subsystem: VMware Virtual Machine Chipset 00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01) Subsystem: VMware Virtual Machine Chipset Kernel driver in use: ata_piix Kernel modules: ata_piix, pata_acpi, ata_generic 00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08) Subsystem: VMware Virtual Machine Chipset Kernel modules: i2c_piix4 00:07.7 System peripheral: VMware Virtual Machine Communication Interface (rev 10) Subsystem: VMware Virtual Machine Communication Interface Kernel driver in use: vmw_vmci Kernel modules: vmw_vmci 00:0f.0 VGA compatible controller: VMware SVGA II Adapter Subsystem: VMware SVGA II Adapter Kernel driver in use: vmwgfx Kernel modules: vmwgfx 00:11.0 PCI bridge: VMware PCI bridge (rev 02) 00:15.0 PCI bridge: VMware PCI Express Root Port (rev 01) Kernel driver in use: pcieport 00:15.1 PCI bridge: VMware PCI Express Root Port (rev 01) Kernel driver in use: pcieport 00:15.2 PCI bridge: VMware PCI Express Root Port (rev 01) Kernel driver in use: pcieport 00:15.3 PCI bridge: VMware PCI Express Root Port (rev 01) Kernel driver in use: pcieport .....
类似下面的布局 https://tldp.org/LDP/tlk/dd/pci.html
二、How is the I/O Address Space mapped to devices?
On an x86 pc the bios normally manages allocation of the flat/physical address space, and everything uses some place in that space. So the BIOS will "enumerate" the pcie devices by going out on each pcie slot to see if anyone is there. There are standard configuration registers that a pcie device must have some of which indicate how much address space and what kind (I/O based or Memory mapped). the bios attempts to make everyone happy and give them what they want. Windows or linux will not remap these devices or addresses, they take what is given to them by the bios. not every pcie system works that way but unfortunately this is how PC's work.
如果你运行 linux 然后找到 lspci 的源代码,有一些库和示例你可以拆开并制作你自己的库和示例来检查你的系统中有哪些设备以及它们的基地址和内存范围是什么。您很可能只想做其他操作系统所做的事情,并读取 pcie 主机控制器以查看已分配的内容,并将该信息提供给该系统上运行的软件。您可能启动一次,打印机获得地址 0xE0000000,下一次获得 0xDB000000,为您的环境提供一种机制来提供这些地址,或者将这些地址抽象为环境地址空间中的某个固定地址,并让您的代码管理到物理地址的转换/设备的真实地址。
我假设通过使用术语实模式,您正在谈论某种 x86 系统风格,这可能是某种风格的 PC。也许是 mac。不确定 mac 究竟是如何做到的,对它们的枚举了解不够。硬件可能仍然是带有北桥和南桥的英特尔处理器,然后是许多 pcie 桥或其他英特尔 pcie 芯片,最终以焊接到电路板(视频芯片等)或 pcie 插槽上的许多 pcie 设备结束用于插卡。如果您运行 linux 并使用 lspci 并查看供应商和部件号,您可以在英特尔网站上找到英特尔(供应商 ID 8086)设备的大部分手册/数据表,并且您可以使用 lspci 及其兄弟程序来检查控制和那些 pcie 控制器中的状态寄存器,再次如果你有兴趣深入挖掘这个,
地址不是标准的,也不是固定的,每个 bios 都是针对该主板型号的半定制,pcie 空间的地址范围通常是整个处理器空间的 1g 或更少,但是随着移动到 64,该窗口正在改变位和需要更多空间(缓慢移动)。该 pcie 窗口的位置取决于硬件(请参阅我提到的各种英特尔设备的数据表,或者通过或 nvidia 或任何人,如果它是 amd 系统)如果 bios 配置为在 pcie 窗口的 32 位模式下运行对于所有 pcie 设备,可能介于 2 g 之间,但当然低于 4 g 标记,但这并不意味着所有这些系统都使用 3 g 标记。对于 64 位,我认为它们也往往接近顶部,但从主板到主板它会发生变化。然后,当涉及到枚举总线时,它既是特定于主板的,也是特定于个人计算机的,一些设备被螺栓/焊接到主板上,并且每次都以相同的顺序被枚举,但是插入插槽的卡必须响应主机,有时会根据谁先回答而被枚举,您可能会启动 20 次并看到相同的布局,再启动一次并且两张卡可能会交换位置,因为它们被枚举的顺序发生了变化。因此,即使您的视频卡看起来总是在同一个地方,也不要在任何地方硬编码该号码,始终扫描 pcie 总线或表或调用图书馆来找出什么在哪里。
是的,如果你升级或降级你的 bios,bios 只是软件,有时 bios 的变化与 pcie 枚举有关(并不少见,比如流行的视频卡在主板上不能很好地工作,他们将 mod 放入 bios 软件更改重置或其他任何东西以使该卡有更好的工作机会)并且这可能会更改整个系统的枚举。
总线架构
本节介绍设备标识、设备寻址和中断。
设备标识
设备识别是确定系统中存在哪些设备的过程。有些设备是自我识别的——设备本身向系统提供信息,以便它可以识别需要使用的设备驱动程序。SBus 和 PCI 本地总线设备是自识别设备的示例。在 SBus 上,信息通常来自存储在设备 FCode PROM 中的一个小的 Forth 程序。大多数 PCI 设备都提供一个包含设备配置信息的配置空间。有关更多信息,请参见sbus(4)和pci(4)手册页。
所有现代总线架构都要求设备能够自我识别。
支持的中断类型
Solaris 支持轮询和向量中断。两者的 Solaris 9 DDI/DKI 中断模型是相同的。有关中断处理的更多信息,请参阅第 7 章中断处理程序。
总线细节
本节介绍特定于 Solaris 支持的总线的寻址和设备配置问题。
PCI本地总线
PCI局部总线是一种专为高速数据传输而设计的高性能总线。PCI 总线位于系统板上,通常用作高度集成的外围组件、外围附加板和主机处理器或内存系统之间的互连机制。主机处理器、主内存和 PCI 总线本身通过 PCI 主桥连接,如图A–3所示。
通过一系列 PCI 总线桥支持互连 I/O 总线的树形结构。从属 PCI 总线桥可以在 PCI 主机桥下扩展,使单个总线系统能够扩展为具有多个辅助总线的复杂系统。PCI 设备可以连接到这些辅助总线中的一条或多条。此外,还可以连接其他总线桥,例如 SCSI 或 USB。
每个 PCI 设备都有唯一的供应商 ID 和设备 ID。同一类型的多个设备通过它们所在总线上的唯一设备号进一步标识。
图 A–3 机器框图
PCI 主机桥提供处理器和外围组件之间的互连。通过 PCI 主机桥,处理器可以独立于其他 PCI 总线主控器直接访问主内存。例如,当 CPU 从主机桥中的高速缓存控制器获取数据时,其他 PCI 设备也可以通过主机桥访问系统内存。这种架构的优势在于它把 I/O 总线与处理器的主机总线分开。
PCI 主机桥还提供 CPU 和外围 I/O 设备之间的数据访问映射。它将每个外围设备映射到主机地址域,以便处理器可以通过编程 I/O 访问设备。在本地总线端,PCI 主机桥将系统内存映射到 PCI 地址域,这样 PCI 设备就可以作为总线主控访问主机内存。图 A–3显示了两个地址域。
PCI地址域(PCI Address Domain)
PCI address domain consists of three distinct address spaces
PCI 地址域由三个不同的地址空间组成:配置(configuration)、内存和 I/O 空间。
PCI 配置地址空间(PCI Configuration Address Space)
配置空间是按地理定义的;换句话说,外围设备的位置由其在互连的 PCI 总线桥树(tree of PCI bus bridges)中的物理位置(physical location)决定。设备由其总线号(bus number)和设备号(slot number插槽号)定位。每个外围设备(peripheral device)在其 PCI 配置空间(PCI configuration space)中都包含一组定义明确的配置寄存器(configuration registers)。这些寄存器(registers )不仅用于识别设备,还用于向配置框架提供设备配置信息。例如,设备配置空间中的基址寄存器(BAR)必须在设备响应数据访问之前进行映射。
生成配置周期的方法取决于主机。在 IA 机器中,使用特殊的 I/O 端口。在其他平台上,PCI 配置空间( PCI configuration space)可以内存映射到主机地址域(host address domain)中对应于 PCI host bridge 的特定地址位置。当处理器访问设备配置寄存器时,请求被路由到 PCI 主桥。然后,桥将访问转换为总线上的适当配置周期。
PCI 配置基址寄存器(PCI Configuration Base Address Registers)
PCI 配置空间由每个设备的最多六个 32 位基地址寄存器组成。这些寄存器提供大小和数据类型信息。系统固件将 PCI 地址域中的基地址分配给这些寄存器。
每个可寻址区域可以是内存或 I/O 空间。基地址寄存器的第 0 位中包含的值标识类型。bit 0 为 0 表示内存空间,为 1 表示 I/O 空间。图 A–4显示了两个基地址寄存器:一个用于内存;另一个用于 I/O 类型。
图 A–4 内存和 I/O 的基址寄存器
PCI内存地址空间
PCI 支持内存空间的 32 位和 64 位地址。系统固件将 PCI 地址域中的内存空间区域分配给 PCI 外围设备。区域的基地址存储在设备的 PCI 配置空间的基地址寄存器中。每个区域的大小必须是 2 的幂,并且分配的基地址必须在等于区域大小的边界上对齐。内存空间中的设备地址被内存映射到主机地址域,以便可以通过处理器的本地加载或存储指令执行对任何设备的数据访问。
PCI I/O 地址空间
PCI 支持 32 位 I/O 空间。I/O 空间可以在不同的平台上以不同的方式访问。具有特殊 I/O 指令的处理器,如 Intel 处理器系列,使用in和out指令访问 I/O 空间。没有特殊 I/O 指令的机器将映射到主机地址域中与 PCI 主机桥对应的地址位置。当处理器访问内存映射地址时,I/O 请求将发送到 PCI 主机桥,然后将地址转换为 I/O 周期并将它们放在 PCI 总线上。内存映射 I/O 由处理器的本地加载/存储指令执行。
PCI 硬件配置文件
PCI 本地总线设备不需要硬件配置文件。然而,在某些情况下,PCI 设备的驱动程序需要使用硬件配置文件来增加驱动程序的私有信息。有关详细信息,请参阅driver.conf(4)和pci(4)手册页。
总线
典型的 SBus 系统由主板(包含 CPU 和 SBus 接口逻辑)、主板上的多个 SBus 设备和多个 SBus 扩展槽组成。SBus 也可以通过适当的总线桥连接到其他类型的总线。
SBus 是按地理位置编址的;每个 SBus 插槽都存在于系统中的固定物理地址。SBus 卡具有不同的地址,具体取决于它插入的插槽。将 SBus 设备移动到新插槽会导致系统将其视为新设备。
SBus 使用轮询中断。当一个 SBus 设备中断时,系统只知道几个设备中的哪一个可能发出了中断。系统中断处理程序必须向每个设备的驱动程序询问它是否负责中断。
SBus 物理地址空间
表 A–1显示了 Sun Ultra 2 计算机的物理地址空间布局。Ultra 2 上的物理地址由 41 位组成。41 位物理地址空间进一步细分为多个由PA(40:33)标识的 33 位地址空间。
Table A–1 Device Physical Space in the Ultra 2
PA(40:33) |
33-bit Space |
Usage |
---|---|---|
0x0 |
0x000000000 - 0x07FFFFFFF |
2 Gbytes Main memory |
0x80 – 0xDF |
Reserved on Ultra 2 |
Reserved on Ultra 2 |
0xE0 |
Processor 0 |
Processor 0 |
0xE1 |
Processor 1 |
Processor 1 |
0xE2 – 0xFD |
Reserved on Ultra 2 |
Reserved on Ultra 2 |
0xFE |
0x000000000 - 0x1FFFFFFFF |
UPA Slave (FFB) |
0xFF |
0x000000000 - 0x0FFFFFFFF |
System I/O space |
|
0x100000000 - 0x10FFFFFFF |
SBus Slot 0 |
|
0x110000000 - 0x11FFFFFFF |
SBus Slot 1 |
|
0x120000000 - 0x12FFFFFFF |
SBus Slot 2 |
|
0x130000000 - 0x13FFFFFFF |
SBus Slot 3 |
|
0x1D0000000 - 0x1DFFFFFFF |
SBus Slot D |
|
0x1E0000000 - 0x1EFFFFFFF |
SBus Slot E |
|
0x1F0000000 - 0x1FFFFFFFF |
SBus Slot F |
物理系统总线地址
SBus 有 32 个地址位,如SBus Specification中所述。表 A–2描述了 Ultra 2 如何使用地址位。
表 A–2 Ultra 2 SBus 地址位
位 |
描述 |
---|---|
0 - 27 |
这些位是 SBus 卡用来寻址卡内容的 SBus 地址线。 |
28 - 31 |
CPU 使用它来选择一个 SBus 插槽。这些位生成 SlaveSelect 线。 |
此寻址方案产生表 A–1中所示的 Ultra 2 地址。其他实现可能使用不同数量的地址位。
Ultra 2 有七个系统总线插槽,其中四个是物理插槽。插槽 0 到 3 可用于 SBus 卡。插槽 4-12 保留。这些插槽按以下方式使用:
-
插槽 D、E 和 F 不是实际的物理插槽,而是指板载直接内存访问 (DMA)、SCSI、以太网和音频控制器。为方便起见,这些被视为插入插槽 D、E 和 F。
笔记 -一些 SBus 插槽是仅供从属使用的插槽。需要 DMA 功能的驱动程序应使用ddi_slaveonly(9F)来确定其设备是否位于支持 DMA 的插槽中。有关此功能的示例,请参阅入口attach()点。
系统总线硬件配置文件
SBus 设备通常不需要硬件配置文件。然而,在某些情况下,SBus 设备的驱动程序需要使用硬件配置文件来增加 SBus 卡提供的信息。有关更多详细信息,请参阅driver.conf(4)和sbus(4) 。
三、Header Type 0 Registers Incompatible With PCI
In a non-bridge PCI Express function, the definitions of the following configuration registers in the function’s PCI-compatible configuration space differ from the PCI spec’s definition of the respective register definitions:
• Status Register
Type 1和Type 0 header都包括一个a class code register ,该寄存器指示所表示的网桥或端点的类型,子类字段以及设备ID和供应商ID寄存器中提供了进一步的信息。
Figure C-1: Enumeration Using Transparent Bridges(使用透明桥接的枚举)
PCI 配置基址寄存器(Base Address Registers)
Base Address Registers 缩写BAR
PCI 配置空间由每个设备的最多六个 32 位基地址寄存器组成。这些寄存器提供大小和数据类型信息。系统固件将 PCI 地址域中的基地址分配给这些寄存器。
每个可寻址区域可以是内存或 I/O 空间。基地址寄存器(BAR)的第 0 位中包含的值标识类型。bit 0 为 0 表示内存空间,为 1 表示 I/O 空间,下图显示了两个基地址寄存器:一个用于内存;另一个用于 I/O 类型。
图 A–4 内存和 I/O 的基址寄存器
PCI内存地址空间
PCI 支持内存空间的 32 位和 64 位地址。系统固件将 PCI 地址域中的内存空间区域分配给 PCI 外围设备。区域的基地址存储在设备的 PCI 配置空间的基地址寄存器中。每个区域的大小必须是 2 的幂,并且分配的基地址必须在等于区域大小的边界上对齐。内存空间中的设备地址被内存映射到主机地址域,以便可以通过处理器的本地加载或存储指令执行对任何设备的数据访问。
,该寄存器指示表示什么类型的网桥或端点,在子类字段以及设备ID和供应商ID寄存器中提供进一步的信息。企业社会责任
https://superuser.com/questions/1645856/pci-device-who-assign-i-o-address-range-bios-driver-or-opeating-system
https://www.mindshare.com/files/ebooks/pci%20express%20system%20architecture.pdf
https://docs.oracle.com/cd/E19683-01/806-5222/hwovr-18/index.html
intel C220 pch(南桥)芯片
https://www.mouser.com/datasheet/2/612/8-series-chipset-pch-spec-update-263662.pdf
https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/7-series-chipset-pch-datasheet.pdf
http://static6.arrow.com/aropdfconversion/a201a2d077d7d3c9f5afb8d4ab50890121115784/599-series-chipset-pch-datasheet.pdf