summaryrefslogtreecommitdiff
path: root/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/nmf-cm/cm/engine/trace/src/panic.c')
-rw-r--r--drivers/staging/nmf-cm/cm/engine/trace/src/panic.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
new file mode 100644
index 00000000000..9cb1a729a92
--- /dev/null
+++ b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Jean-Philippe FASSINO <jean-philippe.fassino@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+#include <cm/inc/cm_type.h>
+#include <cm/engine/component/inc/introspection.h>
+#include <cm/engine/component/inc/bind.h>
+#include <cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h>
+#include <cm/engine/trace/inc/trace.h>
+#include <cm/engine/api/control/irq_engine.h>
+
+#include <cm/engine/utils/inc/convert.h>
+#include <share/communication/inc/nmf_service.h>
+
+
+/*
+ * Panic
+ */
+const struct {
+ char* name;
+ unsigned int info1:1;
+ unsigned int PC:1;
+ unsigned int SP:1;
+ unsigned int interface:1;
+} reason_descrs[] = {
+ {"NONE_PANIC", 0, 0, 0, 0},
+ {"INTERNAL_PANIC", 1, 0, 0, 0},
+ {"MPC_NOT_RESPONDING_PANIC", 0, 0, 0, 0}, /* Should not be useful since in that case CM_getServiceDescription() not call */
+ {"USER_STACK_OVERFLOW", 0, 1, 1, 0},
+ {"SYSTEM_STACK_OVERFLOW", 0, 1, 1, 0},
+ {"UNALIGNED_LONG_ACCESS", 0, 1, 0, 0},
+ {"EVENT_FIFO_OVERFLOW", 0, 0, 0, 1},
+ {"PARAM_FIFO_OVERFLOW", 0, 0, 0, 1},
+ {"INTERFACE_NOT_BINDED", 0, 1, 0, 0},
+ {"USER_PANIC", 1, 0, 0, 0}
+};
+
+static t_component_instance* getCorrespondingInstance(
+ t_panic_reason panicReason,
+ t_uint32 panicThis,
+ t_dup_char *itfName,
+ t_cm_instance_handle *instHandle) {
+ t_component_instance *instance;
+ t_uint32 k;
+
+ for (k=0; k<ComponentTable.idxMax; k++) {
+ if ((instance = componentEntry(k)) == NULL)
+ continue;
+ if(panicReason == PARAM_FIFO_OVERFLOW ||
+ panicReason == EVENT_FIFO_OVERFLOW) {
+ // Panic has been generated by binding component, search the client who has call it
+ // and return the client handle (not the BC one).
+ int i;
+
+ if(instance->thisAddress == panicThis && panicThis == 0) {
+ *itfName = "Internal NMF service";
+ *instHandle = ENTRY2HANDLE(instance, k);
+ return instance;
+ }
+
+ for(i = 0; i < instance->Template->requireNumber; i++) {
+ int nb = instance->Template->requires[i].collectionSize, j;
+ for(j = 0; j < nb; j++) {
+ if(instance->interfaceReferences[i][j].instance != NULL &&
+ instance->interfaceReferences[i][j].instance != (t_component_instance *)NMF_HOST_COMPONENT &&
+ instance->interfaceReferences[i][j].instance != (t_component_instance *)NMF_VOID_COMPONENT &&
+ instance->interfaceReferences[i][j].instance->thisAddress == panicThis)
+ {
+ *itfName = instance->Template->requires[i].name;
+ *instHandle = ENTRY2HANDLE(instance, k);
+ return instance;
+ }
+ }
+ }
+ } else {
+ // The component which has generated the panic is the good one.
+
+ if(instance->thisAddress == panicThis) {
+ *itfName = "?";
+ *instHandle = ENTRY2HANDLE(instance, k);
+ return instance;
+ }
+ }
+ }
+
+ *itfName = "?";
+ *instHandle = 0;
+ return 0;
+}
+
+PUBLIC EXPORT_SHARED t_cm_error CM_ReadMPCString(
+ t_nmf_core_id coreId,
+ t_uint32 dspAddress,
+ char * buffer,
+ t_uint32 bufferSize) {
+
+ while(--bufferSize > 0)
+ {
+ char ch = cm_DSP_ReadXRamWord(coreId, dspAddress++);
+ if(ch == 0)
+ break;
+
+ *buffer++ = ch;
+ };
+
+ *buffer = 0;
+
+ // Reset panicReason
+ cm_writeAttribute(cm_EEM_getExecutiveEngine(coreId)->instance,
+ "rtos/commonpart/serviceReason", MPC_SERVICE_NONE);
+
+ return CM_OK;
+}
+
+/****************/
+/* Generic part */
+/****************/
+PUBLIC EXPORT_SHARED t_cm_error CM_getServiceDescription(
+ t_nmf_core_id coreId,
+ t_cm_service_type *srcType,
+ t_cm_service_description *srcDescr)
+{
+ t_uint32 serviceReason;
+ t_component_instance *ee;
+
+ // Acknowledge interrupt (do it before resetting panicReason)
+ cm_DSP_AcknowledgeDspIrq(coreId, DSP2ARM_IRQ_1);
+
+ ee = cm_EEM_getExecutiveEngine(coreId)->instance;
+
+ // Read panicReason
+ serviceReason = cm_readAttributeNoError(ee, "rtos/commonpart/serviceReason");
+ if(serviceReason == MPC_SERVICE_PRINT)
+ {
+ *srcType = CM_MPC_SERVICE_PRINT;
+
+ srcDescr->u.print.dspAddress = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo0");
+ srcDescr->u.print.value1 = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo1");
+ srcDescr->u.print.value2 = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo2");
+ }
+ else if(serviceReason != MPC_SERVICE_NONE)
+ {
+ t_uint32 panicThis;
+ t_dup_char itfName;
+ t_component_instance *instance;
+
+ *srcType = CM_MPC_SERVICE_PANIC;
+ srcDescr->u.panic.panicReason = (t_panic_reason)serviceReason;
+ srcDescr->u.panic.panicSource = MPC_EE;
+ srcDescr->u.panic.info.mpc.coreid = coreId;
+
+ // Read panicThis
+ panicThis = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo0");
+
+ instance = getCorrespondingInstance(srcDescr->u.panic.panicReason, panicThis, &itfName, &srcDescr->u.panic.info.mpc.faultingComponent);
+
+ LOG_INTERNAL(0, "Error: Panic(%s, %s), This=%x", cm_getDspName(coreId),
+ reason_descrs[srcDescr->u.panic.panicReason].name, (void*)panicThis, 0, 0, 0);
+
+ if(reason_descrs[srcDescr->u.panic.panicReason].interface != 0)
+ {
+ LOG_INTERNAL(0, ", interface=%s", itfName, 0, 0, 0, 0, 0);
+ }
+
+ if(reason_descrs[srcDescr->u.panic.panicReason].info1 != 0)
+ {
+ // Info 1
+ srcDescr->u.panic.info.mpc.panicInfo1 = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo1");
+
+ LOG_INTERNAL(0, ", Info=%x", srcDescr->u.panic.info.mpc.panicInfo1, 0, 0, 0, 0, 0);
+ }
+
+ if(reason_descrs[srcDescr->u.panic.panicReason].PC != 0)
+ {
+ t_uint32 DspAddress = 0xFFFFFFFF;
+ t_uint32 DspSize = 0x0;
+
+ // PC need to be read in rtos/commonpart/serviceInfo1
+ srcDescr->u.panic.info.mpc.panicInfo1 = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo1");
+
+ if(instance != 0)
+ {
+ cm_DSP_GetDspAddress(instance->memories[instance->Template->codeMemory->id], &DspAddress);
+ cm_DSP_GetDspMemoryHandleSize(instance->memories[instance->Template->codeMemory->id], &DspSize);
+ }
+
+ if(DspAddress <= srcDescr->u.panic.info.mpc.panicInfo1 &&
+ srcDescr->u.panic.info.mpc.panicInfo1 < (DspAddress + DspSize))
+ LOG_INTERNAL(0, ", PC:off=%x <abs=%x>",
+ srcDescr->u.panic.info.mpc.panicInfo1 - DspAddress,
+ srcDescr->u.panic.info.mpc.panicInfo1, 0, 0, 0, 0);
+ else
+ LOG_INTERNAL(0, ", PC:<abs=%x>", srcDescr->u.panic.info.mpc.panicInfo1, 0, 0, 0, 0, 0);
+ }
+
+ if(reason_descrs[srcDescr->u.panic.panicReason].SP != 0)
+ {
+ srcDescr->u.panic.info.mpc.panicInfo2 = cm_readAttributeNoError(ee, "rtos/commonpart/serviceInfo2");
+
+ LOG_INTERNAL(0, ", SP=%x", srcDescr->u.panic.info.mpc.panicInfo2, 0, 0, 0, 0, 0);
+ }
+
+ LOG_INTERNAL(0, "\n", 0, 0, 0, 0, 0, 0);
+
+ if(instance != 0)
+ {
+ LOG_INTERNAL(0, "Error: Component=%s<%s>\n",
+ instance->pathname, instance->Template->name, 0, 0, 0, 0);
+ }
+
+ // We don't set rtos/commonpart/serviceReason = MPC_SERVICE_NONE, since we don't want the
+ // MMDSP to continue execution, and we put in in Panic state
+ cm_DSP_SetStatePanic(coreId);
+ }
+ else
+ {
+ *srcType = CM_MPC_SERVICE_NONE;
+ }
+
+ return CM_OK;
+}