diff --git a/drivers/platform/tegra/nvadsp/adsp_shared_struct.h b/drivers/platform/tegra/nvadsp/adsp_shared_struct.h index db0bdf15..bbfaef80 100644 --- a/drivers/platform/tegra/nvadsp/adsp_shared_struct.h +++ b/drivers/platform/tegra/nvadsp/adsp_shared_struct.h @@ -129,6 +129,34 @@ struct nvadsp_os_args { char reserved[128]; } __packed; +/* ARM MODE REGS */ +struct arm_mode_regs_shared { + uint32_t fiq_r13, fiq_r14; + uint32_t irq_r13, irq_r14; + uint32_t svc_r13, svc_r14; + uint32_t abt_r13, abt_r14; + uint32_t und_r13, und_r14; + uint32_t sys_r13, sys_r14; +} __packed; + +/* ARM FAULT FRAME */ +struct arm_fault_frame_shared { + uint32_t spsr; + uint32_t usp; + uint32_t ulr; + uint32_t r[13]; + uint32_t pc; +} __packed; + +/* ADSP ARM EXCEPTION CONTEXT */ +struct nvadsp_exception_context { + struct arm_fault_frame_shared frame; + struct arm_mode_regs_shared regs; + uint32_t stack_addr; + uint32_t stack_dump[32]; + uint32_t exception_reason; +} __packed; + /* ADSP OS info/status. Keep in sync with firmware. */ #define MAX_OS_VERSION_BUF 32 struct nvadsp_os_info { @@ -141,6 +169,7 @@ struct nvadsp_shared_mem { struct nvadsp_app_shared_msg_pool app_shared_msg_pool; struct nvadsp_os_args os_args; struct nvadsp_os_info os_info; + struct nvadsp_exception_context exception_context; } __packed; diff --git a/drivers/platform/tegra/nvadsp/os.c b/drivers/platform/tegra/nvadsp/os.c index 99c088b8..b51bae0a 100644 --- a/drivers/platform/tegra/nvadsp/os.c +++ b/drivers/platform/tegra/nvadsp/os.c @@ -1176,6 +1176,72 @@ static void print_agic_irq_states(void) } } +static void print_arm_mode_regs(void) +{ + struct nvadsp_exception_context *excep_context; + struct arm_fault_frame_shared *shared_frame; + struct arm_mode_regs_shared *shared_regs; + struct nvadsp_shared_mem *shared_mem; + struct device *dev = &priv.pdev->dev; + struct nvadsp_drv_data *drv_data; + + drv_data = platform_get_drvdata(priv.pdev); + shared_mem = drv_data->shared_adsp_os_data; + excep_context = &shared_mem->exception_context; + shared_frame = &excep_context->frame; + shared_regs = &excep_context->regs; + + dev_err(dev, "dumping arm mode register data...\n"); + dev_err(dev, "%c fiq r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_FIQ) ? '*' : ' ', + shared_regs->fiq_r13, shared_regs->fiq_r14); + dev_err(dev, "%c irq r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_IRQ) ? '*' : ' ', + shared_regs->irq_r13, shared_regs->irq_r14); + dev_err(dev, "%c svc r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_SVC) ? '*' : ' ', + shared_regs->svc_r13, shared_regs->svc_r14); + dev_err(dev, "%c und r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_UND) ? '*' : ' ', + shared_regs->und_r13, shared_regs->und_r14); + dev_err(dev, "%c sys r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_SYS) ? '*' : ' ', + shared_regs->sys_r13, shared_regs->sys_r14); + dev_err(dev, "%c abt r13 0x%08x r14 0x%08x\n", + ((shared_frame->spsr & MODE_MASK) == MODE_ABT) ? '*' : ' ', + shared_regs->abt_r13, shared_regs->abt_r14); +} + +static void print_arm_fault_frame(void) +{ + struct nvadsp_exception_context *excep_context; + struct arm_fault_frame_shared *shared_frame; + struct nvadsp_shared_mem *shared_mem; + struct device *dev = &priv.pdev->dev; + struct nvadsp_drv_data *drv_data; + + drv_data = platform_get_drvdata(priv.pdev); + shared_mem = drv_data->shared_adsp_os_data; + excep_context = &shared_mem->exception_context; + shared_frame = &excep_context->frame; + + dev_err(dev, "dumping fault frame...\n"); + dev_err(dev, "r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", + shared_frame->r[0], shared_frame->r[1], shared_frame->r[2], + shared_frame->r[3]); + dev_err(dev, "r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", + shared_frame->r[4], shared_frame->r[5], shared_frame->r[6], + shared_frame->r[7]); + dev_err(dev, "r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", + shared_frame->r[8], shared_frame->r[9], shared_frame->r[10], + shared_frame->r[11]); + dev_err(dev, "r12 0x%08x usp 0x%08x ulr 0x%08x pc 0x%08x\n", + shared_frame->r[12], shared_frame->usp, shared_frame->ulr, + shared_frame->pc); + dev_err(dev, "spsr 0x%08x\n", shared_frame->spsr); + +} + static void dump_thread_name(struct platform_device *pdev, u32 val) { dev_info(&pdev->dev, "%s: adsp current thread: %c%c%c%c\n", @@ -1378,6 +1444,8 @@ void dump_adsp_sys(void) dump_adsp_logs(); dump_mailbox_regs(); + print_arm_fault_frame(); + print_arm_mode_regs(); get_adsp_state(); if (nvadsp_tegra_adma_dump_ch_reg) (*nvadsp_tegra_adma_dump_ch_reg)(); diff --git a/drivers/platform/tegra/nvadsp/os.h b/drivers/platform/tegra/nvadsp/os.h index 0b84f8cf..1878955a 100644 --- a/drivers/platform/tegra/nvadsp/os.h +++ b/drivers/platform/tegra/nvadsp/os.h @@ -54,6 +54,17 @@ #define MIN_ADSP_FREQ 38400000lu /* in Hz */ +/* macros used to find the current mode of ADSP */ +#define MODE_MASK 0x1f +#define MODE_USR 0x10 +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_MON 0x16 +#define MODE_ABT 0x17 +#define MODE_UND 0x1b +#define MODE_SYS 0x1f + enum adsp_os_cmd { ADSP_OS_BOOT_COMPLETE, ADSP_OS_SUSPEND,