Skip to content
Advertisement

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

I am currently going through Linux Device Drivers book and found the functions for reading from I/O memory:

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.

I used ioread64() and iowrite64() in a driver code for reading and writing to a memory-mapped IO register (8 bytes). iowrite64() works but iowrite64() function never returns and my virtual machine (QEMU) froze – all I could do was to restart. I used GDB to debug remotely but no error messages shown. By checking dmesg on host machine, no error message shown either. For more detailed information, please refer to this question.

Since I cannot find a way to figure out why ioread64() failed, I thought I may use ioread32_rep() instead.

By searching through the kernel driver code, I noticed that most of the use cases of ioread32_rep() are some buffers within the device (e.g. those network devices which handle streaming data). If I could use ioread32_rep() to replace ioread64() for merely reading an 8-byte memory mapped register, would that be appropriate?

Any ideas would be appreciated.

Advertisement

Answer

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

On an old 8088 CPU, ioread16(n) does more or less the same as ioread8(n) followed by ioread8(n+1).

For this reason, I suspect that ioread64(n) does more or less the same as ioread32(n) followed by ioread32(n+4) on a 64-bit computer when the hardware is connected using a 32-bit bus.

However, ioread32_rep(n,buffer,2) will perform ioread32(n) (and not (n+4)) twice.

If a real hardware is connected using a 64-bit bus, the electrical signals sent by ioread64 cannot be emulated using ioread32 at all. It depends on that hardware if it accepts two ioread32 instructions instead of one ioread64 instruction.

Some devices may even distinguish between calling ioread32 multiple times and calling ioread32_rep.

QEMU

I don’t know about QEMU, but I know that VMware (another virtual machine software) sometimes does distinguish between ioread32 and ioread32_rep.

and my virtual machine (QEMU) froze

Real hardware may also freeze if you access some I/O registers in a way that is not allowed – I already saw that when accessing PCI registers.

Are you sure that the corresponding address(es) can be accessed using iowrite64 at all?

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement