Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license.  When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2018 Intel Corporation. All rights reserved.
0007 //
0008 // Author: Pan Xiuli <xiuli.pan@linux.intel.com>
0009 //
0010 
0011 #include <linux/module.h>
0012 #include <sound/sof.h>
0013 #include <sound/sof/xtensa.h>
0014 #include "../sof-priv.h"
0015 
0016 struct xtensa_exception_cause {
0017     u32 id;
0018     const char *msg;
0019     const char *description;
0020 };
0021 
0022 /*
0023  * From 4.4.1.5 table 4-64 Exception Causes of Xtensa
0024  * Instruction Set Architecture (ISA) Reference Manual
0025  */
0026 static const struct xtensa_exception_cause xtensa_exception_causes[] = {
0027     {0, "IllegalInstructionCause", "Illegal instruction"},
0028     {1, "SyscallCause", "SYSCALL instruction"},
0029     {2, "InstructionFetchErrorCause",
0030     "Processor internal physical address or data error during instruction fetch"},
0031     {3, "LoadStoreErrorCause",
0032     "Processor internal physical address or data error during load or store"},
0033     {4, "Level1InterruptCause",
0034     "Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register"},
0035     {5, "AllocaCause",
0036     "MOVSP instruction, if caller’s registers are not in the register file"},
0037     {6, "IntegerDivideByZeroCause",
0038     "QUOS, QUOU, REMS, or REMU divisor operand is zero"},
0039     {8, "PrivilegedCause",
0040     "Attempt to execute a privileged operation when CRING ? 0"},
0041     {9, "LoadStoreAlignmentCause", "Load or store to an unaligned address"},
0042     {12, "InstrPIFDataErrorCause",
0043     "PIF data error during instruction fetch"},
0044     {13, "LoadStorePIFDataErrorCause",
0045     "Synchronous PIF data error during LoadStore access"},
0046     {14, "InstrPIFAddrErrorCause",
0047     "PIF address error during instruction fetch"},
0048     {15, "LoadStorePIFAddrErrorCause",
0049     "Synchronous PIF address error during LoadStore access"},
0050     {16, "InstTLBMissCause", "Error during Instruction TLB refill"},
0051     {17, "InstTLBMultiHitCause",
0052     "Multiple instruction TLB entries matched"},
0053     {18, "InstFetchPrivilegeCause",
0054     "An instruction fetch referenced a virtual address at a ring level less than CRING"},
0055     {20, "InstFetchProhibitedCause",
0056     "An instruction fetch referenced a page mapped with an attribute that does not permit instruction fetch"},
0057     {24, "LoadStoreTLBMissCause",
0058     "Error during TLB refill for a load or store"},
0059     {25, "LoadStoreTLBMultiHitCause",
0060     "Multiple TLB entries matched for a load or store"},
0061     {26, "LoadStorePrivilegeCause",
0062     "A load or store referenced a virtual address at a ring level less than CRING"},
0063     {28, "LoadProhibitedCause",
0064     "A load referenced a page mapped with an attribute that does not permit loads"},
0065     {32, "Coprocessor0Disabled",
0066     "Coprocessor 0 instruction when cp0 disabled"},
0067     {33, "Coprocessor1Disabled",
0068     "Coprocessor 1 instruction when cp1 disabled"},
0069     {34, "Coprocessor2Disabled",
0070     "Coprocessor 2 instruction when cp2 disabled"},
0071     {35, "Coprocessor3Disabled",
0072     "Coprocessor 3 instruction when cp3 disabled"},
0073     {36, "Coprocessor4Disabled",
0074     "Coprocessor 4 instruction when cp4 disabled"},
0075     {37, "Coprocessor5Disabled",
0076     "Coprocessor 5 instruction when cp5 disabled"},
0077     {38, "Coprocessor6Disabled",
0078     "Coprocessor 6 instruction when cp6 disabled"},
0079     {39, "Coprocessor7Disabled",
0080     "Coprocessor 7 instruction when cp7 disabled"},
0081 };
0082 
0083 /* only need xtensa atm */
0084 static void xtensa_dsp_oops(struct snd_sof_dev *sdev, const char *level, void *oops)
0085 {
0086     struct sof_ipc_dsp_oops_xtensa *xoops = oops;
0087     int i;
0088 
0089     dev_printk(level, sdev->dev, "error: DSP Firmware Oops\n");
0090     for (i = 0; i < ARRAY_SIZE(xtensa_exception_causes); i++) {
0091         if (xtensa_exception_causes[i].id == xoops->exccause) {
0092             dev_printk(level, sdev->dev,
0093                    "error: Exception Cause: %s, %s\n",
0094                    xtensa_exception_causes[i].msg,
0095                    xtensa_exception_causes[i].description);
0096         }
0097     }
0098     dev_printk(level, sdev->dev,
0099            "EXCCAUSE 0x%8.8x EXCVADDR 0x%8.8x PS       0x%8.8x SAR     0x%8.8x\n",
0100            xoops->exccause, xoops->excvaddr, xoops->ps, xoops->sar);
0101     dev_printk(level, sdev->dev,
0102            "EPC1     0x%8.8x EPC2     0x%8.8x EPC3     0x%8.8x EPC4    0x%8.8x",
0103            xoops->epc1, xoops->epc2, xoops->epc3, xoops->epc4);
0104     dev_printk(level, sdev->dev,
0105            "EPC5     0x%8.8x EPC6     0x%8.8x EPC7     0x%8.8x DEPC    0x%8.8x",
0106            xoops->epc5, xoops->epc6, xoops->epc7, xoops->depc);
0107     dev_printk(level, sdev->dev,
0108            "EPS2     0x%8.8x EPS3     0x%8.8x EPS4     0x%8.8x EPS5    0x%8.8x",
0109            xoops->eps2, xoops->eps3, xoops->eps4, xoops->eps5);
0110     dev_printk(level, sdev->dev,
0111            "EPS6     0x%8.8x EPS7     0x%8.8x INTENABL 0x%8.8x INTERRU 0x%8.8x",
0112            xoops->eps6, xoops->eps7, xoops->intenable, xoops->interrupt);
0113 }
0114 
0115 static void xtensa_stack(struct snd_sof_dev *sdev, const char *level, void *oops,
0116              u32 *stack, u32 stack_words)
0117 {
0118     struct sof_ipc_dsp_oops_xtensa *xoops = oops;
0119     u32 stack_ptr = xoops->plat_hdr.stackptr;
0120     /* 4 * 8chars + 3 ws + 1 terminating NUL */
0121     unsigned char buf[4 * 8 + 3 + 1];
0122     int i;
0123 
0124     dev_printk(level, sdev->dev, "stack dump from 0x%8.8x\n", stack_ptr);
0125 
0126     /*
0127      * example output:
0128      * 0x0049fbb0: 8000f2d0 0049fc00 6f6c6c61 00632e63
0129      */
0130     for (i = 0; i < stack_words; i += 4) {
0131         hex_dump_to_buffer(stack + i, 16, 16, 4,
0132                    buf, sizeof(buf), false);
0133         dev_printk(level, sdev->dev, "0x%08x: %s\n", stack_ptr + i * 4, buf);
0134     }
0135 }
0136 
0137 const struct dsp_arch_ops sof_xtensa_arch_ops = {
0138     .dsp_oops = xtensa_dsp_oops,
0139     .dsp_stack = xtensa_stack,
0140 };
0141 EXPORT_SYMBOL_NS(sof_xtensa_arch_ops, SND_SOC_SOF_XTENSA);
0142 
0143 MODULE_DESCRIPTION("SOF Xtensa DSP support");
0144 MODULE_LICENSE("Dual BSD/GPL");