我可以用 ioread32_rep(addr, buf, 2) 代替 ioread64() 吗?

Can I use ioread32_rep(addr, buf, 2) to replace ioread64()?

我目前正在阅读 Linux 设备驱动程序 一书,找到了从 I/O 内存中读取的函数:

To read from I/O memory, use one of the following: unsigned int ioread8(void *addr); unsigned int ioread16(void *addr); unsigned int ioread32(void *addr);

If you must read or write a series of values to a given I/O memory address, you can use the repeating versions of the functions: void ioread8_rep(void *addr, void *buf, unsigned long count); void ioread16_rep(void *addr, void *buf, unsigned long count); void ioread32_rep(void *addr, void *buf, unsigned long count); These functions read or write count values from the given buf to the given addr. Note that count is expressed in the size of the data being written; ioread32_rep reads count 32-bit values starting at buf.

我在驱动程序代码中使用了 ioread64()iowrite64() 来读取和写入内存映射 IO 寄存器(8 字节)。 iowrite64() 有效,但 iowrite64() 从未运行 returns 并且我的虚拟机 (QEMU) 冻结了——我所能做的就是重新启动。我使用 GDB 进行远程调试,但没有显示任何错误消息。通过检查主机上的 dmesg,也没有显示错误消息。更详细的信息请参考this question.

因为我找不到办法找出 ioread64() 失败的原因,所以我想我可以用 ioread32_rep() 代替。

通过搜索 kernel driver code,我注意到 ioread32_rep() 的大多数用例都是设备内的一些缓冲区(例如那些处理流数据的网络设备)。如果我可以使用 ioread32_rep() 代替 ioread64() 来仅读取一个 8 字节的内存映射寄存器,这样合适吗?

如有任何想法,我们将不胜感激。

ioread32_rep(addr, buf, 2) to replace ioread64()?

在旧的 8088 CPU 上,ioread16(n)ioread8(n) 后跟 ioread8(n+1) 大致相同。

出于这个原因,我怀疑当硬件使用 32 -位总线。

但是,ioread32_rep(n,buffer,2) 将执行 ioread32(n)(而不是 (n+4))两次。

如果使用 64 位总线连接真实硬件,则 ioread64 发送的电信号根本无法使用 ioread32 模拟。如果它接受两条 ioread32 指令而不是一条 ioread64 指令,则取决于该硬件。

有些设备甚至可以区分多次调用 ioread32 和调用 ioread32_rep.

QEMU

我不知道 QEMU,但我知道 VMware(另一个虚拟机软件)有时会区分 ioread32ioread32_rep

and my virtual machine (QEMU) froze

如果您以不允许的方式访问某些 I/O 寄存器,真实硬件也可能会冻结 - 我在访问 PCI 寄存器时已经看到了。

您确定可以使用 iowrite64 访问相应的地址吗?