[PATCH] powerpc: Add an in memory udbg console
Benjamin Herrenschmidt
benh at kernel.crashing.org
Mon Apr 29 19:07:17 EST 2013
On Mon, 2013-04-29 at 16:24 +1000, Alistair Popple wrote:
> This patch adds a new udbg early debug console which utilises
> statically defined input and output buffers stored within the kernel
> BSS. It is primarily designed to assist with bring up of new hardware
> which may not have a working console but which has a method of
> reading/writing kernel memory.
This probably need some memory barriers :-)
Cheers,
Ben.
> Signed-off-by: Alistair Popple <alistair at popple.id.au>
> ---
> arch/powerpc/Kconfig.debug | 23 ++++++++++
> arch/powerpc/include/asm/udbg.h | 1 +
> arch/powerpc/kernel/udbg.c | 3 ++
> arch/powerpc/sysdev/Makefile | 2 +
> arch/powerpc/sysdev/udbg_memcons.c | 85 ++++++++++++++++++++++++++++++++++++
> 5 files changed, 114 insertions(+)
> create mode 100644 arch/powerpc/sysdev/udbg_memcons.c
>
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 5416e28..863d877 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI
> Select this to enable early debugging for the PowerNV platform
> using an "hvsi" console
>
> +config PPC_EARLY_DEBUG_MEMCONS
> + bool "In memory console"
> + help
> + Select this to enable early debugging using an in memory console.
> + This console provides input and output buffers stored within the
> + kernel BSS and should be safe to select on any system. A debugger
> + can then be used to read kernel output or send input to the console.
> endchoice
>
> +config PPC_MEMCONS_OUTPUT_SIZE
> + int "In memory console output buffer size"
> + depends on PPC_EARLY_DEBUG_MEMCONS
> + default 4096
> + help
> + Selects the size of the output buffer (in bytes) of the in memory
> + console.
> +
> +config PPC_MEMCONS_INPUT_SIZE
> + int "In memory console input buffer size"
> + depends on PPC_EARLY_DEBUG_MEMCONS
> + default 128
> + help
> + Selects the size of the input buffer (in bytes) of the in memory
> + console.
> +
> config PPC_EARLY_DEBUG_OPAL
> def_bool y
> depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
> diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
> index 5a7510e..dc59091 100644
> --- a/arch/powerpc/include/asm/udbg.h
> +++ b/arch/powerpc/include/asm/udbg.h
> @@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void);
> extern void __init udbg_init_cpm(void);
> extern void __init udbg_init_usbgecko(void);
> extern void __init udbg_init_wsp(void);
> +extern void __init udbg_init_memcons(void);
> extern void __init udbg_init_ehv_bc(void);
> extern void __init udbg_init_ps3gelic(void);
> extern void __init udbg_init_debug_opal_raw(void);
> diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
> index f974849..efa5c93 100644
> --- a/arch/powerpc/kernel/udbg.c
> +++ b/arch/powerpc/kernel/udbg.c
> @@ -64,6 +64,9 @@ void __init udbg_early_init(void)
> udbg_init_usbgecko();
> #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
> udbg_init_wsp();
> +#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
> + /* In memory console */
> + udbg_init_memcons();
> #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
> udbg_init_ehv_bc();
> #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index b0a518e..99464a7 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -64,6 +64,8 @@ endif
>
> obj-$(CONFIG_PPC_SCOM) += scom.o
>
> +obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o
> +
> subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
>
> obj-$(CONFIG_PPC_XICS) += xics/
> diff --git a/arch/powerpc/sysdev/udbg_memcons.c b/arch/powerpc/sysdev/udbg_memcons.c
> new file mode 100644
> index 0000000..36f5c44
> --- /dev/null
> +++ b/arch/powerpc/sysdev/udbg_memcons.c
> @@ -0,0 +1,85 @@
> +/*
> + * A udbg backend which logs messages and reads input from in memory
> + * buffers.
> + *
> + * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
> + * Copyright (C) 2013 Alistair Popple, IBM Corp
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <asm/page.h>
> +#include <asm/processor.h>
> +#include <asm/udbg.h>
> +
> +struct memcons {
> + char *output_start;
> + char *output_pos;
> + char *output_end;
> + char *input_start;
> + char *input_pos;
> + char *input_end;
> +};
> +
> +static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
> +static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
> +
> +struct memcons memcons = {
> + .output_start = memcons_output,
> + .output_pos = memcons_output,
> + .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
> + .input_start = memcons_input,
> + .input_pos = memcons_input,
> + .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
> +};
> +
> +void memcons_putc(char c)
> +{
> + *memcons.output_pos++ = c;
> + if (memcons.output_pos >= memcons.output_end)
> + memcons.output_pos = memcons.output_start;
> +}
> +
> +int memcons_getc_poll(void)
> +{
> + char c;
> +
> + if (*memcons.input_pos) {
> + c = *memcons.input_pos;
> + *memcons.input_pos++ = 0;
> +
> + if (*memcons.input_pos == '\0' || memcons.input_pos >= memcons.input_end)
> + memcons.input_pos = memcons.input_start;
> +
> + return c;
> + }
> +
> + return -1;
> +}
> +
> +int memcons_getc(void)
> +{
> + int c;
> +
> + while (1) {
> + c = memcons_getc_poll();
> + if (c == -1)
> + cpu_relax();
> + else
> + break;
> + }
> +
> + return c;
> +}
> +
> +void udbg_init_memcons(void)
> +{
> + udbg_putc = memcons_putc;
> + udbg_getc = memcons_getc;
> + udbg_getc_poll = memcons_getc_poll;
> +}
More information about the Linuxppc-dev
mailing list