On 03/01/2016 05:49 PM, Peter Hurley wrote: > 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.
I see. Thank you for pointing this out. I don't have requirements to implement running kgdb over the serial port specified with DBG2. This feature should be supported separately. Thank you Aleksey Makarov >> [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 >> >

