301 lines
9.3 KiB
C
Executable file
301 lines
9.3 KiB
C
Executable file
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Samsung debugging features for Samsung's SoC's.
|
|
*
|
|
* Copyright (c) 2019 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.com
|
|
*/
|
|
|
|
#ifndef SEC_DEBUG_H
|
|
#define SEC_DEBUG_H
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/types.h>
|
|
#include <linux/sec_debug_types.h>
|
|
/*
|
|
* Don't include additional headers. They can cause ABI violation problem
|
|
* because this file is included many built-in drivers.
|
|
*/
|
|
|
|
struct task_struct;
|
|
struct irq_desc;
|
|
struct pt_regs;
|
|
struct freq_log;
|
|
|
|
/*
|
|
* SEC DEBUG LAST KMSG
|
|
*/
|
|
#ifdef CONFIG_SEC_DEBUG
|
|
#define SEC_LKMSG_MAGICKEY 0x0000000a6c6c7546
|
|
|
|
extern void secdbg_lkmg_store(unsigned char *head_ptr,
|
|
unsigned char *curr_ptr, size_t buf_size);
|
|
#else
|
|
#define secdbg_lkmg_store(a, b, c) do {} while(0)
|
|
#endif
|
|
|
|
/*
|
|
* SEC DEBUG MODE
|
|
*/
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_MODE)
|
|
extern int secdbg_mode_check_sj(void);
|
|
extern int secdbg_mode_enter_upload(void);
|
|
#else
|
|
static inline int secdbg_mode_check_sj(void)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int secdbg_mode_enter_upload(void)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* SEC DEBUG - DEBUG SNAPSHOT BASE HOOKING
|
|
*/
|
|
enum {
|
|
DSS_KEVENT_TASK,
|
|
DSS_KEVENT_WORK,
|
|
DSS_KEVENT_IRQ,
|
|
DSS_KEVENT_FREQ,
|
|
DSS_KEVENT_IDLE,
|
|
DSS_KEVENT_THRM,
|
|
DSS_KEVENT_ACPM,
|
|
DSS_KEVENT_MFRQ,
|
|
};
|
|
|
|
#define SD_ESSINFO_KEY_SIZE (32)
|
|
|
|
struct ess_info_offset {
|
|
char key[SD_ESSINFO_KEY_SIZE];
|
|
unsigned long base;
|
|
unsigned long last;
|
|
unsigned int nr;
|
|
unsigned int size;
|
|
unsigned int per_core;
|
|
};
|
|
|
|
/*
|
|
* SEC DEBUG AUTO COMMENT
|
|
*/
|
|
#ifdef CONFIG_SEC_DEBUG_AUTO_COMMENT
|
|
extern void secdbg_comm_log_disable(int type);
|
|
extern void secdbg_comm_log_once(int type);
|
|
#define DEFINE_STATIC_PR_AUTO_NAME_ONCE(name, lvl) \
|
|
static atomic_t ___pr_auto_counter_##name = ATOMIC_INIT(-1); \
|
|
static const char *___pr_auto_level_##name = (lvl)
|
|
|
|
#define pr_auto_name_once(name) \
|
|
({ \
|
|
if (atomic_read(&___pr_auto_counter_##name) <= 0) \
|
|
atomic_inc(&___pr_auto_counter_##name); \
|
|
})
|
|
|
|
#define pr_auto_name(name, fmt, ...) \
|
|
({ \
|
|
if (atomic_read(&___pr_auto_counter_##name) > 0) \
|
|
pr_emerg(fmt, ##__VA_ARGS__); \
|
|
else \
|
|
printk(KERN_AUTO "%s" pr_fmt(fmt), \
|
|
___pr_auto_level_##name, ##__VA_ARGS__); \
|
|
})
|
|
|
|
#define pr_auto_name_disable(name) \
|
|
({ \
|
|
atomic_set(&___pr_auto_counter_##name, 1); \
|
|
})
|
|
|
|
#define pr_auto_name_on(__pr_auto_cond, name, fmt, ...) \
|
|
({ \
|
|
if (__pr_auto_cond) \
|
|
pr_auto_name(name, fmt, ##__VA_ARGS__); \
|
|
else \
|
|
pr_emerg(fmt, ##__VA_ARGS__); \
|
|
})
|
|
|
|
#define pr_auto_on(__pr_auto_cond, lvl, fmt, ...) \
|
|
({ \
|
|
if (__pr_auto_cond) \
|
|
pr_auto(lvl, fmt, ##__VA_ARGS__); \
|
|
else \
|
|
pr_emerg(fmt, ##__VA_ARGS__); \
|
|
})
|
|
#else
|
|
#define DEFINE_STATIC_PR_AUTO_NAME_ONCE(name, lvl)
|
|
#define pr_auto_name_once(name)
|
|
#define pr_auto_name(name, fmt, ...) pr_emerg(fmt, ##__VA_ARGS__)
|
|
#define pr_auto_name_disable(name)
|
|
#define pr_auto_name_on(__pr_auto_cond, name, fmt, ...) pr_emerg(fmt, ##__VA_ARGS__)
|
|
#define pr_auto_on(__pr_auto_cond, lvl, fmt, ...) pr_emerg(fmt, ##__VA_ARGS__)
|
|
#endif /* CONFIG_SEC_DEBUG_AUTO_COMMENT */
|
|
|
|
/*
|
|
* SEC DEBUG EXTRA INFO
|
|
*/
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_EXTRA_INFO)
|
|
enum secdbg_exin_fault_type {
|
|
UNDEF_FAULT,
|
|
BAD_MODE_FAULT,
|
|
WATCHDOG_FAULT,
|
|
KERNEL_FAULT,
|
|
MEM_ABORT_FAULT,
|
|
SP_PC_ABORT_FAULT,
|
|
PAGE_FAULT,
|
|
ACCESS_USER_FAULT,
|
|
EXE_USER_FAULT,
|
|
ACCESS_USER_OUTSIDE_FAULT,
|
|
BUG_FAULT,
|
|
SERROR_FAULT,
|
|
SEABORT_FAULT,
|
|
PTRAUTH_FAULT,
|
|
FAULT_MAX,
|
|
};
|
|
|
|
extern void secdbg_exin_set_finish(void);
|
|
extern void secdbg_exin_set_panic(const char *str);
|
|
extern void secdbg_exin_set_busmon(const char *str);
|
|
extern void secdbg_exin_set_sysmmu(const char *str);
|
|
extern void secdbg_exin_set_smpl(unsigned long count);
|
|
extern void secdbg_exin_set_decon(const char *str);
|
|
extern void secdbg_exin_set_batt(int cap, int volt, int temp, int curr);
|
|
extern void secdbg_exin_set_mfc_error(const char *str);
|
|
extern void secdbg_exin_set_aud(const char *str);
|
|
extern void secdbg_exin_set_gpuinfo(const char *str);
|
|
extern void secdbg_exin_set_epd(const char *str);
|
|
extern void secdbg_exin_set_asv(int bg, int mg, int lg, int g3dg, int mifg);
|
|
extern void secdbg_exin_set_ids(int bids, int mids, int lids, int gids);
|
|
extern void secdbg_exin_set_unfz(const char *comm, int pid);
|
|
extern char *secdbg_exin_get_unfz(void);
|
|
extern void secdbg_exin_set_hardlockup_type(const char *fmt, ...);
|
|
extern void secdbg_exin_set_hardlockup_data(const char *str);
|
|
extern void secdbg_exin_set_hardlockup_freq(const char *domain, struct freq_log *freq);
|
|
extern void secdbg_exin_set_hardlockup_ehld(unsigned int hl_info, unsigned int cpu);
|
|
extern void secdbg_exin_set_ufs(const char *str);
|
|
#else /* !CONFIG_SEC_DEBUG_EXTRA_INFO */
|
|
#define secdbg_exin_set_finish(a) do { } while (0)
|
|
#define secdbg_exin_set_panic(a) do { } while (0)
|
|
#define secdbg_exin_set_busmon(a) do { } while (0)
|
|
#define secdbg_exin_set_sysmmu(a) do { } while (0)
|
|
#define secdbg_exin_set_smpl(a) do { } while (0)
|
|
#define secdbg_exin_set_decon(a) do { } while (0)
|
|
#define secdbg_exin_set_batt(a, b, c, d) do { } while (0)
|
|
#define secdbg_exin_set_mfc_error(a) do { } while (0)
|
|
#define secdbg_exin_set_aud(a) do { } while (0)
|
|
#define secdbg_exin_set_gpuinfo(a) do { } while (0)
|
|
#define secdbg_exin_set_epd(a) do { } while (0)
|
|
#define secdbg_exin_set_asv(a) do { } while (0)
|
|
#define secdbg_exin_set_ids(a) do { } while (0)
|
|
#define secdbg_exin_set_unfz(a) do { } while (0)
|
|
#define secdbg_exin_get_unfz() (NULL)
|
|
#define secdbg_exin_set_hardlockup_type(a, ...) do { } while (0)
|
|
#define secdbg_exin_set_hardlockup_data(a) do { } while (0)
|
|
#define secdbg_exin_set_hardlockup_freq(a, b) do { } while (0)
|
|
#define secdbg_exin_set_hardlockup_ehld(a, b) do { } while (0)
|
|
#define secdbg_exin_set_ufs(a) do { } while (0)
|
|
#endif /* CONFIG_SEC_DEBUG_EXTRA_INFO */
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_WATCHDOGD_FOOTPRINT)
|
|
extern void secdbg_wdd_set_keepalive(void);
|
|
extern void secdbg_wdd_set_start(void);
|
|
extern void secdbg_base_built_wdd_set_emerg_addr(unsigned long addr);
|
|
#else
|
|
#define secdbg_wdd_set_keepalive(a) do { } while (0)
|
|
#define secdbg_wdd_set_start(a) do { } while (0)
|
|
#define secdbg_base_built_wdd_set_emerg_addr(a) do { } while (0)
|
|
#endif
|
|
|
|
#ifdef CONFIG_SEC_DEBUG_FREQ
|
|
extern void secdbg_freq_check(int type, unsigned long index, unsigned long freq);
|
|
#endif
|
|
|
|
#ifdef CONFIG_SEC_DEBUG_SYSRQ_KMSG
|
|
extern size_t secdbg_hook_get_curr_init_ptr(void);
|
|
extern size_t dbg_snapshot_get_curr_ptr_for_sysrq(void);
|
|
#endif
|
|
|
|
/* unfrozen task */
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_UNFROZEN_TASK)
|
|
void secdbg_base_built_set_unfrozen_task(struct task_struct *task, uint64_t count);
|
|
#else
|
|
static inline void secdbg_base_built_set_unfrozen_task(struct task_struct *task, uint64_t count) {}
|
|
#endif /* CONFIG_SEC_DEBUG_UNFROZEN_TASK */
|
|
|
|
/* CONFIG_SEC_DEBUG_BAD_STACK_INFO */
|
|
extern void secdbg_base_set_bs_info_phase(int phase);
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_DTASK)
|
|
static inline void secdbg_dtsk_built_set_data(long type, void *data)
|
|
{
|
|
current->android_oem_data1[0] = (u64)type;
|
|
current->android_oem_data1[1] = (u64)data;
|
|
}
|
|
static inline void secdbg_dtsk_built_clear_data(void)
|
|
{
|
|
secdbg_dtsk_built_set_data(DTYPE_NONE, NULL);
|
|
}
|
|
#else
|
|
#define secdbg_dtsk_built_set_data(a, b) do { } while (0)
|
|
#define secdbg_dtsk_built_clear_data() do { } while (0)
|
|
#endif /* CONFIG_SEC_DEBUG_DTASK */
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_PM_DEVICE_INFO)
|
|
extern void secdbg_base_built_set_device_shutdown_timeinfo(uint64_t start, uint64_t end, uint64_t duration, uint64_t func);
|
|
extern void secdbg_base_built_clr_device_shutdown_timeinfo(void);
|
|
extern void secdbg_base_built_set_shutdown_device(const char *fname, const char *dname);
|
|
extern void secdbg_base_built_set_suspend_device(const char *fname, const char *dname);
|
|
#else
|
|
#define secdbg_base_built_set_device_shutdown_timeinfo(a, b, c, d) do { } while (0)
|
|
#define secdbg_base_built_clr_device_shutdown_timeinfo() do { } while (0)
|
|
#define secdbg_base_built_set_shutdown_device(a, b) do { } while (0)
|
|
#define secdbg_base_built_set_suspend_device(a, b) do { } while (0)
|
|
#endif /* CONFIG_SEC_DEBUG_PM_DEVICE_INFO */
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_TASK_IN_STATE_INFO)
|
|
void secdbg_base_built_set_task_in_pm_suspend(struct task_struct *task);
|
|
void secdbg_base_built_set_task_in_sync_irq(struct task_struct *task, unsigned int irq, struct irq_desc *desc);
|
|
#else
|
|
#define secdbg_base_built_set_task_in_pm_suspend(a) do { } while (0)
|
|
#define secdbg_base_built_set_task_in_sync_irq(a, b, c) do { } while (0)
|
|
#endif /* CONFIG_SEC_DEBUG_PM_DEVICE_INFO */
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_SOFTDOG)
|
|
void secdbg_softdog_show_info(void);
|
|
#else
|
|
#define secdbg_softdog_show_info() do { } while (0)
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_SEC_DEBUG_HANDLE_BAD_STACK)
|
|
extern void secdbg_base_built_check_handle_bad_stack(void);
|
|
#else
|
|
static inline void secdbg_base_built_check_handle_bad_stack(void) { }
|
|
#endif
|
|
|
|
#ifdef CONFIG_SEC_DEBUG_MEMTAB
|
|
#define SDBG_KNAME_LEN 64
|
|
|
|
struct secdbg_member_type {
|
|
char member[SDBG_KNAME_LEN];
|
|
uint16_t size;
|
|
uint16_t offset;
|
|
uint16_t unused[2];
|
|
};
|
|
|
|
#define SECDBG_DEFINE_MEMBER_TYPE(key, st, mem) \
|
|
const struct secdbg_member_type sdbg_##key \
|
|
__attribute__((__section__(".secdbg_mbtab." #key))) = { \
|
|
.member = #key, \
|
|
.size = sizeof_field(struct st, mem), \
|
|
.offset = offsetof(struct st, mem), \
|
|
}
|
|
#else
|
|
#define SECDBG_DEFINE_MEMBER_TYPE(a, b, c)
|
|
#endif /* CONFIG_SEC_DEBUG_MEMTAB */
|
|
|
|
extern struct atomic_notifier_head sec_power_off_notifier_list;
|
|
|
|
extern void secdbg_exin_set_main_ocp(void *main_ocp_cnt, void *main_oi_cnt, int buck_cnt);
|
|
|
|
#endif /* SEC_DEBUG_H */
|
|
|