kernel_samsung_a53x/drivers/samsung/debug/sec_debug_internal.h

563 lines
13 KiB
C
Raw Normal View History

2024-06-15 21:02:09 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* drivers/debug/sec_debug_internal.h
*
* COPYRIGHT(C) 2020 Samsung Electronics Co., Ltd. All Right Reserved.
*
*/
#ifndef __SEC_DEBUG_INTERNAL_H__
#define __SEC_DEBUG_INTERNAL_H__
#include <linux/sec_debug.h>
#include <linux/sizes.h>
#include <linux/coredump.h>
/* TODO: SoC dependent offset, get them from LSI code ? */
#define EXYNOS_PMU_INFORM2 0x0808
#define EXYNOS_PMU_INFORM3 0x080C
/* AP SFR to send some information from kernel to bootloader */
#define SEC_DEBUG_MAGIC_INFORM (EXYNOS_PMU_INFORM2)
#define SEC_DEBUG_PANIC_INFORM (EXYNOS_PMU_INFORM3)
/* 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,
};
/* sec debug buffer format */
struct outbuf {
char buf[SZ_1K];
int index;
int already;
};
/* for sub data-structure of SDN */
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;
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;
uint64_t kimage_voffset;
uint64_t reserved[4];
};
/* kcnst has some kernel constant (offset) data for bootloader */
struct basic_type_int {
uint64_t pa; /* physical address of the variable */
uint32_t size; /* size of basic type. eg sizeof(unsigned long) goes here */
uint32_t count; /* for array types */
};
struct sec_debug_kcnst {
uint64_t nr_cpus;
struct basic_type_int per_cpu_offset;
uint64_t phys_offset;
uint64_t phys_mask;
uint64_t page_offset;
uint64_t page_mask;
uint64_t page_shift;
uint64_t va_bits;
uint64_t kimage_vaddr;
uint64_t kimage_voffset;
uint64_t pa_swapper;
uint64_t pgdir_shift;
uint64_t pud_shift;
uint64_t pmd_shift;
uint64_t ptrs_per_pgd;
uint64_t ptrs_per_pud;
uint64_t ptrs_per_pmd;
uint64_t ptrs_per_pte;
uint64_t kconfig_base;
uint64_t kconfig_size;
uint64_t pa_text;
uint64_t pa_start_rodata;
uint64_t target_dprm_mask;
uint64_t reserved[3];
};
struct member_type {
uint16_t size;
uint16_t offset;
};
typedef struct member_type member_type_int;
typedef struct member_type member_type_long;
typedef struct member_type member_type_longlong;
typedef struct member_type member_type_ptr;
typedef struct member_type member_type_str;
struct struct_thread_info {
uint32_t struct_size;
member_type_long flags;
member_type_ptr task;
member_type_int cpu;
member_type_long rrk;
};
struct struct_task_struct {
uint32_t struct_size;
member_type_long state;
member_type_long exit_state;
member_type_ptr stack;
member_type_int flags;
member_type_int on_cpu;
member_type_int on_rq;
member_type_int cpu;
member_type_int pid;
member_type_str comm;
member_type_ptr tasks_next;
member_type_ptr thread_group_next;
member_type_long fp;
member_type_long sp;
member_type_long pc;
member_type_long sched_info__pcount;
member_type_longlong sched_info__run_delay;
member_type_longlong sched_info__last_arrival;
member_type_longlong sched_info__last_queued;
member_type_int ssdbg_wait__type;
member_type_ptr ssdbg_wait__data;
};
struct irq_stack_info {
uint64_t pcpu_stack; /* IRQ_STACK_PTR(0) */
uint64_t size; /* IRQ_STACK_SIZE */
uint64_t start_sp; /* IRQ_STACK_START_SP */
};
/* task_struct offset data */
struct sec_debug_task {
uint64_t stack_size; /* THREAD_SIZE */
uint64_t start_sp; /* TRHEAD_START_SP */
struct struct_thread_info ti;
struct struct_task_struct ts;
uint64_t init_task;
struct irq_stack_info irq_stack;
};
#define SD_NR_ESSINFO_ITEMS (16)
/* Exynos Debug Snapshot offset data */
struct sec_debug_ess_info {
struct ess_info_offset item[SD_NR_ESSINFO_ITEMS];
};
/* Watchdog driver data */
struct watchdogd_info {
struct task_struct *tsk;
struct thread_info *thr;
struct rtc_time *tm;
unsigned long long last_ping_time;
int last_ping_cpu;
bool init_done;
unsigned long emerg_addr;
};
struct bad_stack_info {
unsigned long magic;
unsigned long esr;
unsigned long far;
unsigned long spel0;
unsigned long cpu;
unsigned long tsk_stk;
unsigned long irq_stk;
unsigned long ovf_stk;
};
struct suspend_dev_info {
uint64_t suspend_func;
uint64_t suspend_device;
uint64_t shutdown_func;
uint64_t shutdown_device;
};
struct sec_debug_kernel_data {
uint64_t task_in_pm_suspend;
uint64_t task_in_sys_reboot;
uint64_t task_in_sys_shutdown;
uint64_t task_in_dev_shutdown;
uint64_t task_in_sysrq_crash;
uint64_t task_in_soft_lockup;
uint64_t cpu_in_soft_lockup;
uint64_t task_in_hard_lockup;
uint64_t cpu_in_hard_lockup;
uint64_t unfrozen_task;
uint64_t unfrozen_task_count;
uint64_t sync_irq_task;
uint64_t sync_irq_num;
uint64_t sync_irq_name;
uint64_t sync_irq_desc;
uint64_t sync_irq_thread;
uint64_t sync_irq_threads_active;
uint64_t dev_shutdown_start;
uint64_t dev_shutdown_end;
uint64_t dev_shutdown_duration;
uint64_t dev_shutdown_func;
unsigned long sysrq_ptr;
struct watchdogd_info wddinfo;
struct bad_stack_info bsi;
struct suspend_dev_info sdi;
};
/* some buffers to use in sec debug module */
enum sdn_map {
SDN_MAP_DUMP_SUMMARY,
SDN_MAP_AUTO_COMMENT,
SDN_MAP_EXTRA_INFO,
SDN_MAP_AUTO_ANALYSIS,
SDN_MAP_INITTASK_LOG,
SDN_MAP_DEBUG_PARAM,
SDN_MAP_FIRST2M_LOG,
SDN_MAP_SPARED_BUFFER,
NR_SDN_MAP,
};
struct sec_debug_buf {
unsigned long base;
unsigned long size;
};
struct sec_debug_map {
struct sec_debug_buf buf[NR_SDN_MAP];
};
/* macro to initialize kernel data structure offset data */
#define SET_MEMBER_TYPE_INFO(PTR, TYPE, MEMBER) \
{ \
(PTR)->size = sizeof(((TYPE *)0)->MEMBER); \
(PTR)->offset = offsetof(TYPE, MEMBER); \
}
struct sec_debug_memtab {
uint64_t table_start_pa;
uint64_t table_end_pa;
uint64_t reserved[4];
};
#define THREAD_START_SP (THREAD_SIZE - 16)
#define IRQ_STACK_START_SP THREAD_START_SP
#define SEC_DEBUG_MAGIC0 (0x11221133)
#define SEC_DEBUG_MAGIC1 (0x12121313)
/* TODO: sdn needs extra info data structure to define it normally, but ... */
/* ------------------------------------------------
* SEC DEBUG EXTRA INFO
* ------------------------------------------------ */
enum shared_buffer_slot {
SLOT_32,
SLOT_64,
SLOT_256,
SLOT_1024,
SLOT_MAIN_END = SLOT_1024,
NR_MAIN_SLOT = 4,
SLOT_BK_32 = NR_MAIN_SLOT,
SLOT_BK_64,
SLOT_BK_256,
SLOT_BK_1024,
SLOT_END = SLOT_BK_1024,
NR_SLOT = 8,
};
struct sec_debug_sb_index {
unsigned int paddr; /* physical address of slot */
unsigned int size; /* size of a item */
unsigned int nr; /* number of items in slot */
unsigned int cnt; /* number of used items in slot */
/* map to indicate which items are added by bootloader */
unsigned long blmark;
};
struct sec_debug_shared_buffer {
/* initial magic code */
unsigned int magic[4];
/* shared buffer index */
struct sec_debug_sb_index sec_debug_sbidx[NR_SLOT];
};
/* TODO: sdn needs auto comment data structure to define it normally, but ... */
/* ------------------------------------------------
* SEC DEBUG AUTO COMMENT
* ------------------------------------------------ */
#define SEC_DEBUG_AUTO_COMM_BUF_SIZE 10
struct sec_debug_auto_comm_buf {
int reserved_0;
int reserved_1;
int reserved_2;
unsigned int offset;
char buf[SZ_4K];
};
struct sec_debug_auto_comment {
int header_magic;
int fault_flag;
int lv5_log_cnt;
u64 lv5_log_order;
int order_map_cnt;
int order_map[SEC_DEBUG_AUTO_COMM_BUF_SIZE];
struct sec_debug_auto_comm_buf auto_comm_buf[SEC_DEBUG_AUTO_COMM_BUF_SIZE];
int tail_magic;
};
/* ------------------------------------------------
* SEC DEBUG GEN3 (Compatible with SEC DEBUG NEXT)
* ------------------------------------------------ */
#define SEC_DEBUG_GEN3_MAGIC0 (0xc3a50421)
#define SEC_DEBUG_GEN3_MAGIC1 (0xe2b42021)
#define LEN_SECDBG_OFFSET_NAME (64)
struct sec_debug_version {
unsigned int magic[2];
unsigned int version[2];
};
#define NR_GEN3_LOGBUF 32
#define NR_GEN3_KEVENT 32
/* LV1 */
struct secdbg_extra_info {
struct sec_debug_shared_buffer data;
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_auto_comment {
struct sec_debug_auto_comment data;
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_kernel_data {
struct sec_debug_kernel_data data;
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_snapshot_offset {
struct ess_info_offset data[NR_GEN3_KEVENT];
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_task_struct {
struct sec_debug_task data;
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_kernel_constant {
struct sec_debug_kcnst data;
char name[LEN_SECDBG_OFFSET_NAME];
};
#define LEN_LOGBUF_NAME (32)
/* LV2 (under secdbg_logbuf_list) */
struct secdbg_logbuf {
uint64_t base;
uint64_t size;
char name[LEN_LOGBUF_NAME];
uint32_t is_storage;
uint32_t offset;
uint32_t partition;
};
/* LV1 */
struct secdbg_logbuf_list {
struct secdbg_logbuf data[NR_GEN3_LOGBUF];
char name[LEN_SECDBG_OFFSET_NAME];
};
/* LV1 */
struct secdbg_memtab {
struct sec_debug_memtab data;
char name[LEN_SECDBG_OFFSET_NAME];
};
/* Offset for LV1 */
struct secdbg_lv1_member {
char name[LEN_SECDBG_OFFSET_NAME];
uint64_t size;
uint64_t addr;
};
enum gen3_lv1_item {
SDN_LV1_LOGBUF_MAP,
SDN_LV1_MEMTAB,
SDN_LV1_KERNEL_SYMBOL,
SDN_LV1_KERNEL_CONSTANT,
SDN_LV1_TASK_STRUCT,
SDN_LV1_SNAPSHOT,
SDN_LV1_SPINLOCK, /* reserved */
SDN_LV1_KERNEL_DATA,
SDN_LV1_AUTO_COMMENT,
SDN_LV1_EXTRA_INFO,
};
/* increase if sec_debug_next is not changed and other feature is upgraded */
#define SEC_DEBUG_KERNEL_UPPER_VERSION (0x1001)
/* increase if sec_debug_next is changed */
#define SEC_DEBUG_KERNEL_LOWER_VERSION (0x1002)
/* SEC DEBUG NEXT DEFINITION */
struct sec_debug_gen3 {
unsigned int magic[2];
unsigned int version[2];
unsigned int used_offset;
unsigned int end_addr;
unsigned int reserved[4];
struct secdbg_lv1_member lv1_data[64];
};
struct sec_debug_base_param {
void *sdn_vaddr;
bool init_sdn_done;
};
/* SEC DEBUG HARDLOCUP INFO */
enum ehld_types {
NO_INSTRET,
NO_INSTRUN,
MAX_ETYPES
};
#if IS_ENABLED(CONFIG_SEC_DEBUG_MEMTAB)
extern struct secdbg_member_type __start__secdbg_member_table[];
extern struct secdbg_member_type __stop__secdbg_member_table[];
#endif
/* function for external call */
extern void *secdbg_base_get_debug_base(int type);
extern unsigned long secdbg_base_get_buf_base(int type);
extern unsigned long secdbg_base_get_buf_size(int type);
extern void *secdbg_base_get_ncva(unsigned long pa);
extern unsigned long secdbg_base_get_end_addr(void);
extern void *secdbg_base_get_kcnst_base(void);
extern int secdbg_part_init_bdev_path(struct device *dev);
#if IS_ENABLED(CONFIG_SEC_DEBUG_LOCKUP_INFO)
void secdbg_base_set_info_hard_lockup(unsigned int cpu, struct task_struct *task);
#endif
/* SEC DEBUG EXTAR INFO */
#define MAX_ITEM_KEY_LEN (16)
#define MAX_ITEM_VAL_LEN (1008)
#define SEC_DEBUG_SHARED_MAGIC0 0xFFFFFFFF
#define SEC_DEBUG_SHARED_MAGIC1 0x95308180
#define SEC_DEBUG_SHARED_MAGIC2 0x15001500
#define SEC_DEBUG_SHARED_MAGIC3 0x00010001
extern int id_get_asb_ver(void);
extern int id_get_product_line(void);
extern char *get_bk_item_val(const char *key);
extern void get_bk_item_val_as_string(const char *key, char *buf);
extern void secdbg_exin_set_hwid(int asb_ver, int psite, const char *dramstr);
extern void secdbg_exin_get_extra_info_A(char *ptr);
extern void secdbg_exin_get_extra_info_B(char *ptr);
extern void secdbg_exin_get_extra_info_C(char *ptr);
extern void secdbg_exin_get_extra_info_F(char *ptr);
extern void secdbg_exin_get_extra_info_M(char *ptr);
extern void secdbg_exin_get_extra_info_T(char *ptr);
int secdbg_atsl_init(void);
#ifndef MODULE
extern void *secdbg_base_built_get_debug_base(int type);
extern unsigned long secdbg_base_built_get_buf_base(int type);
extern unsigned long secdbg_base_built_get_buf_size(int type);
extern void *secdbg_base_built_get_ncva(unsigned long pa);
#if IS_ENABLED(CONFIG_SEC_DEBUG_AUTO_COMMENT)
extern int secdbg_comm_auto_comment_init(void);
#else
static inline int secdbg_comm_auto_comment_init(void)
{
return 0;
}
#endif /* CONFIG_SEC_DEBUG_AUTO_COMMENT */
#if IS_ENABLED(CONFIG_SEC_DEBUG_EXTRA_INFO_BUILT_IN)
extern int secdbg_extra_info_built_init(void);
#else
static inline int secdbg_extra_info_built_init(void)
{
return 0;
}
#endif /* CONFIG_SEC_DEBUG_EXTRA_INFO */
#endif /* !MODULE */
extern void secdbg_ksym_set_kallsyms_info(struct sec_debug_ksyms *ksyms);
/* sec_debug_memtab_built.c */
#if IS_ENABLED(CONFIG_SEC_DEBUG_MEMTAB)
extern void secdbg_base_built_set_memtab_info(struct sec_debug_memtab *mtab);
#else
static inline void secdbg_base_built_set_memtab_info(struct sec_debug_memtab *mtab) { }
#endif
#if IS_ENABLED(CONFIG_SEC_DEBUG_STACKTRACE)
extern void secdbg_stra_show_callstack_auto(struct task_struct *tsk);
#else
static inline void secdbg_stra_show_callstack_auto(struct task_struct *tsk) {}
#endif
#if IS_ENABLED(CONFIG_SEC_DEBUG_COREDUMP)
extern void register_coredump_hook_notes_write(int (*func)(struct coredump_params *));
extern void register_coredump_hook_notes_size(int (*func)(void));
#else
static inline void register_coredump_hook_notes_write(int (*func)(struct coredump_params *)) { }
static inline void register_coredump_hook_notes_size(int (*func)(void)) { }
#endif
#endif /* __SEC_DEBUG_INTERNAL_H__ */