libpciaccess problem with new IO interface
Michael Cree
mcree at orcon.net.nz
Fri Feb 12 19:23:57 PST 2010
I have been trying out the new IO interface routines
(pci_device_open_io, etc.) in libpciaccess with a view that they might
solve the problem of MMIO on idiosyncratic architectures such as the old
Alphas.
In short, those routines do not work, at least not in the Linux sysfs
implementation.
In that implementation libpciaccess opens the sysfs PCI resource file as
a file then reads and writes (via pread and pwrite) are performed on the
resource file for IO byte, word and longword access.
The trouble with this implementation is that reading and writing the PCI
resource files in the Linux sysfs does not appear to be supported by the
kernel. Only memory mapping the resource files is supported.
If I modify the read I/O routines in the file linux-sysfs.c to report
any IO errors as in:
static uint32_t
pci_device_linux_sysfs_read32(struct pci_io_handle *handle, uint32_t port)
{
uint32_t ret;
if (pread(handle->fd, &ret, 4, port) != 4) {
fprintf(stderr, "ERROR: pread failed %d (%s)\n",errno, strerror(errno));
}
return ret;
}
then error number 5 (Input/output error) is returned. Oh, In that
routine I have also modified the offset passed to pread() to be port
only as the offset should be from the start of the resource file, not
the start of memory, methinks.
I test on amd64 architecture a Radeon RV710 card, in particular the
resource at bar 2 which is a 65535 byte region of IO ports.
Interestingly the PCI config reports this resource as memory but it is
obviously IO ports by the way the radeon video driver uses it. So for
my tests I modified pci_device_open_io() in libpciaccess to allow access
to PCI resources indicated as memory.
I attach my test code. I run it as so:
./test-libpci 2:00.0 2 7200 ff
where 2:00.0 is the Radeon card, 2 is the bar, and it will access ports
at 0x7200 through to 0x72ff (which might be recognised by some to be the
default range the radeonhd project's rhd_dump utility dumps). The
utility prints that memory range using the pci_device_map_range() and
direct memory access first, then prints it out using
pci_device_open_io() and pci_io_read32(). Output is:
Found bar 2 at 0xfdde0000 of size 65536.
7200: 0 0 0 0
7210: 0 0 0 0
7220: 0 0 0 0
7230: 0 0 65a2000 0
7240: 0 0 0 0
7250: 0 0 0 0
7260: 0 0 0 0
7270: 0 0 0 0
7280: 0 0 0 0
7290: 0 4 0 0
72a0: 0 0 0 0
72b0: 0 0 0 40
72c0: 0 0 0 0
72d0: 0 0 0 0
72e0: 0 0 0 0
72f0: 0 0 0 0
ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
ERROR: pread failed 5 (Input/output error)
7200: 7f7a 7f7a 7f7a 7f7a
And so on with more pread errors.
Cheers
Michael.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-libpci.c
Type: text/x-csrc
Size: 3238 bytes
Desc: not available
Url : http://lists.x.org/archives/xorg-devel/attachments/20100213/c0ebf262/attachment.c
More information about the xorg-devel
mailing list