From 877cccc561b35b59383487b2ac73e7d8e8ed2f4d Mon Sep 17 00:00:00 2001 From: Pierre Peiffer Date: Fri, 28 Oct 2011 11:12:48 +0200 Subject: 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 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42605 Reviewed-by: QABUILD --- .../nmf-cm/cm/engine/api/control/irq_engine.h | 14 +- .../engine/communication/inc/communication_type.h | 1 - .../cm/engine/component/inc/component_type.h | 1 - .../engine/configuration/inc/configuration_type.h | 1 - drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c | 22 +- .../inc/executive_engine_mgt.h | 6 + .../src/executive_engine_mgt.c | 13 + .../nmf-cm/cm/engine/memory/inc/domain_type.h | 1 - .../nmf-cm/cm/engine/memory/inc/memory_type.h | 1 - .../os_adaptation_layer/inc/os_adaptation_layer.h | 4 + .../cm/engine/perfmeter/inc/perfmeter_type.h | 1 - .../cm/engine/repository_mgt/inc/repository_type.h | 1 - .../staging/nmf-cm/cm/engine/trace/inc/xtitrace.h | 8 + drivers/staging/nmf-cm/cm/engine/trace/src/panic.c | 109 +++++ drivers/staging/nmf-cm/cm/inc/cm_type.h | 1 - drivers/staging/nmf-cm/cm_debug.c | 2 +- drivers/staging/nmf-cm/cm_service.c | 10 +- drivers/staging/nmf-cm/cm_syscall.c | 6 +- drivers/staging/nmf-cm/cmioctl.h | 8 +- drivers/staging/nmf-cm/cmld.c | 448 ++++++++++++++------- drivers/staging/nmf-cm/cmld.h | 46 +++ drivers/staging/nmf-cm/configuration.c | 46 ++- drivers/staging/nmf-cm/configuration.h | 4 +- drivers/staging/nmf-cm/ee/api/panic.idt | 4 +- drivers/staging/nmf-cm/ee/api/trace.idt | 30 ++ drivers/staging/nmf-cm/inc/nmf-def.h | 2 +- drivers/staging/nmf-cm/inc/nmf-limits.h | 1 - drivers/staging/nmf-cm/inc/nmf-tracedescription.h | 1 - drivers/staging/nmf-cm/inc/nmf_type.idt | 1 - drivers/staging/nmf-cm/inc/type.h | 1 - drivers/staging/nmf-cm/inc/typedef.h | 1 - drivers/staging/nmf-cm/nmf/inc/channel_type.h | 1 - drivers/staging/nmf-cm/nmf/inc/component_type.h | 1 - drivers/staging/nmf-cm/nmf/inc/service_type.h | 1 - drivers/staging/nmf-cm/osal-kernel.c | 22 +- drivers/staging/nmf-cm/osal-kernel.h | 6 +- .../nmf-cm/share/communication/inc/nmf_service.h | 1 + drivers/staging/nmf-cm/share/inc/macros.h | 1 - drivers/staging/nmf-cm/share/inc/nmf.h | 1 - 39 files changed, 612 insertions(+), 217 deletions(-) create mode 100644 drivers/staging/nmf-cm/ee/api/trace.idt 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 #include #include +#include /*! * \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 #include +#include + #include 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 #include +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 -#include #include "osal-kernel.h" #include "cm_debug.h" #ifdef CONFIG_DEBUG_FS +#include 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 #include +#include #include #include -#include #include @@ -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 +#include #include #include #include #include -#include #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 #include #include +#include #include #include -#include #include #include @@ -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 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 #include #include +#include +#include #ifdef CONFIG_HAS_WAKELOCK #include #endif @@ -24,7 +26,6 @@ */ #define _CM_ELF_H #include -#include #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 * -- cgit v1.2.3