diff --git a/include/uapi/sound/sof-ipc.h b/include/uapi/sound/sof-ipc.h index 48e6bc867bacf9..a7bcffb7643044 100644 --- a/include/uapi/sound/sof-ipc.h +++ b/include/uapi/sound/sof-ipc.h @@ -952,4 +952,14 @@ struct sof_ipc_dsp_oops_xtensa { uint32_t stack; } __attribute__((packed)); +/* + * Commom debug + */ + +/* panic info include filename and line number */ +struct sof_ipc_panic_info { + char filename[32]; + uint32_t linenum; +} __attribute__((packed)); + #endif diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index ac20b901f32369..2e91bf7cea430b 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -149,8 +149,9 @@ static const struct sof_panic_msg panic_msg[] = { }; int snd_sof_get_status(struct snd_sof_dev *sdev, u32 panic_code, - u32 tracep_code, void *oops, void *stack, - size_t stack_words) + u32 tracep_code, void *oops, + struct sof_ipc_panic_info *panic_info, + void *stack, size_t stack_words) { u32 code; int i; @@ -179,6 +180,8 @@ int snd_sof_get_status(struct snd_sof_dev *sdev, u32 panic_code, dev_err(sdev->dev, "error: trace point %8.8x\n", tracep_code); out: + dev_err(sdev->dev, "error: panic happen at %s:%d\n", + panic_info->filename, panic_info->linenum); sof_oops(sdev, oops); sof_stack(sdev, oops, stack, stack_words); return -EFAULT; diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 8ed608ee6e3055..8068a48c90cc9b 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -296,27 +296,35 @@ static int bdw_set_dsp_D0(struct snd_sof_dev *sdev) static void bdw_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, + struct sof_ipc_panic_info *panic_info, u32 *stack, size_t stack_words) { /* first read regsisters */ bdw_mailbox_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops)); - /* the get the stack */ - bdw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), stack, - stack_words * sizeof(u32)); + /* then get panic info */ + bdw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), + panic_info, sizeof(*panic_info)); + + /* then get the stack */ + bdw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) + + sizeof(*panic_info), stack, + stack_words * sizeof(u32)); } static void bdw_dump(struct snd_sof_dev *sdev, u32 flags) { struct sof_ipc_dsp_oops_xtensa xoops; + struct sof_ipc_panic_info panic_info; u32 stack[BDW_STACK_DUMP_SIZE]; u32 status, panic; /* now try generic SOF status messages */ status = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD); panic = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX); - bdw_get_registers(sdev, &xoops, stack, BDW_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, stack, + bdw_get_registers(sdev, &xoops, &panic_info, stack, + BDW_STACK_DUMP_SIZE); + snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, BDW_STACK_DUMP_SIZE); } diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 14cf6b1082b85e..25d5bf0ed6f31c 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -314,27 +314,35 @@ static void byt_mailbox_read(struct snd_sof_dev *sdev, u32 offset, static void byt_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, + struct sof_ipc_panic_info *panic_info, u32 *stack, size_t stack_words) { /* first read regsisters */ byt_mailbox_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops)); - /* the get the stack */ - byt_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), stack, - stack_words * sizeof(u32)); + /* then get panic info */ + byt_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), + panic_info, sizeof(*panic_info)); + + /* then get the stack */ + byt_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) + + sizeof(*panic_info), stack, + stack_words * sizeof(u32)); } static void byt_dump(struct snd_sof_dev *sdev, u32 flags) { struct sof_ipc_dsp_oops_xtensa xoops; + struct sof_ipc_panic_info panic_info; u32 stack[BYT_STACK_DUMP_SIZE]; u32 status, panic; /* now try generic SOF status messages */ status = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCD); panic = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCX); - byt_get_registers(sdev, &xoops, stack, BYT_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, stack, + byt_get_registers(sdev, &xoops, &panic_info, stack, + BYT_STACK_DUMP_SIZE); + snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, BYT_STACK_DUMP_SIZE); } diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index ba492ac3756658..1270939e1e83f7 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -164,19 +164,26 @@ static void hda_dsp_get_status(struct snd_sof_dev *sdev) static void hda_dsp_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, + struct sof_ipc_panic_info *panic_info, u32 *stack, size_t stack_words) { /* first read registers */ hda_dsp_block_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops)); + /* then get panic info */ + hda_dsp_block_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), + panic_info, sizeof(*panic_info)); + /* then get the stack */ - hda_dsp_block_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), stack, + hda_dsp_block_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) + + sizeof(*panic_info), stack, stack_words * sizeof(u32)); } void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) { struct sof_ipc_dsp_oops_xtensa xoops; + struct sof_ipc_panic_info panic_info; u32 stack[HDA_DSP_STACK_DUMP_SIZE]; u32 status, panic; @@ -189,10 +196,10 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP); if (sdev->boot_complete) { - hda_dsp_get_registers(sdev, &xoops, stack, + hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, HDA_DSP_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, stack, - HDA_DSP_STACK_DUMP_SIZE); + snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, + stack, HDA_DSP_STACK_DUMP_SIZE); } else { dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", status, panic); diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index e4d13b952e9c5f..fef9aa0c8ec249 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -295,27 +295,35 @@ static int hsw_set_dsp_D0(struct snd_sof_dev *sdev) static void hsw_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, + struct sof_ipc_panic_info *panic_info, u32 *stack, size_t stack_words) { /* first read regsisters */ hsw_mailbox_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops)); - /* the get the stack */ - hsw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), stack, - stack_words * sizeof(u32)); + /* then get panic info */ + hsw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), + panic_info, sizeof(*panic_info)); + + /* then get the stack */ + hsw_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) + + sizeof(*panic_info), stack, + stack_words * sizeof(u32)); } static void hsw_dump(struct snd_sof_dev *sdev, u32 flags) { struct sof_ipc_dsp_oops_xtensa xoops; + struct sof_ipc_panic_info panic_info; u32 stack[HSW_STACK_DUMP_SIZE]; u32 status, panic; /* now try generic SOF status messages */ status = snd_sof_dsp_read(sdev, HSW_DSP_BAR, SHIM_IPCD); panic = snd_sof_dsp_read(sdev, HSW_DSP_BAR, SHIM_IPCX); - hsw_get_registers(sdev, &xoops, stack, HSW_STACK_DUMP_SIZE); - snd_sof_get_status(sdev, status, panic, &xoops, stack, + hsw_get_registers(sdev, &xoops, &panic_info, stack, + HSW_STACK_DUMP_SIZE); + snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, HSW_STACK_DUMP_SIZE); } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 43c62793109e7a..f35dcca6550b4a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -484,8 +484,9 @@ int snd_sof_trace_update_pos(struct snd_sof_dev *sdev, struct sof_ipc_dma_trace_posn *posn); void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev); int snd_sof_get_status(struct snd_sof_dev *sdev, u32 panic_code, - u32 tracep_code, void *oops, void *stack, - size_t stack_size); + u32 tracep_code, void *oops, + struct sof_ipc_panic_info *panic_info, + void *stack, size_t stack_size); int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev); /*