/* * Samsung debugging features for Samsung's SoC's. * * Copyright (c) 2014 Samsung Electronics Co., Ltd. * http://www.samsung.com * * 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. */ #ifndef SEC_DEBUG_H #define SEC_DEBUG_H #include #include #include #include #define SEC_DEBUG_MAGIC_PA memblock_start_of_DRAM() #define SEC_DEBUG_MAGIC_VA phys_to_virt(SEC_DEBUG_MAGIC_PA) #define SEC_DEBUG_EXTRA_INFO_VA (SEC_DEBUG_MAGIC_VA + 0x400) #define SEC_DEBUG_DUMPER_LOG_VA (SEC_DEBUG_MAGIC_VA + 0x800) #define BUF_SIZE_MARGIN (SZ_1K - 0x80) #ifdef CONFIG_SEC_DEBUG extern int id_get_asb_ver(void); extern int id_get_product_line(void); extern int sec_debug_setup(void); extern void sec_debug_recovery_reboot(void); extern void sec_debug_reboot_handler(void); extern void sec_debug_panic_handler(void *buf, bool dump); extern void sec_debug_post_panic_handler(void); extern int sec_debug_get_debug_level(void); extern int sec_debug_enter_upload(void); extern void sec_debug_disable_printk_process(void); /* getlog support */ extern void sec_getlog_supply_kernel(void *klog_buf); extern void sec_getlog_supply_platform(unsigned char *buffer, const char *name); extern void sec_gaf_supply_rqinfo(unsigned short curr_offset, unsigned short rq_offset); #else #define int id_get_asb_ver(void) (-1) #define int id_get_product_line(void) (-1) #define sec_debug_setup() (-1) #define sec_debug_recovery_reboot() do { } while (0) #define sec_debug_reboot_handler() do { } while (0) #define sec_debug_panic_handler(a, b) do { } while (0) #define sec_debug_post_panic_handler() do { } while (0) #define sec_debug_get_debug_level() (0) #define sec_debug_disable_printk_process() do { } while (0) #define sec_getlog_supply_kernel(a) do { } while (0) #define sec_getlog_supply_platform(a, b) do { } while (0) #define sec_gaf_supply_rqinfo(a, b) do { } while (0) #endif /* CONFIG_SEC_DEBUG */ #ifdef CONFIG_SEC_DEBUG_RESET_REASON enum sec_debug_reset_reason_t { RR_S = 1, RR_W = 2, RR_D = 3, RR_K = 4, RR_M = 5, RR_P = 6, RR_R = 7, RR_B = 8, RR_N = 9, RR_T = 10, RR_C = 11, }; extern unsigned reset_reason; #endif #ifdef CONFIG_SEC_DEBUG_EXTRA_INFO #define MAX_EXTRA_INFO_HDR_LEN 6 #define MAX_EXTRA_INFO_KEY_LEN 16 #define MAX_EXTRA_INFO_VAL_LEN 1024 #define SEC_DEBUG_BADMODE_MAGIC 0x6261646d enum sec_debug_extra_buf_type { INFO_AID, INFO_KTIME, INFO_BIN, INFO_FTYPE, INFO_FAULT, INFO_BUG, INFO_PANIC, INFO_PC, INFO_LR, INFO_STACK, INFO_REASON, INFO_PINFO, INFO_SYSMMU, INFO_BUSMON, INFO_DPM, INFO_SMPL, INFO_ETC, INFO_ESR, INFO_MERR, INFO_PCB, INFO_SMD, INFO_CHI, INFO_LPI, INFO_CDI, INFO_KLG, INFO_HINT, INFO_LEVEL, INFO_DECON, INFO_WAKEUP, INFO_BATT, INFO_MAX_A, INFO_BID = INFO_MAX_A, INFO_BREASON, INFO_ASB, INFO_PSITE, INFO_DDRID, INFO_RST, INFO_INFO2, INFO_INFO3, INFO_RBASE, INFO_MAGIC, INFO_PWRSRC, INFO_PWROFF, INFO_PINT1, INFO_PINT2, INFO_PINT5, INFO_PINT6, INFO_RVD1, INFO_RVD2, INFO_RVD3, INFO_MAX_B, INFO_CID = INFO_MAX_B, INFO_CREASON, INFO_CPU0, INFO_CPU1, INFO_CPU2, INFO_CPU3, INFO_CPU4, INFO_CPU5, INFO_CPU6, INFO_CPU7, INFO_MAX_C, INFO_MID = INFO_MAX_C, INFO_MREASON, INFO_MFC, INFO_MAX_M, INFO_MAX = INFO_MAX_M, }; struct sec_debug_extra_info_item { char key[MAX_EXTRA_INFO_KEY_LEN]; char val[MAX_EXTRA_INFO_VAL_LEN]; unsigned int max; }; struct sec_debug_panic_extra_info { struct sec_debug_extra_info_item item[INFO_MAX]; }; enum sec_debug_extra_fault_type { UNDEF_FAULT, /* 0 */ BAD_MODE_FAULT, /* 1 */ WATCHDOG_FAULT, /* 2 */ KERNEL_FAULT, /* 3 */ MEM_ABORT_FAULT, /* 4 */ SP_PC_ABORT_FAULT, /* 5 */ PAGE_FAULT, /* 6 */ ACCESS_USER_FAULT, /* 7 */ EXE_USER_FAULT, /* 8 */ ACCESS_USER_OUTSIDE_FAULT, /* 9 */ FAULT_MAX, }; #endif #if 1 /* TODO : MOVE IT LATER */ #define SEC_DEBUG_SHARED_MAGIC0 0xFFFFFFFF #define SEC_DEBUG_SHARED_MAGIC1 0x95308180 #define SEC_DEBUG_SHARED_MAGIC2 0x14F014F0 #define SEC_DEBUG_SHARED_MAGIC3 0x00010001 struct sec_debug_ksyms { uint32_t magic; uint32_t kallsyms_all; uint64_t addresses_pa; uint64_t names_pa; uint64_t num_syms; uint64_t token_table_pa; uint64_t token_index_pa; uint64_t markers_pa; uint64_t sinittext; uint64_t einittext; uint64_t stext; uint64_t etext; uint64_t end; }; struct sec_debug_shared_info { /* initial magic code */ unsigned int magic[4]; /* ksymbol information */ struct sec_debug_ksyms ksyms; /* reset reason extra info for bigdata */ struct sec_debug_panic_extra_info sec_debug_extra_info; /* reset reason extra info for bigdata */ struct sec_debug_panic_extra_info sec_debug_extra_info_backup; /* last 1KB of kernel log */ char last_klog[SZ_1K]; }; extern void sec_debug_set_kallsyms_info(struct sec_debug_shared_info *sec_debug_info); #endif /* TODO : MOVE IT LATER */ #ifdef CONFIG_SEC_DEBUG_EXTRA_INFO extern unsigned long merr_symptom; extern struct exynos_chipid_info exynos_soc_info; extern unsigned int get_smpl_warn_number(void); extern void sec_debug_init_extra_info(struct sec_debug_shared_info *); extern void sec_debug_finish_extra_info(void); extern void sec_debug_store_extra_info(int start, int end); extern void sec_debug_store_extra_info_A(void); extern void sec_debug_store_extra_info_B(void); extern void sec_debug_store_extra_info_C(void); extern void sec_debug_store_extra_info_M(void); extern void sec_debug_set_extra_info_id(void); extern void sec_debug_set_extra_info_ktime(void); extern void sec_debug_set_extra_info_fault(enum sec_debug_extra_fault_type, unsigned long addr, struct pt_regs *regs); extern void sec_debug_set_extra_info_bug(const char *file, unsigned int line); extern void sec_debug_set_extra_info_panic(char *str); extern void sec_debug_set_extra_info_backtrace(struct pt_regs *regs); extern void sec_debug_set_extra_info_backtrace_cpu(struct pt_regs *regs, int cpu); extern void sec_debug_set_extra_info_evt_version(void); extern void sec_debug_set_extra_info_sysmmu(char *str); extern void sec_debug_set_extra_info_busmon(char *str); extern void sec_debug_set_extra_info_dpm_timeout(char *devname); extern void sec_debug_set_extra_info_smpl(unsigned int count); extern void sec_debug_set_extra_info_esr(unsigned int esr); extern void sec_debug_set_extra_info_hint(u64 hint); extern void sec_debug_set_extra_info_merr(void); extern void sec_debug_set_extra_info_decon(unsigned int err); extern void sec_debug_set_extra_info_batt(int cap, int volt, int temp, int curr); extern void sec_debug_set_extra_info_ufs_error(char *str); extern void sec_debug_set_extra_info_zswap(char *str); extern void sec_debug_set_extra_info_mfc_error(char *str); extern void sec_debug_set_extra_info_aud(char *str); #else #define sec_debug_init_extra_info(a) do { } while (0) #define sec_debug_finish_extra_info() do { } while (0) #define sec_debug_store_extra_info(a, b) do { } while (0) #define sec_debug_store_extra_info_A() do { } while (0) #define sec_debug_store_extra_info_C() do { } while (0) #define sec_debug_store_extra_info_M() do { } while (0) #define sec_debug_set_extra_info_id() do { } while (0) #define sec_debug_set_extra_info_ktime() do { } while (0) #define sec_debug_set_extra_info_fault(a, b, c) do { } while (0) #define sec_debug_set_extra_info_bug(a, b) do { } while (0) #define sec_debug_set_extra_info_panic(a) do { } while (0) #define sec_debug_set_extra_info_backtrace(a) do { } while (0) #define sec_debug_set_extra_info_backtrace_cpu(a, b) do { } while (0) #define sec_debug_set_extra_info_evt_version() do { } while (0) #define sec_debug_set_extra_info_sysmmu(a) do { } while (0) #define sec_debug_set_extra_info_busmon(a) do { } while (0) #define sec_debug_set_extra_info_dpm_timeout(a) do { } while (0) #define sec_debug_set_extra_info_smpl(a) do { } while (0) #define sec_debug_set_extra_info_esr(a) do { } while (0) #define sec_debug_set_extra_info_hint(a) do { } while (0) #define sec_debug_set_extra_info_merr() do { } while (0) #define sec_debug_set_extra_info_decon(a) do { } while (0) #define sec_debug_set_extra_info_batt(a, b, c, d) do { } while (0) #define sec_debug_set_extra_info_ufs_error(a) do { } while (0) #define sec_debug_set_extra_info_zswap(a) do { } while (0) #define sec_debug_set_extra_info_mfc_error(a) do { } while (0) #define sec_debug_set_extra_info_aud(a) do { } while (0) #endif /* CONFIG_SEC_DEBUG_EXTRA_INFO */ #ifdef CONFIG_SEC_DEBUG_AUTO_SUMMARY extern void sec_debug_auto_summary_log_disable(int type); extern void sec_debug_auto_summary_log_once(int type); extern void register_set_auto_comm_buf(void (*func)(int type, const char *buf, size_t size)); extern void register_set_auto_comm_lastfreq(void (*func)(int type, int old_freq, int new_freq, u64 time)); #endif #ifdef CONFIG_SEC_DEBUG_INIT_LOG extern void register_init_log_hook_func(void (*func)(const char *buf, size_t size)); #endif #ifdef CONFIG_SEC_DEBUG_LAST_KMSG #define SEC_LKMSG_MAGICKEY 0x0000000a6c6c7546 extern void sec_debug_save_last_kmsg(unsigned char *head_ptr, unsigned char *curr_ptr, size_t buf_size); #else #define sec_debug_save_last_kmsg(a, b, c) do { } while (0) #endif /* CONFIG_SEC_DEBUG_LAST_KMSG */ /* * Samsung TN Logging Options */ #ifdef CONFIG_SEC_AVC_LOG extern void sec_debug_avc_log(char *fmt, ...); #else #define sec_debug_avc_log(a, ...) do { } while (0) #endif /* CONFIG_SEC_AVC_LOG */ /** * sec_debug_tsp_log : Leave tsp log in tsp_msg file. * ( Timestamp + Tsp logs ) * sec_debug_tsp_log_msg : Leave tsp log in tsp_msg file and * add additional message between timestamp and tsp log. * ( Timestamp + additional Message + Tsp logs ) */ #ifdef CONFIG_SEC_DEBUG_TSP_LOG extern void sec_debug_tsp_log(char *fmt, ...); extern void sec_debug_tsp_log_msg(char *msg, char *fmt, ...); extern void sec_debug_tsp_raw_data(char *fmt, ...); extern void sec_debug_tsp_raw_data_msg(char *msg, char *fmt, ...); extern void sec_tsp_raw_data_clear(void); extern void sec_debug_tsp_command_history(char *buf); #else #define sec_debug_tsp_log(a, ...) do { } while (0) #define sec_debug_tsp_log_msg(a, b, ...) do { } while (0) #define sec_debug_tsp_raw_data(a, ...) do { } while (0) #define sec_debug_tsp_raw_data_msg(a, b, ...) do { } while (0) #define sec_tsp_raw_data_clear() do { } while (0) #define sec_debug_tsp_command_history(a) do { } while (0) #endif /* CONFIG_SEC_DEBUG_TSP_LOG */ #ifdef CONFIG_TOUCHSCREEN_DUMP_MODE struct tsp_dump_callbacks { void (*inform_dump)(void); }; #endif extern unsigned int get_smpl_warn_number(void); extern void (*mach_restart)(enum reboot_mode mode, const char *cmd); extern int sec_debug_force_error(const char *val, struct kernel_param *kp); #ifdef CONFIG_SEC_DUMP_SUMMARY #define SEC_DEBUG_SUMMARY_MAGIC0 0xFFFFFFFF #define SEC_DEBUG_SUMMARY_MAGIC1 0x5ECDEB6 #define SEC_DEBUG_SUMMARY_MAGIC2 0x14F014F0 #define SEC_DEBUG_SUMMARY_MAGIC3 0x00010004 #define DUMP_SUMMARY_MAX_SIZE (0x300000) #define SCHED_LOG_MAX 512 struct __irq_log { unsigned long long time; int irq; void *fn; int en; int preempt_count; void *context; }; struct __irq_exit_log { unsigned int irq; unsigned long long time; unsigned long long end_time; unsigned long long elapsed_time; }; struct __sched_log { unsigned long long time; char comm[TASK_COMM_LEN]; pid_t pid; struct task_struct *pTask; }; struct sec_debug_summary_corelog { atomic_t idx_irq[CONFIG_NR_CPUS]; struct __irq_log irq[CONFIG_NR_CPUS][SCHED_LOG_MAX]; atomic_t idx_irq_exit[CONFIG_NR_CPUS]; struct __irq_exit_log irq_exit[CONFIG_NR_CPUS][SCHED_LOG_MAX]; atomic_t idx_sched[CONFIG_NR_CPUS]; struct __sched_log sched[CONFIG_NR_CPUS][SCHED_LOG_MAX]; }; struct sec_debug_summary_sched_log { uint64_t sched_idx_paddr; uint64_t sched_buf_paddr; unsigned int sched_struct_sz; unsigned int sched_array_cnt; uint64_t irq_idx_paddr; uint64_t irq_buf_paddr; unsigned int irq_struct_sz; unsigned int irq_array_cnt; uint64_t irq_exit_idx_paddr; uint64_t irq_exit_buf_paddr; unsigned int irq_exit_struct_sz; unsigned int irq_exit_array_cnt; }; struct sec_debug_summary_kernel_log { uint64_t first_idx_paddr; uint64_t next_idx_paddr; uint64_t log_paddr; uint64_t size_paddr; }; struct sec_debug_summary_excp_kernel { char pc_sym[64]; char lr_sym[64]; char panic_caller[64]; char panic_msg[128]; char thread[32]; }; struct sec_debug_summary_cpu_info { char policy_name[16]; int freq_min; int freq_max; int freq_cur; }; struct sec_debug_summary_data_kernel { char name[16]; char state[16]; int nr_cpus; struct sec_debug_summary_excp_kernel excp; struct sec_debug_summary_cpu_info cpu_info[CONFIG_NR_CPUS]; }; struct sec_debug_summary_ksyms { uint32_t magic; uint32_t kallsyms_all; uint64_t addresses_pa; uint64_t names_pa; uint64_t num_syms; uint64_t token_table_pa; uint64_t token_index_pa; uint64_t markers_pa; struct ksect { uint64_t sinittext; uint64_t einittext; uint64_t stext; uint64_t etext; uint64_t end; } sect; uint64_t relative_base; uint64_t offsets_pa; }; struct sec_debug_summary { unsigned int magic[4]; unsigned long reserved_out_buf; unsigned long reserved_out_size; char summary_cmdline[2048]; char summary_linuxbanner[1024]; struct sec_debug_summary_data_kernel kernel; struct sec_debug_summary_corelog sched_log; struct sec_debug_summary_ksyms ksyms; }; extern void sec_debug_task_sched_log_short_msg(char *msg); extern void sec_debug_task_sched_log(int cpu, struct task_struct *task); extern void sec_debug_irq_sched_log(unsigned int irq, void *fn, int en); extern void sec_debug_irq_enterexit_log(unsigned int irq, unsigned long long start_time); extern void sec_debug_summary_set_kallsyms_info(struct sec_debug_summary *summary_info); int sec_debug_save_cpu_info(void); int sec_debug_save_die_info(const char *str, struct pt_regs *regs); int sec_debug_save_panic_info(const char *str, unsigned long caller); #endif #ifdef CONFIG_SEC_DEBUG_LIMIT_BACKTRACE #define MAX_UNWINDING_LOOP 50 /* maximum number of unwind frame */ #endif #endif /* SEC_DEBUG_H */