PCI Access Clarification
Posted: Mon Mar 30, 2020 10:53 pm
Hey everyone, I've been testing some stuff out recently and I'm back with another clarification question if anyone has time to help out. I'm working on a pci device and feel like I'm missing something when it comes to accessing it. I was able to find my device by locating its vendor_id by looping through all the devices and using ports 0xCF8 and 0xCFC. According to the devices documentation, it stores its base addresses in these locations.
When I try to read the value using the memory base at 0xFC00_0F00 I get a page fault exception because I don't have a page mapped. I tried mapping a page for that address range and was able to successfully read the memory location, but it didn't give the correct result.
I'm not really sure where to look next for debugging this since this is my first time trying to read from a pci device. I think I'm probably doing something wrong in my calculations, or maybe my understanding of how the base addresses need to be used is incorrect. Any help, or suggestions, or if you notice something obvious I'm doing wrong would be greatly appreciated.
Using that info, I was able to determine locations that should be at these locations.Memory aperture base address (PCI configuration space offset 0x10).
The memory aperture base address value at offset 0x10 within the PCI configuration space
is in bits [31:26] of its DWORD. Therefore, to isolate the proper bits, the value should be
logically ANDed with 0xFC000000.
Register aperture base address (PCI configuration space offset 0x18).
The register aperture base value resides in bits [31:14] of its DWORD (at offset 0x18).
Therefore, to isolate the proper bits, the value should be logically ANDed with
0xFFFFC000.
I/O base address (PCI configuration space offset 0x14).
For the I/O base aperture, the actual value is within bits [31:8] of its DWORD (at offset
0x14). Therefore, to isolate the proper bits, the value should be logically ANDed with
0xFFFFFF00.
I wanted to test these mappings by trying to read the vendor id from one of the read only pci configuration copy registers. According to the documentation the register should be accessible with these criteria.memory_base = 0xFC00_0000
io_base = 0xC000
register_base = 0xFEBF000
If I understand that, does that mean I should be able to access it from 0xCF00 using ports, or 0xFC00_0F00 using memory mapped i/o? The value I'm looking for is 0x1002. When I try to read it using a port, I just get 0xFFFF returned, which I assume is what qemu returns if something about that read wasn't valid.VENDOR_ID CFG:0x0000 MMR:0x0F00 MMR_1:0x0F00 IND:0x0F00
When I try to read the value using the memory base at 0xFC00_0F00 I get a page fault exception because I don't have a page mapped. I tried mapping a page for that address range and was able to successfully read the memory location, but it didn't give the correct result.
I'm not really sure where to look next for debugging this since this is my first time trying to read from a pci device. I think I'm probably doing something wrong in my calculations, or maybe my understanding of how the base addresses need to be used is incorrect. Any help, or suggestions, or if you notice something obvious I'm doing wrong would be greatly appreciated.