I have an AMD processor of e2-2000 model. THis is family 0fh. According to family 0fh BKDG I have this code to read device and vendor ID:
ReadPCIConfiguration:
movq $0x80000100, %rax
movq $0x0cf8, %rdx
outl %eax, %dx # sigsegv caught here
movq $0x0cfc, %rdx
inl %dx, %eax
ret
As far as I know the algorithm to read/write PCI configuration is as follows:
- write target bus number, device number function number and offset or register number to configuration address port
- perform 1-, 2- or 4-byte r/w operation from/to configuration data port
Ports 0xcf8..0xcfb - configuration address port (doubleword)
Bits meaning:
- 31 - EnReg - enable the transaction (R/W)
- 24..31 - reserved (R/O)
- 16..23 - BusNum (R/W)
- 11..15 - DevNum (R/W)
- 8..10 - FuncNum (R/W)
- 2..7 - RegNum (R/W)
- 0..1 - Reserved (R/O)
So, I write to bus - 0, dev - 0, func - 1, reg - 00
Am I doing something wrong?
(I run the compiled and linked application from userspace, GNU/Debian "Wheezy" Linux 3.11.6)
Linux does not, by default, allow userland code to write to I/O ports. (Doing so can be quite dangerous from a security perspective.) If you’d like Linux to give your process access to the I/O ports, you have two options:
You can use the
ioperm
system call. However,ioperm
has been deprecated for some time, and Josh Triplett recently pushed a patch that allows users to remove it from the kernel. Avoidioperm
if you want your code to continue working for the forseeable future.You can read from and write to /dev/port. See mem(4). Your process will, obviously, need read and write permissions for /dev/mem; on Wheezy, that means it needs to run as root, unless you change the permissions on the device.