rockchip: add interrupt debugger to dump pt_regs

We install a timer interrupt and dump pt_regs when
the timeout event trigger. This help us to know cpu
state when system hang.

Change-Id: I91aa2322036ae83ac8b9cd299bef9b521995d85b
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2018-06-07 12:01:09 +08:00 committed by Kever Yang
parent 7f571427ef
commit c563adc74e
6 changed files with 92 additions and 0 deletions

View File

@ -424,6 +424,14 @@ config ROCKCHIP_SMCCC
help
This enable support for Rockchip SMC calls
config ROCKCHIP_DEBUGGER
bool "Rockchip debugger"
depends on IRQ
help
This enable support for Rockchip debugger. Now we install a timer interrupt
and dump pt_regs when the timeout event trigger. This helps us to know cpu
state when system hang.
config GICV2
bool "ARM GICv2"

View File

@ -28,6 +28,7 @@ obj-$(CONFIG_ROCKCHIP_CRC) += rockchip_crc.o
obj-$(CONFIG_ROCKCHIP_SMCCC) += rockchip_smccc.o
obj-$(CONFIG_ROCKCHIP_VENDOR_PARTITION) += vendor.o
obj-$(CONFIG_ROCKCHIP_RESOURCE_IMAGE) += resource_img.o
obj-$(CONFIG_ROCKCHIP_DEBUGGER) += rockchip_debugger.o
endif
obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o

View File

@ -25,6 +25,9 @@
#ifdef CONFIG_DRM_ROCKCHIP
#include <video_rockchip.h>
#endif
#ifdef CONFIG_ROCKCHIP_DEBUGGER
#include <rockchip_debugger.h>
#endif
#include <mmc.h>
#include <of_live.h>
#include <dm/root.h>
@ -234,6 +237,16 @@ int board_init(void)
return rk_board_init();
}
int interrupt_debugger_init(void)
{
int ret = 0;
#ifdef CONFIG_ROCKCHIP_DEBUGGER
ret = rockchip_debugger_init();
#endif
return ret;
}
int board_fdt_fixup(void *blob)
{
__maybe_unused int ret = 0;

View File

@ -0,0 +1,48 @@
/*
* (C) Copyright 2018 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <common.h>
#include <irq-generic.h>
#include <rk_timer_irq.h>
/*
* Currently, we support a timer timeout to generate a IRQ to dump cpu context.
*/
#define ROCKCHIP_DEBUGGER_TIMEOUT 5 /* seconds */
static void rockchip_debugger_isr(int irq, void *data)
{
writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
}
int rockchip_debugger_init(void)
{
uint32_t load_count0, load_count1;
uint64_t delay_c = ROCKCHIP_DEBUGGER_TIMEOUT * COUNTER_FREQUENCY;
if (!delay_c)
return 0;
printf("Enable rockchip debugger\n");
/* Disable first */
writel(0, TIMER_BASE + TIMER_CTRL);
/* Config */
load_count0 = (uint32_t)(delay_c);
load_count1 = (uint32_t)(delay_c >> 32);
writel(load_count0, TIMER_BASE + TIMER_LOAD_COUNT0);
writel(load_count1, TIMER_BASE + TIMER_LOAD_COUNT1);
writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
writel(TIMER_EN | TIMER_INT_EN, TIMER_BASE + TIMER_CTRL);
/* Request irq */
irq_install_handler(TIMER_IRQ, rockchip_debugger_isr, NULL);
irq_handler_enable(TIMER_IRQ);
return 0;
}

View File

@ -243,6 +243,11 @@ static int cpu_local_irq_disable(void)
void do_irq(struct pt_regs *pt_regs, unsigned int esr)
{
#ifdef CONFIG_ROCKCHIP_DEBUGGER
printf("\n>>> Rockchip Debugger:\n");
show_regs(pt_regs);
#endif
_do_generic_irq_handler();
}
#else
@ -272,6 +277,11 @@ static int cpu_local_irq_disable(void)
void do_irq(struct pt_regs *pt_regs)
{
#ifdef CONFIG_ROCKCHIP_DEBUGGER
printf("\n>>> Rockchp Debugger:\n");
show_regs(pt_regs);
#endif
_do_generic_irq_handler();
}
#endif

View File

@ -0,0 +1,12 @@
/*
* (C) Copyright 2018 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ROCKCHIP_DEBUGGER_H_
#define _ROCKCHIP_DEBUGGER_H_
int rockchip_debugger_init(void);
#endif