This patch implements loader support for xhci debug and carries both the shared
code for both loader and the kernel.
I think there is still probably stuff to do in here, but I would really like
input from some other people on the overall structure and how to proceed.
Description
xhci debug requires an efi implementation with a working pcie bus and
implements the minimum of xhci required to interface with the controller and to
put a port into debug mode.
xhci debug functions as a console in loader and can be used from cons_probe
(quite early in loader/main.c:main). The cable detection process takes a long
time (on the order of a second) to run making enabling xhci debug by default an
impossible proposition.
It is possible to append "udbc" to the static console list in
efi/loader/main.c:main and a future patch will add this as a build option.
There are outstanding bugs with doing this.
Theory of Operation
udbc probes with the normal console list and allocates and creates its required
data structures during its probe/attach process.
Once probed udbc can be used as an input and output console from the C efi and
loader.
The data structures allocated for udbc are kept in a softc which is kept in
sync with the kernel. During boot the softc is bundled up and passed to the
kernel as a machine dependent module (MODINFOMD_XHCI_DEBUG).
The kernel picks up this data in parse_preload_data.
xhci debug is functional once the kernel has picked up the data structures, but
we are lacking an early pci controller to be able to do the required pcie
transactions until the xhci bus probes much later.
When used with a supported kernel, udbc is able to provide a console for
loader, with a gap between kernel start and xhci probe. xhci debug should
continue to be usable until the xhci controller is reset or the pcie bus is
reset.
Other platforms do not support its use during system or bus suspend - it isn't
clear if this is from experience or from attempts to make the problem space
smaller.
When the console wants to send data it adds the output bytes to a work_queue
and then uses the xhci trbs to submit this to the bus.
Periodically (on output and when polled by the console system) usb transfers
are driven and any input bytes are pulled from a work queue as rx data.
Usage
target: Build loader with support and deploy/install it
Connect your debug target to your debug host via a xhci debug cable (a usb3
cable with vbus removed on one end).
host: On your debug host load the udbc kernel module (freebsd 15 or later).
target: From loader menu break to a command prompt and enter
set console="udbc"
or
set console="comconsole udbc"
host: once the cable/target is detected you will have a functioning usb serial
console device
Known issues/caveats
- there is a stall during loader start up which leads to a single screen of loader menu being rendered then no more if configured as a default console in efi/loader/main.c:main or loader.conf
- usb-c cables require an adapter to enable debug adapter mode (I'm waiting for pcbs to verify this)
- the "dead time" when udbc isn't available in the kernel is at the most annoying time.