/* 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 #include #include #include /* * 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 */