mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-31 10:13:04 +09:00
PD#SWPL-6028 Problem: enable ftrce in ramoops for new tm2 dtbs Solution: enable ftrce in ramoops for new tm2 dtbs Verify: verified ok Change-Id: Ia7ee3b11784a69ef7d6b7671f9ad75c14ae477f7 Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com> Signed-off-by: Luan Yuan <luan.yuan@amlogic.com> debug: improve ftrace_ramoops for io trace [2/2] PD#SWPL-6028 Problem: improve ftrace_ramoops to debug bus hang Solution: 1. in uboot setenv initargs $initargs ramoops_io_en=1 loglevel=3;save;reset 2. in linux command line: cat /sys/module/kernel/parameters/ramoops_io_en to check if success. 3. after watchdog reboot, get trace data with: cat /sys/fs/pstore/ftrace-ramoops-0 Verify: TL1 x301 Change-Id: If1a2582b40a3ded31eedef5355eb0b8a5bf495c3 Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com> debug: save irqflag locally when ftrace_ramoops io [1/1] PD#SWPL-6028 Problem: save irqflag locally when ftrace_ramoops io Solution: save irqflag locally when ftrace_ramoops io Verify: TL1 x301 Change-Id: I6df9700cceaccc97dc983d88ada73197a6968f73 Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com> debug: do not print old_size when ftrace_size is 0 [1/1] PD#SWPL-6028 Problem: do not print old_size when ftrace_size is 0 Solution: do not print old_size when ftrace_size is 0 Verify: TL1 x301 Change-Id: I00a71c83fede14a2606c5e7eea5d8c4fdaeb5553 Signed-off-by: Jianxin Pan <jianxin.pan@amlogic.com> dts: change ftrace-size. [1/1] PD#SWPL-6028 Problem: add ftrace-size. Solution: add ftrace-size. Verify: no. Change-Id: I42d34edf665632dfe29d04df192964238b8e3df8 Signed-off-by: Jianxiong Pan <jianxiong.pan@amlogic.com> Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
148 lines
3.9 KiB
C
148 lines
3.9 KiB
C
/*
|
|
* drivers/amlogic/debug/debug_ftrace_ramoops.c
|
|
*
|
|
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/compiler.h>
|
|
#include <linux/irqflags.h>
|
|
#include <linux/percpu.h>
|
|
#include <linux/smp.h>
|
|
#include <linux/atomic.h>
|
|
#include <linux/types.h>
|
|
#include <linux/ftrace.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/err.h>
|
|
#include <linux/amlogic/debug_ftrace_ramoops.h>
|
|
#include <../../../fs/pstore/internal.h>
|
|
#include <linux/trace_clock.h>
|
|
#include <linux/percpu.h>
|
|
#include <linux/moduleparam.h>
|
|
|
|
static DEFINE_PER_CPU(int, en);
|
|
|
|
#define IRQ_D 1
|
|
|
|
unsigned int dump_iomap;
|
|
core_param(dump_iomap, dump_iomap, uint, 0664);
|
|
|
|
unsigned int ramoops_ftrace_en;
|
|
EXPORT_SYMBOL(ramoops_ftrace_en);
|
|
|
|
int ramoops_io_en;
|
|
EXPORT_SYMBOL(ramoops_io_en);
|
|
core_param(ramoops_io_en, ramoops_io_en, int, 0664);
|
|
|
|
const char *record_name[PSTORE_FLAG_IO_MAX] = {
|
|
"NULL",
|
|
"FUNC",
|
|
"IO-R",
|
|
"IO-W",
|
|
"IO-R-E",
|
|
"IO-W-E",
|
|
};
|
|
|
|
void notrace pstore_ftrace_save(struct pstore_ftrace_record *rec)
|
|
{
|
|
int cpu = raw_smp_processor_id();
|
|
|
|
if (unlikely(oops_in_progress) || unlikely(per_cpu(en, cpu)))
|
|
return;
|
|
per_cpu(en, cpu) = 1;
|
|
pstore_ftrace_encode_cpu(rec, cpu);
|
|
strlcpy(rec->comm, current->comm, sizeof(rec->comm) - 1);
|
|
rec->pid = current->pid;
|
|
rec->time = trace_clock_local();
|
|
psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)rec,
|
|
0, sizeof(*rec), psinfo);
|
|
per_cpu(en, cpu) = 0;
|
|
}
|
|
EXPORT_SYMBOL(pstore_ftrace_save);
|
|
|
|
static void notrace pstore_function_dump(struct pstore_ftrace_record *rec,
|
|
struct seq_file *s)
|
|
{
|
|
unsigned long sec = 0, ms = 0;
|
|
unsigned long long time = rec->time;
|
|
|
|
do_div(time, 1000000);
|
|
sec = (unsigned long)time / 1000;
|
|
ms = (unsigned long)time % 1000;
|
|
seq_printf(s, "[%04ld.%03ld@%d] <%5d-%s> <%pf <- %pF>\n",
|
|
sec, ms, pstore_ftrace_decode_cpu(rec), rec->pid, rec->comm,
|
|
(void *)rec->ip, (void *)rec->parent_ip);
|
|
}
|
|
|
|
void notrace pstore_io_rw_dump(struct pstore_ftrace_record *rec,
|
|
struct seq_file *s)
|
|
{
|
|
unsigned long sec = 0, ms = 0;
|
|
unsigned long long time = rec->time;
|
|
unsigned int cpu = pstore_ftrace_decode_cpu(rec);
|
|
|
|
do_div(time, 1000000);
|
|
sec = (unsigned long)time / 1000;
|
|
ms = (unsigned long)time % 1000;
|
|
seq_printf(s, "[%04ld.%03ld@%d] <%5d-%6s> <%6s %08lx-%8lx> <%pf <- %pF>\n",
|
|
sec, ms, cpu, rec->pid, rec->comm, record_name[rec->flag],
|
|
rec->val1, (rec->flag == PSTORE_FLAG_IO_W) ? rec->val2 : 0,
|
|
(void *)rec->ip, (void *)rec->parent_ip);
|
|
}
|
|
|
|
void notrace pstore_ftrace_dump(struct pstore_ftrace_record *rec,
|
|
struct seq_file *s)
|
|
{
|
|
switch (rec->flag & PSTORE_FLAG_MASK) {
|
|
case PSTORE_FLAG_FUNC:
|
|
pstore_function_dump(rec, s);
|
|
break;
|
|
case PSTORE_FLAG_IO_R:
|
|
case PSTORE_FLAG_IO_W:
|
|
case PSTORE_FLAG_IO_W_END:
|
|
case PSTORE_FLAG_IO_R_END:
|
|
pstore_io_rw_dump(rec, s);
|
|
break;
|
|
default:
|
|
seq_printf(s, "Unknown Msg:%x\n", rec->flag);
|
|
}
|
|
}
|
|
|
|
void notrace pstore_io_save(unsigned long reg, unsigned long val,
|
|
unsigned long parant, unsigned int flag,
|
|
unsigned long *irq_flag)
|
|
{
|
|
struct pstore_ftrace_record rec;
|
|
|
|
if (!ramoops_ftrace_en || !ramoops_io_en)
|
|
return;
|
|
|
|
if ((flag == PSTORE_FLAG_IO_R || flag == PSTORE_FLAG_IO_W) && IRQ_D)
|
|
local_irq_save(*irq_flag);
|
|
|
|
rec.ip = CALLER_ADDR0;
|
|
rec.parent_ip = parant;
|
|
rec.flag = flag;
|
|
rec.val1 = reg;
|
|
rec.val2 = val;
|
|
pstore_ftrace_save(&rec);
|
|
|
|
if ((flag == PSTORE_FLAG_IO_R_END || flag == PSTORE_FLAG_IO_W_END) &&
|
|
IRQ_D)
|
|
local_irq_restore(*irq_flag);
|
|
}
|
|
EXPORT_SYMBOL(pstore_io_save);
|
|
|