Question

Can I use I/O ports (asm: in, out instructions) to transfer data via PCI Express on modern x86_64 CPU or I can uses only BARs for MMIO(Memory Mapped I/O) and for DMA(Direct Memory Acces to memory mapped regions of PCI-E devices)?

Was it helpful?

Solution

PCI-based buses, including PCI Express, support three different address spaces: memory address space, I/O address space, and configuration address space. On x86 PCs, including those that use x86_64 CPUs, the memory address space is mapped 1:1 (more or less) with the physical address space of the CPU. The I/O address space is mapped 1:1 with the I/O address space of the CPU. The configuration address space is mapped into a fixed location in the physical address space chosen by the BIOS at boot time.

This means the x86 IN/OUT instructions can access PCI Express devices, but only if the device actually allocates part of the I/O address space. Generally speaking the only devices that do are those that are backwards compatible with ISA cards. For example a PCI Express serial card will provide an interface compatible with the 8250 UART through I/O space so that it can be used with standard serial port drivers. If it used memory mapped I/O instead the device would require its own custom driver.

Other PCE Express devices that still use I/O space include modern devices like video cards (for VGA compatibility) and SATA interfaces (for IDE compatibility). Anything new that doesn't need legacy support will use memory mapped I/O exclusively. There's no advantage other than backwards compatibility for using the I/O address space.

I should also point out that your use of BAR is incorrect. The BARs (Base Address Registers) are used by OS (or BIOS/firmware) to allocate regions of the memory and/or I/O space to the device. They exist in the configuration address space can't be used to transfer data. For example, a PCI Express serial card would have a BAR that determines where its 8450 compatible registers are mapped into I/O space. The OS would map them into a location that's not used by any other device.

While on a PC the OS would use memory mapped I/O to read and write to the BARs, a driver wouldn't. In order to transfer data the driver would access the regions of PCI memory or I/O space that have been allocated to the device through the BARs. These regions would contain registers that are used directly to transfer data, registers for setting up DMA to do the transfer or mapped to RAM on the device where the data is held.

(I should also add its possible to use part of a device's PCI configuration space as device specific registers for performing transfers, configuration or anything else. A hypothetical non-backwards compatible PCI Express serial card would probably not define any BARs at all and instead map its UART registers in its configuration space.)

OTHER TIPS

I only know of the later versions. All PCIe access code that I've written uses BARs and Memory Mapped IO. I think that I/O ports are rather rarely used today, because an interface using those is inherently really slow. The number of addressable ports is very limited, too. However, whether your specific device requires I/O ports depends on the implementation of the hardware. Basically, the architecture seems to allow I/O port based addressing also to PCIe devices, as for instance the graphics card still reserves some ports.

Be aware that directly issuing in our out commands from user code in a modern operating system will cause an protection fault, because these commands are reserved for driver code.

Yes I think they in out can be used but without it can also be used but u had to write ur own os. In windows nt like system they are protected but u can used with special privilege program to access io port. That's it

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top