aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/systracker/backtrace32.c
blob: 96ab81d0dfc28170058c4abdd02f9901a5ad6024 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kallsyms.h>
#include <linux/interrupt.h>
#include <linux/mtk_ram_console.h>
#include <linux/sched.h>
#include <asm/signal.h>
#include <mach/sync_write.h>

//defined in backstrace32.asm
extern asmlinkage void c_backtrace_ramconsole_print(unsigned long fp, int pmode);

void dump_backtrace_entry_ramconsole_print(unsigned long where, unsigned long from, unsigned long frame)
{
    char str_buf[256];

#ifdef CONFIG_KALLSYMS
    snprintf(str_buf, sizeof(str_buf), "[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
#else
    snprintf(str_buf, sizeof(str_buf), "Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
    aee_sram_fiq_log(str_buf);
}

void dump_regs(const char *fmt, const char v1, const unsigned int reg, const unsigned int reg_val)
{
    char str_buf[256];
    snprintf(str_buf, sizeof(str_buf), fmt, v1, reg, reg_val);
    aee_sram_fiq_log(str_buf);
}

static int verify_stack(unsigned long sp)
{
    if (sp < PAGE_OFFSET ||(sp > (unsigned long)high_memory && high_memory != NULL))
        return -EFAULT;

    return 0;
}

void aee_dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
    char str_buf[256];
    unsigned int fp, mode;
    int ok = 1;

    snprintf(str_buf, sizeof(str_buf), "PC is 0x%lx, LR is 0x%lx\n", regs->ARM_pc, regs->ARM_lr);
    aee_sram_fiq_log(str_buf);

    if (!tsk)
        tsk = current;

    if (regs) {
        fp = regs->ARM_fp;
        mode = processor_mode(regs);
    } else if (tsk != current) {
        fp = thread_saved_fp(tsk);
        mode = 0x10;
    } else {
        asm("mov %0, fp" : "=r" (fp) : : "cc");
        mode = 0x10;
    }

    if (!fp) {
        aee_sram_fiq_log("no frame pointer");
        ok = 0;
    } else if (verify_stack(fp)) {
        aee_sram_fiq_log("invalid frame pointer");
        ok = 0;
    } else if (fp < (unsigned long)end_of_stack(tsk))
        aee_sram_fiq_log("frame pointer underflow");
    aee_sram_fiq_log("\n");

    if (ok)
        c_backtrace_ramconsole_print(fp, mode);

}