summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Peiffer <pierre.peiffer@stericsson.com>2011-10-28 11:12:48 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:07:04 +0200
commit877cccc561b35b59383487b2ac73e7d8e8ed2f4d (patch)
tree660a34937aa57f336537f89dbf3ca49216ff503a
parenta1fc7f07ad31944d0ba0b1a958193182155e4156 (diff)
U8500 CM: Add support to get DSP OST Trace on ARM
Provide two new devices /dev/cm_sia_trace and /dev/cm_sva_trace that allow any user to retrieve live OST traces coming from DSP components by doing 'cat /dev/cm_sia_trace > file.bin'. This traces are till now available through XTI device. This feature also requires some change in OSTTrace component to be fully operationnal. ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson ID: 324035 ST-Ericsson Linux next: NA Change-Id: I593c2f82be750bc1738281ee25d875b5a784ea04 Signed-off-by: Pierre Peiffer <pierre.peiffer@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42605 Reviewed-by: QABUILD
-rw-r--r--drivers/staging/nmf-cm/cm/engine/api/control/irq_engine.h14
-rw-r--r--drivers/staging/nmf-cm/cm/engine/communication/inc/communication_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/component/inc/component_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/configuration/inc/configuration_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c22
-rw-r--r--drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h6
-rw-r--r--drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/src/executive_engine_mgt.c13
-rw-r--r--drivers/staging/nmf-cm/cm/engine/memory/inc/domain_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/memory/inc/memory_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h4
-rw-r--r--drivers/staging/nmf-cm/cm/engine/perfmeter/inc/perfmeter_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/repository_mgt/inc/repository_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h8
-rw-r--r--drivers/staging/nmf-cm/cm/engine/trace/src/panic.c109
-rw-r--r--drivers/staging/nmf-cm/cm/inc/cm_type.h1
-rw-r--r--drivers/staging/nmf-cm/cm_debug.c2
-rw-r--r--drivers/staging/nmf-cm/cm_service.c10
-rw-r--r--drivers/staging/nmf-cm/cm_syscall.c6
-rw-r--r--drivers/staging/nmf-cm/cmioctl.h8
-rw-r--r--drivers/staging/nmf-cm/cmld.c448
-rw-r--r--drivers/staging/nmf-cm/cmld.h46
-rw-r--r--drivers/staging/nmf-cm/configuration.c46
-rw-r--r--drivers/staging/nmf-cm/configuration.h4
-rw-r--r--drivers/staging/nmf-cm/ee/api/panic.idt4
-rw-r--r--drivers/staging/nmf-cm/ee/api/trace.idt30
-rw-r--r--drivers/staging/nmf-cm/inc/nmf-def.h2
-rw-r--r--drivers/staging/nmf-cm/inc/nmf-limits.h1
-rw-r--r--drivers/staging/nmf-cm/inc/nmf-tracedescription.h1
-rw-r--r--drivers/staging/nmf-cm/inc/nmf_type.idt1
-rw-r--r--drivers/staging/nmf-cm/inc/type.h1
-rw-r--r--drivers/staging/nmf-cm/inc/typedef.h1
-rw-r--r--drivers/staging/nmf-cm/nmf/inc/channel_type.h1
-rw-r--r--drivers/staging/nmf-cm/nmf/inc/component_type.h1
-rw-r--r--drivers/staging/nmf-cm/nmf/inc/service_type.h1
-rw-r--r--drivers/staging/nmf-cm/osal-kernel.c22
-rw-r--r--drivers/staging/nmf-cm/osal-kernel.h6
-rw-r--r--drivers/staging/nmf-cm/share/communication/inc/nmf_service.h1
-rw-r--r--drivers/staging/nmf-cm/share/inc/macros.h1
-rw-r--r--drivers/staging/nmf-cm/share/inc/nmf.h1
39 files changed, 612 insertions, 217 deletions
diff --git a/drivers/staging/nmf-cm/cm/engine/api/control/irq_engine.h b/drivers/staging/nmf-cm/cm/engine/api/control/irq_engine.h
index 20313f13256..e3974764e91 100644
--- a/drivers/staging/nmf-cm/cm/engine/api/control/irq_engine.h
+++ b/drivers/staging/nmf-cm/cm/engine/api/control/irq_engine.h
@@ -14,6 +14,7 @@
#include <share/inc/nmf.h>
#include <cm/inc/cm_type.h>
#include <nmf/inc/service_type.h>
+#include <ee/api/trace.idt>
/*!
* \brief MPCs -> HOST communication handler
@@ -49,7 +50,8 @@ PUBLIC IMPORT_SHARED void CM_ProcessMpcEvent(t_nmf_core_id coreId);
typedef enum { // Allowed since i
CM_MPC_SERVICE_NONE = 0, //!< No service found
CM_MPC_SERVICE_PANIC = 1, //!< Panic service found
- CM_MPC_SERVICE_PRINT = 2 //!< Print service found
+ CM_MPC_SERVICE_PRINT = 2, //!< Print service found
+ CM_MPC_SERVICE_TRACE = 3 //!< Trace service found
} t_cm_service_type;
//!< Service description type
/*!
@@ -105,4 +107,14 @@ PUBLIC IMPORT_SHARED t_cm_error CM_ReadMPCString(
char * buffer,
t_uint32 bufferSize);
+typedef enum {
+ CM_MPC_TRACE_NONE = 0,
+ CM_MPC_TRACE_READ = 1,
+ CM_MPC_TRACE_READ_OVERRUN = 2
+} t_cm_trace_type;
+
+PUBLIC IMPORT_SHARED t_cm_trace_type CM_ENGINE_GetNextTrace(
+ t_nmf_core_id coreId,
+ struct t_nmf_trace *trace);
+
#endif /* CONTROL_IRQ_ENGINE_H */
diff --git a/drivers/staging/nmf-cm/cm/engine/communication/inc/communication_type.h b/drivers/staging/nmf-cm/cm/engine/communication/inc/communication_type.h
index db426845a82..53a6ff39b07 100644
--- a/drivers/staging/nmf-cm/cm/engine/communication/inc/communication_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/communication/inc/communication_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Communication Component Manager API type.
*/
diff --git a/drivers/staging/nmf-cm/cm/engine/component/inc/component_type.h b/drivers/staging/nmf-cm/cm/engine/component/inc/component_type.h
index 35571dde06d..2e769ec8b22 100644
--- a/drivers/staging/nmf-cm/cm/engine/component/inc/component_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/component/inc/component_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Components Component Manager API type.
*
diff --git a/drivers/staging/nmf-cm/cm/engine/configuration/inc/configuration_type.h b/drivers/staging/nmf-cm/cm/engine/configuration/inc/configuration_type.h
index abfe452cf78..af29d584ba4 100644
--- a/drivers/staging/nmf-cm/cm/engine/configuration/inc/configuration_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/configuration/inc/configuration_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Configuration Component Manager API type.
*/
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c
index 7950cd99007..274a1b6b59f 100644
--- a/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c
@@ -94,8 +94,26 @@ static t_interface_description* getInterfaceDescription(t_tmp_elfdescription *el
// Search if interfane already loaded
for(itf = interfaceList; itf != NULL; itf = itf->next) {
if(itf->type == itfType) {
- // TODO Sanity check
-
+ if (itf->methodNumber != elfitf->methodNumber) {
+ ERROR("When loading component template %s:\n\tNumber of methods in interface type %s\n\tdiffers from previous declaration: was %d, found %d\n",
+ getElfHeaderReference(elftmp, (void*)elftmp->elfheader->templateName), itfType, itf->methodNumber, elfitf->methodNumber, 0, 0);
+ //Do not fail for now for compatibility reason
+ //goto out_itf_type;
+ }
+ if (cmIntensiveCheckState) {
+ for(i = 0; i < itf->methodNumber; i++) {
+ if (cm_StringCompare(itf->methodNames[i], getElfHeaderReference(elftmp, (void*)elfitf->methodNames[i]), MAX_INTERNAL_STRING_LENGTH) != 0) {
+ ERROR("When loading component template %s:\n"
+ "\tName of method number %d in interface type %s\n"
+ "\tdiffers from previous declaration: previous name was %s, new name found is %s\n",
+ getElfHeaderReference(elftmp, (void*)elftmp->elfheader->templateName), i,
+ itfType, itf->methodNames[i],
+ getElfHeaderReference(elftmp, (void*)elfitf->methodNames[i]), 0);
+ //Do not fail for now for compatibility reason
+ //goto out_itf_type;
+ }
+ }
+ }
itf->referenceCounter++;
cm_StringRelease(itfType);
return itf;
diff --git a/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h b/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h
index aacffd15a17..0894410ae0d 100644
--- a/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h
+++ b/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h
@@ -24,6 +24,12 @@ typedef struct {
t_memory_handle handle;
t_cm_logical_address addr;
} panicArea;
+
+ // Trace Management
+ t_uint32 readTracePointer;
+ t_uint32 lastReadedTraceRevision;
+ t_memory_handle traceDataHandle;
+ struct t_nmf_trace *traceDataAddr;
} t_ee_state;
//TODO, juraj, this should be done more properly, like accessor method, instead making this global variable..
diff --git a/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/src/executive_engine_mgt.c b/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/src/executive_engine_mgt.c
index f2c833ff7dc..4df3d7ee0f5 100644
--- a/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/src/executive_engine_mgt.c
+++ b/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/src/executive_engine_mgt.c
@@ -21,6 +21,8 @@
#include <cm/engine/power_mgt/inc/power.h>
#include <cm/engine/perfmeter/inc/mpcload.h>
+#include <cm/engine/trace/inc/xtitrace.h>
+
#include <share/communication/inc/nmf_service.h>
t_ee_state eeState[NB_CORE_IDS];
@@ -130,6 +132,16 @@ PUBLIC t_cm_error cm_EEM_Init(
return error;
}
+ if((error = cm_SRV_allocateTraceBufferMemory(coreId, cm_DSP_GetState(coreId)->domainEE)) != CM_OK)
+ {
+ cm_PFM_deallocatePerfmeterDataMemory(coreId);
+ cm_EEM_freePanicArea(coreId);
+ cm_delayedDestroyComponent(eeState[coreId].instance);
+ eeState[coreId].instance = (t_component_instance *)0;
+ cm_DSP_Shutdown(coreId);
+ return error;
+ }
+
/* set initial stack value */
cm_writeAttribute(eeState[coreId].instance, "rtos/scheduler/topOfStack", cm_DSP_getStackAddr(coreId));
@@ -179,6 +191,7 @@ PUBLIC void cm_EEM_Close(t_nmf_core_id coreId)
cm_DSP_setStackSize(coreId, 0);
cm_delayedDestroyComponent(eeState[coreId].instance);
eeState[coreId].instance = (t_component_instance *)0;
+ cm_SRV_deallocateTraceBufferMemory(coreId);
cm_PFM_deallocatePerfmeterDataMemory(coreId);
cm_EEM_freePanicArea(coreId);
cm_DSP_Shutdown(coreId);
diff --git a/drivers/staging/nmf-cm/cm/engine/memory/inc/domain_type.h b/drivers/staging/nmf-cm/cm/engine/memory/inc/domain_type.h
index 7463f82eb89..354315d4d72 100644
--- a/drivers/staging/nmf-cm/cm/engine/memory/inc/domain_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/memory/inc/domain_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/***************************************************************************/
/* file : domain.h
* author : NMF team
diff --git a/drivers/staging/nmf-cm/cm/engine/memory/inc/memory_type.h b/drivers/staging/nmf-cm/cm/engine/memory/inc/memory_type.h
index 91246f1ec0e..dbdba4c3d9d 100644
--- a/drivers/staging/nmf-cm/cm/engine/memory/inc/memory_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/memory/inc/memory_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Public Component Manager Memory API type.
*
diff --git a/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h b/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h
index f57c92ea41b..c9ec864795f 100644
--- a/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h
+++ b/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h
@@ -44,6 +44,10 @@ typedef t_uint8 t_nmf_osal_sync_error;
#define SEM_TIMEOUT_NORMAL 3000
#define SEM_TIMEOUT_DEBUG 300000
+/*!
+ * \brief Operations used to support additionnal OS-specific debug feature
+ * \ingroup CM_ENGINE_OSAL_API
+ */
struct osal_debug_operations {
void (*component_create)(t_component_instance *component);
void (*component_destroy)(t_component_instance *component);
diff --git a/drivers/staging/nmf-cm/cm/engine/perfmeter/inc/perfmeter_type.h b/drivers/staging/nmf-cm/cm/engine/perfmeter/inc/perfmeter_type.h
index 78de395acc2..8733c20b21b 100644
--- a/drivers/staging/nmf-cm/cm/engine/perfmeter/inc/perfmeter_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/perfmeter/inc/perfmeter_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Public Component Manager Performance Meter API type.
*
diff --git a/drivers/staging/nmf-cm/cm/engine/repository_mgt/inc/repository_type.h b/drivers/staging/nmf-cm/cm/engine/repository_mgt/inc/repository_type.h
index 59abc269236..30ef8004c48 100644
--- a/drivers/staging/nmf-cm/cm/engine/repository_mgt/inc/repository_type.h
+++ b/drivers/staging/nmf-cm/cm/engine/repository_mgt/inc/repository_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Components Component Manager API type.
*
diff --git a/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h b/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h
index 6ab960b69b2..1efd4f1e699 100644
--- a/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h
+++ b/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h
@@ -39,4 +39,12 @@ void cm_TRC_traceMemAlloc(t_nmfTraceAllocatorCommandDescription command, t_uint8
void cm_TRC_traceMem(t_nmfTraceAllocCommandDescription command, t_uint8 allocId, t_uint32 startAddress, t_uint32 memorySize);
+/*************************/
+/* MMDSP trace buffer */
+/*************************/
+PUBLIC t_cm_error cm_SRV_allocateTraceBufferMemory(t_nmf_core_id coreId, t_cm_domain_id domainId);
+PUBLIC void cm_SRV_deallocateTraceBufferMemory(t_nmf_core_id coreId);
+
+
+
#endif /* __INC_CM_TRACE_H */
diff --git a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
index 9cb1a729a92..e59d9f8b1ba 100644
--- a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
+++ b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c
@@ -13,6 +13,111 @@
#include <cm/engine/utils/inc/convert.h>
#include <share/communication/inc/nmf_service.h>
+PUBLIC t_cm_error cm_SRV_allocateTraceBufferMemory(t_nmf_core_id coreId, t_cm_domain_id domainId)
+{
+ t_ee_state *state = cm_EEM_getExecutiveEngine(coreId);
+
+ state->traceDataHandle = cm_DM_Alloc(domainId, SDRAM_EXT16,
+ TRACE_BUFFER_SIZE * sizeof(struct t_nmf_trace) / 2, CM_MM_ALIGN_WORD, TRUE);
+ if (state->traceDataHandle == INVALID_MEMORY_HANDLE)
+ return CM_NO_MORE_MEMORY;
+ else
+ {
+ t_uint32 mmdspAddr;
+ int i;
+
+ state->traceDataAddr = (struct t_nmf_trace*)cm_DSP_GetHostLogicalAddress(state->traceDataHandle);
+ cm_DSP_GetDspAddress(state->traceDataHandle, &mmdspAddr);
+ cm_writeAttribute(state->instance, "rtos/commonpart/traceDataAddr", mmdspAddr);
+
+ eeState[coreId].readTracePointer = 0;
+ eeState[coreId].lastReadedTraceRevision = 0;
+
+ for(i = 0; i < TRACE_BUFFER_SIZE; i++)
+ state->traceDataAddr[i].revision = 0;
+
+ return CM_OK;
+ }
+}
+
+PUBLIC void cm_SRV_deallocateTraceBufferMemory(t_nmf_core_id coreId)
+{
+ t_ee_state *state = cm_EEM_getExecutiveEngine(coreId);
+
+ state->traceDataAddr = 0;
+ cm_DM_Free(state->traceDataHandle, TRUE);
+}
+
+static t_uint32 swapHalfWord(t_uint32 word)
+{
+ return (word >> 16) | (word << 16);
+}
+
+PUBLIC EXPORT_SHARED t_cm_trace_type CM_ENGINE_GetNextTrace(
+ t_nmf_core_id coreId,
+ struct t_nmf_trace *trace)
+{
+ t_ee_state *state = cm_EEM_getExecutiveEngine(coreId);
+ t_uint32 foundRevision;
+ t_cm_trace_type type;
+
+ OSAL_LOCK_API();
+ if (state->traceDataAddr == NULL) {
+ type = CM_MPC_TRACE_NONE;
+ goto out;
+ }
+
+ foundRevision = swapHalfWord(state->traceDataAddr[state->readTracePointer].revision);
+
+ if(foundRevision <= state->lastReadedTraceRevision)
+ {
+ // It's an old trace forgot it
+ type = CM_MPC_TRACE_NONE;
+ }
+ else
+ {
+ struct t_nmf_trace *traceRaw;
+
+ if(foundRevision == state->lastReadedTraceRevision + 1)
+ {
+ type = CM_MPC_TRACE_READ;
+ }
+ else
+ {
+ type = CM_MPC_TRACE_READ_OVERRUN;
+ /*
+ * If we find that revision is bigger, thus we are in overrun, then we take the writePointer + 1 which
+ * correspond to the older one.
+ * => Here there is a window where the MMDSP could update writePointer just after
+ */
+ state->readTracePointer = (cm_readAttributeNoError(state->instance, "rtos/commonpart/writePointer") + 1) % TRACE_BUFFER_SIZE;
+ }
+
+ traceRaw = &state->traceDataAddr[state->readTracePointer];
+
+ trace->timeStamp = swapHalfWord(traceRaw->timeStamp);
+ trace->componentId = swapHalfWord(traceRaw->componentId);
+ trace->traceId = swapHalfWord(traceRaw->traceId);
+ trace->paramOpt = swapHalfWord(traceRaw->paramOpt);
+ trace->componentHandle = swapHalfWord(traceRaw->componentHandle);
+ trace->parentHandle = swapHalfWord(traceRaw->parentHandle);
+
+ trace->params[0] = swapHalfWord(traceRaw->params[0]);
+ trace->params[1] = swapHalfWord(traceRaw->params[1]);
+ trace->params[2] = swapHalfWord(traceRaw->params[2]);
+ trace->params[3] = swapHalfWord(traceRaw->params[3]);
+
+ state->readTracePointer = (state->readTracePointer + 1) % TRACE_BUFFER_SIZE;
+ state->lastReadedTraceRevision = swapHalfWord(traceRaw->revision);
+ trace->revision = state->lastReadedTraceRevision;
+ }
+
+out:
+ OSAL_UNLOCK_API();
+
+ return type;
+}
+
/*
* Panic
@@ -139,6 +244,10 @@ PUBLIC EXPORT_SHARED t_cm_error CM_getServiceDescription(
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_TRACE)
+ {
+ *srcType = CM_MPC_SERVICE_TRACE;
+ }
else if(serviceReason != MPC_SERVICE_NONE)
{
t_uint32 panicThis;
diff --git a/drivers/staging/nmf-cm/cm/inc/cm_type.h b/drivers/staging/nmf-cm/cm/inc/cm_type.h
index 83a34ecd706..780e27ca600 100644
--- a/drivers/staging/nmf-cm/cm/inc/cm_type.h
+++ b/drivers/staging/nmf-cm/cm/inc/cm_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Component Manager types.
*
diff --git a/drivers/staging/nmf-cm/cm_debug.c b/drivers/staging/nmf-cm/cm_debug.c
index a934aa33e92..26446e19cdb 100644
--- a/drivers/staging/nmf-cm/cm_debug.c
+++ b/drivers/staging/nmf-cm/cm_debug.c
@@ -5,12 +5,12 @@
*/
#include <linux/proc_fs.h>
-#include <linux/sched.h>
#include "osal-kernel.h"
#include "cm_debug.h"
#ifdef CONFIG_DEBUG_FS
+#include <linux/sched.h>
static struct dentry *cm_dir; /* nmf-cm/ */
static struct dentry *proc_dir; /* nmf-cm/proc/ */
diff --git a/drivers/staging/nmf-cm/cm_service.c b/drivers/staging/nmf-cm/cm_service.c
index 70cf6f37524..a2a6ffa5b57 100644
--- a/drivers/staging/nmf-cm/cm_service.c
+++ b/drivers/staging/nmf-cm/cm_service.c
@@ -12,9 +12,9 @@
#include <linux/module.h>
#include <linux/plist.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock_types.h>
-#include <linux/sched.h>
#include <cm/engine/api/control/irq_engine.h>
@@ -71,7 +71,7 @@ void dispatch_service_msg(struct osal_msg *msg)
spin_lock_bh(&channelPriv->bh_lock);
plist_add(&new_msg->msg_entry, &channelPriv->messageQueue);
spin_unlock_bh(&channelPriv->bh_lock);
- wake_up_interruptible(&channelPriv->waitq);
+ wake_up(&channelPriv->waitq);
}
}
@@ -113,6 +113,12 @@ static void service_tasklet_func(unsigned long unused)
desc.u.print.value2);
break;
}
+ case CM_MPC_SERVICE_TRACE:
+ spin_lock_bh(&osalEnv.mpc[i].trace_reader_lock);
+ if (osalEnv.mpc[i].trace_reader)
+ wake_up_process(osalEnv.mpc[i].trace_reader);
+ spin_unlock_bh(&osalEnv.mpc[i].trace_reader_lock);
+ break;
default:
pr_err("[CM] %s: MPC Service Type %d not supported\n", __func__, type);
}
diff --git a/drivers/staging/nmf-cm/cm_syscall.c b/drivers/staging/nmf-cm/cm_syscall.c
index a687e0206a3..ca8d664abb4 100644
--- a/drivers/staging/nmf-cm/cm_syscall.c
+++ b/drivers/staging/nmf-cm/cm_syscall.c
@@ -5,11 +5,11 @@
*/
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <cm/engine/api/cm_engine.h>
-#include <linux/sched.h>
#include "cmioctl.h"
#include "osal-kernel.h"
#include "cmld.h"
@@ -1397,9 +1397,9 @@ int cmld_PrivReserveMemory(struct cm_process_priv *procPriv, unsigned int physAd
/* Mark this memory area reserved for a mapping for this thread ID */
/* It must not be already reserved but this should not happen */
if (curr->tid) {
- /*pr_err("%s: thread %d can't reseveved memory %x already "
+ pr_err("%s: thread %d can't reseveved memory %x already "
"reserved for %d\n",
- __func__, current->pid, physAddr, (int)curr->tid);*/
+ __func__, current->pid, physAddr, curr->tid);
err = -EBUSY;
} else {
curr->tid = current->pid;
diff --git a/drivers/staging/nmf-cm/cmioctl.h b/drivers/staging/nmf-cm/cmioctl.h
index 96481be38b8..5f7d5b6a349 100644
--- a/drivers/staging/nmf-cm/cmioctl.h
+++ b/drivers/staging/nmf-cm/cmioctl.h
@@ -29,9 +29,11 @@ enum cmdma_type {
CMDMA_PER_2_MEM
};
-#define CMLD_DEV_NAME \
- { "cm_control", \
- "cm_channel" \
+#define CMLD_DEV_NAME \
+ { "cm_control", \
+ "cm_channel", \
+ "cm_sia_trace", \
+ "cm_sva_trace", \
}
/*
diff --git a/drivers/staging/nmf-cm/cmld.c b/drivers/staging/nmf-cm/cmld.c
index ef9753de7a4..53e07cd3137 100644
--- a/drivers/staging/nmf-cm/cmld.c
+++ b/drivers/staging/nmf-cm/cmld.c
@@ -14,9 +14,9 @@
#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/mm.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
-#include <linux/sched.h>
#include <cm/inc/cm_def.h>
#include <cm/engine/api/cm_engine.h>
@@ -29,7 +29,7 @@
#include "cm_service.h"
#include "cm_dma.h"
-#define CMDRIVER_PATCH_VERSION 117
+#define CMDRIVER_PATCH_VERSION 122
#define O_FLUSH 0x1000000
static int cmld_major;
@@ -233,111 +233,6 @@ static void freeProcessPriv(struct kref *ref)
OSAL_Free(entry);
}
-/** Driver's open method
- * Allocates per-process resources: private data, wait queue,
- * memory area descriptors linked list, message queue.
- *
- * \return POSIX error code
- */
-static int cmld_open(struct inode *inode, struct file *file)
-{
- struct cm_process_priv *procPriv = getProcessPriv();
-
- if (IS_ERR(procPriv))
- return PTR_ERR(procPriv);
-
- if (iminor(inode) == 0)
- file->private_data = procPriv;
- else {
- struct cm_channel_priv *channelPriv = (struct cm_channel_priv*)OSAL_Alloc(sizeof(*channelPriv));
- if (channelPriv == NULL) {
- kref_put(&procPriv->ref, freeProcessPriv);
- return -ENOMEM;
- }
-
- channelPriv->proc = procPriv;
- channelPriv->state = CHANNEL_OPEN;
-
- /* Initialize wait_queue, lists and mutexes */
- init_waitqueue_head(&channelPriv->waitq);
- plist_head_init(&channelPriv->messageQueue);
- INIT_LIST_HEAD(&channelPriv->skelList);
- spin_lock_init(&channelPriv->bh_lock);
- mutex_init(&channelPriv->msgQueueLock);
- mutex_init(&channelPriv->skelListLock);
-
- tasklet_disable(&cmld_service_tasklet);
- mutex_lock(&channel_lock);
- list_add(&channelPriv->entry, &channel_list);
- mutex_unlock(&channel_lock);
- tasklet_enable(&cmld_service_tasklet);
-
- file->private_data = channelPriv; // store channel private struct in file descriptor
- }
- return 0;
-}
-
-/** Driver's release method.
- * Frees any per-process pending resource: components, bindings, memory areas.
- *
- * \return POSIX error code
- */
-static int cmld_release(struct inode *inode, struct file *file)
-{
- struct cm_process_priv* procPriv;
-
- /* The driver must guarantee that all related resources are released.
- Thus all these checks below are necessary to release all remaining
- resources still linked to this 'client', in case of abnormal process
- exit.
- => These are error cases !
- In the usual case, nothing should be done except the free of
- the cmPriv itself
- */
-
- if (iminor(inode) != 0) {
- struct cm_channel_priv* channelPriv;
- channelPriv = file->private_data;
- procPriv = channelPriv->proc;
-
- /* We don't need to synchronize here by using the skelListLock:
- the list is only accessed during ioctl() and we can't be here
- if an ioctl() is on-going */
- if (list_empty(&channelPriv->skelList)) {
- /* There is no pending MPC->HOST binding
- => we can quietly delete the channel */
- tasklet_disable(&cmld_service_tasklet);
- mutex_lock(&channel_lock);
- list_del(&channelPriv->entry);
- mutex_unlock(&channel_lock);
- tasklet_enable(&cmld_service_tasklet);
-
- /* Free all remaining messages if any */
- freeMessages(channelPriv);
-
- /* Free the per-channel descriptor */
- OSAL_Free(channelPriv);
- } else {
- /* Uh: there are still some MPC->HOST binding but we don't have the
- required info to unbind them.
- => we must keep all skel structures because possibly used in OSAL_PostDfc
- (incoming callback msg) */
- /* We flag the channel as closed to discard any new msg that will never be read anyway */
- channelPriv->state = CHANNEL_CLOSED;
-
- /* Already Free all remaining messages if any,
- they will never be read anyway */
- freeMessages(channelPriv);
- }
- } else
- procPriv = file->private_data;
-
- kref_put(&procPriv->ref, freeProcessPriv);
- file->private_data = NULL;
-
- return 0;
-}
-
/** Reads Component Manager messages destinated to this process.
* The message is composed by three fields:
* 1) mpc2host handle (distinguishes interfaces)
@@ -347,19 +242,16 @@ static int cmld_release(struct inode *inode, struct file *file)
* \note cfr GetEvent()
* \return POSIX error code
*/
-static ssize_t cmld_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t cmld_channel_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
int err = 0;
- struct cm_channel_priv* channelPriv = (struct cm_channel_priv*)(file->private_data);
+ struct cm_channel_priv* channelPriv = file->private_data;
int msgSize = 0;
struct plist_head* messageQueue;
struct osal_msg* msg;
t_os_message *os_msg = (t_os_message *)buf;
int block = !(file->f_flags & O_NONBLOCK);
- if (iminor(file->f_dentry->d_inode) == 0)
- return -ENOSYS;
-
messageQueue = &channelPriv->messageQueue;
if (mutex_lock_killable(&channelPriv->msgQueueLock))
@@ -459,19 +351,21 @@ out:
*
* \return POSIX error code
*/
-static int cmld_flush(struct file *file, fl_owner_t id)
+static int cmld_channel_flush(struct file *file, fl_owner_t id)
{
- if (iminor(file->f_dentry->d_inode) != 0) {
- struct cm_channel_priv* channelPriv = (struct cm_channel_priv*)(file->private_data);
- file->f_flags |= O_FLUSH;
- wake_up_interruptible(&channelPriv->waitq);
- }
+ struct cm_channel_priv* channelPriv = file->private_data;
+ file->f_flags |= O_FLUSH;
+ wake_up(&channelPriv->waitq);
return 0;
}
-static long cmld_channel_ctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long cmld_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct cm_channel_priv *channelPriv = file->private_data;
+#ifdef CONFIG_DEBUG_FS
+ if (wait_event_interruptible(dump_waitq, (!cmld_dump_ongoing)))
+ return -ERESTARTSYS;
+#endif
switch(cmd) {
/*
@@ -480,7 +374,7 @@ static long cmld_channel_ctl(struct file *file, unsigned int cmd, unsigned long
case CM_BINDCOMPONENTTOCMCORE:
return cmld_BindComponentToCMCore(channelPriv, (CM_BindComponentToCMCore_t *)arg);
case CM_FLUSHCHANNEL:
- return cmld_flush(file, 0);
+ return cmld_channel_flush(file, 0);
default:
pr_err("CM(%s): unsupported command %i\n", __func__, cmd);
return -EINVAL;
@@ -488,9 +382,18 @@ static long cmld_channel_ctl(struct file *file, unsigned int cmd, unsigned long
return 0;
}
-static long cmld_control_ctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long cmld_control_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct cm_process_priv* procPriv = file->private_data;
+#ifdef CONFIG_DEBUG_FS
+ if (cmd == CM_PRIV_DEBUGFS_DUMP_DONE) {
+ cmld_dump_ongoing = false;
+ wake_up(&dump_waitq);
+ return 0;
+ } else if (wait_event_interruptible(dump_waitq, (!cmld_dump_ongoing)))
+ return -ERESTARTSYS;
+#endif
+
switch(cmd) {
/*
* All wrapped CM SYSCALL
@@ -695,7 +598,6 @@ static long cmld_control_ctl(struct file *file, unsigned int cmd, unsigned long
cmld_user_has_debugfs = true;
#endif
return 0;
- case CM_PRIV_DEBUGFS_DUMP_DONE:
case CM_PRIV_DEBUGFS_WAIT_DUMP:
return 0;
default:
@@ -706,29 +608,6 @@ static long cmld_control_ctl(struct file *file, unsigned int cmd, unsigned long
return 0;
}
-/** Driver's ioctl method
- * Implements user/kernel crossing for SYSCALL API.
- *
- * \return POSIX error code
- */
-static long cmld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-#ifdef CONFIG_DEBUG_FS
- if (cmd == CM_PRIV_DEBUGFS_DUMP_DONE) {
- cmld_dump_ongoing = false;
- wake_up_interruptible(&dump_waitq);
- return 0;
- } else if (wait_event_interruptible(dump_waitq, (!cmld_dump_ongoing)))
- return -ERESTARTSYS;
-#endif
-
- if (iminor(filp->f_dentry->d_inode) == 0) {
- return cmld_control_ctl(filp, cmd, arg);
- } else {
- return cmld_channel_ctl(filp, cmd, arg);
- }
-}
-
/** VMA open callback function
*/
static void cmld_vma_open(struct vm_area_struct* vma) {
@@ -755,7 +634,7 @@ static struct vm_operations_struct cmld_remap_vm_ops = {
*
* \return POSIX error code
*/
-static int cmld_mmap(struct file* file, struct vm_area_struct* vma)
+static int cmld_control_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
struct list_head* listHead;
@@ -827,6 +706,278 @@ static int cmld_mmap(struct file* file, struct vm_area_struct* vma)
return 0;
}
+/* Driver's release method for /dev/cm_channel */
+static int cmld_channel_release(struct inode *inode, struct file *file)
+{
+ struct cm_channel_priv* channelPriv = file->private_data;
+ struct cm_process_priv* procPriv = channelPriv->proc;
+
+ /*
+ * The driver must guarantee that all related resources are released.
+ * Thus all these checks below are necessary to release all remaining
+ * resources still linked to this 'client', in case of abnormal process
+ * exit.
+ * => These are error cases !
+ * In the usual case, nothing should be done except the free of
+ * the cmPriv itself
+ */
+
+ /* We don't need to synchronize here by using the skelListLock:
+ the list is only accessed during ioctl() and we can't be here
+ if an ioctl() is on-going */
+ if (list_empty(&channelPriv->skelList)) {
+ /* There is no pending MPC->HOST binding
+ => we can quietly delete the channel */
+ tasklet_disable(&cmld_service_tasklet);
+ mutex_lock(&channel_lock);
+ list_del(&channelPriv->entry);
+ mutex_unlock(&channel_lock);
+ tasklet_enable(&cmld_service_tasklet);
+
+ /* Free all remaining messages if any */
+ freeMessages(channelPriv);
+
+ /* Free the per-channel descriptor */
+ OSAL_Free(channelPriv);
+ } else {
+ /*
+ * Uh: there are still some MPC->HOST binding but we don't have
+ * the required info to unbind them.
+ * => we must keep all skel structures because possibly used in
+ * OSAL_PostDfc (incoming callback msg). We flag the channel as
+ * closed to discard any new msg that will never be read anyway
+ */
+ channelPriv->state = CHANNEL_CLOSED;
+
+ /* Already Free all remaining messages if any,
+ they will never be read anyway */
+ freeMessages(channelPriv);
+ }
+
+ kref_put(&procPriv->ref, freeProcessPriv);
+ file->private_data = NULL;
+
+ return 0;
+}
+
+/* Driver's release method for /dev/cm_control */
+static int cmld_control_release(struct inode *inode, struct file *file)
+{
+ struct cm_process_priv* procPriv = file->private_data;
+
+ kref_put(&procPriv->ref, freeProcessPriv);
+ file->private_data = NULL;
+
+ return 0;
+}
+
+static struct file_operations cmld_control_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = cmld_control_ioctl,
+ .mmap = cmld_control_mmap,
+ .release = cmld_control_release,
+};
+
+static int cmld_control_open(struct file *file)
+{
+ struct cm_process_priv *procPriv = getProcessPriv();
+ if (IS_ERR(procPriv))
+ return PTR_ERR(procPriv);
+ file->private_data = procPriv;
+ file->f_op = &cmld_control_fops;
+ return 0;
+}
+
+static struct file_operations cmld_channel_fops = {
+ .owner = THIS_MODULE,
+ .read = cmld_channel_read,
+ .unlocked_ioctl = cmld_channel_ioctl,
+ .flush = cmld_channel_flush,
+ .release = cmld_channel_release,
+};
+
+static int cmld_channel_open(struct file *file)
+{
+ struct cm_process_priv *procPriv = getProcessPriv();
+ struct cm_channel_priv *channelPriv;
+
+ if (IS_ERR(procPriv))
+ return PTR_ERR(procPriv);
+
+ channelPriv = (struct cm_channel_priv*)OSAL_Alloc(sizeof(*channelPriv));
+ if (channelPriv == NULL) {
+ kref_put(&procPriv->ref, freeProcessPriv);
+ return -ENOMEM;
+ }
+
+ channelPriv->proc = procPriv;
+ channelPriv->state = CHANNEL_OPEN;
+
+ /* Initialize wait_queue, lists and mutexes */
+ init_waitqueue_head(&channelPriv->waitq);
+ plist_head_init(&channelPriv->messageQueue);
+ INIT_LIST_HEAD(&channelPriv->skelList);
+ spin_lock_init(&channelPriv->bh_lock);
+ mutex_init(&channelPriv->msgQueueLock);
+ mutex_init(&channelPriv->skelListLock);
+
+ tasklet_disable(&cmld_service_tasklet);
+ mutex_lock(&channel_lock);
+ list_add(&channelPriv->entry, &channel_list);
+ mutex_unlock(&channel_lock);
+ tasklet_enable(&cmld_service_tasklet);
+
+ file->private_data = channelPriv;
+ file->f_op = &cmld_channel_fops;
+ return 0;
+}
+
+static ssize_t cmld_sxa_trace_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct mpcConfig *mpc = file->private_data;
+ size_t written = 0;
+ struct t_nmf_trace trace;
+ t_cm_trace_type traceType;
+ struct mmdsp_trace mmdsp_tr = {
+ .media = TB_MEDIA_FILE,
+ .receiver_dev = TB_DEV_PC,
+ .sender_dev = TB_DEV_TRACEBOX,
+ .unused = TB_TRACEBOX,
+ .receiver_obj = DEFAULT_RECEIVERR_OBJ,
+ .sender_obj = DEFAULT_SENDER_OBJ,
+ .transaction_id = 0,
+ .message_id = TB_TRACE_MSG,
+ .master_id = mpc->coreId+1,
+ .channel_id = 0,
+ .ost_version = OST_VERSION,
+ .entity = ENTITY,
+ .protocol_id = PROTOCOL_ID,
+ .btrace_hdr_flag = 0,
+ .btrace_hdr_subcategory = 0,
+ };
+
+ while ((count - written) >= sizeof(mmdsp_tr)) {
+ traceType = CM_ENGINE_GetNextTrace(mpc->coreId, &trace);
+
+ switch (traceType) {
+ case CM_MPC_TRACE_READ_OVERRUN:
+ mmdsp_tr.size =
+ cpu_to_be16(offsetof(struct mmdsp_trace,
+ ost_version)
+ -offsetof(struct mmdsp_trace,
+ receiver_obj));
+ mmdsp_tr.message_id = TB_TRACE_EXCEPTION_MSG;
+ mmdsp_tr.ost_master_id = TB_EXCEPTION_LONG_OVRF_PACKET;
+ if (copy_to_user(&buf[written], &mmdsp_tr,
+ offsetof(struct mmdsp_trace,
+ ost_version)))
+ return -EFAULT;
+ written += offsetof(struct mmdsp_trace, ost_version);
+ if ((count - written) < sizeof(mmdsp_tr))
+ break;
+ case CM_MPC_TRACE_READ: {
+ u16 param_nr = (u16)trace.paramOpt;
+ u16 handle_valid = (u16)(trace.paramOpt >> 16);
+ u32 to_write = offsetof(struct mmdsp_trace,
+ parent_handle);
+ mmdsp_tr.transaction_id = trace.revision%256;
+ mmdsp_tr.message_id = TB_TRACE_MSG;
+ mmdsp_tr.ost_master_id = OST_MASTERID;
+ mmdsp_tr.timestamp = cpu_to_be64(trace.timeStamp);
+ mmdsp_tr.timestamp2 = cpu_to_be64(trace.timeStamp);
+ mmdsp_tr.component_id = cpu_to_be32(trace.componentId);
+ mmdsp_tr.trace_id = cpu_to_be32(trace.traceId);
+ mmdsp_tr.btrace_hdr_category = (trace.traceId>>16)&0xFF;
+ mmdsp_tr.btrace_hdr_size = BTRACE_HEADER_SIZE
+ + sizeof(trace.params[0]) * param_nr;
+ if (handle_valid) {
+ mmdsp_tr.parent_handle = trace.parentHandle;
+ mmdsp_tr.component_handle =
+ trace.componentHandle;
+ to_write += sizeof(trace.parentHandle)
+ + sizeof(trace.componentHandle);
+ mmdsp_tr.btrace_hdr_size +=
+ sizeof(trace.parentHandle)
+ + sizeof(trace.componentHandle);
+ }
+ mmdsp_tr.size =
+ cpu_to_be16(to_write
+ + (sizeof(trace.params[0])*param_nr)
+ - offsetof(struct mmdsp_trace,
+ receiver_obj));
+ mmdsp_tr.length = to_write
+ + (sizeof(trace.params[0])*param_nr)
+ - offsetof(struct mmdsp_trace,
+ timestamp2);
+ if (copy_to_user(&buf[written], &mmdsp_tr, to_write))
+ return -EFAULT;
+ written += to_write;
+ /* write param */
+ to_write = sizeof(trace.params[0]) * param_nr;
+ if (copy_to_user(&buf[written], trace.params, to_write))
+ return -EFAULT;
+ written += to_write;
+ break;
+ }
+ case CM_MPC_TRACE_NONE:
+ default:
+ if ((file->f_flags & O_NONBLOCK) || written)
+ return written;
+ spin_lock_bh(&mpc->trace_reader_lock);
+ mpc->trace_reader = current;
+ spin_unlock_bh(&mpc->trace_reader_lock);
+ schedule_timeout_killable(msecs_to_jiffies(200));
+ spin_lock_bh(&mpc->trace_reader_lock);
+ mpc->trace_reader = NULL;
+ spin_unlock_bh(&mpc->trace_reader_lock);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ }
+ }
+ return written;
+}
+
+/* Driver's release method for /dev/cm_sxa_trace */
+static int cmld_sxa_trace_release(struct inode *inode, struct file *file)
+{
+ struct mpcConfig *mpc = file->private_data;
+ atomic_dec(&mpc->trace_read_count);
+ return 0;
+}
+
+static struct file_operations cmld_sxa_trace_fops = {
+ .owner = THIS_MODULE,
+ .read = cmld_sxa_trace_read,
+ .release = cmld_sxa_trace_release,
+};
+
+static int cmld_sxa_trace_open(struct file *file, struct mpcConfig *mpc)
+{
+ if (atomic_add_unless(&mpc->trace_read_count, 1, 1) == 0)
+ return -EBUSY;
+
+ file->private_data = mpc;
+ file->f_op = &cmld_sxa_trace_fops;
+ return 0;
+}
+
+/* driver open() call: specific */
+static int cmld_open(struct inode *inode, struct file *file)
+{
+ switch (iminor(inode)) {
+ case 0:
+ return cmld_control_open(file);
+ case 1:
+ return cmld_channel_open(file);
+ case 2:
+ return cmld_sxa_trace_open(file, &osalEnv.mpc[SIA]);
+ case 3:
+ return cmld_sxa_trace_open(file, &osalEnv.mpc[SVA]);
+ default:
+ return -ENOSYS;
+ }
+}
+
/** MPC Events tasklet
* The parameter is used to know from which interrupts we're comming
* and which core to pass to CM_ProcessMpcEvent():
@@ -882,12 +1033,7 @@ static irqreturn_t panic_handler(int irq, void *idx)
*/
static struct file_operations cmld_fops = {
.owner = THIS_MODULE,
- .read = cmld_read,
- .unlocked_ioctl = cmld_ioctl,
- .mmap = cmld_mmap,
.open = cmld_open,
- .flush = cmld_flush,
- .release = cmld_release,
};
/**
diff --git a/drivers/staging/nmf-cm/cmld.h b/drivers/staging/nmf-cm/cmld.h
index 4c5a5bed7e6..17e6c55ff61 100644
--- a/drivers/staging/nmf-cm/cmld.h
+++ b/drivers/staging/nmf-cm/cmld.h
@@ -79,6 +79,52 @@ extern bool cmld_user_has_debugfs; /**< Whether user side has proper support of
extern bool cmld_dump_ongoing; /**< Whether a dump is on-going */
#endif
+/* Structure used to embed DSP traces */
+#define TB_MEDIA_FILE 0x1C
+#define TB_DEV_PC 0x10
+#define TB_DEV_TRACEBOX 0x4C
+#define TB_TRACEBOX 0x7C
+#define DEFAULT_RECEIVERR_OBJ 0x0
+#define DEFAULT_SENDER_OBJ 0x0A
+#define TB_TRACE_MSG 0x94
+#define TB_TRACE_EXCEPTION_MSG 0x95
+#define TB_EXCEPTION_LONG_OVRF_PACKET 0x07
+#define OST_MASTERID 0x08
+#define OST_VERSION 0x05
+#define ENTITY 0xAA
+#define PROTOCOL_ID 0x03
+#define BTRACE_HEADER_SIZE 4
+
+struct __attribute__ ((__packed__)) mmdsp_trace {
+ u8 media;
+ u8 receiver_dev;
+ u8 sender_dev;
+ u8 unused;
+ u16 size;
+ u8 receiver_obj;
+ u8 sender_obj;
+ u8 transaction_id;
+ u8 message_id;
+ u8 master_id;
+ u8 channel_id;
+ u64 timestamp;
+ u8 ost_master_id;
+ u8 ost_version;
+ u8 entity;
+ u8 protocol_id;
+ u8 length;
+ u64 timestamp2;
+ u32 component_id;
+ u32 trace_id;
+ u8 btrace_hdr_size;
+ u8 btrace_hdr_flag;
+ u8 btrace_hdr_category;
+ u8 btrace_hdr_subcategory;
+ u32 parent_handle;
+ u32 component_handle;
+ u32 params[4];
+};
+
/** Lock/unlock per process mutex
*
* \note Must be taken before tasklet_disable (if necessary)!
diff --git a/drivers/staging/nmf-cm/configuration.c b/drivers/staging/nmf-cm/configuration.c
index d62bcb45500..523874fc586 100644
--- a/drivers/staging/nmf-cm/configuration.c
+++ b/drivers/staging/nmf-cm/configuration.c
@@ -21,28 +21,30 @@ struct OsalEnvironment osalEnv =
{
.mpc = {
{
- .coreId = SVA_CORE_ID,
- .name = "sva",
- .base_phys = (void*)U8500_SVA_BASE,
- .interrupt0 = IRQ_DB8500_SVA,
- .interrupt1 = IRQ_DB8500_SVA2,
- .mmdsp_regulator = NULL,
- .pipe_regulator = NULL,
- .monitor_tsk = NULL,
- .hwmem_code = NULL,
- .hwmem_data = NULL,
+ .coreId = SVA_CORE_ID,
+ .name = "sva",
+ .base_phys = (void*)U8500_SVA_BASE,
+ .interrupt0 = IRQ_DB8500_SVA,
+ .interrupt1 = IRQ_DB8500_SVA2,
+ .mmdsp_regulator = NULL,
+ .pipe_regulator = NULL,
+ .monitor_tsk = NULL,
+ .hwmem_code = NULL,
+ .hwmem_data = NULL,
+ .trace_read_count = ATOMIC_INIT(0),
},
{
- .coreId = SIA_CORE_ID,
- .name = "sia",
- .base_phys = (void*)U8500_SIA_BASE,
- .interrupt0 = IRQ_DB8500_SIA,
- .interrupt1 = IRQ_DB8500_SIA2,
- .mmdsp_regulator = NULL,
- .pipe_regulator = NULL,
- .monitor_tsk = NULL,
- .hwmem_code = NULL,
- .hwmem_data = NULL,
+ .coreId = SIA_CORE_ID,
+ .name = "sia",
+ .base_phys = (void*)U8500_SIA_BASE,
+ .interrupt0 = IRQ_DB8500_SIA,
+ .interrupt1 = IRQ_DB8500_SIA2,
+ .mmdsp_regulator = NULL,
+ .pipe_regulator = NULL,
+ .monitor_tsk = NULL,
+ .hwmem_code = NULL,
+ .hwmem_data = NULL,
+ .trace_read_count = ATOMIC_INIT(0),
}
},
.esram_regulator = { NULL, NULL},
@@ -125,16 +127,20 @@ int init_config(void)
pr_err("SDRAM data size for SVA must be greater than 0\n");
return -EINVAL;
}
+
osalEnv.mpc[SVA].nbYramBanks = cfgMpcYBanks_SVA;
osalEnv.mpc[SVA].eeId = cfgSchedulerTypeHybrid_SVA ? HYBRID_EXECUTIVE_ENGINE : SYNCHRONOUS_EXECUTIVE_ENGINE;
osalEnv.mpc[SVA].sdram_code.size = cfgMpcSDRAMCodeSize_SVA * ONE_KB;
osalEnv.mpc[SVA].sdram_data.size = cfgMpcSDRAMDataSize_SVA * ONE_KB;
osalEnv.mpc[SVA].base.size = 128*ONE_KB; //we expose only TCM24
+ spin_lock_init(&osalEnv.mpc[SVA].trace_reader_lock);
+
osalEnv.mpc[SIA].nbYramBanks = cfgMpcYBanks_SIA;
osalEnv.mpc[SIA].eeId = cfgSchedulerTypeHybrid_SIA ? HYBRID_EXECUTIVE_ENGINE : SYNCHRONOUS_EXECUTIVE_ENGINE;
osalEnv.mpc[SIA].sdram_code.size = cfgMpcSDRAMCodeSize_SIA * ONE_KB;
osalEnv.mpc[SIA].sdram_data.size = cfgMpcSDRAMDataSize_SIA * ONE_KB;
osalEnv.mpc[SIA].base.size = 128*ONE_KB; //we expose only TCM24
+ spin_lock_init(&osalEnv.mpc[SIA].trace_reader_lock);
return 0;
}
diff --git a/drivers/staging/nmf-cm/configuration.h b/drivers/staging/nmf-cm/configuration.h
index 35072831a13..f4146dc6117 100644
--- a/drivers/staging/nmf-cm/configuration.h
+++ b/drivers/staging/nmf-cm/configuration.h
@@ -20,12 +20,14 @@
#endif
/* Embedded Static RAM base address */
-#define ESRAM_BASE (U8500_ESRAM_BASE + 0x10000) // V1/V2 config: 0-64k: secure;
+/* config: 0-64k: secure */
+#define ESRAM_BASE (U8500_ESRAM_BASE + U8500_ESRAM_DMA_LCPA_OFFSET)
/*
* Embedded ram size for CM (in Kb)
* 5 banks of 128k: skip the first half bank (secure) and the last
* one (used for MCDE/B2R2), but include DMA part (4k after the secure part)
+ * to give access from DSP side
*/
#define ESRAM_SIZE 448
enum {
diff --git a/drivers/staging/nmf-cm/ee/api/panic.idt b/drivers/staging/nmf-cm/ee/api/panic.idt
index f971fdad8c5..71996b8a55e 100644
--- a/drivers/staging/nmf-cm/ee/api/panic.idt
+++ b/drivers/staging/nmf-cm/ee/api/panic.idt
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \defgroup NMF_EE_TYPE Execution Engine Common Type Definitions
* \ingroup COMMON
@@ -55,7 +54,8 @@ typedef enum {
INTERFACE_NOT_BINDED = 8,
USER_PANIC = 9,
UNBIND_INTERRUPT = 10,
- EVENT_FIFO_IN_USE = 11
+ EVENT_FIFO_IN_USE = 11,
+ RESERVED_PANIC = 2 //for COMPATIBILITY with previous versions of NMF, to be deprecated
} t_panic_reasonDescription;
/*!
diff --git a/drivers/staging/nmf-cm/ee/api/trace.idt b/drivers/staging/nmf-cm/ee/api/trace.idt
new file mode 100644
index 00000000000..f4d4c8615e2
--- /dev/null
+++ b/drivers/staging/nmf-cm/ee/api/trace.idt
@@ -0,0 +1,30 @@
+/*
+ * 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, with
+ * user space exemption described in the top-level COPYING file in
+ * the Linux kernel source tree.
+ */
+/*!
+ * \defgroup NMF_EE_TYPE Execution Engine Common Type Definitions
+ * \ingroup COMMON
+ */
+
+#ifndef __INC_TRACE_IDT
+#define __INC_TRACE_IDT
+
+struct t_nmf_trace
+{
+ t_uint32 revision;
+ t_uint32 timeStamp;
+ t_uint32 componentId;
+ t_uint32 traceId;
+ t_uint32 paramOpt;
+ t_uint32 componentHandle;
+ t_uint32 parentHandle;
+ t_uint32 params[4];
+};
+
+#define TRACE_BUFFER_SIZE 128
+
+#endif
diff --git a/drivers/staging/nmf-cm/inc/nmf-def.h b/drivers/staging/nmf-cm/inc/nmf-def.h
index e671198f7b9..7cdea18996b 100644
--- a/drivers/staging/nmf-cm/inc/nmf-def.h
+++ b/drivers/staging/nmf-cm/inc/nmf-def.h
@@ -21,7 +21,7 @@
*
* \ingroup NMF_VERSION
*/
-#define NMF_VERSION ((2 << 16) | (10 << 8) | (118))
+#define NMF_VERSION ((2 << 16) | (10 << 8) | (122))
/*!
* \brief Get NMF major version corresponding to NMF version number
diff --git a/drivers/staging/nmf-cm/inc/nmf-limits.h b/drivers/staging/nmf-cm/inc/nmf-limits.h
index a942e542233..374795f91e0 100644
--- a/drivers/staging/nmf-cm/inc/nmf-limits.h
+++ b/drivers/staging/nmf-cm/inc/nmf-limits.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Common Nomadik Multiprocessing Framework limits definition
*
diff --git a/drivers/staging/nmf-cm/inc/nmf-tracedescription.h b/drivers/staging/nmf-cm/inc/nmf-tracedescription.h
index 9611803b978..bce589079b9 100644
--- a/drivers/staging/nmf-cm/inc/nmf-tracedescription.h
+++ b/drivers/staging/nmf-cm/inc/nmf-tracedescription.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief NMF xti/stm trace format description
*
diff --git a/drivers/staging/nmf-cm/inc/nmf_type.idt b/drivers/staging/nmf-cm/inc/nmf_type.idt
index e8cc4e09946..dda547a463e 100644
--- a/drivers/staging/nmf-cm/inc/nmf_type.idt
+++ b/drivers/staging/nmf-cm/inc/nmf_type.idt
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
#ifndef NMF_TYPE_H_
#define NMF_TYPE_H_
diff --git a/drivers/staging/nmf-cm/inc/type.h b/drivers/staging/nmf-cm/inc/type.h
index d6eafe9aea5..3075505aee5 100644
--- a/drivers/staging/nmf-cm/inc/type.h
+++ b/drivers/staging/nmf-cm/inc/type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/* inc/type.h - Programming Model.
*
* Copyright (c) 2006, 2007, 2008 STMicroelectronics.
diff --git a/drivers/staging/nmf-cm/inc/typedef.h b/drivers/staging/nmf-cm/inc/typedef.h
index 97af9dec2c2..a29e6b88fde 100644
--- a/drivers/staging/nmf-cm/inc/typedef.h
+++ b/drivers/staging/nmf-cm/inc/typedef.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \defgroup COMMON Common types and definitions
*
diff --git a/drivers/staging/nmf-cm/nmf/inc/channel_type.h b/drivers/staging/nmf-cm/nmf/inc/channel_type.h
index 7d439ebf0cf..91a733dbbbf 100644
--- a/drivers/staging/nmf-cm/nmf/inc/channel_type.h
+++ b/drivers/staging/nmf-cm/nmf/inc/channel_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Common Nomadik Multiprocessing Framework type definition
*
diff --git a/drivers/staging/nmf-cm/nmf/inc/component_type.h b/drivers/staging/nmf-cm/nmf/inc/component_type.h
index 08b63b21225..26217554158 100644
--- a/drivers/staging/nmf-cm/nmf/inc/component_type.h
+++ b/drivers/staging/nmf-cm/nmf/inc/component_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Common Nomadik Multiprocessing Framework type definition
*
diff --git a/drivers/staging/nmf-cm/nmf/inc/service_type.h b/drivers/staging/nmf-cm/nmf/inc/service_type.h
index 3e5473338ee..06d5c72dce9 100644
--- a/drivers/staging/nmf-cm/nmf/inc/service_type.h
+++ b/drivers/staging/nmf-cm/nmf/inc/service_type.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Service type and data used through service callback.
* \defgroup NMF_SERVICE NMF Service Callback types and data definition
diff --git a/drivers/staging/nmf-cm/osal-kernel.c b/drivers/staging/nmf-cm/osal-kernel.c
index 94aa11fc91c..e79e35db106 100644
--- a/drivers/staging/nmf-cm/osal-kernel.c
+++ b/drivers/staging/nmf-cm/osal-kernel.c
@@ -353,7 +353,7 @@ void OSAL_PostDfc(t_nmf_mpc2host_handle upLayerTHIS, t_uint32 methodIndex, t_eve
spin_unlock_bh(&skelwrapper->channelPriv->bh_lock);
/* Wake up process' wait queue */
- wake_up_interruptible(&skelwrapper->channelPriv->waitq);
+ wake_up(&skelwrapper->channelPriv->waitq);
}
@@ -755,8 +755,8 @@ static int dspload_monitor(void *idx)
/* init counter */
if (CM_GetMpcLoadCounter(mpc->coreId,
&mpc->oldLoadCounter) != CM_OK)
- pr_err("CM Driver: Failed to init load counter for %s\n",
- mpc->name);
+ pr_warn("CM Driver: Failed to init load counter for %s\n",
+ mpc->name);
while (!kthread_should_stop()) {
t_cm_mpc_load_counter loadCounter;
@@ -919,7 +919,7 @@ void OSAL_DisablePwrRessource(t_nmf_power_resource resource, t_uint32 firstParam
/* Compute the relative end address of the range,
relative to base address of BANK1 */
- secondParam = (firstParam+secondParam-(U8500_ESRAM_BASE+0x20000)-1);
+ secondParam = (firstParam+secondParam-U8500_ESRAM_BANK1-1);
/* if end is below base address of BANK1, it means that full
range of addresses is on Bank0 */
@@ -927,16 +927,16 @@ void OSAL_DisablePwrRessource(t_nmf_power_resource resource, t_uint32 firstParam
break;
/* Compute the index of the last bank accessed among
esram 1+2 and esram 3+4 banks */
- secondParam /= 0x40000;
+ secondParam /= (2*U8500_ESRAM_BANK_SIZE);
WARN_ON(secondParam > 1);
/* Compute the index of the first bank accessed among esram 1+2
and esram 3+4 banks
Do not manage Bank 0 (secured, must be always ON) */
- if (firstParam < (U8500_ESRAM_BASE+0x20000))
+ if (firstParam < U8500_ESRAM_BANK1)
firstParam = 0;
else
- firstParam = (firstParam-(U8500_ESRAM_BASE+0x20000))/0x40000;
+ firstParam = (firstParam-U8500_ESRAM_BANK1)/(2*U8500_ESRAM_BANK_SIZE);
/* power off the banks 1+2 and 3+4 if accessed. */
for (i=firstParam; i<=secondParam; i++) {
@@ -1032,7 +1032,7 @@ t_cm_error OSAL_EnablePwrRessource(t_nmf_power_resource resource, t_uint32 first
/* Compute the relative end address of the range, relative
to base address of BANK1 */
- secondParam = (firstParam+secondParam-(U8500_ESRAM_BASE+0x20000)-1);
+ secondParam = (firstParam+secondParam-U8500_ESRAM_BANK1-1);
/* if end is below base address of BANK1, it means that full
range of addresses is on Bank0 */
@@ -1040,16 +1040,16 @@ t_cm_error OSAL_EnablePwrRessource(t_nmf_power_resource resource, t_uint32 first
break;
/* Compute the index of the last bank accessed among esram 1+2
and esram 3+4 banks */
- secondParam /= 0x40000;
+ secondParam /= (2*U8500_ESRAM_BANK_SIZE);
WARN_ON(secondParam > 1);
/* Compute the index of the first bank accessed among esram 1+2
and esram 3+4 banks
Do not manage Bank 0 (secured, must be always ON) */
- if (firstParam < (U8500_ESRAM_BASE+0x20000))
+ if (firstParam < U8500_ESRAM_BANK1)
firstParam = 0;
else
- firstParam = (firstParam-(U8500_ESRAM_BASE+0x20000))/0x40000;
+ firstParam = (firstParam-U8500_ESRAM_BANK1)/(2*U8500_ESRAM_BANK_SIZE);
/* power on the banks 1+2 and 3+4 if accessed. */
for (i=firstParam; i<=secondParam; i++) {
diff --git a/drivers/staging/nmf-cm/osal-kernel.h b/drivers/staging/nmf-cm/osal-kernel.h
index 7a71bdd591d..29b82368d8d 100644
--- a/drivers/staging/nmf-cm/osal-kernel.h
+++ b/drivers/staging/nmf-cm/osal-kernel.h
@@ -11,6 +11,8 @@
#include <linux/interrupt.h>
#include <linux/hwmem.h>
#include <linux/regulator/consumer.h>
+#include <linux/plist.h>
+#include <linux/version.h>
#ifdef CONFIG_HAS_WAKELOCK
#include <linux/wakelock.h>
#endif
@@ -24,7 +26,6 @@
*/
#define _CM_ELF_H
#include <cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h>
-#include <linux/plist.h>
#include "configuration.h"
@@ -56,6 +57,9 @@ struct mpcConfig {
#endif
struct task_struct *monitor_tsk; /**< task to monitor the dsp load; */
t_cm_mpc_load_counter oldLoadCounter; /**< previous load counter of the DSP */
+ atomic_t trace_read_count; /**< number of trace reader */
+ spinlock_t trace_reader_lock;
+ struct task_struct *trace_reader;/**< current reader task */
#ifdef CONFIG_DEBUG_FS
struct dentry *dir; /**< debugfs dir entry */
struct dentry *comp_dir; /**< debugfs component dir entry */
diff --git a/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h b/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h
index 5ec08434492..71dfc534f97 100644
--- a/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h
+++ b/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h
@@ -12,5 +12,6 @@
#define MPC_SERVICE_NONE 0
#define MPC_SERVICE_BOOT 0xB001
#define MPC_SERVICE_PRINT 0x1234
+#define MPC_SERVICE_TRACE 0x789
#endif
diff --git a/drivers/staging/nmf-cm/share/inc/macros.h b/drivers/staging/nmf-cm/share/inc/macros.h
index c96fe031c25..7d2c2289cd3 100644
--- a/drivers/staging/nmf-cm/share/inc/macros.h
+++ b/drivers/staging/nmf-cm/share/inc/macros.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief NMF Macro API.
*/
diff --git a/drivers/staging/nmf-cm/share/inc/nmf.h b/drivers/staging/nmf-cm/share/inc/nmf.h
index 8be8b41e5e3..2f73311c2f3 100644
--- a/drivers/staging/nmf-cm/share/inc/nmf.h
+++ b/drivers/staging/nmf-cm/share/inc/nmf.h
@@ -5,7 +5,6 @@
* user space exemption described in the top-level COPYING file in
* the Linux kernel source tree.
*/
-
/*!
* \brief Common Nomadik Multiprocessing Framework type definition
*