Skip to content

Commit

Permalink
Merge branch 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/tip

Pull x86 debug updates from Ingo Molnar:
 "The biggest update is the addition of USB3 debug port based
  early-console.

  Greg was fine with the USB changes and with the routing of these
  patches:

    https://www.spinics.net/lists/linux-usb/msg155093.html"

* 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  usb/doc: Add document for USB3 debug port usage
  usb/serial: Add DBC debug device support to usb_debug
  x86/earlyprintk: Add support for earlyprintk via USB3 debug port
  usb/early: Add driver for xhci debug capability
  x86/timers: Add simple udelay calibration
  • Loading branch information
torvalds committed May 2, 2017
2 parents 2cc12e2 + 1b32627 commit 7d6a31c
Show file tree
Hide file tree
Showing 11 changed files with 1,438 additions and 6 deletions.
1 change: 1 addition & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
earlyprintk=pciserial,bus:device.function[,baudrate]
earlyprintk=xdbc[xhciController#]

earlyprintk is useful when the kernel crashes before
the normal console is initialized. It is not enabled by
Expand Down
100 changes: 100 additions & 0 deletions Documentation/usb/usb3-debug-port.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
===============
USB3 debug port
===============

:Author: Lu Baolu <[email protected]>
:Date: March 2017

GENERAL
=======

This is a HOWTO for using the USB3 debug port on x86 systems.

Before using any kernel debugging functionality based on USB3
debug port, you need to::

1) check whether any USB3 debug port is available in
your system;
2) check which port is used for debugging purposes;
3) have a USB 3.0 super-speed A-to-A debugging cable.

INTRODUCTION
============

The xHCI debug capability (DbC) is an optional but standalone
functionality provided by the xHCI host controller. The xHCI
specification describes DbC in the section 7.6.

When DbC is initialized and enabled, it will present a debug
device through the debug port (normally the first USB3
super-speed port). The debug device is fully compliant with
the USB framework and provides the equivalent of a very high
performance full-duplex serial link between the debug target
(the system under debugging) and a debug host.

EARLY PRINTK
============

DbC has been designed to log early printk messages. One use for
this feature is kernel debugging. For example, when your machine
crashes very early before the regular console code is initialized.
Other uses include simpler, lockless logging instead of a full-
blown printk console driver and klogd.

On the debug target system, you need to customize a debugging
kernel with CONFIG_EARLY_PRINTK_USB_XDBC enabled. And, add below
kernel boot parameter::

"earlyprintk=xdbc"

If there are multiple xHCI controllers in your system, you can
append a host contoller index to this kernel parameter. This
index starts from 0.

Current design doesn't support DbC runtime suspend/resume. As
the result, you'd better disable runtime power management for
USB subsystem by adding below kernel boot parameter::

"usbcore.autosuspend=-1"

Before starting the debug target, you should connect the debug
port to a USB port (root port or port of any external hub) on
the debug host. The cable used to connect these two ports
should be a USB 3.0 super-speed A-to-A debugging cable.

During early boot of the debug target, DbC will be detected and
initialized. After initialization, the debug host should be able
to enumerate the debug device in debug target. The debug host
will then bind the debug device with the usb_debug driver module
and create the /dev/ttyUSB device.

If the debug device enumeration goes smoothly, you should be able
to see below kernel messages on the debug host::

# tail -f /var/log/kern.log
[ 1815.983374] usb 4-3: new SuperSpeed USB device number 4 using xhci_hcd
[ 1815.999595] usb 4-3: LPM exit latency is zeroed, disabling LPM.
[ 1815.999899] usb 4-3: New USB device found, idVendor=1d6b, idProduct=0004
[ 1815.999902] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1815.999903] usb 4-3: Product: Remote GDB
[ 1815.999904] usb 4-3: Manufacturer: Linux
[ 1815.999905] usb 4-3: SerialNumber: 0001
[ 1816.000240] usb_debug 4-3:1.0: xhci_dbc converter detected
[ 1816.000360] usb 4-3: xhci_dbc converter now attached to ttyUSB0

You can use any communication program, for example minicom, to
read and view the messages. Below simple bash scripts can help
you to check the sanity of the setup.

.. code-block:: sh
===== start of bash scripts =============
#!/bin/bash
while true ; do
while [ ! -d /sys/class/tty/ttyUSB0 ] ; do
:
done
cat /dev/ttyUSB0
done
===== end of bash scripts ===============
27 changes: 25 additions & 2 deletions arch/x86/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ config TRACE_IRQFLAGS_SUPPORT

source "lib/Kconfig.debug"

config EARLY_PRINTK_USB
bool

config X86_VERBOSE_BOOTUP
bool "Enable verbose x86 bootup info messages"
default y
Expand All @@ -23,19 +26,20 @@ config EARLY_PRINTK
This is useful for kernel debugging when your machine crashes very
early before the console code is initialized. For normal operation
it is not recommended because it looks ugly and doesn't cooperate
with klogd/syslogd or the X server. You should normally N here,
with klogd/syslogd or the X server. You should normally say N here,
unless you want to debug such a crash.

config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
depends on EARLY_PRINTK && PCI
select EARLY_PRINTK_USB
---help---
Write kernel log output directly into the EHCI debug port.

This is useful for kernel debugging when your machine crashes very
early before the console code is initialized. For normal operation
it is not recommended because it looks ugly and doesn't cooperate
with klogd/syslogd or the X server. You should normally N here,
with klogd/syslogd or the X server. You should normally say N here,
unless you want to debug such a crash. You need usb debug device.

config EARLY_PRINTK_EFI
Expand All @@ -48,6 +52,25 @@ config EARLY_PRINTK_EFI
This is useful for kernel debugging when your machine crashes very
early before the console code is initialized.

config EARLY_PRINTK_USB_XDBC
bool "Early printk via the xHCI debug port"
depends on EARLY_PRINTK && PCI
select EARLY_PRINTK_USB
---help---
Write kernel log output directly into the xHCI debug port.

One use for this feature is kernel debugging, for example when your
machine crashes very early before the regular console code is
initialized. Other uses include simpler, lockless logging instead of
a full-blown printk console driver + klogd.

For normal production environments this is normally not recommended,
because it doesn't feed events into klogd/syslogd and doesn't try to
print anything on the screen.

You should normally say N here, unless you want to debug early
crashes or need a very simple printk logging facility.

config X86_PTDUMP_CORE
def_bool n

Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/intel-mid.h>
#include <asm/pgtable.h>
#include <linux/usb/ehci_def.h>
#include <linux/usb/xhci-dbgp.h>
#include <linux/efi.h>
#include <asm/efi.h>
#include <asm/pci_x86.h>
Expand Down Expand Up @@ -381,6 +382,10 @@ static int __init setup_early_printk(char *buf)
if (!strncmp(buf, "efi", 3))
early_console_register(&early_efi_console, keep);
#endif
#ifdef CONFIG_EARLY_PRINTK_USB_XDBC
if (!strncmp(buf, "xdbc", 4))
early_xdbc_parse_parameter(buf + 4);
#endif

buf++;
}
Expand Down
26 changes: 26 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <linux/tboot.h>
#include <linux/jiffies.h>

#include <linux/usb/xhci-dbgp.h>
#include <video/edid.h>

#include <asm/mtrr.h>
Expand Down Expand Up @@ -811,6 +812,26 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
return 0;
}

static void __init simple_udelay_calibration(void)
{
unsigned int tsc_khz, cpu_khz;
unsigned long lpj;

if (!boot_cpu_has(X86_FEATURE_TSC))
return;

cpu_khz = x86_platform.calibrate_cpu();
tsc_khz = x86_platform.calibrate_tsc();

tsc_khz = tsc_khz ? : cpu_khz;
if (!tsc_khz)
return;

lpj = tsc_khz * 1000;
do_div(lpj, HZ);
loops_per_jiffy = lpj;
}

/*
* Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures
Expand Down Expand Up @@ -959,6 +980,8 @@ void __init setup_arch(char **cmdline_p)
*/
x86_configure_nx();

simple_udelay_calibration();

parse_early_param();

#ifdef CONFIG_MEMORY_HOTPLUG
Expand Down Expand Up @@ -1095,6 +1118,9 @@ void __init setup_arch(char **cmdline_p)
memblock_set_current_limit(ISA_END_ADDRESS);
e820__memblock_setup();

if (!early_xdbc_setup_hardware())
early_xdbc_register_console();

reserve_bios_regions();

if (efi_enabled(EFI_MEMMAP)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/

obj-$(CONFIG_USB) += misc/
obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/
obj-$(CONFIG_EARLY_PRINTK_USB) += early/

obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/early/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
#

obj-$(CONFIG_EARLY_PRINTK_DBGP) += ehci-dbgp.o
obj-$(CONFIG_EARLY_PRINTK_USB_XDBC) += xhci-dbc.o
Loading

0 comments on commit 7d6a31c

Please sign in to comment.