Re: PCI port I/O and memory-mapped I/O

From: orbit <ordinarybit_at_proton.me>
Date: Wed, 17 Sep 2025 07:27:56 UTC

On Wednesday, September 17th, 2025 at 10:49 AM, Konstantin Belousov <kostikbel@gmail.com> wrote:

> On Tue, Sep 16, 2025 at 05:36:51PM -0700, Warner Losh wrote:
> 
> > On Tue, Sep 16, 2025 at 9:26 AM orbit ordinarybit@proton.me wrote:
> > 
> > > Hi,
> > > 
> > > I am exploring PCI device driver at the moment were I could see my FreeBSD
> > > system having this Intel gigabit NIC detected as shown in the dmesg.
> > > 
> > > em0: <Intel(R) PRO/1000 Legacy Network Connection 1.1.0> port
> > > 0xd010-0xd017 mem 0xf0000000-0xf001ffff irq 9 at device 3.0 on pci0
> > > 
> > > Can someone confirm if the "port 0xd010-0xd017" and "mem
> > > 0xf0000000-0xf001ffff" pertains respectively to the PCI port I/O space
> > > and the PCI memory space being allocated to this Intel network driver upon
> > > attachment? If yes, does the Intel network controller chip use these ranges
> 
> Yes they are. More exactly, these are BARs for PCI function.
> You may also want to look at the output of pciconf(8) -lvcb for your device.
>

I see, while checking the pciconf output, port I/O and memory-mapped I/O are enabled

em0@pci0:0:3:0: class=0x020000 card=0x001e8086 chip=0x100e8086 rev=0x02 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '82540EM Gigabit Ethernet Controller'
    class      = network
    subclass   = ethernet
    bar   [10] = type Memory, range 32, base 0xf0000000, size 131072, enabled
    bar   [18] = type I/O Port, range 32, base 0xd010, size 8, enabled
    cap 01[dc] = powerspec 2  supports D0 D3  current D0
    cap 07[e4] = PCI-X supports 2048 burst read, 1 split transaction

and looking at the code here https://cgit.freebsd.org/src/plain/sys/dev/e1000/if_em.c?h=releng/11.4 specific to the allocation of PCI resources function, I can see it uses the SYS_RES_MEMORY for memory-mapped I/O. So, given that port I/O and memory-mapped I/O are supported and enabled on this em0 device, then is it up to the driver developer to choose what bus allocation resources should be used? As I read bus_alloc_resource(9), there is also SYS_RES_IOPORT available for port I/O resource allocation.  

static int
em_allocate_pci_resources(struct adapter *adapter)
{
	device_t	dev = adapter->dev;
	int		rid;

	rid = PCIR_BAR(0);
	adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE);
	if (adapter->memory == NULL) {
		device_printf(dev, "Unable to allocate bus resource: memory\n");
		return (ENXIO);
	}
	...
	return (0);
}
 
> > > of memory addresses to map its control and status registers? If not, what
> > > are the usage of these port and memory address ranges?
> 
> This is really a question about specific device. You should consult the
> datasheet or programming manual from the vendor to see what for the BARs
> are used.
> 
> Usually indeed BARs are directly handled by hardware as the control
> and communication resource. Sometimes BARs contain registers that
> point to bus space regions where actual registers are located.
>

Alright, let me check that.

> > Yes. Those are the addresses that the BIOS assigned to them, and that
> > FreeBSD picked up. That's the hardware register file for the network
> > controller.
> > 
> > The actual physical address is typically mapped 1:1 to the PCI Bus address,
> > but sometimes an iommu remaps.
> 
> 
> At least on x86, IOMMU remaps requests from devices to system memory,
> not requests from CPU to devices.