内存映射 IO - IO 设备如何知道值已更改?

Memory mapped IO - how does IO device know value has changed?

IO 设备如何知道内存中属于它的值在 memory mapped IO 中发生了变化?

例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA 设备如何知道? VGA 设备是否不断轮询内存位置?或者 CPU 是否会在设备更改值时以某种方式通知设备(如果是,如何通知?)?

示例架构是 MIPS。鉴于 MIPS instruction set 没有 inout 指令,我不明白它如何与示例中的 VGA 设备通信(更改时)。再比如ARM架构。

在memory-mappedI/O中,对设备的内存区域执行内存read/write将导致CPU与设备执行交易fetch/store 该值——直接通过 CPU 的内存总线,或通过辅助总线(例如 ARM 系统上的 AHB/APB)。此内存事务直接通知设备值正在更改;无需单独通知。

您假设 memory-mapped I/O 由普通 RAM 映射。 事实并非如此。 事实上,这些设备的行为方式可能与真实内存完全不同!例如,典型的 UART 或 SPI 设备实现可能有一个数据寄存器,可以写入该数据寄存器以传输数据,或从中读取以检索接收到的数据。同样,中断寄存器具有 "clear on read" 或 "write 1 to clear" 语义的情况并不少见。

它的价值:在实践中,许多帧缓冲区图形实现实际上就像普通内存一样。不同之处在于内存存储在 dual-ported RAM(或 time-multiplexed 总线)中,视频 RAMDAC 不断读取该内存以将其内容传输到连接的显示器。

指定为memory-mapped I/O (MMIO) 的物理地址space 的区域未映射到主内存(系统内存);它被映射到 I/O 寄存器,这些寄存器是 I/O 设备的物理部分。

为了确定如何处理内存访问(读取或写入),处理器首先检查目标内存地址所属区域的类型。在任何 MIPS 处理器中,至少有两种类型:Uncached 和 Cached。 MMIO 区域始终未缓存。未缓存的内存访问请求直接发送到主内存控制器,而不检查或影响任何缓存。但是,I/O 未缓存内存访问请求被发送到 I/O 控制器,最终请求将到达目标 I/O 设备。

现在 CPU 和 I/O 设备如何相互通信完全由 I/O 设备本身指定。因此,I/O 设备将有一个规范,讨论有多少 I/O 寄存器以及应如何使用它们中的每一个。 I/O 寄存器可用于保存状态标志、控制标志、要由 CPU 读取或写入的数据或它们的某种组合。请注意,由于 I/O 寄存器在物理上是 I/O 设备的一部分,因此可以设计 I/O 设备,以便它可以检测何时读取或写入其任何寄存器并根据需要采取相应的行动。

I/O 设备可以向 CPU 发送中断,以通知它某些数据可用或者它可能出于某种原因需要注意。 CPU 还可以通过检查某些状态标志来频繁轮询 I/O 设备,然后采取相应的措施。