In order to access PCI Configuration Space, I/O port address 0xCF8, 0xCFC is used according to various articles.
mov eax, dword 0x80000000
mov dx, word 0x0CF8
out dx, eax
mov dx, word 0x0CFC
in eax, dx
The value of eax in the above code was 0x12378086, which means vendor ID = 0x8086 and device ID = 0x1237.
Here's the question.
Q1. I've seen this method only works for PCI Configuration Space. Then, what is the other method to access PCIe Configuration Space?
"This extended configuration space cannot be accessed using the legacy PCI method (through ports 0xCF8 and 0xCFC)"
https://wiki.osdev.org/PCI_Express
But some other articles say this legacy method is compatible with PCIe Configuration Space as well.
This is confusing.
Q2. If the legacy 0xCF8, 0xCFC works with PCIe Configuration Space as well, NASM assembly source code in detail (not about linux) will be truly appreciated, because I've seen plenty of ECAM(Enhanced Configuration Access Mechanism) articles but all of them were about conceptual content.
Hardware Spec:
Motherboard : P775TM1
Processor : Intel i7 8700K
You read the quote
out of context.
Here is the quote in context (emphasis mine):
The author was talking about the part of the PCIe configuration space that starts at 0x100.
In the beginning there was a configuration space, for each PCI device function, of 256 bytes.
This space was accessed using the PCI legacy mechanism (we can ignore the fact there were two mechanisms) at ports 0xcf8 and 0xcfc.
The PCIe extended this space from 256 bytes to 4KiB and introduced a new mechanism to access the configuration space (all of it).
So, to recap:
Quoting the PCIe specification:
Its very (very) likely that Intel's CPUs will support the legacy PCI configuration mechanism for many years to come.
Internally, the part of the uncore that generates PCI configuration transactions (i.e. the System Agent/UBox) is already using only PCIe configuration transactions (i.e. the same MMCFG type that is generated by the ECAM) but the legacy software interface was not removed.
Since the PCIe root complex is within the CPU, the CPU is the only concern when it comes to legacy PCI software compatibility (legacy PCI is need a PCIe to PCI bridge that will probably expose a configuration mechanism).
In short, you can safely use the legacy PCI mechanism to access the first 256 bytes (per function) of the PCIe configuration space.
Actually, unless Intel finds a new way to configure the uncore devices, the legacy mechanism will never go away because it is required to configure the ECAM itself.
The legacy mechanism is straight forward to use, you already posted some code using it. I'm not sure what else is needed.
You can use it like this:
THIS CODE IS UNTESTED
If you were referring to the content of the configuration space (i.e. what to set), that's too broad.
You can read the datasheet of the device of interest, they usually document even the standard registers defined in the PCI specification.
Alternatively, you can read the PCI specification itself.
If you were asking how to use the ECAM, read Brendan's answer.
The only thing I can add is that, for your CPU, you can find the base of the ECAM by reading the register PCIEXBAR (offset 60h) from the (legacy) PCI configuration space of the iMC of the CPU (bus 0, dev 0, fun 0).
Something like this:
The firmware has already configured everything to use this area correctly.