hvc_dcc: bind driver to core0 for reads and writes
PATCH 1/3 hvc_dcc: bind driver to core0 for reads and writes
Some debuggers, such as Trace32 from Lauterbach GmbH, do not handle reads/writes from/to DCC on secondary cores. Each core has its own DCC device registers, so when a core reads or writes from/to DCC, it only accesses its own DCC device. Since kernel code can run on any core, every time the kernel wants to write to the console, it might write to a different DCC.
In SMP mode, Trace32 only uses the DCC on core 0. In AMP mode, it creates multiple windows, and each window shows the DCC output only from that core's DCC. The result is that console output is either lost or scattered across windows.
Selecting this option will enable code that serializes all console input and output to core 0. The DCC driver will create input and output FIFOs that all cores will use. Reads and writes from/to DCC are handled by a workqueue that runs only core 0.
--- drivers/tty/hvc/Kconfig | 21 +++++++ drivers/tty/hvc/hvc_dcc.c | 157 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 1 deletion(-)
drivers/tty/hvc/Kconfig +21 -0
@@ -95,6 +95,27 @@ config HVC_DCC driver. This console is used through a JTAG only on ARM. If you don't have a JTAG then you probably don't want this option. +config HVC_DCC_SERIALIZE_SMP + bool "Use DCC only on core 0" + depends on SMP && HVC_DCC + help + Some debuggers, such as Trace32 from Lauterbach GmbH, do not handle + reads/writes from/to DCC on more than one core. Each core has its + own DCC device registers, so when a core reads or writes from/to DCC, + it only accesses its own DCC device. Since kernel code can run on + any core, every time the kernel wants to write to the console, it + might write to a different DCC. + + In SMP mode, Trace32 only uses the DCC on core 0. In AMP mode, it + creates multiple windows, and each window shows the DCC output + only from that core's DCC. The result is that console output is + either lost or scattered across windows. + + Selecting this option will enable code that serializes all console + input and output to core 0. The DCC driver will create input and + output FIFOs that all cores will use. Reads and writes from/to DCC + are handled by a workqueue that runs only core 0. + config HVC_BFIN_JTAG bool "Blackfin JTAG console" depends on BLACKFIN
drivers/tty/hvc/hvc_dcc.c +156 -1
188 lines not on this page · raw message
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH 2/3 hvc_dcc: don't ignore errors during initialization
hvc_instantiate() and hvc_alloc() return errors if they fail, so don't ignore them.
--- drivers/tty/hvc/hvc_dcc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/tty/hvc/hvc_dcc.c +13 -4
@@ -225,20 +225,29 @@ static const struct hv_ops hvc_dcc_get_put_ops = {static int __init hvc_dcc_console_init (void ) { +int ret; + +/* This always runs on boot core */ if (!hvc_dcc_check ())return -ENODEV ; -hvc_instantiate (0 ,0 , &hvc_dcc_get_put_ops); -return 0 ; +/* Returns -1 if error */ + ret =hvc_instantiate (0 ,0 , &hvc_dcc_get_put_ops); + +return ret <0 ? -ENODEV :0 ; }console_initcall (hvc_dcc_console_init);static int __init hvc_dcc_init (void ) { +struct hvc_struct *p; + +/* This can run on any core */ if (!hvc_dcc_check ())return -ENODEV ; -hvc_alloc (0 ,0 , &hvc_dcc_get_put_ops,128 ); -return 0 ; + p =hvc_alloc (0 ,0 , &hvc_dcc_get_put_ops,128 ); + +return IS_ERR (p) ?PTR_ERR (p) :0 ; }device_initcall (hvc_dcc_init);
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v2 3/3 ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In reply to Timur TabiFrom: Abhimanyu Kapur <[email protected]>
Add support for debug communications channel based hvc console for arm64 cpus.
--- arch/arm64/include/asm/dcc.h | 52 ++++++++++++++++++++++++++++++++++++++++++++ drivers/tty/hvc/Kconfig | 2 +- drivers/tty/hvc/hvc_dcc.c | 11 ++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/dcc.h
arch/arm64/include/asm/dcc.h new file +52 -0
@@ -0,0 +1,52 @@ +/* Copyright (c) 2014 The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* A call to __dcc_getchar() or __dcc_putchar() is typically followed by +* a call to __dcc_getstatus(). We want to make sure that the CPU does +* not speculative read the DCC status before executing the read or write +* instruction. That's what the ISBs are for. +* +* The 'volatile' ensures that the compiler does not cache the status bits, +* and instead reads the DCC register every time. +*/ +#ifndef __ASM_DCC_H +#define __ASM_DCC_H + +#include <asm/barrier.h> + +static inline u32 __dcc_getstatus (void ) +{ +u32 ret; + + asmvolatile ("mrs %0, mdccsr_el0" :"=r" (ret)); + +return ret; +} + +static inline char __dcc_getchar (void ) +{ +char c; + + asmvolatile ("mrs %0, dbgdtrrx_el0" :"=r" (c)); +isb (); + +return c; +} + +static inline void __dcc_putchar (char c) +{ + asmvolatile ("msr dbgdtrtx_el0, %0" + :/* No output register */ + :"r" (c)); +isb (); +} + +#endif
drivers/tty/hvc/Kconfig +1 -1
@@ -88,7 +88,7 @@ config HVC_UDBG config HVC_DCC bool "ARM JTAG DCC console" - depends on ARM + depends on ARM || ARM64 select HVC_DRIVER help This console uses the JTAG DCC on ARM to create a console under the HVC
drivers/tty/hvc/hvc_dcc.c +11 -0
@@ -226,11 +226,22 @@ static const struct hv_ops hvc_dcc_get_put_ops = {static int __init hvc_dcc_console_init (void ) {int ret; +#ifdef CONFIG_ARM64 +u32 val; +#endif /* This always runs on boot core */ if (!hvc_dcc_check ())return -ENODEV ; +#ifdef CONFIG_ARM64 +/* Disable user-space access to DCC */ + asm("msr mdscr_el1, %0 " +"orr %0, %0, #4096 " /* TDCC */ +"msr %0, mdscr_el1 " + :"=r" (val)); +#endif +/* Returns -1 if error */ ret =hvc_instantiate (0 ,0 , &hvc_dcc_get_put_ops);
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Quoted 7 lines · Timur Tabi
Selecting this option will enable code that serializes all console input and output to core 0. The DCC driver will create input and output FIFOs that all cores will use. Reads and writes from/to DCC are handled by a workqueue that runs only core 0.
Signed-off-by Shanker Donthineni <[email protected]>
Somehow the original author got dropped when I made this patch. This patch should say:
From: Shanker Donthineni <[email protected]>
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Quoted 12 lines · Timur Tabi
Some debuggers, such as Trace32 from Lauterbach GmbH, do not handle reads/writes from/to DCC on secondary cores. Each core has its own DCC device registers, so when a core reads or writes from/to DCC, it only accesses its own DCC device. Since kernel code can run on any core, every time the kernel wants to write to the console, it might write to a different DCC.
In SMP mode, Trace32 only uses the DCC on core 0. In AMP mode, it creates multiple windows, and each window shows the DCC output only from that core's DCC. The result is that console output is either lost or scattered across windows.
Quoted 4 lines
Selecting this option will enable code that serializes all console input and output to core 0. The DCC driver will create input and output FIFOs that all cores will use. Reads and writes from/to DCC are handled by a workqueue that runs only core 0.
What happens if CPU0 is hotplugged off?
Will
Quoted 6 lines · Will Deacon
Quoted 4 lines
Quoted 4 lines
Selecting this option will enable code that serializes all console input and output to core 0. The DCC driver will create input and output FIFOs that all cores will use. Reads and writes from/to DCC are handled by a workqueue that runs only core 0.
What happens if CPU0 is hotplugged off?
I guess the whole thing just breaks.
I don't know what to say. Trace32's DCC window is latched to CPU0. If that CPU is hotplugged off, then I don't think there's a mechanism for Trace32 to migrate to another CPU. It will broken no matter what.
That's why this feature is disabled by default. If you're working on an SMP ARM system and using Trace32, you will need this patch. It might be possible for Lauterbach to fix Trace32 to provide this feature internally in some situations (e.g. SMP mode where there's one window for all cores), but not in every situation.
I can add a "depends on !CPU_HOTPLUG" to the Kconfig, but I think that's overkill. This is really a "use it if you need it" patch, and DCC is used mostly for debugging.
Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.