uart: allow UART_DEV_DBGPORT for fdt consoles

Allow fdt devices to be used as debug ports for gdb(4).

A debug console can be specified with the "freebsd,debug-path" property
in the device tree's /chosen node, or using the environment variable
hw.fdt.dbgport.

The device should be specified by its name in the device tree, for
example hw.fdt.dbgport="serial2".

PR:		251053
Submitted by:	Dmitry Salychev <dsl@mcusim.org>
Submitted by:   stevek (original patch, D5986)
Reviewed by:	andrew, mhorne
Differential Revision:	https://reviews.freebsd.org/D27422
This commit is contained in:
Mitchell Horne 2020-12-02 21:01:52 +00:00
parent f42f3b2955
commit 1c5d066a72
4 changed files with 22 additions and 15 deletions

View File

@ -175,26 +175,39 @@ uart_fdt_find_by_node(phandle_t node, int class_list)
int int
uart_cpu_fdt_probe(struct uart_class **classp, bus_space_tag_t *bst, uart_cpu_fdt_probe(struct uart_class **classp, bus_space_tag_t *bst,
bus_space_handle_t *bsh, int *baud, u_int *rclk, u_int *shiftp, bus_space_handle_t *bsh, int *baud, u_int *rclk, u_int *shiftp,
u_int *iowidthp) u_int *iowidthp, const int devtype)
{ {
const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout", const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout",
"stdin-path", "stdin", NULL}; "stdin-path", "stdin", NULL};
const char *propnames_dbgport[] = {"freebsd,debug-path", NULL};
const char **name; const char **name;
struct uart_class *class; struct uart_class *class;
phandle_t node, chosen; phandle_t node, chosen;
pcell_t br, clk, shift, iowidth; pcell_t br, clk, shift, iowidth;
char *cp; char *cp = NULL;
int err; int err;
/* Has the user forced a specific device node? */ /* Has the user forced a specific device node? */
cp = kern_getenv("hw.fdt.console"); switch (devtype) {
case UART_DEV_DBGPORT:
cp = kern_getenv("hw.fdt.dbgport");
name = propnames_dbgport;
break;
case UART_DEV_CONSOLE:
cp = kern_getenv("hw.fdt.console");
name = propnames;
break;
default:
return (ENXIO);
}
if (cp == NULL) { if (cp == NULL) {
/* /*
* Retrieve /chosen/std{in,out}. * Retrieve a node from /chosen.
*/ */
node = -1; node = -1;
if ((chosen = OF_finddevice("/chosen")) != -1) { if ((chosen = OF_finddevice("/chosen")) != -1) {
for (name = propnames; *name != NULL; name++) { for (; *name != NULL; name++) {
if (phandle_chosen_propdev(chosen, *name, if (phandle_chosen_propdev(chosen, *name,
&node) == 0) &node) == 0)
break; break;

View File

@ -100,15 +100,11 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
if (uart_cpu_acpi_spcr(devtype, di) == 0) if (uart_cpu_acpi_spcr(devtype, di) == 0)
return (0); return (0);
#endif #endif
if (devtype != UART_DEV_CONSOLE)
return (ENXIO);
err = ENXIO; err = ENXIO;
#ifdef FDT #ifdef FDT
if (err != 0) { if (err != 0) {
err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk, err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk,
&shift, &iowidth); &shift, &iowidth, devtype);
} }
#endif #endif
if (err != 0) if (err != 0)

View File

@ -87,10 +87,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
if (!err) if (!err)
return (0); return (0);
if (devtype != UART_DEV_CONSOLE) err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk,
return (ENXIO); &shift, &iowidth, devtype);
err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk, &shift, &iowidth);
if (err != 0) if (err != 0)
return (err); return (err);

View File

@ -51,7 +51,7 @@ SET_DECLARE(uart_fdt_class_set, struct ofw_compat_data );
DATA_SET(uart_fdt_class_set, data) DATA_SET(uart_fdt_class_set, data)
int uart_cpu_fdt_probe(struct uart_class **, bus_space_tag_t *, int uart_cpu_fdt_probe(struct uart_class **, bus_space_tag_t *,
bus_space_handle_t *, int *, u_int *, u_int *, u_int *); bus_space_handle_t *, int *, u_int *, u_int *, u_int *, const int);
int uart_fdt_get_clock(phandle_t node, pcell_t *cell); int uart_fdt_get_clock(phandle_t node, pcell_t *cell);
int uart_fdt_get_shift(phandle_t node, pcell_t *cell); int uart_fdt_get_shift(phandle_t node, pcell_t *cell);
int uart_fdt_get_io_width(phandle_t node, pcell_t *cell); int uart_fdt_get_io_width(phandle_t node, pcell_t *cell);