我可以用 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(另一个虚拟机软件)有时会区分 ioread32
和 ioread32_rep
。
and my virtual machine (QEMU) froze
如果您以不允许的方式访问某些 I/O 寄存器,真实硬件也可能会冻结 - 我在访问 PCI 寄存器时已经看到了。
您确定可以使用 iowrite64
访问相应的地址吗?
我目前正在阅读 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 writecount
values from the givenbuf
to the givenaddr
. Note thatcount
is expressed in the size of the data being written;ioread32_rep
readscount
32-bit values starting atbuf
.
我在驱动程序代码中使用了 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(另一个虚拟机软件)有时会区分 ioread32
和 ioread32_rep
。
and my virtual machine (QEMU) froze
如果您以不允许的方式访问某些 I/O 寄存器,真实硬件也可能会冻结 - 我在访问 PCI 寄存器时已经看到了。
您确定可以使用 iowrite64
访问相应的地址吗?