* Query Regarding PCI Configuration Space Mapping and BAR Programming
@ 2025-03-19 17:57 Muni Sekhar
2025-03-19 19:15 ` Bjorn Helgaas
0 siblings, 1 reply; 5+ messages in thread
From: Muni Sekhar @ 2025-03-19 17:57 UTC (permalink / raw)
To: linux-pci
Dear Linux-PCI Maintainers,
I have a few questions regarding PCI configuration space and Base
Address Register (BAR) programming:
PCI Configuration Space Mapping:
PCI devices have standard registers (Device ID, Vendor ID, Status,
Command, etc.) in their configuration space.
These registers are mapped to memory locations. How can we determine
the exact memory location where these configuration space registers
are mapped?
Base Address Registers (BARs) Programming:
How are BAR registers programmed, and what ensures they do not
conflict with other devices mapped memory in the system?
If a BAR mapping clashes with another device’s memory range, how does
the system handle this?
Does the BIOS/firmware allocate BAR addresses, or does the OS have a
role in reconfiguring them during device initialization?
If you could provide any source code references from the Linux kernel
that handle these aspects, it would be greatly appreciated.
Looking forward to your insights.
--
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Query Regarding PCI Configuration Space Mapping and BAR Programming
2025-03-19 17:57 Query Regarding PCI Configuration Space Mapping and BAR Programming Muni Sekhar
@ 2025-03-19 19:15 ` Bjorn Helgaas
2025-03-20 1:49 ` Hans Zhang
2025-03-21 11:08 ` Muni Sekhar
0 siblings, 2 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2025-03-19 19:15 UTC (permalink / raw)
To: Muni Sekhar; +Cc: linux-pci
On Wed, Mar 19, 2025 at 11:27:07PM +0530, Muni Sekhar wrote:
> Dear Linux-PCI Maintainers,
>
> I have a few questions regarding PCI configuration space and Base
> Address Register (BAR) programming:
>
> PCI Configuration Space Mapping:
> PCI devices have standard registers (Device ID, Vendor ID, Status,
> Command, etc.) in their configuration space.
> These registers are mapped to memory locations.
In general, config registers are not mapped to memory locations.
Some systems use the ECAM mechanism for config access, which is
basically memory-mapped I/O that converts CPU memory accesses to PCI
config accesses. This mechanism is hidden inside the Linux config
accessors (pci_read_config_word(), etc), and drivers should not use
ECAM directly.
> How can we determine
> the exact memory location where these configuration space registers
> are mapped?
Drivers use pci_read_config_word() and similar interfaces to access
config registers. Userspace can use the setpci utility.
> Base Address Registers (BARs) Programming:
> How are BAR registers programmed, and what ensures they do not
> conflict with other devices mapped memory in the system?
> If a BAR mapping clashes with another device’s memory range, how does
> the system handle this?
>
> Does the BIOS/firmware allocate BAR addresses, or does the OS have a
> role in reconfiguring them during device initialization?
On x86 systems, the BIOS generally assigns BAR addresses. Linux
doesn't change these unless they are invalid. Some firmware does not
assign BARs, and generally firmware does not assign BARs for hot-added
devices. In those cases, Linux assigns them.
If Linux notices a conflict, it tries to reassign BARs to avoid the
conflict.
> If you could provide any source code references from the Linux kernel
> that handle these aspects, it would be greatly appreciated.
Here's the function that reads BARs when Linux enumerates a device:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/probe.c?id=v6.13#n176
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Query Regarding PCI Configuration Space Mapping and BAR Programming
2025-03-19 19:15 ` Bjorn Helgaas
@ 2025-03-20 1:49 ` Hans Zhang
2025-03-21 11:08 ` Muni Sekhar
1 sibling, 0 replies; 5+ messages in thread
From: Hans Zhang @ 2025-03-20 1:49 UTC (permalink / raw)
To: Bjorn Helgaas, Muni Sekhar; +Cc: linux-pci
On 2025/3/20 03:15, Bjorn Helgaas wrote:
> EXTERNAL EMAIL
>
> On Wed, Mar 19, 2025 at 11:27:07PM +0530, Muni Sekhar wrote:
>> Dear Linux-PCI Maintainers,
>>
>> I have a few questions regarding PCI configuration space and Base
>> Address Register (BAR) programming:
>>
>> PCI Configuration Space Mapping:
>> PCI devices have standard registers (Device ID, Vendor ID, Status,
>> Command, etc.) in their configuration space.
>> These registers are mapped to memory locations.
>
> In general, config registers are not mapped to memory locations.
>
Yes, this is just a segment of the address visible to the CPU, not the
actual memory.
Best regards,
Hans
> Some systems use the ECAM mechanism for config access, which is
> basically memory-mapped I/O that converts CPU memory accesses to PCI
> config accesses. This mechanism is hidden inside the Linux config
> accessors (pci_read_config_word(), etc), and drivers should not use
> ECAM directly.
>
>> How can we determine
>> the exact memory location where these configuration space registers
>> are mapped?
>
> Drivers use pci_read_config_word() and similar interfaces to access
> config registers. Userspace can use the setpci utility.
>
>> Base Address Registers (BARs) Programming:
>> How are BAR registers programmed, and what ensures they do not
>> conflict with other devices mapped memory in the system?
>> If a BAR mapping clashes with another device’s memory range, how does
>> the system handle this?
>>
>> Does the BIOS/firmware allocate BAR addresses, or does the OS have a
>> role in reconfiguring them during device initialization?
>
> On x86 systems, the BIOS generally assigns BAR addresses. Linux
> doesn't change these unless they are invalid. Some firmware does not
> assign BARs, and generally firmware does not assign BARs for hot-added
> devices. In those cases, Linux assigns them.
>
> If Linux notices a conflict, it tries to reassign BARs to avoid the
> conflict.
>
>> If you could provide any source code references from the Linux kernel
>> that handle these aspects, it would be greatly appreciated.
>
> Here's the function that reads BARs when Linux enumerates a device:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/probe.c?id=v6.13#n176
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Query Regarding PCI Configuration Space Mapping and BAR Programming
2025-03-19 19:15 ` Bjorn Helgaas
2025-03-20 1:49 ` Hans Zhang
@ 2025-03-21 11:08 ` Muni Sekhar
2025-03-21 17:30 ` Bjorn Helgaas
1 sibling, 1 reply; 5+ messages in thread
From: Muni Sekhar @ 2025-03-21 11:08 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci
On Thu, Mar 20, 2025 at 12:45 AM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> On Wed, Mar 19, 2025 at 11:27:07PM +0530, Muni Sekhar wrote:
> > Dear Linux-PCI Maintainers,
> >
> > I have a few questions regarding PCI configuration space and Base
> > Address Register (BAR) programming:
> >
> > PCI Configuration Space Mapping:
> > PCI devices have standard registers (Device ID, Vendor ID, Status,
> > Command, etc.) in their configuration space.
> > These registers are mapped to memory locations.
>
> In general, config registers are not mapped to memory locations.
>
> Some systems use the ECAM mechanism for config access, which is
> basically memory-mapped I/O that converts CPU memory accesses to PCI
> config accesses. This mechanism is hidden inside the Linux config
> accessors (pci_read_config_word(), etc), and drivers should not use
> ECAM directly.
Thanks for the clarification.
Both pci_bus_read_config_word() and pci_user_read_config_word() eventually call:
res = bus->ops->read(bus, devfn, pos, len, &data);
ret = dev->bus->ops->read(dev->bus, dev->devfn, pos, sizeof(type), &data);
This suggests that both kernel-space (pci_read_config_*()) and
user-space (pci_user_read_config_*()) accessors use the same
underlying function for configuration space access.
Could you confirm if my understanding is correct?
I tried locating the implementation of bus->ops->read() but could not
find its definition in the kernel source.Even using the function_graph
tracer, I was unable to capture the exact function being executed.
Could you point me to where this function is defined in the kernel?
>
> > How can we determine
> > the exact memory location where these configuration space registers
> > are mapped?
>
> Drivers use pci_read_config_word() and similar interfaces to access
> config registers. Userspace can use the setpci utility.
>
> > Base Address Registers (BARs) Programming:
> > How are BAR registers programmed, and what ensures they do not
> > conflict with other devices mapped memory in the system?
> > If a BAR mapping clashes with another device’s memory range, how does
> > the system handle this?
> >
> > Does the BIOS/firmware allocate BAR addresses, or does the OS have a
> > role in reconfiguring them during device initialization?
>
> On x86 systems, the BIOS generally assigns BAR addresses. Linux
> doesn't change these unless they are invalid. Some firmware does not
> assign BARs, and generally firmware does not assign BARs for hot-added
> devices. In those cases, Linux assigns them.
Once a hotplug event is detected (either via a PCIe hotplug interrupt
or an ACPI event), which kernel function is responsible for
dynamically assigning the Bus, Device, and Function (BDF) number to
the new device?
Additionally, which function in the kernel assigns Base Address
Registers (BARs) for the hotplugged device?
I appreciate your time and assistance in clarifying these points.
>
> If Linux notices a conflict, it tries to reassign BARs to avoid the
> conflict.
>
> > If you could provide any source code references from the Linux kernel
> > that handle these aspects, it would be greatly appreciated.
>
> Here's the function that reads BARs when Linux enumerates a device:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/probe.c?id=v6.13#n176
--
Thanks,
Sekhar
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Query Regarding PCI Configuration Space Mapping and BAR Programming
2025-03-21 11:08 ` Muni Sekhar
@ 2025-03-21 17:30 ` Bjorn Helgaas
0 siblings, 0 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2025-03-21 17:30 UTC (permalink / raw)
To: Muni Sekhar; +Cc: linux-pci
On Fri, Mar 21, 2025 at 04:38:09PM +0530, Muni Sekhar wrote:
> On Thu, Mar 20, 2025 at 12:45 AM Bjorn Helgaas <helgaas@kernel.org> wrote:
> > On Wed, Mar 19, 2025 at 11:27:07PM +0530, Muni Sekhar wrote:
> > > Dear Linux-PCI Maintainers,
> > >
> > > I have a few questions regarding PCI configuration space and Base
> > > Address Register (BAR) programming:
> > >
> > > PCI Configuration Space Mapping:
> > > PCI devices have standard registers (Device ID, Vendor ID, Status,
> > > Command, etc.) in their configuration space.
> > > These registers are mapped to memory locations.
> >
> > In general, config registers are not mapped to memory locations.
> >
> > Some systems use the ECAM mechanism for config access, which is
> > basically memory-mapped I/O that converts CPU memory accesses to PCI
> > config accesses. This mechanism is hidden inside the Linux config
> > accessors (pci_read_config_word(), etc), and drivers should not use
> > ECAM directly.
>
> Both pci_bus_read_config_word() and pci_user_read_config_word() eventually call:
> res = bus->ops->read(bus, devfn, pos, len, &data);
> ret = dev->bus->ops->read(dev->bus, dev->devfn, pos, sizeof(type), &data);
>
> This suggests that both kernel-space (pci_read_config_*()) and
> user-space (pci_user_read_config_*()) accessors use the same
> underlying function for configuration space access.
> Could you confirm if my understanding is correct?
That's correct.
> I tried locating the implementation of bus->ops->read() but could not
> find its definition in the kernel source.Even using the function_graph
> tracer, I was unable to capture the exact function being executed.
> Could you point me to where this function is defined in the kernel?
Each struct pci_bus has a "struct pci_ops *ops" pointer. The struct
pci_ops supplies config accessors. These are platform-dependent or
host bridge-dependent.
For x86, it's typically pci_root_ops:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/pci/common.c?id=v6.13#n72
> > > How can we determine
> > > the exact memory location where these configuration space registers
> > > are mapped?
> >
> > Drivers use pci_read_config_word() and similar interfaces to access
> > config registers. Userspace can use the setpci utility.
> >
> > > Base Address Registers (BARs) Programming:
> > > How are BAR registers programmed, and what ensures they do not
> > > conflict with other devices mapped memory in the system?
> > > If a BAR mapping clashes with another device’s memory range, how does
> > > the system handle this?
> > >
> > > Does the BIOS/firmware allocate BAR addresses, or does the OS have a
> > > role in reconfiguring them during device initialization?
> >
> > On x86 systems, the BIOS generally assigns BAR addresses. Linux
> > doesn't change these unless they are invalid. Some firmware does not
> > assign BARs, and generally firmware does not assign BARs for hot-added
> > devices. In those cases, Linux assigns them.
>
> Once a hotplug event is detected (either via a PCIe hotplug interrupt
> or an ACPI event), which kernel function is responsible for
> dynamically assigning the Bus, Device, and Function (BDF) number to
> the new device?
The kernel doesn't assign the BDF. The bus number is the bus on which
the new device lives. This is determined by the PCI host bridge and
any bridges in the path to the device. The PCI bus number below a
host bridge is determined by firmware or a native host bridge driver.
The bus numbers below other bridges are configured either by firmware
or by the Linux core setting the bridge secondary bus number. This is
mostly in pci_scan_child_bus_extend().
The device and function numbers are basically a function of the
hardware device.
> Additionally, which function in the kernel assigns Base Address
> Registers (BARs) for the hotplugged device?
Start in pciehp_configure_device(), which calls
pci_assign_unassigned_bridge_resources():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/hotplug/pciehp_pci.c?id=v6.13#n32
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-03-21 17:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-19 17:57 Query Regarding PCI Configuration Space Mapping and BAR Programming Muni Sekhar
2025-03-19 19:15 ` Bjorn Helgaas
2025-03-20 1:49 ` Hans Zhang
2025-03-21 11:08 ` Muni Sekhar
2025-03-21 17:30 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox