PCIE has three spaces – memory space, IO space, and configuration space, among which memory space is the commonly used space for PCIE devices, IO space is for compatibility with previous PCI devices (PCIE devices rarely use IO space now), and configuration space is the information space of PCIE devices (ID, BAR, etc. are written inside, and the host kernel program initializes by reading the configuration space information of PCIE, thus allocating PCI bus domain space to the Endpoint and other operations).
PIO does not mean reading and writing IO space; the principle is still reading and writing memory space. PIO read/write is similar to reading and writing registers, where data (generally 32bit) is written to a specific memory address each time. The operations of reading and writing PIO using official driver instructions are essentially the same as using WinDriver to operate Read/Write Memory, but the official driver limits the data length for each operation to 1DW (32bit), and data larger than 1DW will be sent multiple times.





Read 3DW data.
Note that according to the PCIE protocol’s Mwr, the maximum data size for a single Mwr/Mrd can be 4096Bytes. The above data larger than 4Bytes is sent in multiple Mwr operations, which is the driver’s approach. The timing diagram shows that the signals meet the requirements, but what about the actual data of the signals? Now let’s analyze these data by taking reading and writing 12Bytes of Memory as an example.
Write/Read Memory uses three types of messages – Mwr/Mrd/CplD. When using the PCIE IP, the underlying details can be overlooked, but parsing the received TLP and sending compliant TLP is the focus.
For Mwr/CplD, the data they carry is the data itself, and there is nothing to analyze; the focus is on the Header in the TLP. The Mrd message only has a Header, so analyzing the Header is the key.
Note that Mwr/Mrd is address routing, while CplD is ID (Bus/Device/Function) routing. This is stipulated by the protocol. The so-called routing can be simply understood as the RC being able to send the data to the target device based on the address/ID among numerous PCIE transmission paths because the kernel program initializes and allocates PCIE bus domain space for each BAR, and each BAR space address is independently mapped, while the ID uniquely determines based on (Bus/Device/Function).
The Header format for Mwr/Mrd is as follows:

The Header format for CplD is as follows:

Mwr:Header:0x0000_0000_df20_2000_0000_000f_4000_0001Data: 0x0000_0000_0000_0000_0000_0000_0102_0304Header:0x0000_0000_df20_2004_0000_000f_4000_0001Data:0x0000_0000_000_0000_0000_0000_0506_0708Header:0x0000_0000_df20_2008_0000_000f_4000_0001Data:0x0000_0000_0000_0000_0000_0000_090a_0b0c
For the Mwr Header, analyzing against the protocol format makes it easy to know that the first Header address (32bit) is df20_2000, the data length Length (in DW) is 1, and the message type [Fmt,Type]=0x40 (indicating a 3DW Mwr), byte enable [last DW BE,first DW BE]=0x0f. Other information can be filled in as needed, and it is particularly important to note that TLP is in big-endian format, [Fmt,Type]=axis_master_tdata[31:24], which actually represents the position of 0Byte, and other DW data is similar.
Mrd:Header:0x0000_0000_df20_2000_0000_000f_0000_0001Header:0x0000_0000_df20_2004_0000_000f_0000_0001Header:0x0000_0000_df20_2008_0000_000f_0000_0001
For the Mrd Header, analyzing against the protocol format makes it easy to know that the address (32bit) is df20_2000, the requested data length Length (in DW) is 1, and the message type [Fmt,Type]=0x00 (indicating a 3DW Mrd), byte enable [last DW BE,first DW BE]=0x0f. Other information can be filled in as needed, and for further understanding, refer to the PCIE protocol specification.
CplD:Header:0x0000_0000_0000_0000_0100_0004_4a00_0001Data:0x0000_0000_0000_0000_0000_0000_0102_0304Header:0x0000_0000_0000_0010_0100_0004_4a00_0001Data:0x0000_0000_0000_0000_0000_0000_0506_0708Header:0x0000_0000_0000_0020_0100_0004_4a00_0001Data:0x0000_0000_0000_0000_0000_0000_090a_0b0c
For the CplD Header, it uses ID routing, making it easy to know that the Requester ID is 0x0000, the Completer ID is 0x0100, the reply data length Length (in DW) is 1, and the message type [Fmt,Type]=0x4a (indicating CplD). The Byte Count is 0x004, TAG is 0x00, and other information can be filled in as needed. The specific meanings can be found in the PCIE protocol specification.