Page MenuHomeFreeBSD

List I/O window settings of bridges via a new -B flag in list mode.
ClosedPublic

Authored by jhb on Nov 15 2015, 8:08 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mar 22 2024, 9:27 PM
Unknown Object (File)
Mar 22 2024, 9:26 PM
Unknown Object (File)
Mar 22 2024, 9:26 PM
Unknown Object (File)
Mar 8 2024, 5:57 AM
Unknown Object (File)
Jan 4 2024, 5:24 PM
Unknown Object (File)
Jan 4 2024, 5:24 PM
Unknown Object (File)
Jan 4 2024, 5:08 PM
Unknown Object (File)
Jan 4 2024, 3:40 AM
Subscribers

Details

Summary

Add a new -B flag for use with list mode (-l) that lists details about
bridges. Currently this includes information about what resources a
bridge decodes on the upstream side for use by downstream devices including
bus numbers, I/O port resources, and memory resources. Windows and bus
ranges are enumerated for both PCI-PCI bridges and PCI-CardBus bridges.

To simplify the implementation, all enumeration is done by reading the
appropriate config space registers directly rather than querying the
bridge driver in the kernel via new ioctls. This does result in a few
limitations.

First, an unimplemented window in a PCI-PCI bridge cannot be accurately
detected as accurate detection requires writing to the window base
register. That is not safe for pciconf(8). Instead, this assumes that
any window where both the base and limit read as all zeroes is
unimplemented.

Second, the PCI-PCI bridge driver in a tree has a few quirks for
PCI-PCI bridges that use subtractive decoding but do not indicate that
via the progif config register. The list of quirks is duplicated in
pciconf's source.

Note: This was inspired by looking at issues on the Cavium ThunderX
box. This will let us more easily see what the bridges look like to
help get NEW_PCIB up and running.

Test Plan
  • Tested on both my x220 and my T40. Sample output from the T40 (which has a CardBus bridge) will be in a followup comment.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

jhb retitled this revision from to List I/O window settings of bridges via a new -B flag in list mode..
jhb updated this object.
jhb edited the test plan for this revision. (Show Details)
jhb added a reviewer: imp.
jhb added a subscriber: emaste.

Sample output:

pcib6@pci0:0:30:0:      class=0x060401 card=0x20f417aa chip=0x24488086 rev=0x93 hdr=0x01
    bus range  = 21-24
    window[1c] = type I/O Port, range 16, addr 0x5000-0x8fff, enabled
    window[20] = type Memory, range 32, addr 0xf4300000-0xf7ffffff, enabled
    window[24] = type Prefetchable Memory, range 64, addr 0xf0000000-0xf3ffffff, enabled
    decode     = ISA, subtractive
...
cbb0@pci0:21:0:0:       class=0x060700 card=0x20c617aa chip=0x04761180 rev=0xba hdr=0x02
    bus range  = 22-24
    window[1c] = type Memory, range 32, addr 0xfff00000-0xfffff, disabled
    window[24] = type Memory, range 32, addr 0xfff00000-0xfffff, disabled
    window[2c] = type I/O Port, range 16, addr 0x5000-0x50fc, enabled
    window[34] = type I/O Port, range 16, addr 0xfffc-0, disabled

(This is with rl0 inserted in cbb0 using the following resources:)

rl0: <D-Link DFE-690TXD 10/100BaseTX> port 0x5000-0x50ff irq 16 at device 0.0 on cardbus0
imp edited edge metadata.

This looks generally good. I didn't check to see that you'd dotted all the i's or crossed all the t's except for a couple of things I knew off the top of my head. Those were either good, or I had some nit-picky comments that really just boiled down to 'well, in theory this could suck, but in practice you are fine.'

usr.sbin/pciconf/pciconf.c
328 ↗(On Diff #10213)

This is generally a good assumption. x86 it's totally true for any Wintel box.
For most embedded, 0 is a special address that's either not present, or
mapped to some memory thing, or something that isn't PCI (like the
devices in the SoC).

Spec wise, 0 isn't what not implemented is. all f's is. However, 0 is a common
value that winds up there.

382 ↗(On Diff #10213)

At least one Toshiba "host bridge" is like the Intel mobile device. Likely more.

Crazy idea: This code is clearly copied from the kernel. Any chance we can do like cam does and have a libpci that's the useful bits from the kernel compiled as a userland library?

This revision is now accepted and ready to land.Nov 16 2015, 8:08 PM
usr.sbin/pciconf/pciconf.c
328 ↗(On Diff #10213)

sparc64 defines a special macro to let it not treat a BAR of zero as invalid. I imagine it might not be infeasible for it to have a window that starts at zero either.

This is a quote from the PCI-PCI Bridge 1.2 spec for the I/O window in 3.2.5.6:

If a bridge does not implement an I/O address range, then both the I/O Base and I/O
Limit registers must be implemented as read-only registers that return zero when read.

There is a similar statement about the prefetch window in 3.2.5.9.

382 ↗(On Diff #10213)

The table is a straight copy from pci_pci.c. I think a libpci that has some of pciconf in it as a userland library might be interesting. I'm less certain about a library shared with the kernel as I'm not sure there's a lot to share.

If we wanted this list to only be in one place another approach we could do would be to add
PCI quirks for this and actually hack the progif register value returned to be 0x01 instead of 0x00. That would let both pciconf and pci_pci.c "transparently" see these as subtractive bridges, but it would also mean not exposing the real register value to userland. I think I prefer being able to see the "real" thing whenever possible for debugging though.

usr.sbin/pciconf/pciconf.8
171 ↗(On Diff #10213)

This seems a bit confusing to me at first read, although I'm not sure of a clearer way to express it (just that "binary log" does not read as an obvious as log-base-2 to me).

usr.sbin/pciconf/pciconf.8
171 ↗(On Diff #10213)

I stole the phrase from something else I was reading recently. It has the same form as "natural log"at least. There is a wikipedia page for "binary logarithm", though a Google search for "binary log" mostly turns up hits for MySQL / Maria.

Looking back I really wish I had called this "width" instead of range. For the windows it would be much more convenient to refer to the decoded window as a range and use width for 16 vs 32, etc. However, I worry that renaming range now for BARs might break some bizarre script and I think windows and BARs should be consistent. (The pci bus driver calls this range for BARs internally which is why I used that name initially.)

This revision was automatically updated to reflect the committed changes.