2

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)?

Alex
  • 12,578
  • 15
  • 99
  • 195

3 Answers3

4

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.)

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
1

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.

PMF
  • 14,535
  • 3
  • 23
  • 49
  • Thanks. Do you mean by BAR and Memory Mapped IO is the same, these notions are equivalent? – Alex Nov 10 '13 at 15:51
  • 1
    Yes, they're more or less equivalent. If I remember correctly, BAR is just a pre-allocated address range that belongs to the device (and whose address is assigned when the device is first seen), while one can dynamically allocate more memory to be used for Memory Mapped IO. Depending on the hardware, the "BAR"s backing memory might be on the given device instead of the RAM, but that doesn't really matter from a programming point of view (unless you need to support Hot-Plugging). – PMF Nov 10 '13 at 16:52
  • A BAR is a register in a PCI device that defines an address range. Each BAR in a device can define either an MMIO range or an I/O range. The type and size of the address range is fixed by the device, not by software. A BAR never refers to system RAM; it always maps to address space on the device, which is usually backed by device registers, but could be backed by RAM. – prl Sep 17 '17 at 19:37
-2

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