On 02/29/2016 04:42 AM, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requirements' [1] mentions DBG2 (Microsoft Debug
> Port Table 2) [2] as a mandatory ACPI table that specifies debug ports.
> 
> - Implement macros
> 
>       ACPI_DBG2_DECLARE(name, type, subtype, setup_fn, data_ptr)
> 
>   that defines a handler for the port of given type and subtype.
> 
> - For each declared port that is also described in the ACPI DBG2 table
>   call the provided callback.

On 02/22/2016 06:43 AM, Aleksey Makarov wrote:
> On 02/19/2016 08:20 PM, Christopher Covington wrote:
>> Can the device specified in DBG2 be used for both earlycon and KGDB? If it 
>> can only be used for one, let's make sure the choice of earlycon vs KGDB is 
>> intentional rather than accidental.
> 
> I just sent the DBG2 series.  It enables an earlycon on DBG2 port with
> an "earlycon=acpi_dbg2" option (we can discuss particular name).
> If you need KGDB on that port just support it for that port in the kernel
> (i. e. add a new instance of ACPI_DBG2_DECLARE() macros for that port, see 
> the patches)
> and change the command line options.
> I hope that is OK.  We could continue this discussion in the DBG2 thread.

This method will not work for kgdb, since kgdb doesn't actually
implement the i/o but rather runs on top of a console.


> [1] 
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://go.microsoft.com/fwlink/p/?LinkId=234837
> 
> Signed-off-by: Aleksey Makarov <[email protected]>
> ---
>  drivers/acpi/Kconfig              |  3 ++
>  drivers/acpi/Makefile             |  1 +
>  drivers/acpi/dbg2.c               | 88 
> +++++++++++++++++++++++++++++++++++++++
>  include/asm-generic/vmlinux.lds.h |  1 +
>  include/linux/acpi_dbg2.h         | 48 +++++++++++++++++++++
>  5 files changed, 141 insertions(+)
>  create mode 100644 drivers/acpi/dbg2.c
>  create mode 100644 include/linux/acpi_dbg2.h
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..660666e 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -57,6 +57,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
>  config ACPI_CCA_REQUIRED
>       bool
>  
> +config ACPI_DBG2_TABLE
> +     bool
> +
>  config ACPI_DEBUGGER
>       bool "AML debugger interface"
>       select ACPI_DEBUG
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 7395928..3b5f1ea 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -83,6 +83,7 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)              += bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)  += cppc_acpi.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
> +obj-$(CONFIG_ACPI_DBG2_TABLE)        += dbg2.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y                  := processor_driver.o
> diff --git a/drivers/acpi/dbg2.c b/drivers/acpi/dbg2.c
> new file mode 100644
> index 0000000..0f0f6ca
> --- /dev/null
> +++ b/drivers/acpi/dbg2.c
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: DBG2: " fmt
> +
> +#include <linux/acpi_dbg2.h>
> +#include <linux/acpi.h>
> +#include <linux/kernel.h>
> +
> +static const char * __init type2string(u16 type)
> +{
> +     switch (type) {
> +     case ACPI_DBG2_SERIAL_PORT:
> +             return "SERIAL";
> +     case ACPI_DBG2_1394_PORT:
> +             return "1394";
> +     case ACPI_DBG2_USB_PORT:
> +             return "USB";
> +     case ACPI_DBG2_NET_PORT:
> +             return "NET";
> +     default:
> +             return "?";
> +     }
> +}
> +
> +static const char * __init subtype2string(u16 subtype)
> +{
> +     switch (subtype) {
> +     case ACPI_DBG2_16550_COMPATIBLE:
> +             return "16550_COMPATIBLE";
> +     case ACPI_DBG2_16550_SUBSET:
> +             return "16550_SUBSET";
> +     case ACPI_DBG2_ARM_PL011:
> +             return "ARM_PL011";
> +     case ACPI_DBG2_ARM_SBSA_32BIT:
> +             return "ARM_SBSA_32BIT";
> +     case ACPI_DBG2_ARM_SBSA_GENERIC:
> +             return "ARM_SBSA_GENERIC";
> +     case ACPI_DBG2_ARM_DCC:
> +             return "ARM_DCC";
> +     case ACPI_DBG2_BCM2835:
> +             return "BCM2835";
> +     default:
> +             return "?";
> +     }
> +}
> +
> +int __init acpi_dbg2_setup(struct acpi_table_header *table, const void *data)
> +{
> +     struct acpi_table_dbg2 *dbg2 = (struct acpi_table_dbg2 *)table;
> +     struct acpi_dbg2_data *dbg2_data = (struct acpi_dbg2_data *)data;
> +     struct acpi_dbg2_device *dbg2_device, *dbg2_end;
> +     int i;
> +
> +     dbg2_device = ACPI_ADD_PTR(struct acpi_dbg2_device, dbg2,
> +                                dbg2->info_offset);
> +     dbg2_end = ACPI_ADD_PTR(struct acpi_dbg2_device, dbg2, table->length);
> +
> +     for (i = 0; i < dbg2->info_count; i++) {
> +             if (dbg2_device + 1 > dbg2_end) {
> +                     pr_err("device pointer overflows, bad table\n");
> +                     return 0;
> +             }
> +
> +             if (dbg2_device->port_type == dbg2_data->port_type &&
> +                 dbg2_device->port_subtype == dbg2_data->port_subtype) {
> +                     if (dbg2_device->port_type == ACPI_DBG2_SERIAL_PORT)
> +                             pr_info("debug port: SERIAL; subtype: %s\n",
> +                                  subtype2string(dbg2_device->port_subtype));
> +                     else
> +                             pr_info("debug port: %s\n",
> +                                     type2string(dbg2_device->port_type));
> +                     dbg2_data->setup(dbg2_device, dbg2_data->data);
> +             }
> +
> +             dbg2_device = ACPI_ADD_PTR(struct acpi_dbg2_device, dbg2_device,
> +                                        dbg2_device->length);
> +     }
> +
> +     return 0;
> +}
> diff --git a/include/asm-generic/vmlinux.lds.h 
> b/include/asm-generic/vmlinux.lds.h
> index 8f5a12a..8cc49ba 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -526,6 +526,7 @@
>       IRQCHIP_OF_MATCH_TABLE()                                        \
>       ACPI_PROBE_TABLE(irqchip)                                       \
>       ACPI_PROBE_TABLE(clksrc)                                        \
> +     ACPI_PROBE_TABLE(dbg2)                                          \
>       EARLYCON_TABLE()
>  
>  #define INIT_TEXT                                                    \
> diff --git a/include/linux/acpi_dbg2.h b/include/linux/acpi_dbg2.h
> new file mode 100644
> index 0000000..125ae7e
> --- /dev/null
> +++ b/include/linux/acpi_dbg2.h
> @@ -0,0 +1,48 @@
> +#ifndef _ACPI_DBG2_H_
> +#define _ACPI_DBG2_H_
> +
> +#ifdef CONFIG_ACPI_DBG2_TABLE
> +
> +#include <linux/kernel.h>
> +
> +struct acpi_dbg2_device;
> +struct acpi_table_header;
> +
> +struct acpi_dbg2_data {
> +     u16 port_type;
> +     u16 port_subtype;
> +     int (*setup)(struct acpi_dbg2_device *, void *);
> +     void *data;
> +};
> +
> +int acpi_dbg2_setup(struct acpi_table_header *header, const void *data);
> +
> +/**
> + * ACPI_DBG2_DECLARE() - Define handler for ACPI DBG2 port
> + * @name:    Identifier to compose name of table data
> + * @type:    Type of the port
> + * @subtype: Subtype of the port
> + * @setup_fn:        Function to be called to setup the port
> + *           (of type int (*)(struct acpi_dbg2_device *, void *);)
> + * @data_ptr:        Sideband data provided back to the driver
> + */
> +#define ACPI_DBG2_DECLARE(name, type, subtype, setup_fn, data_ptr)   \
> +     static const struct acpi_dbg2_data                              \
> +             __acpi_dbg2_data_##name __used = {                      \
> +                     .port_type = type,                              \
> +                     .port_subtype = subtype,                        \
> +                     .setup = setup_fn,                              \
> +                     .data = data_ptr,                               \
> +                };                                                   \
> +     ACPI_DECLARE_PROBE_ENTRY(dbg2, name, ACPI_SIG_DBG2,             \
> +                              acpi_dbg2_setup, &__acpi_dbg2_data_##name)
> +
> +#else
> +
> +#define ACPI_DBG2_DECLARE(name, type, subtype, setup_fn, data_ptr)   \
> +     static const void *__acpi_dbg_data_##name[]                     \
> +             __used __initdata = { (void *)setup_fn, (void *)data_ptr }
> +
> +#endif
> +
> +#endif
> 

Reply via email to