From 8bbaaf6aa2dce9eef6467bdcb129c7493a3ce813 Mon Sep 17 00:00:00 2001 From: Pierre Peiffer Date: Fri, 9 Sep 2011 14:45:37 +0200 Subject: U8500 CM: send a DSP Panic if it's not responding * Generate a DSP Panic and send it to user process when the DSP does not respond anymore. The issue is that when a process is using a DSP (ie has some components deployed on a DSP) without any activity (no interaction with the DSP), the driver needs to tell it when the DSP is dead. This Panic message is there to solve this issue. * Force wake-up of MMDSP before changing hardware power state This a work around for prcmu issue. ST-Ericsson ID: 359048 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Pierre Peiffer Change-Id: I920cc6a8e79e7dc9b39bd77f700a9e0e056b6a81 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32584 Reviewed-by: Pierre PEIFFER Tested-by: Pierre PEIFFER --- .../nmf-cm/cm/engine/component/src/initializer.c | 23 +++++++++++++++++++--- .../nmf-cm/cm/engine/component/src/instantiater.c | 8 -------- .../staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c | 2 +- .../os_adaptation_layer/inc/os_adaptation_layer.h | 15 +++++++++++++- .../nmf-cm/cm/engine/power_mgt/src/cmpower.c | 18 +++++++++++++++++ drivers/staging/nmf-cm/cm/engine/trace/src/panic.c | 20 +++++++++---------- drivers/staging/nmf-cm/cm_debug.c | 2 +- drivers/staging/nmf-cm/cmld.c | 2 +- drivers/staging/nmf-cm/ee/api/panic.idt | 3 ++- drivers/staging/nmf-cm/inc/nmf-def.h | 2 +- drivers/staging/nmf-cm/osal-kernel.c | 22 +++++++++++++++++++++ 11 files changed, 90 insertions(+), 27 deletions(-) diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c b/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c index 011dfa18398..7f99b710401 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c @@ -24,6 +24,7 @@ /* private prototype */ PRIVATE t_cm_error cm_COMP_generic(t_nmf_core_id coreId, t_event_params_handle paramArray, t_uint32 paramNumber, t_uint32 serviceIndex); +PRIVATE void cm_COMP_generatePanic(t_nmf_core_id coreId); /* * This module is tightly coupled with cm_DSP_components one (communication/initializer) @@ -153,8 +154,10 @@ PUBLIC t_cm_error cm_COMP_CallService( error = cm_COMP_generic(pComp->Template->dspId, params, sizeof(params) / sizeof(t_uint16), serviceIndex); if (isSynchronous == TRUE && error == CM_OK) { - if (OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) != SYNC_OK) + if (OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) != SYNC_OK) { + cm_COMP_generatePanic(pComp->Template->dspId); error = CM_MPC_NOT_RESPONDING; + } } return error; @@ -180,6 +183,7 @@ PUBLIC void cm_COMP_Flush(t_nmf_core_id coreId) { if (cm_COMP_generic(coreId, params, sizeof(params) / sizeof(t_uint16), NMF_DESTROY_INDEX) != CM_OK || OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) != SYNC_OK) { + cm_COMP_generatePanic(coreId); ERROR("CM_MPC_NOT_RESPONDING: can't call flush service\n", 0, 0, 0, 0, 0, 0); } } @@ -250,8 +254,10 @@ PUBLIC t_cm_error cm_COMP_ULPForceWakeup( error = cm_COMP_generic(coreId, NULL, 0, NMF_ULP_FORCEWAKEUP); if (error == CM_OK) { - if (OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) != SYNC_OK) + if (OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) != SYNC_OK) { + cm_COMP_generatePanic(coreId); error = CM_MPC_NOT_RESPONDING; + } } return error; @@ -335,8 +341,10 @@ PRIVATE t_cm_error cm_COMP_generic( t_uint32 i; // wait for an event in fifo - if (OSAL_SEMAPHORE_WAIT_TIMEOUT(initializerDesc[coreId].fifoSemHandle) != SYNC_OK) + if (OSAL_SEMAPHORE_WAIT_TIMEOUT(initializerDesc[coreId].fifoSemHandle) != SYNC_OK) { + cm_COMP_generatePanic(coreId); return CM_MPC_NOT_RESPONDING; + } // AllocEvent @@ -364,3 +372,12 @@ unlock: return error; } +PRIVATE void cm_COMP_generatePanic(t_nmf_core_id coreId) +{ + const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId); + + if (pDspDesc->state != MPC_STATE_PANIC) { + cm_DSP_SetStatePanic(coreId); + OSAL_GeneratePanic(coreId, 0); + } +} diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c b/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c index bd410c9acd9..92c28b63171 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c @@ -551,15 +551,7 @@ t_cm_error cm_startComponent(t_component_instance* component, t_nmf_client_id cl value, sizeof(value)) == CM_OK) { - // The PRCMU seem not supporting the transition of asking HW IP on while DSP in retention - // -> Thus force wake up of the MMDSP before asking the transition - if ((error = cm_EEM_ForceWakeup(component->Template->dspId)) != CM_OK) - return error; - error = cm_PWR_EnableMPC(MPC_PWR_HWIP, component->Template->dspId); - - cm_EEM_AllowSleep(component->Template->dspId); - if(error != CM_OK) return error; } diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c b/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c index 452d0f1b175..5f6641b188d 100644 --- a/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c +++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfmmdsp.c @@ -28,7 +28,7 @@ static const t_elfmemory mmdspMemories[NUMBER_OF_MMDSP_MEMORY] = { {9, INTERNAL_YRAM24, 0, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "YRAM"}, /* 2: Y memory */ {10, SDRAM_EXT24, SDRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "SDRAM24"}, /* 5: SDRAM24 */ {11, SDRAM_EXT16, SDRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 2, "SDRAM16"}, /* 6: SDRAM16 */ - {12, ESRAM_EXT24, ESRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "ESRAM24"}, /* 8: ESRAM24 */ + {12, ESRAM_EXT24, ESRAMMEM24_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 4, "ESRAM24"}, /* 8: ESRAM24 */ {13, ESRAM_EXT16, ESRAMMEM16_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_PRIVATE, MEM_DATA, 3, 2, "ESRAM16"}, /* 9: ESRAM16 */ {14, LOCKED_CODE, SDRAMTEXT_BASE_ADDR, CM_MM_ALIGN_2WORDS, MEM_SHARABLE, MEM_CODE, 8, 8, "LOCKED_CODE"}, /* : .locked */ }; 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 e2f6e8dec81..f57c92ea41b 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 @@ -430,6 +430,20 @@ PUBLIC void OSAL_DisableServiceMessages(void); */ PUBLIC void OSAL_EnableServiceMessages(void); +/*! + * \brief Generate 'software' panic due to dsp crash + * + * We request that the os part generate a panic to notify cm users +* that a problem occur but not dsp panic has been sent (for example +* a dsp crash) + * + * \param[in] t_nmf_core_id : core_id is the id of dsp for which we need to generate a panic. + * \param[in] reason : additional information. Today only 0 is valid. + * + * \ingroup CM_ENGINE_OSAL_API + */ +PUBLIC void OSAL_GeneratePanic(t_nmf_core_id coreId, t_uint32 reason); + extern /*const*/ t_nmf_osal_sync_handle lockHandleApi; extern /*const*/ t_nmf_osal_sync_handle lockHandleCom; extern /*const*/ t_nmf_osal_sem_handle semHandle; @@ -471,7 +485,6 @@ extern /*const*/ t_nmf_osal_sem_handle semHandle; */ #define OSAL_SEMAPHORE_WAIT_TIMEOUT(semHandle) OSAL_SemaphoreWaitTimed(semHandle, (cm_PWR_GetMode() == NORMAL_PWR_MODE)?SEM_TIMEOUT_NORMAL:SEM_TIMEOUT_DEBUG) - /****************/ /* Generic part */ /****************/ diff --git a/drivers/staging/nmf-cm/cm/engine/power_mgt/src/cmpower.c b/drivers/staging/nmf-cm/cm/engine/power_mgt/src/cmpower.c index 37ba11314f9..a104486db6c 100644 --- a/drivers/staging/nmf-cm/cm/engine/power_mgt/src/cmpower.c +++ b/drivers/staging/nmf-cm/cm/engine/power_mgt/src/cmpower.c @@ -9,6 +9,7 @@ #include #include #include +#include // ------------------------------------------------------------------------------- // Compilation flags @@ -93,11 +94,20 @@ PUBLIC t_cm_error cm_PWR_EnableMPC( if(_pwrMPCHWIPCountT[coreId]++ == 0) { LOG_INTERNAL(__PWR_DEBUG_TRACE_LEVEL, "[Pwr] MPC %s HW IP enable clock\n",cm_getDspName(coreId), 0, 0, 0, 0, 0); + + // The PRCMU seem not supporting the transition of asking HW IP on while DSP in retention + // -> Thus force wake up of the MMDSP before asking the transition + if ((error = cm_EEM_ForceWakeup(coreId)) != CM_OK) + return error; + if((error = OSAL_EnablePwrRessource(CM_OSAL_POWER_SxA_HARDWARE, coreId, 0)) != CM_OK) { ERROR("[Pwr] MPC %s HW IP clock can't be enabled\n", cm_getDspName(coreId), 0, 0, 0, 0, 0); + cm_EEM_AllowSleep(coreId); return error; } + + cm_EEM_AllowSleep(coreId); } break; } @@ -122,7 +132,15 @@ PUBLIC void cm_PWR_DisableMPC( if(--_pwrMPCHWIPCountT[coreId] == 0) { LOG_INTERNAL(__PWR_DEBUG_TRACE_LEVEL, "[Pwr] MPC %s HW IP disable clock\n",cm_getDspName(coreId), 0, 0, 0, 0, 0); + + // The PRCMU seem not supporting the transition of asking HW IP on while DSP in retention + // -> Thus force wake up of the MMDSP before asking the transition + if (cm_EEM_ForceWakeup(coreId) != CM_OK) + return; + OSAL_DisablePwrRessource(CM_OSAL_POWER_SxA_HARDWARE, coreId, 0); + + cm_EEM_AllowSleep(coreId); } break; } 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 8a4d499ce41..68552b38229 100644 --- a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c +++ b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c @@ -24,16 +24,16 @@ const struct { unsigned int SP:1; unsigned int interface:1; } reason_descrs[] = { - {"NONE_PANIC", 0, 0, 0, 0}, - {"INTERNAL_PANIC", 1, 0, 0, 0}, - {"Reserved Panic", 0, 0, 0, 0}, - {"USER_STACK_OVERFLOW", 0, 1, 1, 0}, - {"SYSTEM_STACK_OVERFLOW", 0, 1, 1, 0}, - {"UNALIGNED_LONG_ACCESS", 0, 1, 0, 0}, - {"EVENT_FIFO_OVERFLOW", 0, 0, 0, 1}, - {"PARAM_FIFO_OVERFLOW", 0, 0, 0, 1}, - {"INTERFACE_NOT_BINDED", 0, 0, 0, 0}, - {"USER_PANIC", 1, 0, 0, 0} + {"NONE_PANIC", 0, 0, 0, 0}, + {"INTERNAL_PANIC", 1, 0, 0, 0}, + {"MPC_NOT_RESPONDING_PANIC", 0, 0, 0, 0}, /* Should not be useful since in that case CM_getServiceDescription() not call */ + {"USER_STACK_OVERFLOW", 0, 1, 1, 0}, + {"SYSTEM_STACK_OVERFLOW", 0, 1, 1, 0}, + {"UNALIGNED_LONG_ACCESS", 0, 1, 0, 0}, + {"EVENT_FIFO_OVERFLOW", 0, 0, 0, 1}, + {"PARAM_FIFO_OVERFLOW", 0, 0, 0, 1}, + {"INTERFACE_NOT_BINDED", 0, 0, 0, 0}, + {"USER_PANIC", 1, 0, 0, 0} }; static t_component_instance* getCorrespondingInstance( diff --git a/drivers/staging/nmf-cm/cm_debug.c b/drivers/staging/nmf-cm/cm_debug.c index cb753ea2593..a934aa33e92 100644 --- a/drivers/staging/nmf-cm/cm_debug.c +++ b/drivers/staging/nmf-cm/cm_debug.c @@ -195,7 +195,7 @@ static ssize_t domain_read(struct file *file, char __user *userbuf, int ret=0; OSAL_LOCK_API(); - if ((domain->domain.coreId != -1) + if ((domain->domain.coreId != MASK_ALL8) && (domain->dbgCooky != NULL)) { t_cm_allocator_status status; t_uint32 dOffset; diff --git a/drivers/staging/nmf-cm/cmld.c b/drivers/staging/nmf-cm/cmld.c index d735323c572..d96ceaa3fe5 100644 --- a/drivers/staging/nmf-cm/cmld.c +++ b/drivers/staging/nmf-cm/cmld.c @@ -28,7 +28,7 @@ #include "cm_service.h" #include "cm_dma.h" -#define CMDRIVER_PATCH_VERSION 115 +#define CMDRIVER_PATCH_VERSION 117 #define O_FLUSH 0x1000000 static int cmld_major; diff --git a/drivers/staging/nmf-cm/ee/api/panic.idt b/drivers/staging/nmf-cm/ee/api/panic.idt index 612dfcc8b4b..f971fdad8c5 100644 --- a/drivers/staging/nmf-cm/ee/api/panic.idt +++ b/drivers/staging/nmf-cm/ee/api/panic.idt @@ -30,6 +30,7 @@ typedef t_uint8 t_panic_reason; * Reason | Information | Behavior * ------------------------------------------------------------------- * INTERNAL_PANIC | Not interpreted | Fatal panic, stop MPC + * MPC_NOT_RESPONDING_PANIC | Not interpreted | Fatal panic, stop MPC * USER_STACK_OVERFLOW | Faulting address & SPu | Fatal panic, stop MPC * SYSTEM_STACK_OVERFLOW | Faulting address & SPu | Fatal panic, stop MPC * UNALIGNED_LONG_ACCESS | Indicative Faulting address & SPu | Fatal panic, stop MPC @@ -45,7 +46,7 @@ typedef t_uint8 t_panic_reason; */ typedef enum { INTERNAL_PANIC = 1, - RESERVED_PANIC = 2, + MPC_NOT_RESPONDING_PANIC = 2, USER_STACK_OVERFLOW = 3, SYSTEM_STACK_OVERFLOW = 4, UNALIGNED_LONG_ACCESS = 5, diff --git a/drivers/staging/nmf-cm/inc/nmf-def.h b/drivers/staging/nmf-cm/inc/nmf-def.h index f7a60383198..fc2539eefca 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) | (115)) +#define NMF_VERSION ((2 << 16) | (10 << 8) | (117)) /*! * \brief Get NMF major version corresponding to NMF version number diff --git a/drivers/staging/nmf-cm/osal-kernel.c b/drivers/staging/nmf-cm/osal-kernel.c index d50d1215646..4ab3552bd75 100644 --- a/drivers/staging/nmf-cm/osal-kernel.c +++ b/drivers/staging/nmf-cm/osal-kernel.c @@ -1068,6 +1068,28 @@ t_cm_error OSAL_EnablePwrRessource(t_nmf_power_resource resource, t_uint32 first return CM_OK; } +/*! + * \brief Generate 'software' panic to notify cm users + * that a problem occurs but no dsp panic has been sent yet + * (for example a dsp crash) + * \ingroup CM_ENGINE_OSAL_API + */ +void OSAL_GeneratePanic(t_nmf_core_id coreId, t_uint32 reason) +{ + struct osal_msg msg; + + /* Create and dispatch a shutdown service message */ + msg.msg_type = MSG_SERVICE; + msg.d.srv.srvType = NMF_SERVICE_PANIC; + msg.d.srv.srvData.panic.panicReason = MPC_NOT_RESPONDING_PANIC; + msg.d.srv.srvData.panic.panicSource = MPC_EE; + msg.d.srv.srvData.panic.info.mpc.coreid = coreId; + msg.d.srv.srvData.panic.info.mpc.faultingComponent = 0; + msg.d.srv.srvData.panic.info.mpc.panicInfo1 = reason; + msg.d.srv.srvData.panic.info.mpc.panicInfo2 = 0; + dispatch_service_msg(&msg); +} + /*! * \brief Generate an OS-Panic. Called in from CM_ASSERT(). * \ingroup CM_ENGINE_OSAL_API -- cgit v1.2.3