Page MenuHomeFreeBSD

Use PCI bus+slot for matching UARTs to consoles
AbandonedPublic

Authored by cperciva on Feb 16 2022, 12:43 AM.
Tags
None
Referenced Files
Unknown Object (File)
Feb 19 2024, 11:22 AM
Unknown Object (File)
Dec 20 2023, 7:07 AM
Unknown Object (File)
Dec 13 2023, 8:16 AM
Unknown Object (File)
Aug 15 2023, 6:09 AM
Unknown Object (File)
Aug 15 2023, 4:11 AM
Unknown Object (File)
May 3 2023, 9:06 PM
Unknown Object (File)
Feb 17 2023, 2:33 AM
Unknown Object (File)
Feb 10 2023, 7:21 PM
Subscribers

Details

Summary

Prior to this commit we only compared the bus access structure -- if
the address used to access the UART when it is probed matches the
address used to access a console (as detected earlier in the boot),
it is deemed to be the same device.

On EC2 "Graviton" systems, the console is detected via the ACPI SPCR
table with an address of 0x90A0000, but when it is discovered by
probing the PCI bus is shows up at 0x80118000. Using the PCI address
to match the UART to the console fixes userspace console logging.

Inspired by: Greg V
Sponsored by: https://www.patreon.com/cperciva
MFC after: 2 weeks

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 44473
Build 41361: arc lint + arc unit

Event Timeline

This is inspired by D19896, but I moved the matching from uart_bus_pci.c into uart_core.c to join the existing uart/console matching code. I also dropped the PCI VendorId / DeviceId since I don't think they're needed, and added a 'valid' field to the PCI data struct to avoid problems if we have a uart in slot #0 of bus #0.

I'm hesitant on this. PCI bus numbering varies from boot to boot, potentially, as devices come and go (though in theory the ACPI info should report the moved values). FreeBSD can also renumber busses (or there's been talk of this), so I'm not entirely sure about moving to using ths.

sys/dev/uart/uart_cpu.h
58

Domain? How do we know this is in the right PCI root complex?

sys/dev/uart/uart_cpu_acpi.c
186

While slot numbers are invariant, bus numbers are arbitrary. How do we know this bus number matches FreeBSD's notion of bus number?

sys/dev/uart/uart_core.c
50

This introduces a dependency on the PCI routines being compiled into the kernel. Though maybe that's a lost cause at this point.

568

I really do not like bus specific routines in the core matching code which strives to be more bus independent.
Though I don't have a better suggestion at the moment.

Thanks Warner! I wasn't sure that this was the right approach, and now I'm even more doubtful.

Another option which occurs to me is to have a quirk flag which says "there's only one device with this PCI vendor/device combination" and match the Amazon PCI serial device in that case. Certainly on existing instances there's no danger of ever having more than one such device. Thoughts?

sys/dev/uart/uart_cpu.h
58

I have no idea. SPCR tables only specify "bus" and "slot" so I assumed that was enough to uniquely identify the device...

sys/dev/uart/uart_cpu_acpi.c
186

I have no idea. I assumed that the bus number provided by the SPCR table was meaningful... otherwise why is it even there?

sys/dev/uart/uart_cpu_acpi.c
186

The numbers will probably be meaningful relative to other ACPI tables. The PSCI PCI segment will be the same as the _SEG value that pci_get_domain appears to return.

The SPCR PCI bus number likely aligns with the bus_start and bus_end we have in pci_host_generic_acpi.c. In acpi_pcib_acpi.c the former is named ap_bus, however it doesn't have a concept of the latter. In both drivers pci_get_bus will return the start address, however we may need a new ivar to read the end.

sys/dev/uart/uart_cpu_acpi.c
186

Yea. ACPI's bus numbers are consistent within the tables.
I have changes that are in flight to allow UEFI path names to be used for devices. Maybe there needs to be a similar notion, though it seems to be a bit of overkill for this. Maybe we could see if there's a ACPI handle that we can create from this and use that to match, since that will be unique. IT's a similar idea, without all the hair UEFI will need.

sys/dev/uart/uart_cpu.h
58

I think vendor/device matching should almost guarantee that it's the right device.

sys/dev/uart/uart_cpu.h
58

There's also a 'segment' that's later in the table

sys/dev/uart/uart_cpu_acpi.c
185

This should be && here. 0xffff is not a valid PCI vendor or device ID. We have symbolic constants for them: PCIV_INVALID should be used for both.

Reading the spec it talks about THE device, so I think we can assume that it will be unique.