关于x86 I/O口地址和IN/OUT指令的问题 [英] Question About x86 I/O Port Addresses and IN/OUT Instructions

查看:15
本文介绍了关于x86 I/O口地址和IN/OUT指令的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,这是 PC 总线系统的简化视图(不包括我知道的桥接器).

As I know it, this is a simplified view of PC bus system (it excludes the bridges I'm aware of it).

如图所示:

据我所知,在现代 x86 CPU 中,我们有 65536 字节(0000-FFFF)的地址空间.这些是 I/O 地址.在 x86 中,IN 和 OUT 指令用于通过 I/O 端口与设备通信.

and we have an address space of 65536 bytes (0000-FFFF) in modern x86 CPUs as far as I know. These are I/O addresses. In x86 IN and OUT instructions are used to communicate with devices through I/O ports.

考虑到 PC (x86 cpu) 以下是我的问题:

Considering PCs (x86 cpus) the following are my questions:

  1. 我可以在不使用 PCI 或任何其他总线的情况下将设备添加到此 I/O 总线吗?我的意思是与 IN/OUT 的直接通信.如果是,如何分配 I/O 地址?它们不冲突吗?

  1. Can I add a device to this I/O bus without using PCI or any other bus? I mean a direct communication with IN/OUT. If yes how are I/O addresses assigned? Don't they conflict?

如果我的 CPU 支持 PCI 和 I²C(有些支持!),CPU 如何区分它们的 I/O 地址?它如何知道一个 I/O 地址属于 PCI 还是 I²C.

If my CPU supports PCI and I²C (yes some do!), how does the CPU differentiate between their I/O addresses? How does it know that an I/O address belongs to PCI or I²C.

(顺便说一句,我不知道 I²C 地址是否只是合乎逻辑的而不是关于 I/O 端口,但这是另一个我也需要回答的问题)

(btw I don't know if I²C addresses are just logical and not about I/O ports but this is another question I also need the answer of)

推荐答案

1) 我可以在不使用 PCI 或任何其他总线的情况下将设备添加到此 I/O 总线吗?

1) Can I add a device to this I/O bus without using PCI or any other bus?

理论上;是的.但是,对于现代系统,没有共享/公共总线(现在是点对点链接");内存控制器和 PCI 主机都内置在与 CPU 相同的芯片中,这意味着(除非您是像英特尔这样的 CPU 供应商的员工)您将不得不处理高速串行链接(快速路径,超传输、PCIe 或 DMI),它们既不便宜也不易于连接(换言之,它不像 1980 年代那样,您可以连接一个又好又慢的 ISA 总线).

In theory; yes. However, for modern systems there's no shared/common bus (it's "point to point links" now); and memory controllers and PCI hosts are all built into the same chip as the CPUs which means that (unless you're an employee of a CPU vendor like Intel) you'll have to deal with high-speed serial links (Quick-path, Hyper-transport, PCIe or DMI) which aren't cheap or easy to interface to (in other words, it's not like the 1980s where you have a nice and slow ISA bus to hook into).

如果是,I/O 地址是如何分配的?他们不冲突吗?

If yes how are I/O addresses assigned? Don't they conflict?

传统设备使用由历史/兼容性分配的固定 IO 端口.其他一切都由一种IO 端口范围分配器"(内置于固件和/或操作系统中)动态分配,该分配器在 PCI 配置空间中配置 BAR(基址范围"寄存器).有一些(现已弃用/不存在)替代方案 - 由 ISA 卡上的物理跳线或 DIP 开关手动分配,ISA即插即用"规范在许多设备支持它之前大部分被 PCI 取代,以及存在于其他类型的总线(MCA 和 EISA)用于动态资源分配.当然,大多数现代设备根本不使用 IO 端口(而是使用内存映射寄存器).

Legacy devices use fixed IO ports that were assigned by history/compatibility. Everything else is assigned dynamically by a kind of "IO port range allocator" (built into the firmware and/or operating system) that configures BARs ("Base Address Range" registers) in PCI configuration space. There were some (now deprecated/non-existent) alternatives - manually assigned by physical jumpers or dip switches on ISA cards, an ISA "plug and play" spec that mostly got replaced by PCI before many devices supported it, and features that existed in other kinds of buses (MCA and EISA) for dynamic resource assignment. Of course most modern devices don't use IO ports at all (and use memory mapped registers instead).

2-) 如果我的 CPU 支持 PCI 和 I²C(有些支持!),cpu 如何区分它们的 I/O 地址?它如何知道一个 I/O 地址属于 PCI 还是 I²C.

2-) If my CPU supports PCI and I²C (yes some do!), how does the cpu differentiate between their I/O addresses? How does it know that an I/O address belongs to PCI or I²C.

对于 I²C,可能在某处(在 IO 端口地址空间或物理地址空间中)有一对寄存器用于向/从 I²C 总线发送和接收字节.I²C 总线上的所有内容都将通过这 2 个寄存器进行访问,并且 I²C 总线上的任何内容都无法访问 I²C 总线上的任何内容(包括无法访问任何 IO 端口和无法访问任何物理地址).

For I²C, there'd probably be a pair of registers somewhere (either in the IO port address space or the physical address space) for sending and receiving a byte to/from the I²C bus. Everything on the I²C bus will be accessed through those 2 registers, and nothing on the I²C bus will have access to anything that isn't on the I²C bus (including not having any access to any IO ports and not having any access to any physical addresses).

大多数情况下(如以太网、视频、USB...),您有一个控制器(具有 CPU 可以直接访问的寄存器)来控制 CPU 无法直接访问的内容(LAN、显示器信号、USB插入 USB 总线的设备,...).

Mostly (like ethernet, video, USB, ...) you have a controller (that has registers the CPU can access directly) that controls something that the CPU can't access directly (LAN, signals to the monitor, USB devices plugged into a USB bus, ...).

(简化)示例

让我们假设(由于out dx,al指令)CPU在共享总线或链接上发送一条消息,上面写着command = WRITE, space = IO port space,地址 = 0x1234,大小 = 1 字节,数据 = 0x56".该消息可能被 PCI 主机控制器拦截,它查看详细信息(哪个地址在哪个地址空间)并决定将消息转发到 PCI 总线上的PCI 到 LPC 桥接器"设备.当PCI 到 LPC 桥接器"收到消息时,它可能会查看详细信息(地址空间中的哪个地址)并意识到它对应于 I²C 总线控制器并将其转发给 I²C 总线控制器.I²C 总线控制器可能会解码消息并在 I²C 总线上发送字节 0x56(来自消息的数据"部分).然后,可能正在侦听 I²C 总线的设备看到 0x56 字节并通过将字节 0x78 通过 I²C 总线发送回 I²C 总线控制器进行响应,控制器将值 0x78 存储在内部缓冲寄存器中.

Let's assume that (because of an out dx,al instruction) the CPU sends a message on a shared bus or a link that says "command = WRITE, space = IO port space, address = 0x1234, size = 1 byte, data = 0x56". This message might be intercepted by a PCI host controller, which looks at the details (which address in which address space) and decides to forward the message to an "PCI to LPC bridge" device on a PCI bus. When the "PCI to LPC bridge" gets the message it might look at the details (which address in which address space) and realize it corresponds to an I²C bus controller and forward it to the I²C bus controller. The I²C bus controller might decode the message and send the byte 0x56 (from the "data" part of the message) on the I²C bus. Then, maybe a device that's listening on the I²C bus sees that 0x56 byte and responds by sending the byte 0x78 back over the I²C bus to the I²C bus controller, where the controller stores the value 0x78 in an internal buffer register.

下一步;(由于 in al,dx 指令)CPU 可能会发送另一条消息说command = READ,space = IO 端口空间,address = 0x1234,size = 1 byte".此消息将遵循与前一个相同的路径(因为地址和地址空间相同)并最终到达 I²C 总线控制器.I²C 总线控制器可能会解码该消息并意识到该消息要求从 I²C 总线控制器的内部缓冲寄存器(其保持之前的值 0x78)读取;所以 I²C 总线控制器发回消息command = READ_REPLY, space = IO port space, address = 0x1234, size = 1 byte, data = 0x78".该回复消息将返回到 CPU(再次使用相同的路径,但方向相反——例如,到 PCI 到 LPC 桥,然后到 PCI 主机控制器,然后到 CPU).当 CPU 收到回复时,它可以完成导致它的原始指令(例如,将 al 设置为READ_reply"消息中的值以完成 in al,dx> 说明).

Next; (because of an in al,dx instruction) the CPU might send another message that says "command = READ, space = IO port space, address = 0x1234, size = 1 byte". This message would follow the same path as the previous one (because the address and address space is the same) and end up at the I²C bus controller. The I²C bus controller might decode the message and realize the message is asking to read from the I²C bus controller's internal buffer register (which holds the value 0x78 from before); so the I²C bus controller sends back the message "command = READ_REPLY, space = IO port space, address = 0x1234, size = 1 byte, data = 0x78". This reply message would go back to the CPU (using the same path again, but in the opposite direction - e.g. to PCI to LPC bridge, then to PCI host controller, then to CPU). When the CPU gets the reply it can complete the original instruction that caused it (e.g. set al to the value that was in the "READ_reply" message to complete the in al,dx instruction).

这里的重点是 CPU 不能直接向 I²C 总线上的设备发送任何内容(CPU 只能与 I²C 总线控制器通信);并且 I²C 总线上的任何设备都不能直接向 CPU 发送任何内容(它们也只能与 I²C 总线控制器通信).I²C 总线上没有任何东西需要了解 IO 端口;CPU 总线/链路上的任何内容都不需要了解 I²C 总线上的字节.

The point here is that CPU can't send anything directly to a device on the I²C bus (a CPU can only talk to the I²C bus controller); and no device on the I²C bus can send anything directly to the CPU either (they can only talk to the I²C bus controller too). Nothing on the I²C bus needs to know anything about IO ports; and nothing on the CPU's bus/links need to know anything about bytes on the I²C bus.

还有;CPU 只是发送和接收消息.它不知道它们被发送后会发生什么,也不知道如何(例如)command = READ"消息将被转发到什么地方,也不知道哪个设备将发回command = READ_REPLY"消息.路由主要取决于消息所采用路径中每一步的逻辑.例如,PCI 主机控制器可能被配置为将 0x0000 到 0x2000 范围内的 IO 端口访问的所有消息转发到 PCI 总线,而 PCI 到 LPC 桥可能被配置为转发 0x1234 范围内的 IO 端口访问的所有消息到 0x1235 到 I²C 总线控制器.

Also; the CPU is just sending and receiving messages. It has no idea what happens to them after they're sent, and doesn't know how (e.g.) a "command = READ" message will be forwarded by what to where, and doesn't know which device will send back a "command = READ_REPLY" message. The routing mostly depends on logic at each step in the path that the message takes. For example, the PCI host controller might be configured to forward all messages for IO port accesses in the range 0x0000 to 0x2000 to a PCI bus, and the PCI to LPC bridge might be configured to forward all messages for IO port accesses in the range 0x1234 to 0x1235 to the I²C bus controller.

这篇关于关于x86 I/O口地址和IN/OUT指令的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆