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

查看:274
本文介绍了关于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).

如下图所示:

As in this image:

,到目前为止,现代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 cpus),以下是我的问题:

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地址?

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.

(btw,我不知道),它如何知道该I / O地址属于PCI还是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内置在同一芯片中,这意味着(除非您是像Intel这样的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总线接收字节。 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端口空间,地址= 0x1234,大小= 1个字节,data = 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.

下一步; (由于 al,dx 指令),CPU可能会发送另一条消息,内容为 command = READ,space = IO port space,address = 0x1234,大小= 1个字节。该消息将遵循与前一条相同的路径(因为地址和地址空间相同),并最终到达I²C总线控制器。 I²C总线控制器可能会解码该消息,并意识到该消息正在请求从I²C总线控制器的内部缓冲寄存器中读取(该寄存器以前的值为0x78);因此I²C总线控制器发送回消息 命令= READ_REPLY,空间= IO端口空间,地址= 0x1234,大小= 1字节,数据= 0x78 。此回复消息将返回给CPU(再次使用相同的路径,但方向相反-例如,从PCI到LPC桥,再到PCI主机控制器,再到CPU)。当CPU获得答复时,它可以完成引起它的原始指令(例如,将 al 设置为 READ_reply消息中的值以完成 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天全站免登陆