Re: git: 097bd33dd7a6 - main - uart: DBG2 support to find the debug uart

From: Jessica Clarke <jrtc27_at_freebsd.org>
Date: Fri, 17 May 2024 16:18:09 UTC
On 17 May 2024, at 17:12, Andrew Turner <andrew@FreeBSD.org> wrote:
> 
> The branch main has been updated by andrew:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=097bd33dd7a687cd3ad7fd4bc7ededa3b9e00e28
> 
> commit 097bd33dd7a687cd3ad7fd4bc7ededa3b9e00e28
> Author:     Andrew Turner <andrew@FreeBSD.org>
> AuthorDate: 2024-03-12 18:15:29 +0000
> Commit:     Andrew Turner <andrew@FreeBSD.org>
> CommitDate: 2024-05-17 16:07:15 +0000
> 
>    uart: DBG2 support to find the debug uart
> 
>    The Debug Port Table 2 (DBG2) contains information on which devices
>    can be used for debugging purposes.
> 
>    Add support to the uart driver to use the DBG2 table when enabled from
>    loader.
> 
>    Sponsored by:   Arm Ltd
>    Differential Revision:  https://reviews.freebsd.org/D44359
> ---
> sys/dev/uart/uart_cpu_acpi.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 83 insertions(+)
> 
> diff --git a/sys/dev/uart/uart_cpu_acpi.c b/sys/dev/uart/uart_cpu_acpi.c
> index 9c9ffc1e3194..53fe459e64a1 100644
> --- a/sys/dev/uart/uart_cpu_acpi.c
> +++ b/sys/dev/uart/uart_cpu_acpi.c
> @@ -210,12 +210,95 @@ out:
> return (error);
> }
> 
> +static int
> +uart_cpu_acpi_dbg2(struct uart_devinfo *di)
> +{
> + vm_paddr_t dbg2_physaddr;
> + ACPI_TABLE_DBG2 *dbg2;
> + ACPI_DBG2_DEVICE *dbg2_dev;
> + ACPI_GENERIC_ADDRESS *base_address;
> + struct acpi_uart_compat_data *cd;
> + struct uart_class *class;
> + int error;
> + bool found;
> +
> + /* Look for the SPCR table. */
> + dbg2_physaddr = acpi_find_table(ACPI_SIG_DBG2);
> + if (dbg2_physaddr == 0)
> + return (ENXIO);
> +
> + dbg2 = acpi_map_table(dbg2_physaddr, ACPI_SIG_DBG2);
> + if (dbg2 == NULL) {
> + printf("Unable to map the DBG2 table!\n");
> + return (ENXIO);
> + }
> +
> + error = ENXIO;
> +
> + dbg2_dev = (ACPI_DBG2_DEVICE *)((vm_offset_t)dbg2 + dbg2->InfoOffset);
> + found = false;
> + while ((vm_offset_t)dbg2_dev + dbg2_dev->Length <=

Can this please use uintptr_t or char * for pointer arithmetic rather
than the not-a-pointer vm_offset_t throughout?

Jess

> +    (vm_offset_t)dbg2 + dbg2->Header.Length) {
> + if (dbg2_dev->PortType != ACPI_DBG2_SERIAL_PORT)
> + goto next;
> +
> + /* XXX: Too restrictive? */
> + if (dbg2_dev->RegisterCount != 1)
> + goto next;
> +
> + cd = uart_cpu_acpi_scan(dbg2_dev->PortSubtype);
> + if (cd == NULL)
> + goto next;
> +
> + class = cd->cd_class;
> + base_address = (ACPI_GENERIC_ADDRESS *)
> +    ((vm_offset_t)dbg2_dev + dbg2_dev->BaseAddressOffset);
> +
> + error = uart_cpu_acpi_init_devinfo(di, class, base_address);
> + if (error == 0) {
> + found = true;
> + break;
> + }
> +
> +next:
> + dbg2_dev = (ACPI_DBG2_DEVICE *)
> +    ((vm_offset_t)dbg2_dev + dbg2_dev->Length);
> + }
> + if (!found)
> + goto out;
> +
> + /* XXX: Find the correct value */
> + di->baudrate = 115200;
> +
> + /* Apply device tweaks. */
> + if ((cd->cd_quirks & UART_F_IGNORE_SPCR_REGSHFT) ==
> +    UART_F_IGNORE_SPCR_REGSHFT) {
> + di->bas.regshft = cd->cd_regshft;
> + }
> +
> + /* Create a bus space handle. */
> + error = bus_space_map(di->bas.bst, base_address->Address,
> +    uart_getrange(class), 0, &di->bas.bsh);
> +
> +out:
> + acpi_unmap_table(dbg2);
> + return (error);
> +}
> +
> int
> uart_cpu_acpi_setup(int devtype, struct uart_devinfo *di)
> {
> + char *cp;
> +
> switch(devtype) {
> case UART_DEV_CONSOLE:
> return (uart_cpu_acpi_spcr(devtype, di));
> + case UART_DEV_DBGPORT:
> + /* Use the Debug Port Table 2 (DBG2) to find a debug uart */
> + cp = kern_getenv("hw.acpi.enable_dbg2");
> + if (cp != NULL && strcasecmp(cp, "yes") == 0)
> + return (uart_cpu_acpi_dbg2(di));
> + break;
> }
> return (ENXIO);
> }