From 96cbc30f4a4b9ae712d117fe96a57be0f3a6be68 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Fri, 21 Oct 2011 11:03:05 +0200 Subject: staging: nmf-cm: Add NMF/CM driver This is driver for loading code to a DSP Signed-off-by: Philippe Langlais Signed-off-by: Robert Marklund --- drivers/staging/nmf-cm/configuration.c | 115 +++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 drivers/staging/nmf-cm/configuration.c (limited to 'drivers/staging/nmf-cm/configuration.c') diff --git a/drivers/staging/nmf-cm/configuration.c b/drivers/staging/nmf-cm/configuration.c new file mode 100644 index 00000000000..175b6152b40 --- /dev/null +++ b/drivers/staging/nmf-cm/configuration.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Pierre Peiffer for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +/** \file configuration.c + * + * Nomadik Multiprocessing Framework Linux Driver + * + */ + +#include +#include + +#include "osal-kernel.h" + +/* Per-driver environment */ +struct OsalEnvironment osalEnv = +{ + .mpc = { + { + .coreId = SVA_CORE_ID, + .name = "sva", + .baseP = (void*)SVA_BASE_ADDR, + .interrupt0 = IRQ_DB8500_SVA, + .interrupt1 = IRQ_DB8500_SVA2, + .mmdsp_regulator = NULL, + .pipe_regulator = NULL, + .monitor_tsk = NULL, + .hwmemCode = NULL, + .hwmemData = NULL, + }, + { + .coreId = SIA_CORE_ID, + .name = "sia", + .baseP = (void*)SIA_BASE_ADDR, + .interrupt0 = IRQ_DB8500_SIA, + .interrupt1 = IRQ_DB8500_SIA2, + .mmdsp_regulator = NULL, + .pipe_regulator = NULL, + .monitor_tsk = NULL, + .hwmemCode = NULL, + .hwmemData = NULL, + } + }, + .esram_regulator = { NULL, NULL}, + .dsp_sleep = { + .sia_auto_pm_enable = PRCMU_AUTO_PM_OFF, + .sia_power_on = 0, + .sia_policy = PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, + .sva_auto_pm_enable = PRCMU_AUTO_PM_OFF, + .sva_power_on = 0, + .sva_policy = PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, + }, + .dsp_idle = { + .sia_auto_pm_enable = PRCMU_AUTO_PM_OFF, + .sia_power_on = 0, + .sia_policy = PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, + .sva_auto_pm_enable = PRCMU_AUTO_PM_OFF, + .sva_power_on = 0, + .sva_policy = PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, + }, +}; + +module_param_call(cm_debug_level, param_set_int, param_get_int, + &cm_debug_level, S_IWUSR|S_IRUGO); +MODULE_PARM_DESC(cm_debug_level, "Debug level of NMF Core"); + +module_param_call(cm_error_break, param_set_bool, param_get_bool, + &cm_error_break, S_IWUSR|S_IRUGO); +MODULE_PARM_DESC(cm_error_break, "Stop on error (in an infinite loop, for debugging purpose)"); + +module_param_call(cmIntensiveCheckState, param_set_bool, param_get_bool, + &cmIntensiveCheckState, S_IWUSR|S_IRUGO); +MODULE_PARM_DESC(cmIntensiveCheckState, "Add additional intensive checks"); + +DECLARE_MPC_PARAM(SVA, SDRAM_DATA_SIZE, "", 1); + +DECLARE_MPC_PARAM(SIA, 0, "\n\t\t\t(0 means shared with SVA)", 2); + +int cfgCommunicationLocationInSDRAM = 1; +module_param(cfgCommunicationLocationInSDRAM, bool, S_IRUGO); +MODULE_PARM_DESC(cfgCommunicationLocationInSDRAM, "Location of communications (SDRAM or ESRAM)"); + +int cfgSemaphoreTypeHSEM = 1; +module_param(cfgSemaphoreTypeHSEM, bool, S_IRUGO); +MODULE_PARM_DESC(cfgSemaphoreTypeHSEM, "Semaphore used (HSEM or LSEM)"); + +int cfgESRAMSize = ESRAM_SIZE; +module_param(cfgESRAMSize, uint, S_IRUGO); +MODULE_PARM_DESC(cfgESRAMSize, "Size of ESRAM used in the CM (in Kb)"); + +int init_config(void) +{ + if (cfgMpcSDRAMCodeSize_SVA == 0 || cfgMpcSDRAMCodeSize_SIA == 0) { + pr_err("SDRAM code size must be greater than 0\n"); + return -EINVAL; + } + + if (cfgMpcSDRAMDataSize_SVA == 0) { + 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].sdramCodeSize = cfgMpcSDRAMCodeSize_SVA * ONE_KB; + osalEnv.mpc[SVA].sdramDataSize = cfgMpcSDRAMDataSize_SVA * ONE_KB; + osalEnv.mpc[SIA].nbYramBanks = cfgMpcYBanks_SIA; + osalEnv.mpc[SIA].eeId = cfgSchedulerTypeHybrid_SIA ? HYBRID_EXECUTIVE_ENGINE : SYNCHRONOUS_EXECUTIVE_ENGINE; + osalEnv.mpc[SIA].sdramCodeSize = cfgMpcSDRAMCodeSize_SIA * ONE_KB; + osalEnv.mpc[SIA].sdramDataSize = cfgMpcSDRAMDataSize_SIA * ONE_KB; + + return 0; +} -- cgit v1.2.3 From 410e1fe46039ea15870a9078d0dd11ddb3bae064 Mon Sep 17 00:00:00 2001 From: Pierre Peiffer Date: Tue, 23 Aug 2011 09:13:49 +0200 Subject: U8500 CM: provide MMDSP dump in case of Panic Implement support of debugfs: - Provide several live information through debugfs - Provide support of MMDSP core dump also through debugfs, when a panic occurs. Rework the allocator to enhance the MMDSP stack allocation. ST-Ericsson ID: 356478 ST-Ericsson Linux next: - ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Pierre Peiffer Change-Id: I19e21a8a0cfa23e9085c2c429ce13f973c552818 --- drivers/staging/nmf-cm/Makefile | 2 +- .../engine/communication/fifo/inc/nmf_fifo_arm.h | 1 - .../cm/engine/communication/src/communication.c | 1 + .../nmf-cm/cm/engine/component/inc/description.h | 2 +- .../nmf-cm/cm/engine/component/inc/instance.h | 5 +- .../nmf-cm/cm/engine/component/inc/nmfheaderabi.h | 6 +- .../nmf-cm/cm/engine/component/src/binder.c | 94 +-- .../nmf-cm/cm/engine/component/src/binder_check.c | 30 +- .../cm/engine/component/src/component_wrapper.c | 143 ++-- .../nmf-cm/cm/engine/component/src/dspevent.c | 6 +- .../nmf-cm/cm/engine/component/src/initializer.c | 6 +- .../nmf-cm/cm/engine/component/src/instantiater.c | 104 +-- .../nmf-cm/cm/engine/component/src/introspection.c | 28 +- .../nmf-cm/cm/engine/component/src/loader.c | 5 +- .../configuration/src/configuration_wrapper.c | 28 +- drivers/staging/nmf-cm/cm/engine/dsp/inc/dsp.h | 1 - drivers/staging/nmf-cm/cm/engine/dsp/src/dsp.c | 13 +- drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c | 6 +- .../staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c | 17 +- .../inc/executive_engine_mgt.h | 4 + .../src/executive_engine_mgt.c | 49 +- .../staging/nmf-cm/cm/engine/memory/inc/domain.h | 1 + .../nmf-cm/cm/engine/memory/inc/remote_allocator.h | 10 +- .../cm/engine/memory/inc/remote_allocator_utils.h | 3 +- .../staging/nmf-cm/cm/engine/memory/src/domain.c | 37 +- .../nmf-cm/cm/engine/memory/src/memory_wrapper.c | 1 + .../nmf-cm/cm/engine/memory/src/migration.c | 1 + .../nmf-cm/cm/engine/memory/src/remote_allocator.c | 405 +++++----- .../cm/engine/memory/src/remote_allocator_utils.c | 94 +-- .../os_adaptation_layer/inc/os_adaptation_layer.h | 10 + .../os_adaptation_layer/src/os_adaptation_layer.c | 17 +- .../nmf-cm/cm/engine/perfmeter/src/mpcload.c | 7 +- .../staging/nmf-cm/cm/engine/power_mgt/inc/power.h | 6 +- .../nmf-cm/cm/engine/power_mgt/src/cmpower.c | 6 +- .../cm/engine/repository_mgt/src/repository_mgt.c | 21 +- drivers/staging/nmf-cm/cm/engine/trace/src/panic.c | 12 +- drivers/staging/nmf-cm/cm/engine/trace/src/trace.c | 14 +- .../staging/nmf-cm/cm/engine/utils/src/string.c | 2 + drivers/staging/nmf-cm/cm_debug.c | 838 +++++++++++++++++++++ drivers/staging/nmf-cm/cm_debug.h | 19 + drivers/staging/nmf-cm/cm_service.c | 32 +- drivers/staging/nmf-cm/cmioctl.h | 9 + drivers/staging/nmf-cm/cmld.c | 157 ++-- drivers/staging/nmf-cm/cmld.h | 9 + drivers/staging/nmf-cm/configuration.c | 74 +- drivers/staging/nmf-cm/configuration.h | 9 +- drivers/staging/nmf-cm/inc/nmf-def.h | 2 +- drivers/staging/nmf-cm/osal-kernel.c | 147 ++-- drivers/staging/nmf-cm/osal-kernel.h | 63 +- 49 files changed, 1752 insertions(+), 805 deletions(-) create mode 100644 drivers/staging/nmf-cm/cm_debug.c create mode 100644 drivers/staging/nmf-cm/cm_debug.h (limited to 'drivers/staging/nmf-cm/configuration.c') diff --git a/drivers/staging/nmf-cm/Makefile b/drivers/staging/nmf-cm/Makefile index 0728ac5bc3f..7745132f35e 100644 --- a/drivers/staging/nmf-cm/Makefile +++ b/drivers/staging/nmf-cm/Makefile @@ -34,7 +34,7 @@ ifdef KERNELRELEASE GENERIC_CM_FILES := $(filter-out $(CMENGINESRC_COPY_NO_BUILD), $(GENERIC_CM_FILES)) CM_OBJS := $(GENERIC_CM_FILES:.c=.o) - CM_OBJS += cmld.o cm_syscall.o osal-kernel.o cm_service.o configuration.o + CM_OBJS += cmld.o cm_syscall.o osal-kernel.o cm_service.o cm_debug.o configuration.o CM_OBJS += cm_dma.o obj-$(CONFIG_U8500_CM) := cm.o diff --git a/drivers/staging/nmf-cm/cm/engine/communication/fifo/inc/nmf_fifo_arm.h b/drivers/staging/nmf-cm/cm/engine/communication/fifo/inc/nmf_fifo_arm.h index 41c4f7a7ad6..0463d6a71a5 100644 --- a/drivers/staging/nmf-cm/cm/engine/communication/fifo/inc/nmf_fifo_arm.h +++ b/drivers/staging/nmf-cm/cm/engine/communication/fifo/inc/nmf_fifo_arm.h @@ -13,7 +13,6 @@ #include #include #include -#include #include /* diff --git a/drivers/staging/nmf-cm/cm/engine/communication/src/communication.c b/drivers/staging/nmf-cm/cm/engine/communication/src/communication.c index 5bd9fbe22fa..ead1e090d7c 100644 --- a/drivers/staging/nmf-cm/cm/engine/communication/src/communication.c +++ b/drivers/staging/nmf-cm/cm/engine/communication/src/communication.c @@ -131,6 +131,7 @@ PUBLIC t_cm_error cm_COM_AllocateMpc(t_nmf_core_id coreId) return CM_OK; oom: cm_COM_FreeMpc(coreId); + ERROR("CM_NO_MORE_MEMORY: fifo_alloc() failed in cm_COM_AllocateMpc()\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; } diff --git a/drivers/staging/nmf-cm/cm/engine/component/inc/description.h b/drivers/staging/nmf-cm/cm/engine/component/inc/description.h index b7d3c34654d..9a03ac5d2f7 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/inc/description.h +++ b/drivers/staging/nmf-cm/cm/engine/component/inc/description.h @@ -21,7 +21,7 @@ typedef struct _t_interface_description { t_uint16 referenceCounter; //!< Number of template referencing the interface t_uint8 methodNumber; //!< Number of method in the interfaces struct _t_interface_description* next; - t_dup_char methodNames[]; //!< Array of method names + t_dup_char methodNames[1]; //!< Array of method names } t_interface_description; /*! diff --git a/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h b/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h index 9172d99db79..0a7d80e2e02 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h +++ b/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h @@ -55,7 +55,7 @@ typedef struct t_component_instance { t_component_state state; //!< Component state t_nmf_ee_priority priority; //!< Executive engine component priority - t_component_template *template; //!< Component template + t_component_template *Template; //!< Component template t_uint32 thisAddress; //!< Cached value of cm_DSP_GetDspAddress(component->memories[data], &thisAddress); @@ -71,6 +71,7 @@ typedef struct t_component_instance { struct t_client_of_singleton *clientOfSingleton; //!< Client of singleton list t_memory_handle loadMapHandle; // handle of allocated memory for the loadMap structure and name; + void *dbgCooky; //!< pointer to OS internal data } t_component_instance; t_component_template* cm_lookupTemplate(t_nmf_core_id dspId, t_dup_char str); @@ -115,7 +116,7 @@ t_cm_error cm_loadComponent( * \ingroup COMPONENT_INTERNAL */ t_cm_error cm_unloadComponent( - t_component_template *template); + t_component_template *reftemplate); /*! * \internal diff --git a/drivers/staging/nmf-cm/cm/engine/component/inc/nmfheaderabi.h b/drivers/staging/nmf-cm/cm/engine/component/inc/nmfheaderabi.h index 59d2186f157..9eae19b2f70 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/inc/nmfheaderabi.h +++ b/drivers/staging/nmf-cm/cm/engine/component/inc/nmfheaderabi.h @@ -28,7 +28,7 @@ typedef struct { char *type; //!< Type of this Interface t_uint8 methodNumber; //!< Number of method in the interfaces t_uint8 reserved1, reserved2, reserved3; - char *methodNames[]; //!< Array of method names + char *methodNames[1]; //!< Array of method names [methodNumber] } t_elf_interface_description; /*! @@ -64,7 +64,7 @@ typedef struct { t_uint8 collectionSize; //!< Size of the collection (1 if not a collection) t_uint8 reserved1, reserved2; t_elf_interface_description *interface; //!< Interface description - t_elf_interface_require_index indexes[]; /*!< Require information for each collection index + t_elf_interface_require_index indexes[1]; /*!< Require information for each collection index \note Real type: indexes[collectionSize], available only if not static interface */ } t_elf_required_interface; @@ -89,7 +89,7 @@ typedef struct { t_uint8 collectionSize; //!< Size of the collection (1 if not a collection) t_uint8 reserved1; t_elf_interface_description *interface; //!< Interface description - t_uint32 methodSymbols[]; /*!< Symbol of the real name of methods of the interface for each collection index + t_uint32 methodSymbols[1]; /*!< Symbol of the real name of methods of the interface for each collection index \note Real type: methodSymbols[collectionSize][methodNumber] \note Use relocation in order to get symbol information*/ } t_elf_provided_interface; diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/binder.c b/drivers/staging/nmf-cm/cm/engine/component/src/binder.c index 8586fdfcbc8..e82828f012b 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/binder.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/binder.c @@ -76,8 +76,8 @@ static void cm_bindLowLevelInterface( { const t_component_instance* client = itfRequire->client; t_component_instance* server = (t_component_instance*)itfLocalBC->server; - t_interface_require *require = &client->template->requires[itfRequire->requireIndex]; - t_interface_provide* provide = &server->template->provides[itfLocalBC->provideIndex]; + t_interface_require *require = &client->Template->requires[itfRequire->requireIndex]; + t_interface_provide* provide = &server->Template->provides[itfLocalBC->provideIndex]; int k, j; if(require->indexes != NULL) @@ -139,7 +139,7 @@ static void cm_bindLowLevelInterface( } else { - t_function_relocation *reloc = client->template->delayedRelocation; + t_function_relocation *reloc = client->Template->delayedRelocation; while(reloc != NULL) { for(j = 0; j < provide->interface->methodNumber; j++) { @@ -174,7 +174,7 @@ static void cm_bindLowLevelInterface( * cm_destroyInstance() of server to succeed (interrupt line bindings are * destroyed after the check in cm_destroyInstance() */ - if (client->template->classe != FIRMWARE) + if (client->Template->classe != FIRMWARE) server->providedItfUsedCount++; } } @@ -194,7 +194,7 @@ static void cm_registerLowLevelInterfaceToConst( // This is an unbind from a true component (not to void) // Do not count bindings from EE (ie interrupt line) if ((targetInstance == NULL) - && (client->template->classe != FIRMWARE) + && (client->Template->classe != FIRMWARE) && (itfRef->instance != (t_component_instance *)NMF_VOID_COMPONENT) && (itfRef->instance != NULL)) { @@ -211,14 +211,14 @@ static void cm_bindLowLevelInterfaceToConst( const t_dsp_address functionAddress, const t_component_instance* targetInstance) { const t_component_instance* client = itfRequire->client; - t_interface_require *require = &client->template->requires[itfRequire->requireIndex]; + t_interface_require *require = &client->Template->requires[itfRequire->requireIndex]; int j, k; // If DSP is off/panic/... -> write nothing if( require->indexes != NULL - && cm_DSP_GetState(client->template->dspId)->state == MPC_STATE_BOOTED) + && cm_DSP_GetState(client->Template->dspId)->state == MPC_STATE_BOOTED) { t_interface_require_index *requireindex = &require->indexes[itfRequire->collectionIndex]; @@ -295,8 +295,8 @@ t_cm_error cm_bindInterface( cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_SYNCHRONOUS, itfRequire->client, itfProvide->server, - itfRequire->client->template->requires[itfRequire->requireIndex].name, - itfProvide->server->template->provides[itfProvide->provideIndex].name); + itfRequire->client->Template->requires[itfRequire->requireIndex].name, + itfProvide->server->Template->provides[itfProvide->provideIndex].name); return CM_OK; } @@ -312,7 +312,7 @@ void cm_unbindInterface( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_SYNCHRONOUS, itfRequire->client, NULL, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); cm_bindLowLevelInterfaceToConst(itfRequire, @@ -329,12 +329,12 @@ t_cm_error cm_bindInterfaceToVoid( itfRequire->client->pathname, itfRequire->client, itfRequire->origName, 0, 0, 0); cm_bindLowLevelInterfaceToConst(itfRequire, - cm_EEM_getExecutiveEngine(itfRequire->client->template->dspId)->voidAddr, + cm_EEM_getExecutiveEngine(itfRequire->client->Template->dspId)->voidAddr, (t_component_instance*)NMF_VOID_COMPONENT); cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_SYNCHRONOUS, itfRequire->client, NULL, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); return CM_OK; @@ -369,7 +369,7 @@ t_cm_error cm_bindInterfaceTrace( const t_interface_provide_description *itfProvide, t_elfdescription *elfhandleTrace) { - t_interface_require *require = &itfRequire->client->template->requires[itfRequire->requireIndex]; + t_interface_require *require = &itfRequire->client->Template->requires[itfRequire->requireIndex]; t_interface_require_description bcitfRequire; t_interface_provide_description bcitfProvide; t_trace_bf_info *bfInfo; @@ -418,8 +418,8 @@ t_cm_error cm_bindInterfaceTrace( cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_SYNCHRONOUS, itfRequire->client, itfProvide->server, - itfRequire->client->template->requires[itfRequire->requireIndex].name, - itfProvide->server->template->provides[itfProvide->provideIndex].name); + itfRequire->client->Template->requires[itfRequire->requireIndex].name, + itfProvide->server->Template->provides[itfProvide->provideIndex].name); return CM_OK; } @@ -435,7 +435,7 @@ void cm_unbindInterfaceTrace( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_SYNCHRONOUS, itfRequire->client, NULL, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); /* Unbind Client from Event Binding Component */ @@ -464,7 +464,7 @@ t_cm_error cm_bindInterfaceAsynchronous( t_uint32 fifosize, t_dsp_memory_type_id dspEventMemType, t_elfdescription *elfhandleEvent) { - t_interface_require *require = &itfRequire->client->template->requires[itfRequire->requireIndex]; + t_interface_require *require = &itfRequire->client->Template->requires[itfRequire->requireIndex]; t_interface_require_description eventitfRequire; t_interface_provide_description eventitfProvide; t_async_bf_info *bfInfo; @@ -536,8 +536,8 @@ t_cm_error cm_bindInterfaceAsynchronous( cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_ASYNCHRONOUS, itfRequire->client, itfProvide->server, - itfRequire->client->template->requires[itfRequire->requireIndex].name, - itfProvide->server->template->provides[itfProvide->provideIndex].name); + itfRequire->client->Template->requires[itfRequire->requireIndex].name, + itfProvide->server->Template->provides[itfProvide->provideIndex].name); return CM_OK; } @@ -553,7 +553,7 @@ void cm_unbindInterfaceAsynchronous( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_ASYNCHRONOUS, itfRequire->client, NULL, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); /* Unbind Client from Event Binding Component */ @@ -586,8 +586,8 @@ PRIVATE t_cm_error cm_createParamsFifo(t_component_instance *stub, t_uint32 *fifoElemSize, t_uint32 bcDescSize) { - t_nmf_core_id stubcore = (stub != NULL) ?(stub->template->dspId): ARM_CORE_ID; - t_nmf_core_id skelcore = (skeleton != NULL) ?(skeleton->template->dspId) : ARM_CORE_ID; + t_nmf_core_id stubcore = (stub != NULL) ?(stub->Template->dspId): ARM_CORE_ID; + t_nmf_core_id skelcore = (skeleton != NULL) ?(skeleton->Template->dspId) : ARM_CORE_ID; t_component_instance *bcnotnull = (stub != NULL) ? stub : skeleton; int _fifoelemsize; @@ -601,8 +601,10 @@ PRIVATE t_cm_error cm_createParamsFifo(t_component_instance *stub, /* Allocation of the fifo params */ *fifo = fifo_alloc(stubcore, skelcore, _fifoelemsize, fifosize, 1+bcDescSize, paramsLocation, extendedFieldLocation, domainId); /* 1+nbMethods fro hostBCThis_or_TOP space */ - if(*fifo == NULL) + if(*fifo == NULL) { + ERROR("CM_NO_MORE_MEMORY: fifo_alloc() failed in cm_createParamsFifo()\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; + } if(stub != NULL) { @@ -639,7 +641,7 @@ PRIVATE t_cm_error cm_createDSPSkeleton( t_elfdescription *elfhandleSkeleton, t_dspskel_bf_info *bfInfo) { - t_interface_provide *provide = &itfProvide->server->template->provides[itfProvide->provideIndex]; + t_interface_provide *provide = &itfProvide->server->Template->provides[itfProvide->provideIndex]; t_interface_require_description skelitfRequire; t_cm_error error; unsigned int fifoeventsize = 0; @@ -715,7 +717,7 @@ t_cm_error cm_bindComponentFromCMCore( t_dsp_memory_type_id dspEventMemType, t_elfdescription *elfhandleSkeleton, t_host2mpc_bf_info **bfInfo) { - t_interface_provide *provide = &itfProvide->server->template->provides[itfProvide->provideIndex]; + t_interface_provide *provide = &itfProvide->server->Template->provides[itfProvide->provideIndex]; t_dsp_offset shareVarOffset; t_cm_error error; @@ -771,7 +773,7 @@ t_cm_error cm_bindComponentFromCMCore( fifo_params_setSharedField( (*bfInfo)->fifo, 1+i, - skel->template->provides[0].indexes[0][i].methodAddresses + skel->Template->provides[0].indexes[0][i].methodAddresses ); } } @@ -779,7 +781,7 @@ t_cm_error cm_bindComponentFromCMCore( cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_ASYNCHRONOUS, ARM_TRACE_COMPONENT, itfProvide->server, NULL, - itfProvide->server->template->provides[itfProvide->provideIndex].name); + itfProvide->server->Template->provides[itfProvide->provideIndex].name); return CM_OK; } @@ -788,7 +790,7 @@ void cm_unbindComponentFromCMCore( t_host2mpc_bf_info* bfInfo) { t_component_instance *skel = bfInfo->dspskeleton.skelInstance; t_interface_reference* itfProvide = &skel->interfaceReferences[0][0]; - t_interface_provide *provide = &itfProvide->instance->template->provides[itfProvide->provideIndex]; + t_interface_provide *provide = &itfProvide->instance->Template->provides[itfProvide->provideIndex]; LOG_INTERNAL(1, "\n##### UnBind HOST -> %s/%x.%s #####\n", itfProvide->instance->pathname, itfProvide->instance, provide->name, 0, 0, 0); @@ -796,7 +798,7 @@ void cm_unbindComponentFromCMCore( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_ASYNCHRONOUS, ARM_TRACE_COMPONENT, itfProvide->instance, NULL, - itfProvide->instance->template->provides[itfProvide->provideIndex].name); + itfProvide->instance->Template->provides[itfProvide->provideIndex].name); // Destroy FIFO params cm_destroyParamsFifo(bfInfo->fifo); @@ -866,7 +868,7 @@ t_cm_error cm_bindComponentToCMCore( t_uint32 context, t_elfdescription *elfhandleStub, t_mpc2host_bf_info ** bfInfo) { - t_interface_require *require = &itfRequire->client->template->requires[itfRequire->requireIndex]; + t_interface_require *require = &itfRequire->client->Template->requires[itfRequire->requireIndex]; t_interface_provide_description itfstubProvide; t_cm_error error; t_uint32 fifoelemsize; @@ -921,7 +923,7 @@ t_cm_error cm_bindComponentToCMCore( cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_ASYNCHRONOUS, itfRequire->client, ARM_TRACE_COMPONENT, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); return error; @@ -936,7 +938,7 @@ void cm_unbindComponentToCMCore( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_ASYNCHRONOUS, itfRequire->client, ARM_TRACE_COMPONENT, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); /* Unbind virtual interface coms */ @@ -962,7 +964,7 @@ t_cm_error cm_bindInterfaceDistributed( t_dsp_memory_type_id dspEventMemType, t_elfdescription *elfhandleSkeleton, t_elfdescription *elfhandleStub) { - t_interface_require *require = &itfRequire->client->template->requires[itfRequire->requireIndex]; + t_interface_require *require = &itfRequire->client->Template->requires[itfRequire->requireIndex]; t_interface_provide_description itfstubProvide; t_cm_error error; t_mpc2mpc_bf_info *bfInfo; @@ -1041,15 +1043,15 @@ t_cm_error cm_bindInterfaceDistributed( fifo_params_setSharedField( bfInfo->fifo, 1+i, - skel->template->provides[0].indexes[0][i].methodAddresses + skel->Template->provides[0].indexes[0][i].methodAddresses ); } } cm_TRC_traceBinding(TRACE_BIND_COMMAND_BIND_ASYNCHRONOUS, itfRequire->client, itfProvide->server, - itfRequire->client->template->requires[itfRequire->requireIndex].name, - itfProvide->server->template->provides[itfProvide->provideIndex].name); + itfRequire->client->Template->requires[itfRequire->requireIndex].name, + itfProvide->server->Template->provides[itfProvide->provideIndex].name); return CM_OK; } @@ -1066,7 +1068,7 @@ void cm_unbindInterfaceDistributed( cm_TRC_traceBinding(TRACE_BIND_COMMAND_UNBIND_ASYNCHRONOUS, itfRequire->client, NULL, - itfRequire->client->template->requires[itfRequire->requireIndex].name, + itfRequire->client->Template->requires[itfRequire->requireIndex].name, NULL); /* Unbind virtual interface */ @@ -1138,15 +1140,15 @@ void cm_destroyRequireInterface(t_component_instance* component, t_nmf_client_id /* * Special code for SINGLETON handling */ - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { if(getNumberOfBind(component) > 0) return; } - for(i = 0; i < component->template->requireNumber; i++) + for(i = 0; i < component->Template->requireNumber; i++) { - int nb = component->template->requires[i].collectionSize; + int nb = component->Template->requires[i].collectionSize; for(j = 0; j < nb; j++) { if(component->interfaceReferences[i][j].instance != NULL) @@ -1157,7 +1159,7 @@ void cm_destroyRequireInterface(t_component_instance* component, t_nmf_client_id itfRequire.client = component; itfRequire.requireIndex = i; itfRequire.collectionIndex = j; - itfRequire.origName = component->template->requires[i].name; + itfRequire.origName = component->Template->requires[i].name; switch (itfRef->bfInfoID) { case BF_SYNCHRONOUS: @@ -1202,7 +1204,7 @@ void cm_registerSingletonBinding( t_interface_provide_description* itfProvide, t_nmf_client_id clientId) { - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, FALSE, clientId); if(cl != NULL) @@ -1226,7 +1228,7 @@ t_bool cm_unregisterSingletonBinding( t_interface_provide_description* itfProvide, t_nmf_client_id clientId) { - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, FALSE, clientId); if(cl != NULL) @@ -1251,17 +1253,17 @@ t_bool cm_unregisterSingletonBinding( LOG_INTERNAL(1, " -> Singleton[%d] : All required of %s/%x logically unbound, perform physical unbind\n", clientId, itfRequire->client->pathname, itfRequire->client, 0, 0, 0); - (void)cm_EEM_ForceWakeup(component->template->dspId); + (void)cm_EEM_ForceWakeup(component->Template->dspId); // This is the last binding unbind all !!! cm_destroyRequireInterface(component, clientId); - cm_EEM_AllowSleep(component->template->dspId); + cm_EEM_AllowSleep(component->Template->dspId); } else if(itfProvide->server != NULL) { t_interface_require* itfReq; - itfReq = &itfRequire->client->template->requires[itfRequire->requireIndex]; + itfReq = &itfRequire->client->Template->requires[itfRequire->requireIndex]; if((itfReq->requireTypes & OPTIONAL_REQUIRE) != 0x0) return TRUE; } diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/binder_check.c b/drivers/staging/nmf-cm/cm/engine/component/src/binder_check.c index b141064c1c1..8a3c3c33de8 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/binder_check.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/binder_check.c @@ -29,7 +29,7 @@ t_cm_error cm_checkValidClient( if(itfRef->instance != (t_component_instance*)NULL) { - if(client->template->classe == SINGLETON) + if(client->Template->classe == SINGLETON) { // Singleton is immutable thus we can't rebind it, nevertheless it's not an issue *bindable = FALSE; @@ -41,11 +41,11 @@ t_cm_error cm_checkValidClient( if(itfRef->instance == (const t_component_instance*)NMF_VOID_COMPONENT) ERROR("CM_INTERFACE_ALREADY_BINDED(): Component (%s<%s>.s) already bound to VOID\n", - client->pathname, client->template->name, requiredItfClientName, 0, 0, 0); + client->pathname, client->Template->name, requiredItfClientName, 0, 0, 0); else ERROR("CM_INTERFACE_ALREADY_BINDED(): Component (%s<%s>.s) already bound to another server (%s<%s>.%s)\n", - client->pathname, client->template->name, requiredItfClientName, - itfRef->instance->pathname, itfRef->instance->template->name, itfRef->instance->template->provides[itfRef->provideIndex].name); + client->pathname, client->Template->name, requiredItfClientName, + itfRef->instance->pathname, itfRef->instance->Template->name, itfRef->instance->Template->provides[itfRef->provideIndex].name); return CM_INTERFACE_ALREADY_BINDED; } } @@ -53,7 +53,7 @@ t_cm_error cm_checkValidClient( // Delayed Component LC state check done only if not optional required interface or intrinsic one that has been solved by loader { - t_interface_require* itfReq = &client->template->requires[itfRequire->requireIndex]; + t_interface_require* itfReq = &client->Template->requires[itfRequire->requireIndex]; if((itfReq->requireTypes & (OPTIONAL_REQUIRE | INTRINSEC_REQUIRE)) == 0) { if(client->state == STATE_RUNNABLE) @@ -107,7 +107,7 @@ t_cm_error cm_checkValidBinding( // If this is a singleton which has been already bound check that next binding is at the same server if(*bindable == FALSE - && client->template->classe == SINGLETON) + && client->Template->classe == SINGLETON) { t_interface_reference* itfRef = &client->interfaceReferences[itfRequire->requireIndex][itfRequire->collectionIndex]; while( itfRef->instance != server @@ -117,7 +117,7 @@ t_cm_error cm_checkValidBinding( if(itfRef->instance == (const t_component_instance*)NMF_VOID_COMPONENT) { ERROR("CM_INTERFACE_ALREADY_BINDED(): Singleton (%s<%s>.s) already bound to VOID\n", - client->pathname, client->template->name, requiredItfClientName, 0, 0, 0); + client->pathname, client->Template->name, requiredItfClientName, 0, 0, 0); return CM_INTERFACE_ALREADY_BINDED; } else if(itfRef->bfInfoID == BF_ASYNCHRONOUS || itfRef->bfInfoID == BF_TRACE) @@ -131,16 +131,16 @@ t_cm_error cm_checkValidBinding( else { ERROR("CM_INTERFACE_ALREADY_BINDED(): Singleton (%s<%s>.s) already bound to different server (%s<%s>.%s)\n", - client->pathname, client->template->name, requiredItfClientName, - itfRef->instance->pathname, itfRef->instance->template->name, itfRef->instance->template->provides[itfRef->provideIndex].name); + client->pathname, client->Template->name, requiredItfClientName, + itfRef->instance->pathname, itfRef->instance->Template->name, itfRef->instance->Template->provides[itfRef->provideIndex].name); return CM_INTERFACE_ALREADY_BINDED; } } } // Check if provided and required type matches - require = &client->template->requires[itfRequire->requireIndex]; - provide = &server->template->provides[itfProvide->provideIndex]; + require = &client->Template->requires[itfRequire->requireIndex]; + provide = &server->Template->provides[itfProvide->provideIndex]; if(require->interface != provide->interface) { ERROR("CM_ILLEGAL_BINDING(%s, %s)\n", require->interface->type, provide->interface->type, 0, 0, 0, 0); @@ -149,7 +149,7 @@ t_cm_error cm_checkValidBinding( // Check if static required interface binded to singleton component if((require->requireTypes & STATIC_REQUIRE) && - (server->template->classe != SINGLETON)) + (server->Template->classe != SINGLETON)) { ERROR("CM_ILLEGAL_BINDING(): Can't bind static required interface to not singleton component\n", 0, 0, 0, 0, 0, 0); @@ -175,14 +175,14 @@ t_cm_error cm_checkValidUnbinding( if ((error = cm_getRequiredInterface(client, requiredItfClientName, itfRequire)) != CM_OK) return error; - itfReq = &client->template->requires[itfRequire->requireIndex]; + itfReq = &client->Template->requires[itfRequire->requireIndex]; // Check if the requiredItfClientName is required by client component if ((error = cm_lookupInterface(itfRequire, itfProvide)) != CM_OK) { // We allow to unbind optional required of singleton even if not binded, since it could have been unbound previously but we don't // want to break bind singleton reference counter - if((client->template->classe == SINGLETON) && + if((client->Template->classe == SINGLETON) && (itfReq->requireTypes & OPTIONAL_REQUIRE) != 0x0) return CM_OK; @@ -190,7 +190,7 @@ t_cm_error cm_checkValidUnbinding( } // Singleton is immutable, don't unbind it - if(client->template->classe == SINGLETON) + if(client->Template->classe == SINGLETON) return CM_OK; /* if interface is optionnal then allow unbinding even if not stop */ diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/component_wrapper.c b/drivers/staging/nmf-cm/cm/engine/component/src/component_wrapper.c index 07d20d0266e..88e6b4749ec 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/component_wrapper.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/component_wrapper.c @@ -139,7 +139,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_DestroyComponent( } else { - t_nmf_core_id coreId = component->template->dspId; + t_nmf_core_id coreId = component->Template->dspId; (void)cm_EEM_ForceWakeup(coreId); @@ -171,18 +171,19 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_FlushComponents(t_nmf_client_id client (void)cm_EEM_ForceWakeup(SIA_CORE_ID); /* Destroy all host2mpc bindings */ + OSAL_LOCK_COM(); for (i=0; iclientId == clientId)) { cm_delEntry(&Host2MpcBindingTable, i); OSAL_UNLOCK_COM(); cm_unbindComponentFromCMCore(bfInfo); - } else - OSAL_UNLOCK_COM(); + OSAL_LOCK_COM(); + } } + OSAL_UNLOCK_COM(); /* First, stop all remaining components for this client */ for (i=0; itemplate->classe == FIRMWARE) || + (instance->Template->classe == FIRMWARE) || /* Skip all binding components */ - (cm_StringCompare(instance->template->name, "_ev.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_st.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_sk.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_tr.", 4) == 0)) + (cm_StringCompare(instance->Template->name, "_ev.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_st.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_sk.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_tr.", 4) == 0)) continue; /* * Special code for SINGLETON handling */ - if(instance->template->classe == SINGLETON) + if(instance->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(instance, FALSE, clientId); if(cl == NULL) @@ -218,7 +219,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_FlushComponents(t_nmf_client_id client // Stop the component error = cm_stopComponent(instance, clientId); if (error != CM_OK && error != CM_COMPONENT_NOT_STARTED) - LOG_INTERNAL(0, "Error stopping component %s/%x (%s, error=%d, client=%u)\n", instance->pathname, instance, instance->template->name, error, clientId, 0); + LOG_INTERNAL(0, "Error stopping component %s/%x (%s, error=%d, client=%u)\n", instance->pathname, instance, instance->Template->name, error, clientId, 0); // Destroy dependencies cm_destroyRequireInterface(instance, clientId); @@ -230,12 +231,12 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_FlushComponents(t_nmf_client_id client if ((instance = componentEntry(i)) == NULL) continue; if (/* skip EE */ - (instance->template->classe == FIRMWARE) || + (instance->Template->classe == FIRMWARE) || /* Skip all binding components */ - (cm_StringCompare(instance->template->name, "_ev.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_st.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_sk.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_tr.", 4) == 0)) { + (cm_StringCompare(instance->Template->name, "_ev.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_st.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_sk.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_tr.", 4) == 0)) { continue; } @@ -243,7 +244,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_FlushComponents(t_nmf_client_id client /* * Special code for SINGLETON handling */ - if(instance->template->classe == SINGLETON) + if(instance->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(instance, FALSE, clientId); if(cl == NULL) @@ -316,7 +317,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponent( goto out; // Check that client and server component run on same DSP - if (itfRequire.client->template->dspId != itfProvide.server->template->dspId) + if (itfRequire.client->Template->dspId != itfProvide.server->Template->dspId) { error = CM_ILLEGAL_BINDING; goto out; @@ -325,7 +326,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponent( // Check if we really need to bind if(bindable) { - if ((error = cm_EEM_ForceWakeup(itfRequire.client->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfRequire.client->Template->dspId)) != CM_OK) goto out; /* @@ -336,7 +337,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponent( else error = cm_bindInterface(&itfRequire, &itfProvide); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); } cm_registerSingletonBinding(client, &itfRequire, &itfProvide, clientId); @@ -376,7 +377,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponent( // Check if we really need to unbind if(cm_unregisterSingletonBinding(client, &itfRequire, &itfProvide, clientId)) { - (void)cm_EEM_ForceWakeup(itfRequire.client->template->dspId); + (void)cm_EEM_ForceWakeup(itfRequire.client->Template->dspId); if(bfInfoID == BF_SYNCHRONOUS) cm_unbindInterface(&itfRequire); @@ -385,7 +386,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponent( &itfRequire, (t_trace_bf_info*)itfRequire.client->interfaceReferences[itfRequire.requireIndex][itfRequire.collectionIndex].bfInfo); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); error = CM_OK; } @@ -416,12 +417,12 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentToVoid( // Check if we really need to bind if(bindable) { - if ((error = cm_EEM_ForceWakeup(itfRequire.client->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfRequire.client->Template->dspId)) != CM_OK) goto out; error = cm_bindInterfaceToVoid(&itfRequire); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); } cm_registerSingletonBinding(client, &itfRequire, NULL, clientId); @@ -496,13 +497,13 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentAsynchronous( if(bindable) { // Create the binding and bind it to the client (or all sub-components clients ....) - if (itfRequire.client->template->dspId != itfProvide.server->template->dspId) + if (itfRequire.client->Template->dspId != itfProvide.server->Template->dspId) { - if ((error = cm_EEM_ForceWakeup(itfRequire.client->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfRequire.client->Template->dspId)) != CM_OK) goto out; - if ((error = cm_EEM_ForceWakeup(itfProvide.server->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfProvide.server->Template->dspId)) != CM_OK) { - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); goto out; } @@ -515,12 +516,12 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentAsynchronous( elfhandleSkeletonOrEvent, elfhandleStub); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); - cm_EEM_AllowSleep(itfProvide.server->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); + cm_EEM_AllowSleep(itfProvide.server->Template->dspId); } else { - if ((error = cm_EEM_ForceWakeup(itfRequire.client->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfRequire.client->Template->dspId)) != CM_OK) goto out; // This is a acynchronous communication @@ -531,7 +532,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentAsynchronous( dspEventMemType, elfhandleSkeletonOrEvent); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); } } @@ -570,8 +571,8 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponentAsynchronous( // Check if this is a Asynchronous binding if(bfInfoID == BF_DSP2DSP) { - t_nmf_core_id clientDsp = itfRequire.client->template->dspId; - t_nmf_core_id serverDsp = itfProvide.server->template->dspId; + t_nmf_core_id clientDsp = itfRequire.client->Template->dspId; + t_nmf_core_id serverDsp = itfProvide.server->Template->dspId; (void)cm_EEM_ForceWakeup(clientDsp); (void)cm_EEM_ForceWakeup(serverDsp); @@ -587,7 +588,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponentAsynchronous( } else if(bfInfoID == BF_ASYNCHRONOUS) { - t_nmf_core_id clientDsp = itfRequire.client->template->dspId; + t_nmf_core_id clientDsp = itfRequire.client->Template->dspId; (void)cm_EEM_ForceWakeup(clientDsp); @@ -641,7 +642,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentFromCMCore( &itfProvide)) != CM_OK) goto out; - if ((error = cm_EEM_ForceWakeup(itfProvide.server->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfProvide.server->Template->dspId)) != CM_OK) goto out; switch(eventMemType) @@ -665,7 +666,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentFromCMCore( elfhandleSkeleton, &bfInfo); - cm_EEM_AllowSleep(itfProvide.server->template->dspId); + cm_EEM_AllowSleep(itfProvide.server->Template->dspId); out: cm_ELF_CloseFile(TRUE, elfhandleSkeleton); @@ -681,9 +682,9 @@ out: if (error != CM_OK) { OSAL_LOCK_API(); - (void)cm_EEM_ForceWakeup(itfProvide.server->template->dspId); + (void)cm_EEM_ForceWakeup(itfProvide.server->Template->dspId); cm_unbindComponentFromCMCore(bfInfo); - cm_EEM_AllowSleep(itfProvide.server->template->dspId); + cm_EEM_AllowSleep(itfProvide.server->Template->dspId); OSAL_UNLOCK_API(); } } @@ -709,7 +710,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponentFromCMCore( // Check if this is a DSP to Host binding //if(bfInfo->id != BF_HOST2DSP) // return CM_ILLEGAL_UNBINDING; - coreId = bfInfo->dspskeleton.skelInstance->template->dspId; + coreId = bfInfo->dspskeleton.skelInstance->Template->dspId; (void)cm_EEM_ForceWakeup(coreId); @@ -756,7 +757,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentToCMCore( // Check if we really need to bind if(bindable) { - if ((error = cm_EEM_ForceWakeup(itfRequire.client->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(itfRequire.client->Template->dspId)) != CM_OK) goto out; error = cm_bindComponentToCMCore( @@ -766,7 +767,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_BindComponentToCMCore( elfhandleStub, (t_mpc2host_bf_info**)mpc2hostId); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); } cm_registerSingletonBinding(client, &itfRequire, NULL, clientId); @@ -811,11 +812,11 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_UnbindComponentToCMCore( // Check if we really need to unbind if(cm_unregisterSingletonBinding(client, &itfRequire, &itfProvide, clientId)) { - (void)cm_EEM_ForceWakeup(itfRequire.client->template->dspId); + (void)cm_EEM_ForceWakeup(itfRequire.client->Template->dspId); cm_unbindComponentToCMCore(&itfRequire, bfInfo); - cm_EEM_AllowSleep(itfRequire.client->template->dspId); + cm_EEM_AllowSleep(itfRequire.client->Template->dspId); error = CM_OK; } @@ -838,7 +839,7 @@ PUBLIC EXPORT_SHARED t_event_params_handle CM_ENGINE_AllocEvent(t_cm_bf_host2mpc if(bfInfo->dspskeleton.skelInstance->interfaceReferences[0][0].instance->state != STATE_RUNNABLE) { ERROR("CM_COMPONENT_NOT_STARTED: Call interface before start component %s<%s>\n", bfInfo->dspskeleton.skelInstance->pathname, - bfInfo->dspskeleton.skelInstance->template->name, 0, 0, 0, 0); + bfInfo->dspskeleton.skelInstance->Template->name, 0, 0, 0, 0); } eventHandle = cm_AllocEvent(bfInfo->fifo); @@ -891,13 +892,13 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_ReadComponentAttribute( error = CM_INVALID_COMPONENT_HANDLE; else { - if ((error = cm_EEM_ForceWakeup(component->template->dspId)) != CM_OK) + if ((error = cm_EEM_ForceWakeup(component->Template->dspId)) != CM_OK) goto out; // t_uint24 -> t_uint32 possible since we know it same size error = cm_readAttribute(component, attrName, (t_uint32*)attrValue); - cm_EEM_AllowSleep(component->template->dspId); + cm_EEM_AllowSleep(component->Template->dspId); } out: @@ -921,7 +922,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentListHeader( *headerComponent = 0; for (i=0; i < ComponentTable.idxMax; i++) { if ((componentEntry(i) != NULL) && - (componentEntry(i)->template->classe != FIRMWARE) && + (componentEntry(i)->Template->classe != FIRMWARE) && (domainDesc[componentEntry(i)->domainId].client == client)) { *headerComponent = ENTRY2HANDLE(componentEntry(i), i);; break; @@ -950,7 +951,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentListNext( *nextComponent = 0; for (i++; i < ComponentTable.idxMax; i++) { if ((componentEntry(i) != NULL) && - (componentEntry(i)->template->classe != FIRMWARE) && + (componentEntry(i)->Template->classe != FIRMWARE) && (domainDesc[componentEntry(i)->domainId].client == client)) { *nextComponent = ENTRY2HANDLE(componentEntry(i), i);; break; @@ -985,9 +986,9 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentDescription( } else { cm_StringCopy( templateName, - comp->template->name, + comp->Template->name, templateNameLength); - *coreId = comp->template->dspId; + *coreId = comp->Template->dspId; cm_StringCopy( localName, comp->pathname, @@ -1018,7 +1019,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentRequiredInterfaceNumber( if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; } else { - *numberRequiredInterfaces = comp->template->requireNumber; + *numberRequiredInterfaces = comp->Template->requireNumber; error = CM_OK; } @@ -1046,29 +1047,29 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentRequiredInterface( // Sanity check if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; - } else if(index >= comp->template->requireNumber) { + } else if(index >= comp->Template->requireNumber) { error = CM_NO_SUCH_REQUIRED_INTERFACE; } else { cm_StringCopy( itfName, - comp->template->requires[index].name, + comp->Template->requires[index].name, itfNameLength); cm_StringCopy( itfType, - comp->template->requires[index].interface->type, + comp->Template->requires[index].interface->type, itfTypeLength); - if(comp->template->requires[index].requireTypes & COLLECTION_REQUIRE) - *collectionSize = comp->template->requires[index].collectionSize; + if(comp->Template->requires[index].requireTypes & COLLECTION_REQUIRE) + *collectionSize = comp->Template->requires[index].collectionSize; else *collectionSize = -1; if(requireState != NULL) { *requireState = 0; - if(comp->template->requires[index].requireTypes & COLLECTION_REQUIRE) + if(comp->Template->requires[index].requireTypes & COLLECTION_REQUIRE) *requireState |= CM_REQUIRE_COLLECTION; - if(comp->template->requires[index].requireTypes & OPTIONAL_REQUIRE) + if(comp->Template->requires[index].requireTypes & OPTIONAL_REQUIRE) *requireState |= CM_REQUIRE_OPTIONAL; - if(comp->template->requires[index].requireTypes & STATIC_REQUIRE) + if(comp->Template->requires[index].requireTypes & STATIC_REQUIRE) *requireState |= CM_REQUIRE_STATIC; } @@ -1119,9 +1120,9 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentRequiredInterfaceBinding( } else if(*server != 0) { cm_StringCopy( serverItfName, - itfProvide.server->template->provides[itfProvide.provideIndex].name, + itfProvide.server->Template->provides[itfProvide.provideIndex].name, serverItfNameLength); - if(itfProvide.server->template->provides[itfProvide.provideIndex].provideTypes & COLLECTION_PROVIDE) { + if(itfProvide.server->Template->provides[itfProvide.provideIndex].provideTypes & COLLECTION_PROVIDE) { int len = cm_StringLength(serverItfName, serverItfNameLength); serverItfName[len++] = '['; if(itfProvide.collectionIndex >= 100) @@ -1158,7 +1159,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentProvidedInterfaceNumber( if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; } else { - *numberProvidedInterfaces = comp->template->provideNumber; + *numberProvidedInterfaces = comp->Template->provideNumber; error = CM_OK; } @@ -1185,19 +1186,19 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentProvidedInterface( // Sanity check if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; - } else if(index >= comp->template->provideNumber) { + } else if(index >= comp->Template->provideNumber) { error = CM_NO_SUCH_PROVIDED_INTERFACE; } else { cm_StringCopy( itfName, - comp->template->provides[index].name, + comp->Template->provides[index].name, itfNameLength); cm_StringCopy( itfType, - comp->template->provides[index].interface->type, + comp->Template->provides[index].interface->type, itfTypeLength); - if(comp->template->provides[index].provideTypes & COLLECTION_PROVIDE) - *collectionSize = comp->template->provides[index].collectionSize; + if(comp->Template->provides[index].provideTypes & COLLECTION_PROVIDE) + *collectionSize = comp->Template->provides[index].collectionSize; else *collectionSize = -1; @@ -1225,7 +1226,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentPropertyNumber( if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; } else { - *numberProperties = comp->template->propertyNumber; + *numberProperties = comp->Template->propertyNumber; error = CM_OK; } @@ -1249,12 +1250,12 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetComponentPropertyName( // Sanity check if (NULL == comp) { error = CM_INVALID_COMPONENT_HANDLE; - } else if(index >= comp->template->propertyNumber) { + } else if(index >= comp->Template->propertyNumber) { error = CM_NO_SUCH_PROPERTY; } else { cm_StringCopy( propertyName, - comp->template->properties[index].name, + comp->Template->properties[index].name, propertyNameLength); error = CM_OK; diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/dspevent.c b/drivers/staging/nmf-cm/cm/engine/component/src/dspevent.c index 0c055c7f6f9..0d5e89e0515 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/dspevent.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/dspevent.c @@ -33,8 +33,10 @@ t_cm_error dspevent_createDspEventFifo( // Allocate fifo *pHandle = cm_DM_Alloc(pComp->domainId, dspEventMemType, fifoNbElem*fifoElemSizeInWord, CM_MM_ALIGN_2WORDS, TRUE); - if(*pHandle == INVALID_MEMORY_HANDLE) - return CM_NO_MORE_MEMORY; + if(*pHandle == INVALID_MEMORY_HANDLE) { + ERROR("CM_NO_MORE_MEMORY: dspevent_createDspEventFifo()\n", 0, 0, 0, 0, 0, 0); + return CM_NO_MORE_MEMORY; + } cm_DSP_GetDspAddress(*pHandle, &dspElementAddr); 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 72bc286d1d4..625d0a06796 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/initializer.c @@ -49,7 +49,7 @@ PUBLIC t_cm_error cm_COMP_INIT_Init(t_nmf_core_id coreId) // Get interface description if((error = cm_getProvidedInterface(ee, "service", &itfProvide)) != CM_OK) return error; - provide = &ee->template->provides[itfProvide.provideIndex]; + provide = &ee->Template->provides[itfProvide.provideIndex]; if ((error = dspevent_createDspEventFifo( @@ -78,6 +78,7 @@ PUBLIC t_cm_error cm_COMP_INIT_Init(t_nmf_core_id coreId) { OSAL_DestroySemaphore(initializerDesc[coreId].fifoSemHandle); dspevent_destroyDspEventFifo(initializerDesc[coreId].dspfifoHandle); + ERROR("CM_NO_MORE_MEMORY: fifo_alloc() failed in cm_COMP_INIT_Init()\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; } @@ -92,6 +93,7 @@ PUBLIC t_cm_error cm_COMP_INIT_Init(t_nmf_core_id coreId) OSAL_DestroySemaphore(initializerDesc[coreId].fifoSemHandle); fifo_free(initializerDesc[coreId].downlinkFifo); dspevent_destroyDspEventFifo(initializerDesc[coreId].dspfifoHandle); + ERROR("CM_NO_MORE_MEMORY: fifo_alloc() failed in cm_COMP_INIT_Init()\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; } @@ -144,7 +146,7 @@ PUBLIC t_cm_error cm_COMP_CallService( params[INIT_COMPONENT_CMD_METHOD_INDEX] = (t_uint16)(methodAddress & 0xFFFF); params[INIT_COMPONENT_CMD_METHOD_INDEX+1] = (t_uint16)(methodAddress >> 16); - error = cm_COMP_generic(pComp->template->dspId, params, sizeof(params) / sizeof(t_uint16), serviceIndex); + 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) 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 7897a237838..2a61d4a7433 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/instantiater.c @@ -110,16 +110,16 @@ static void cm_DestroyComponentMemory(t_component_instance *component) } } - for(i = 0; i < component->template->requireNumber; i++) + for(i = 0; i < component->Template->requireNumber; i++) { OSAL_Free(component->interfaceReferences[i]); } cm_StringRelease(component->pathname); - cm_ELF_FreeInstance(component->template->dspId, component->template->memories, component->memories); + cm_ELF_FreeInstance(component->Template->dspId, component->Template->memories, component->memories); - cm_unloadComponent(component->template); + cm_unloadComponent(component->Template); OSAL_Free(component); } @@ -130,12 +130,15 @@ static void cm_DestroyComponentMemory(t_component_instance *component) void cm_delayedDestroyComponent(t_component_instance *component) { int i; + if (osal_debug_ops.component_destroy) + osal_debug_ops.component_destroy(component); + /* * Remove component from load map here */ cm_DSPABI_RemoveLoadMap( component->domainId, - component->template->name, + component->Template->name, component->memories, component->pathname, component); @@ -146,28 +149,28 @@ void cm_delayedDestroyComponent(t_component_instance *component) { /* * disconnect interrupt handler if needed */ - for(i = 0; i < component->template->provideNumber; i++) + for(i = 0; i < component->Template->provideNumber; i++) { - if(component->template->provides[i].interruptLine) + if(component->Template->provides[i].interruptLine) { - cm_unbindInterfaceStaticInterrupt(component->template->dspId, component->template->provides[i].interruptLine); + cm_unbindInterfaceStaticInterrupt(component->Template->dspId, component->Template->provides[i].interruptLine); } } /* * Update dsp stack size if needed */ - if (component->template->minStackSize > MIN_STACK_SIZE) + if (component->Template->minStackSize > MIN_STACK_SIZE) { - if (cm_EEM_isStackUpdateNeed(component->template->dspId, component->priority, FALSE, component->template->minStackSize)) + if (cm_EEM_isStackUpdateNeed(component->Template->dspId, component->priority, FALSE, component->Template->minStackSize)) { t_uint32 newStackValue; t_uint32 maxComponentStackSize; maxComponentStackSize = cm_getMaxStackValue(component); - cm_EEM_UpdateStack(component->template->dspId, component->priority, maxComponentStackSize, &newStackValue); - if (cm_DSP_GetState(component->template->dspId)->state == MPC_STATE_BOOTED) - cm_COMP_UpdateStack(component->template->dspId, newStackValue); + cm_EEM_UpdateStack(component->Template->dspId, component->priority, maxComponentStackSize, &newStackValue); + if (cm_DSP_GetState(component->Template->dspId)->state == MPC_STATE_BOOTED) + cm_COMP_UpdateStack(component->Template->dspId, newStackValue); } } @@ -253,7 +256,7 @@ t_cm_error cm_instantiateComponent(const char* templateName, } component->interfaceReferences = (t_interface_reference**)((char*)component + sizeof(t_component_instance)); - component->template = template; + component->Template = template; /* * Update linked list @@ -300,7 +303,7 @@ t_cm_error cm_instantiateComponent(const char* templateName, component->thisAddress = 0xFFFFFFFF; component->state = STATE_NONE; - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { // Return same handle for singleton component struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, TRUE, domainDesc[domainId].client); if(cl == NULL) @@ -450,6 +453,9 @@ t_cm_error cm_instantiateComponent(const char* templateName, else component->state = STATE_STOPPED; + if (osal_debug_ops.component_create) + osal_debug_ops.component_create(component); + *refcomponent = component; return CM_OK; } @@ -495,7 +501,7 @@ t_cm_error cm_startComponent(t_component_instance* component, t_nmf_client_id cl /* * Special code for SINGLETON handling */ - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, FALSE, clientId); if(cl != NULL) @@ -515,15 +521,15 @@ t_cm_error cm_startComponent(t_component_instance* component, t_nmf_client_id cl /* * Check that all required binding have been binded! */ - for(i = 0; i < component->template->requireNumber; i++) + for(i = 0; i < component->Template->requireNumber; i++) { - int nb = component->template->requires[i].collectionSize, j; + int nb = component->Template->requires[i].collectionSize, j; for(j = 0; j < nb; j++) { if(component->interfaceReferences[i][j].instance == NULL && - (component->template->requires[i].requireTypes & (OPTIONAL_REQUIRE | INTRINSEC_REQUIRE)) == 0) + (component->Template->requires[i].requireTypes & (OPTIONAL_REQUIRE | INTRINSEC_REQUIRE)) == 0) { - ERROR("CM_REQUIRE_INTERFACE_UNBINDED: Required interface '%s'.'%s' binded\n", component->pathname, component->template->requires[i].name, 0, 0, 0, 0); + ERROR("CM_REQUIRE_INTERFACE_UNBINDED: Required interface '%s'.'%s' binded\n", component->pathname, component->Template->requires[i].name, 0, 0, 0, 0); return CM_REQUIRE_INTERFACE_UNBINDED; } } @@ -542,12 +548,12 @@ t_cm_error cm_startComponent(t_component_instance* component, t_nmf_client_id cl { // 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) + if ((error = cm_EEM_ForceWakeup(component->Template->dspId)) != CM_OK) return error; - error = cm_PWR_EnableMPC(MPC_PWR_HWIP, component->template->dspId); + error = cm_PWR_EnableMPC(MPC_PWR_HWIP, component->Template->dspId); - cm_EEM_AllowSleep(component->template->dspId); + cm_EEM_AllowSleep(component->Template->dspId); if(error != CM_OK) return error; @@ -556,16 +562,16 @@ t_cm_error cm_startComponent(t_component_instance* component, t_nmf_client_id cl /* * Call starter if available */ - if(component->template->LCCStartAddress != 0) + if(component->Template->LCCStartAddress != 0) { - if (cm_DSP_GetState(component->template->dspId)->state != MPC_STATE_BOOTED) + if (cm_DSP_GetState(component->Template->dspId)->state != MPC_STATE_BOOTED) { return CM_MPC_NOT_RESPONDING; } else if ((error = cm_COMP_CallService( - (component->priority > cm_EEM_getExecutiveEngine(component->template->dspId)->instance->priority)?NMF_START_SYNC_INDEX:NMF_START_INDEX, + (component->priority > cm_EEM_getExecutiveEngine(component->Template->dspId)->instance->priority)?NMF_START_SYNC_INDEX:NMF_START_INDEX, component, - component->template->LCCStartAddress)) != CM_OK) + component->Template->LCCStartAddress)) != CM_OK) { if (error == CM_MPC_NOT_RESPONDING) ERROR("CM_MPC_NOT_RESPONDING: can't call starter '%s'\n", component->pathname, 0, 0, 0, 0, 0); @@ -589,7 +595,7 @@ t_cm_error cm_stopComponent(t_component_instance* component, t_nmf_client_id cli /* * Special code for SINGLETON handling */ - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, FALSE, clientId); if(cl != NULL) @@ -616,7 +622,7 @@ t_cm_error cm_stopComponent(t_component_instance* component, t_nmf_client_id cli value, sizeof(value)) == CM_OK); - if (cm_DSP_GetState(component->template->dspId)->state != MPC_STATE_BOOTED) + if (cm_DSP_GetState(component->Template->dspId)->state != MPC_STATE_BOOTED) { error = CM_MPC_NOT_RESPONDING; } @@ -625,12 +631,12 @@ t_cm_error cm_stopComponent(t_component_instance* component, t_nmf_client_id cli /* * Call stopper if available */ - if(component->template->LCCStopAddress != 0) + if(component->Template->LCCStopAddress != 0) { if ((error = cm_COMP_CallService( isHwProperty ? NMF_STOP_SYNC_INDEX : NMF_STOP_INDEX, component, - component->template->LCCStopAddress)) != CM_OK) + component->Template->LCCStopAddress)) != CM_OK) { if (error == CM_MPC_NOT_RESPONDING) ERROR("CM_MPC_NOT_RESPONDING: can't call stopper '%s'\n", component->pathname, 0, 0, 0, 0, 0); @@ -643,7 +649,7 @@ t_cm_error cm_stopComponent(t_component_instance* component, t_nmf_client_id cli */ if(isHwProperty) { - cm_PWR_DisableMPC(MPC_PWR_HWIP, component->template->dspId); + cm_PWR_DisableMPC(MPC_PWR_HWIP, component->Template->dspId); } return error; @@ -654,7 +660,7 @@ t_cm_error cm_destroyInstance(t_component_instance* component, t_destroy_state f int i, j; LOG_INTERNAL(1, "\n##### Destroy %s/%x (%s) component on %s #####\n", - component->pathname, component, component->template->name, cm_getDspName(component->template->dspId), 0, 0); + component->pathname, component, component->Template->name, cm_getDspName(component->Template->dspId), 0, 0); /* * Component life cycle sanity check; do it only when destroying last reference. @@ -667,15 +673,15 @@ t_cm_error cm_destroyInstance(t_component_instance* component, t_destroy_state f // CM_ASSERT component->state == STATE_STOPPED // Check that all required binding have been unbound! - for(i = 0; i < component->template->requireNumber; i++) + for(i = 0; i < component->Template->requireNumber; i++) { - int nb = component->template->requires[i].collectionSize; + int nb = component->Template->requires[i].collectionSize; for(j = 0; j < nb; j++) { if(component->interfaceReferences[i][j].instance != NULL) { ERROR("CM_COMPONENT_NOT_UNBINDED: Required interface %s/%x.%s still binded\n", - component->pathname, component, component->template->requires[i].name, 0, 0, 0); + component->pathname, component, component->Template->requires[i].name, 0, 0, 0); return CM_COMPONENT_NOT_UNBINDED; } } @@ -694,19 +700,19 @@ t_cm_error cm_destroyInstance(t_component_instance* component, t_destroy_state f { if ((componentEntry(idx) == NULL) || (componentEntry(idx) == component)) continue; - for (i = 0; i < componentEntry(idx)->template->requireNumber; i++) + for (i = 0; i < componentEntry(idx)->Template->requireNumber; i++) { - for (j = 0; j < componentEntry(idx)->template->requires[i].collectionSize; j++) + for (j = 0; j < componentEntry(idx)->Template->requires[i].collectionSize; j++) { if(componentEntry(idx)->interfaceReferences[i][j].instance == component - && component->template->provides[componentEntry(idx)->interfaceReferences[i][j].provideIndex].interruptLine == 0) + && component->Template->provides[componentEntry(idx)->interfaceReferences[i][j].provideIndex].interruptLine == 0) { ERROR(" -> %s/%x.%s still used by %s/%x.%s\n", component->pathname, component, - component->template->provides[componentEntry(idx)->interfaceReferences[i][j].provideIndex].name, + component->Template->provides[componentEntry(idx)->interfaceReferences[i][j].provideIndex].name, componentEntry(idx)->pathname, componentEntry(idx), - componentEntry(idx)->template->requires[i].name); + componentEntry(idx)->Template->requires[i].name); } } } @@ -718,18 +724,18 @@ t_cm_error cm_destroyInstance(t_component_instance* component, t_destroy_state f // Sanity check finished, here, we will do the JOB whatever error - if (cm_DSP_GetState(component->template->dspId)->state == MPC_STATE_BOOTED) + if (cm_DSP_GetState(component->Template->dspId)->state == MPC_STATE_BOOTED) { /* * Call destroy if available */ /* Call the destructor only if we don't want to force the destruction */ - if(forceDestroy != DESTROY_WITHOUT_CHECK_CALL && component->template->LCCDestroyAddress != 0) + if(forceDestroy != DESTROY_WITHOUT_CHECK_CALL && component->Template->LCCDestroyAddress != 0) { if (cm_COMP_CallService( NMF_DESTROY_INDEX, component, - component->template->LCCDestroyAddress) != CM_OK) + component->Template->LCCDestroyAddress) != CM_OK) { ERROR("CM_MPC_NOT_RESPONDING: can't call destroy '%s'\n", component->pathname, 0, 0, 0, 0, 0); } @@ -750,7 +756,7 @@ t_cm_error cm_destroyInstanceForClient(t_component_instance* component, t_destro /* * Special code for SINGLETON handling */ - if(component->template->classe == SINGLETON) + if(component->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = cm_getClientOfSingleton(component, FALSE, clientId); int nbinstance; @@ -762,7 +768,7 @@ t_cm_error cm_destroyInstanceForClient(t_component_instance* component, t_destro if(nbinstance > 0) { LOG_INTERNAL(1, "##### Singleton : Delete handle of %s/%x (%s) component on %s [%d] provItf=%d #####\n", - component->pathname, component, component->template->name, cm_getDspName(component->template->dspId), + component->pathname, component, component->Template->name, cm_getDspName(component->Template->dspId), nbinstance, component->providedItfUsedCount); return CM_OK; } @@ -776,7 +782,7 @@ t_cm_error cm_destroyInstanceForClient(t_component_instance* component, t_destro static t_uint32 cm_getMaxStackValue(t_component_instance *pComponent) { - t_nmf_executive_engine_id executiveEngineId = cm_EEM_getExecutiveEngine(pComponent->template->dspId)->executiveEngineId; + t_nmf_executive_engine_id executiveEngineId = cm_EEM_getExecutiveEngine(pComponent->Template->dspId)->executiveEngineId; t_uint32 res = MIN_STACK_SIZE; unsigned int i; @@ -784,11 +790,11 @@ static t_uint32 cm_getMaxStackValue(t_component_instance *pComponent) { if ((componentEntry(i) != NULL) && (componentEntry(i) != pComponent) && - (pComponent->template->dspId == componentEntry(i)->template->dspId) && + (pComponent->Template->dspId == componentEntry(i)->Template->dspId) && (executiveEngineId == SYNCHRONOUS_EXECUTIVE_ENGINE || componentEntry(i)->priority == pComponent->priority)) { - if (componentEntry(i)->template->minStackSize > res) - res = componentEntry(i)->template->minStackSize; + if (componentEntry(i)->Template->minStackSize > res) + res = componentEntry(i)->Template->minStackSize; } } diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/introspection.c b/drivers/staging/nmf-cm/cm/engine/component/src/introspection.c index a4e0a01a242..3855f97ded8 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/introspection.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/introspection.c @@ -15,7 +15,7 @@ t_cm_error cm_getComponentProperty( const char *propName, char value[MAX_PROPERTY_VALUE_LENGTH], t_uint32 valueLength){ - t_component_template* template = component->template; + t_component_template* template = component->Template; int i; for(i = 0; i < template->propertyNumber; i++) { @@ -40,11 +40,11 @@ static t_attribute* cm_getAttributeDescriptor( { int i; - for(i = 0; i < component->template->attributeNumber; i++) + for(i = 0; i < component->Template->attributeNumber; i++) { - if(cm_StringCompare(component->template->attributes[i].name, attrName, MAX_ATTRIBUTE_NAME_LENGTH) == 0) + if(cm_StringCompare(component->Template->attributes[i].name, attrName, MAX_ATTRIBUTE_NAME_LENGTH) == 0) { - return &component->template->attributes[i]; + return &component->Template->attributes[i]; } } @@ -76,7 +76,7 @@ t_cm_logical_address cm_getAttributeHostAddr( if((attribute = cm_getAttributeDescriptor(component, attrName)) == NULL) return 0x0; - // TODO JPF: component->template->attributes[i].memory.offset could be converted in byte during load + // TODO JPF: component->Template->attributes[i].memory.offset could be converted in byte during load return cm_DSP_GetHostLogicalAddress(component->memories[attribute->memory.memory->id]) + attribute->memory.offset * attribute->memory.memory->memEntSize; } @@ -96,7 +96,7 @@ t_cm_error cm_readAttribute( return CM_NO_SUCH_ATTRIBUTE; } - // TODO JPF: component->template->attributes[i].memory.offset could be converted in byte during load + // TODO JPF: component->Template->attributes[i].memory.offset could be converted in byte during load hostAddr = cm_DSP_GetHostLogicalAddress(component->memories[attribute->memory.memory->id]) + attribute->memory.offset * attribute->memory.memory->memEntSize; @@ -137,7 +137,7 @@ t_cm_error cm_writeAttribute( return CM_NO_SUCH_ATTRIBUTE; } - // TODO JPF: component->template->attributes[i].memory.offset could be converted in byte during load + // TODO JPF: component->Template->attributes[i].memory.offset could be converted in byte during load hostAddr = cm_DSP_GetHostLogicalAddress(component->memories[attribute->memory.memory->id]) + attribute->memory.offset * attribute->memory.memory->memEntSize; @@ -173,7 +173,7 @@ t_dsp_address cm_getFunction( if((error = cm_getProvidedInterface(component, interfaceName, &itfProvide)) != CM_OK) return error; - provide = &component->template->provides[itfProvide.provideIndex]; + provide = &component->Template->provides[itfProvide.provideIndex]; for(i = 0; i < provide->interface->methodNumber; i++) { @@ -232,12 +232,12 @@ PUBLIC t_cm_error cm_getProvidedInterface(const t_component_instance* server, t_interface_provide_description *itfProvide){ int i; - for(i = 0; i < server->template->provideNumber; i++) + for(i = 0; i < server->Template->provideNumber; i++) { int collectionIndex; - if(compareItfName(server->template->provides[i].name, itfName, &collectionIndex) == 0) + if(compareItfName(server->Template->provides[i].name, itfName, &collectionIndex) == 0) { - t_interface_provide *provide = &server->template->provides[i]; + t_interface_provide *provide = &server->Template->provides[i]; if(collectionIndex >= 0) { if(! (provide->provideTypes & COLLECTION_PROVIDE)) { @@ -287,10 +287,10 @@ t_cm_error cm_getRequiredInterface(const t_component_instance* client, t_interface_require_description *itfRequire){ int i; - for(i = 0; i < client->template->requireNumber; i++) { + for(i = 0; i < client->Template->requireNumber; i++) { int collectionIndex; - if(compareItfName(client->template->requires[i].name, itfName, &collectionIndex) == 0) { - t_interface_require *require = &client->template->requires[i]; + if(compareItfName(client->Template->requires[i].name, itfName, &collectionIndex) == 0) { + t_interface_require *require = &client->Template->requires[i]; if(collectionIndex >= 0) { if(! (require->requireTypes & COLLECTION_REQUIRE)) { ERROR("CM_NO_SUCH_REQUIRED_INTERFACE(%s, %s)\n", diff --git a/drivers/staging/nmf-cm/cm/engine/component/src/loader.c b/drivers/staging/nmf-cm/cm/engine/component/src/loader.c index 762f74c4479..ad6af00f5a5 100644 --- a/drivers/staging/nmf-cm/cm/engine/component/src/loader.c +++ b/drivers/staging/nmf-cm/cm/engine/component/src/loader.c @@ -15,6 +15,7 @@ void START(void); void END(char*); +#undef NHASH #define NHASH 79 //Use a prime number! #define MULT 17 @@ -107,9 +108,9 @@ t_uint32 cm_resolvSymbol( int i, j; // Search if this method is provided by EE and resolve it directly - for(i = 0; i < ee->template->provideNumber; i++) + for(i = 0; i < ee->Template->provideNumber; i++) { - t_interface_provide* provide = &ee->template->provides[i]; + t_interface_provide* provide = &ee->Template->provides[i]; for(j = 0; j < provide->interface->methodNumber; j++) { diff --git a/drivers/staging/nmf-cm/cm/engine/configuration/src/configuration_wrapper.c b/drivers/staging/nmf-cm/cm/engine/configuration/src/configuration_wrapper.c index 34789752b7d..bc3952e63b4 100644 --- a/drivers/staging/nmf-cm/cm/engine/configuration/src/configuration_wrapper.c +++ b/drivers/staging/nmf-cm/cm/engine/configuration/src/configuration_wrapper.c @@ -89,20 +89,20 @@ PUBLIC void CM_ENGINE_Destroy(void) if ((instance = componentEntry(i)) == NULL) continue; clientId = domainDesc[instance->domainId].client; - LOG_INTERNAL(0, "Found a remaining component %s (%s) when destroying the CM !!!\n", instance->pathname, instance->template->name, 0, 0, 0, 0); + LOG_INTERNAL(0, "Found a remaining component %s (%s) when destroying the CM !!!\n", instance->pathname, instance->Template->name, 0, 0, 0, 0); if (/* skip EE */ - (instance->template->classe == FIRMWARE) || + (instance->Template->classe == FIRMWARE) || /* Skip all binding components */ - (cm_StringCompare(instance->template->name, "_ev.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_st.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_sk.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_tr.", 4) == 0)) + (cm_StringCompare(instance->Template->name, "_ev.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_st.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_sk.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_tr.", 4) == 0)) continue; /* * Special code for SINGLETON handling */ - if(instance->template->classe == SINGLETON) + if(instance->Template->classe == SINGLETON) { struct t_client_of_singleton* cl = instance->clientOfSingleton; @@ -126,7 +126,7 @@ PUBLIC void CM_ENGINE_Destroy(void) // Stop the component error = cm_stopComponent(instance, clientId); if (error != CM_OK && error != CM_COMPONENT_NOT_STARTED) - LOG_INTERNAL(0, "Error stopping component %s/%x (%s, error=%d, client=%u)\n", instance->pathname, instance, instance->template->name, error, clientId, 0); + LOG_INTERNAL(0, "Error stopping component %s/%x (%s, error=%d, client=%u)\n", instance->pathname, instance, instance->Template->name, error, clientId, 0); // Destroy dependencies cm_destroyRequireInterface(instance, clientId); @@ -142,16 +142,16 @@ PUBLIC void CM_ENGINE_Destroy(void) clientId = domainDesc[instance->domainId].client; if (/* skip EE */ - (instance->template->classe == FIRMWARE) || + (instance->Template->classe == FIRMWARE) || /* Skip all binding components */ - (cm_StringCompare(instance->template->name, "_ev.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_st.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_sk.", 4) == 0) || - (cm_StringCompare(instance->template->name, "_tr.", 4) == 0)) { + (cm_StringCompare(instance->Template->name, "_ev.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_st.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_sk.", 4) == 0) || + (cm_StringCompare(instance->Template->name, "_tr.", 4) == 0)) { continue; } - if(instance->template->classe == SINGLETON) + if(instance->Template->classe == SINGLETON) { clientId = instance->clientOfSingleton->clientId; } diff --git a/drivers/staging/nmf-cm/cm/engine/dsp/inc/dsp.h b/drivers/staging/nmf-cm/cm/engine/dsp/inc/dsp.h index 5cd65289ff8..439deac115f 100644 --- a/drivers/staging/nmf-cm/cm/engine/dsp/inc/dsp.h +++ b/drivers/staging/nmf-cm/cm/engine/dsp/inc/dsp.h @@ -17,7 +17,6 @@ #include #include #include -#include #include diff --git a/drivers/staging/nmf-cm/cm/engine/dsp/src/dsp.c b/drivers/staging/nmf-cm/cm/engine/dsp/src/dsp.c index de4ea3b7ba5..7646f6301de 100644 --- a/drivers/staging/nmf-cm/cm/engine/dsp/src/dsp.c +++ b/drivers/staging/nmf-cm/cm/engine/dsp/src/dsp.c @@ -528,20 +528,27 @@ PUBLIC t_cm_error cm_DSP_setStackSize(t_nmf_core_id coreId, t_uint32 newStackSiz { t_uint8 nbXramBanks; t_uint32 xramSize; + t_cm_error error; /* compute size of xram allocator */ nbXramBanks = SxA_NB_BLOCK_RAM - mpcDesc[coreId].nbYramBank; /* check first that required stack size is less then xram memory ....*/ - if (newStackSize >= nbXramBanks * 4 * ONE_KB) + if (newStackSize >= nbXramBanks * 4 * ONE_KB) { + ERROR("CM_NO_MORE_MEMORY: cm_DSP_setStackSize(), required stack size doesn't fit in XRAM.\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; + } /* compute new xram allocator size */ xramSize = nbXramBanks * 4 * ONE_KB - newStackSize; /* try to resize it */ - return cm_MM_ResizeAllocator(cm_DSP_GetAllocator(coreId, INTERNAL_XRAM24), - xramSize << dspMemoryTypeId2OffsetShifter[INTERNAL_XRAM24]); + if ((error = cm_MM_ResizeAllocator(cm_DSP_GetAllocator(coreId, INTERNAL_XRAM24), + xramSize << dspMemoryTypeId2OffsetShifter[INTERNAL_XRAM24])) == CM_NO_MORE_MEMORY) { + ERROR("CM_NO_MORE_MEMORY: Couldn't resize stack in cm_DSP_setStackSize()\n", 0, 0, 0, 0, 0, 0); + } + + return error; } PUBLIC t_cm_error cm_DSP_IsNbYramBanksValid(t_nmf_core_id coreId, t_uint8 nbYramBanks) 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 2efe6edbf69..84f841ef443 100644 --- a/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c +++ b/drivers/staging/nmf-cm/cm/engine/elf/src/elfload.c @@ -103,7 +103,7 @@ static t_interface_description* getInterfaceDescription(t_tmp_elfdescription *el } // Create a new interface if not exists - itf = (t_interface_description*)OSAL_Alloc_Zero(sizeof(t_interface_description) + sizeof(char*) * (elfitf->methodNumber /*- 1*/)); + itf = (t_interface_description*)OSAL_Alloc_Zero(sizeof(t_interface_description) + sizeof(t_dup_char) * (elfitf->methodNumber - 1)); if(itf == NULL) goto out_itf_type; itf->referenceCounter = 1; @@ -343,7 +343,7 @@ t_cm_error cm_ELF_CheckFile( elfhandle->requires[i].requireTypes, 0, 0, 0); CM_ASSERT(elfhandle->requires[i].collectionSize != 0); - ref += sizeof(t_elf_required_interface); + ref = (char*)&require->indexes[0]; if((elfhandle->requires[i].requireTypes & VIRTUAL_REQUIRE) == 0 && (elfhandle->requires[i].requireTypes & STATIC_REQUIRE) == 0) @@ -420,7 +420,7 @@ t_cm_error cm_ELF_CheckFile( 0,0, 0, 0); CM_ASSERT(elfhandle->provides[i].collectionSize != 0); - ref += sizeof(t_elf_required_interface); + ref = (char*)&provide->methodSymbols[0]; { t_uint32 *methodSymbols = (t_uint32*)ref; diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c index 8826e727970..26e66c4a640 100644 --- a/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c +++ b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c @@ -28,6 +28,7 @@ static struct LoadMapHdr *headerAddresses[NB_CORE_IDS] = {0, }; static t_uint32 headerOffsets[NB_CORE_IDS] = {0, }; static t_uint32 entryNumber[NB_CORE_IDS] = {0, }; +#undef myoffsetof #define myoffsetof(TYPE, MEMBER) ((unsigned int) &((TYPE *)0)->MEMBER) t_cm_error cm_DSPABI_AddLoadMap( @@ -45,8 +46,10 @@ t_cm_error cm_DSPABI_AddLoadMap( { headerHandle[coreId] = cm_DM_Alloc(domainId, SDRAM_EXT16, sizeof(struct LoadMapHdr)/2, CM_MM_ALIGN_2WORDS, TRUE); - if (headerHandle[coreId] == INVALID_MEMORY_HANDLE) + if (headerHandle[coreId] == INVALID_MEMORY_HANDLE) { + ERROR("CM_NO_MORE_MEMORY: Unable to allocate loadmap in cm_DSPABI_AddLoadMap()\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; + } headerAddresses[coreId] = (struct LoadMapHdr*)cm_DSP_GetHostLogicalAddress(headerHandle[coreId]); @@ -87,8 +90,10 @@ t_cm_error cm_DSPABI_AddLoadMap( handle = cm_DM_Alloc(domainId, SDRAM_EXT16, sizeof(struct LoadMapItem)/2 + (1 + fnlenaligned/2) + (1 + lnlenaligned/2), CM_MM_ALIGN_2WORDS, TRUE); - if (handle == INVALID_MEMORY_HANDLE) + if (handle == INVALID_MEMORY_HANDLE) { + ERROR("CM_NO_MORE_MEMORY: Unable to allocate loadmap entry in cm_DSPABI_AddLoadMap\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; + } pItem = (struct LoadMapItem*)cm_DSP_GetHostLogicalAddress(handle); cm_DSP_GetDspAddress(handle, &dspentry); @@ -126,13 +131,13 @@ t_cm_error cm_DSPABI_AddLoadMap( "Previou (first) component name %s<%s>\n", curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem, curItem->pARMThis ? (char*)(((t_component_instance *)&curItem->pARMThis)->pathname) : "", - curItem->pARMThis ? (char*)(((t_component_instance *)&curItem->pARMThis)->template->name) : "", 0, 0); + curItem->pARMThis ? (char*)(((t_component_instance *)&curItem->pARMThis)->Template->name) : "", 0, 0); else ERROR("AddLoadMap: Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n" "Previous valid component name %s<%s>", curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem, prevItem->pARMThis ? (char*)(((t_component_instance *)&prevItem->pARMThis)->pathname) : "", - prevItem->pARMThis ? (char*)(((t_component_instance *)&prevItem->pARMThis)->template->name) : "", 0, 0); + prevItem->pARMThis ? (char*)(((t_component_instance *)&prevItem->pARMThis)->Template->name) : "", 0, 0); return CM_INVALID_DATA; } curItemDspAdress = (t_uint32)curItem->pNextItem; @@ -388,14 +393,14 @@ t_cm_error cm_DSPABI_CheckLoadMap_nolock(t_nmf_core_id coreId) count, curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem, (char*)(((t_component_instance *)&curItem->pARMThis)->pathname), - (char*)(((t_component_instance *)&curItem->pARMThis)->template->name), 0); + (char*)(((t_component_instance *)&curItem->pARMThis)->Template->name), 0); else ERROR("CheckLoadMap: Memory corruption in MMDSP (count=%d): at data DSP address=%x or ARM address=%x\n" "Previous valid component name %s<%s>", count, curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem, (char*)(((t_component_instance *)&prevItem->pARMThis)->pathname), - (char*)(((t_component_instance *)&prevItem->pARMThis)->template->name), 0); + (char*)(((t_component_instance *)&prevItem->pARMThis)->Template->name), 0); dump--; return CM_INVALID_COMPONENT_HANDLE; } 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 3f995982088..aacffd15a17 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 @@ -20,6 +20,10 @@ typedef struct { t_uint32 traceState; t_uint32 printLevel; t_uint32 nbOfForceWakeup; + struct { + t_memory_handle handle; + t_cm_logical_address addr; + } panicArea; } 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 14889ec6e4d..f2c833ff7dc 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 @@ -27,6 +27,8 @@ t_ee_state eeState[NB_CORE_IDS]; /****************************************************************** Functions ****************************************************************************/ +static t_cm_error cm_EEM_allocPanicArea(t_nmf_core_id coreId, t_cm_domain_id domainId); +static void cm_EEM_freePanicArea(t_nmf_core_id coreId); PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetExecutiveEngineHandle( t_cm_domain_id domainId, @@ -109,9 +111,19 @@ PUBLIC t_cm_error cm_EEM_Init( return error; } + /* allocate sdram memory for panic area */ + error = cm_EEM_allocPanicArea(coreId, cm_DSP_GetState(coreId)->domainEE); + if (error != CM_OK) { + cm_delayedDestroyComponent(eeState[coreId].instance); + eeState[coreId].instance = (t_component_instance *)0; + cm_DSP_Shutdown(coreId); + return error; + } + /* allocate sdram memory to share perfmeters data */ error = cm_PFM_allocatePerfmeterDataMemory(coreId, cm_DSP_GetState(coreId)->domainEE); if (error != CM_OK) { + cm_EEM_freePanicArea(coreId); cm_delayedDestroyComponent(eeState[coreId].instance); eeState[coreId].instance = (t_component_instance *)0; cm_DSP_Shutdown(coreId); @@ -168,7 +180,7 @@ PUBLIC void cm_EEM_Close(t_nmf_core_id coreId) cm_delayedDestroyComponent(eeState[coreId].instance); eeState[coreId].instance = (t_component_instance *)0; cm_PFM_deallocatePerfmeterDataMemory(coreId); - + cm_EEM_freePanicArea(coreId); cm_DSP_Shutdown(coreId); } @@ -323,8 +335,13 @@ t_cm_error cm_EEM_ForceWakeup(t_nmf_core_id coreId) else if ((error = cm_COMP_ULPForceWakeup(coreId)) != CM_OK) { if (error == CM_MPC_NOT_RESPONDING) { - ERROR("CM_MPC_NOT_RESPONDING: DSP %s can't be wakeup'ed\n", cm_getDspName(coreId), 0, 0, 0, 0, 0); - cm_DSP_SetStatePanic(coreId); + if(cm_DSP_GetState(coreId)->state == MPC_STATE_PANIC) + /* Don't print error which has been done by Panic handling */; + else + { + ERROR("CM_MPC_NOT_RESPONDING: DSP %s can't be wakeup'ed\n", cm_getDspName(coreId), 0, 0, 0, 0, 0); + cm_DSP_SetStatePanic(coreId); + } } return error; } @@ -347,3 +364,29 @@ void cm_EEM_AllowSleep(t_nmf_core_id coreId) } } } + +/* internal api */ +t_cm_error cm_EEM_allocPanicArea(t_nmf_core_id coreId, t_cm_domain_id domainId) +{ + t_cm_error error = CM_OK; + + eeState[coreId].panicArea.handle = cm_DM_Alloc(cm_DSP_GetState(coreId)->domainEE, SDRAM_EXT24, 45 /* 42 registers, pc, 2 magic words */,CM_MM_ALIGN_WORD, TRUE); + if (eeState[coreId].panicArea.handle == INVALID_MEMORY_HANDLE) + error = CM_NO_MORE_MEMORY; + else { + t_uint32 mmdspAddr; + + eeState[coreId].panicArea.addr = cm_DSP_GetHostLogicalAddress(eeState[coreId].panicArea.handle); + cm_DSP_GetDspAddress(eeState[coreId].panicArea.handle, &mmdspAddr); + + cm_writeAttribute(eeState[coreId].instance, "rtos/commonpart/panicDataAddr", mmdspAddr); + } + + return error; +} + +void cm_EEM_freePanicArea(t_nmf_core_id coreId) +{ + eeState[coreId].panicArea.addr = 0; + cm_DM_Free(eeState[coreId].panicArea.handle, TRUE); +} diff --git a/drivers/staging/nmf-cm/cm/engine/memory/inc/domain.h b/drivers/staging/nmf-cm/cm/engine/memory/inc/domain.h index bf75915c259..07caee2d8c1 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/inc/domain.h +++ b/drivers/staging/nmf-cm/cm/engine/memory/inc/domain.h @@ -52,6 +52,7 @@ typedef struct { t_cm_domain_id parent_ref; //parent domain reference } child; } scratch; + void *dbgCooky; //pointer to OS internal data } t_cm_domain_desc; #ifdef DEBUG diff --git a/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator.h b/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator.h index e639c94cb46..f556c6f7056 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator.h +++ b/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator.h @@ -76,8 +76,11 @@ typedef t_cm_chunk* t_memory_handle; //TODO, juraj, add memType to alloc struct ? typedef struct cm_allocator_desc { const char *pAllocName; /* Name of the allocator */ - t_uint32 size; /* Size of the allocator */ + t_uint32 maxSize; /* Max size of the allocator -> Potentially increase/decrease by stack management */ + t_uint32 sbrkSize; /* Current size of allocator */ + t_uint32 offset; /* Offset of the allocator */ t_cm_chunk *chunks; /* Array of chunk */ + t_cm_chunk *lastChunk; /* Null terminated last chunk of previous array declaration */ t_cm_chunk *free_mem_chunks[BINS]; /* List of free memory */ struct cm_allocator_desc* next; /* List of allocator */ } t_cm_allocator_desc; @@ -158,12 +161,11 @@ PUBLIC t_memory_handle cm_MM_Alloc( * * \ingroup MEMORY_INTERNAL */ -PUBLIC t_memory_handle cm_MM_Realloc( +PUBLIC t_cm_error cm_MM_Realloc( t_cm_allocator_desc* alloc, const t_cm_size size, const t_uint32 offset, - const t_cm_memory_alignment memAlignment, - const t_memory_handle handle); + t_memory_handle *handle); /*! * \brief Frees the allocated chunk * diff --git a/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator_utils.h b/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator_utils.h index ce99e4d7a94..0a7c901187b 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator_utils.h +++ b/drivers/staging/nmf-cm/cm/engine/memory/inc/remote_allocator_utils.h @@ -20,14 +20,13 @@ typedef enum { PUBLIC void updateFreeList(t_cm_allocator_desc* alloc, t_cm_chunk* chunk); -PUBLIC void linkChunk(t_cm_chunk* prev,t_cm_chunk* add); +PUBLIC void linkChunk(t_cm_allocator_desc* alloc, t_cm_chunk* prev,t_cm_chunk* add); PUBLIC void unlinkChunk(t_cm_allocator_desc* alloc,t_cm_chunk* current); PUBLIC void unlinkFreeMem(t_cm_allocator_desc* alloc,t_cm_chunk* current); PUBLIC void linkFreeMemBefore(t_cm_chunk* add, t_cm_chunk* next); PUBLIC void linkFreeMemAfter(t_cm_chunk* prev,t_cm_chunk* add); -PUBLIC void mergeChunk(t_cm_allocator_desc* alloc,t_cm_chunk *c,t_cm_chunk *destroy); PUBLIC t_cm_chunk* splitChunk(t_cm_allocator_desc* alloc, t_cm_chunk *chunk, t_uint32 offset, t_mem_split_position position); #endif /*REMOTE_ALLOCATOR_UTILS_H_*/ diff --git a/drivers/staging/nmf-cm/cm/engine/memory/src/domain.c b/drivers/staging/nmf-cm/cm/engine/memory/src/domain.c index 61cb25b39ec..8524183ce19 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/src/domain.c +++ b/drivers/staging/nmf-cm/cm/engine/memory/src/domain.c @@ -13,6 +13,7 @@ #include #include #include +#include /* * domain_memory structure is all we need @@ -42,6 +43,7 @@ static void cm_DM_DomainError(const t_cm_domain_id parentId, const t_nmf_client_ domainDesc.scratch.parent.handle = 0; \ domainDesc.scratch.child.alloc = 0; \ domainDesc.scratch.child.parent_ref = 0; \ + domainDesc.dbgCooky = NULL; \ } while (0) #define FIND_DOMAIN_ID(domainId) \ @@ -204,6 +206,9 @@ PUBLIC t_cm_error cm_DM_CreateDomain(const t_nmf_client_id client, const t_cm_do domainDesc[domainId].client = client; domainDesc[domainId].domain = *domain; + if (osal_debug_ops.domain_create) + osal_debug_ops.domain_create(domainId); + *handle = domainId; return CM_OK; @@ -280,21 +285,15 @@ PUBLIC t_cm_error cm_DM_CreateDomainScratch(const t_nmf_client_id client, const if ((oldMin > scratchMin) || (oldMax < scratchMax)) { t_uint32 newMin = (oldMin > scratchMin)?scratchMin:oldMin; t_uint32 newMax = (oldMax < scratchMax)?scratchMax:oldMax; - t_uint16 userData; - /* save user data lost during realloc, user data do not change */ - cm_MM_GetMemoryHandleUserData(domainDesc[parentId].scratch.parent.handle, &userData, 0); - memhandle = cm_MM_Realloc(cm_DM_getAllocator(parentId, ESRAM_EXT16), newMax - newMin, newMin, - CM_MM_MPC_ALIGN_NONE, domainDesc[parentId].scratch.parent.handle); - if (memhandle == 0) { + if(cm_MM_Realloc(cm_DM_getAllocator(parentId, ESRAM_EXT16), newMax - newMin, newMin, + &domainDesc[parentId].scratch.parent.handle) != CM_OK) + { /* failed to extend the zone */ cm_DM_DestroyDomain(*handle); cm_DM_DomainError(parentId, client); return CM_NO_MORE_MEMORY; } - - cm_MM_SetMemoryHandleUserData(memhandle, userData); - domainDesc[parentId].scratch.parent.handle = memhandle; } } @@ -382,7 +381,6 @@ PUBLIC t_cm_error cm_DM_DestroyDomain(t_cm_domain_id handle) t_uint32 oldMax = 0x0; t_uint32 scratchMin = domainDesc[handle].domain.esramData.offset; t_uint32 scratchMax = domainDesc[handle].domain.esramData.offset + domainDesc[handle].domain.esramData.size; - t_memory_handle memhandle; /* compute the remaining reserved zone size */ for(i = 0; i < MAX_USER_DOMAIN_NB; i++) { @@ -400,20 +398,15 @@ PUBLIC t_cm_error cm_DM_DestroyDomain(t_cm_domain_id handle) /* resize the scratch zone */ if ((oldMin > scratchMin) || (oldMax < scratchMax)) { - t_uint16 userData; - - /* save user data lost during realloc, user data do not change */ - cm_MM_GetMemoryHandleUserData(domainDesc[parentId].scratch.parent.handle, &userData, 0); - memhandle = cm_MM_Realloc(cm_DM_getAllocator(parentId, ESRAM_EXT16), oldMax - oldMin, oldMin, - CM_MM_MPC_ALIGN_NONE, domainDesc[parentId].scratch.parent.handle); - CM_ASSERT(memhandle); //the realloc shouldn't fail.. - - cm_MM_SetMemoryHandleUserData(memhandle, userData); - domainDesc[parentId].scratch.parent.handle = memhandle; + CM_ASSERT(cm_MM_Realloc(cm_DM_getAllocator(parentId, ESRAM_EXT16), oldMax - oldMin, oldMin, + &domainDesc[parentId].scratch.parent.handle) == CM_OK); //the realloc shouldn't fail.. } } } + if (osal_debug_ops.domain_destroy) + osal_debug_ops.domain_destroy(handle); + //reset the domain desc INIT_DOMAIN_STRUCT(domainDesc[handle]); @@ -482,6 +475,10 @@ PUBLIC t_memory_handle cm_DM_Alloc(t_cm_domain_id domainId, t_dsp_memory_type_id cm_DSP_GetState(coreId)->allocator[memType]->baseAddress.physical + cm_MM_GetOffset(handle), cm_MM_GetSize(handle)); } + } else { + LOG_INTERNAL(0, "CM_NO_MORE_MEMORY domainId: %d, memType %d, wordSize %d, alignement %d\n", + domainId, memType, wordSize, memAlignment, 0, 0); + cm_MM_DumpMemory(alloc, offset, offset + size); } return handle; diff --git a/drivers/staging/nmf-cm/cm/engine/memory/src/memory_wrapper.c b/drivers/staging/nmf-cm/cm/engine/memory/src/memory_wrapper.c index f7d47be924d..37bea690e48 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/src/memory_wrapper.c +++ b/drivers/staging/nmf-cm/cm/engine/memory/src/memory_wrapper.c @@ -102,6 +102,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_AllocMpcMemory( if(*pHandle == (t_cm_memory_handle)INVALID_MEMORY_HANDLE) { OSAL_UNLOCK_API(); + ERROR("CM_NO_MORE_MEMORY: CM_AllocMpcMemory() failed\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; } diff --git a/drivers/staging/nmf-cm/cm/engine/memory/src/migration.c b/drivers/staging/nmf-cm/cm/engine/memory/src/migration.c index 35813a56bf2..d68898d830e 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/src/migration.c +++ b/drivers/staging/nmf-cm/cm/engine/memory/src/migration.c @@ -79,6 +79,7 @@ static t_cm_error _cm_migration_initSegment( handle = cm_DM_Alloc(dst, ESRAM_EXT16, size >> 1, CM_MM_ALIGN_AHB_BURST, TRUE); //note: byte to half-word conversion if (handle == 0) { + ERROR("CM_NO_MORE_MEMORY: Unable to init segment for migration\n", 0, 0, 0, 0, 0, 0); return CM_NO_MORE_MEMORY; } diff --git a/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator.c b/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator.c index 3df552aca4d..ec23e28917c 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator.c +++ b/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator.c @@ -18,7 +18,6 @@ #include #include -static t_cm_chunk* cm_MM_RA_getLastChunk(t_cm_allocator_desc* alloc); static void cm_MM_RA_checkAllocator(t_cm_allocator_desc* alloc); //static void cm_MM_RA_checkAlloc(t_cm_allocator_desc* alloc, t_uint32 size, t_uint32 align, t_uint32 min, t_uint32 max); @@ -56,18 +55,12 @@ PUBLIC t_cm_allocator_desc* cm_MM_CreateAllocator(t_cm_size size, t_uint32 offse alloc->next = ListOfAllocators; ListOfAllocators = alloc; - /* Create first chunk */ - alloc->chunks = allocChunk(); - /* assign name */ alloc->pAllocName = name; - alloc->chunks->size = size; - alloc->chunks->offset = offset; - alloc->chunks->alloc = alloc; - alloc->free_mem_chunks[bin_index(alloc->chunks->size)] = alloc->chunks; - - alloc->size = size; + alloc->maxSize = size; + alloc->sbrkSize = 0; + alloc->offset = offset; //TODO, juraj, alloc impacts trace format cm_TRC_traceMemAlloc(TRACE_ALLOCATOR_COMMAND_CREATE, 0, size, name); @@ -111,65 +104,17 @@ PUBLIC t_cm_error cm_MM_DeleteAllocator(t_cm_allocator_desc *alloc) PUBLIC t_cm_error cm_MM_ResizeAllocator(t_cm_allocator_desc *alloc, t_cm_size size) { - t_cm_error error; - /* sanity check */ if (size == 0) return CM_INVALID_PARAMETER; - if((error = fillChunkPool()) != CM_OK) - return error; - - if (size > alloc->size) { - /* ok, increase allocator */ - t_uint32 deltaSize = size - alloc->size; - t_cm_chunk *last = cm_MM_RA_getLastChunk(alloc); - - if (last->status == MEM_FREE) { - /* last chunk is a free one, just increase size */ - unlinkFreeMem(alloc, last); - last->size += deltaSize; - alloc->size += deltaSize; - /* now list of free chunk is potentially no more ordered */ - updateFreeList(alloc, last); - } else { - /* last chunk is a used one, add new free chunk */ - last->size += deltaSize; - splitChunk(alloc, last, last->offset + deltaSize, FREE_CHUNK_AFTER); - alloc->size += deltaSize; - } - } else { - /* reduce allocator */ - t_uint32 deltaSize = alloc->size - size; - t_cm_chunk *last = cm_MM_RA_getLastChunk(alloc); - - /* check if resize is possible */ - if (last->status == MEM_USED) - return CM_NO_MORE_MEMORY; - if (last->size < deltaSize) - return CM_NO_MORE_MEMORY; - - /* ok, rezise can be performed */ - if (last->size == deltaSize) { - t_cm_chunk *prev = last->prev; - - /* remove last free chunk */ - mergeChunk(alloc, prev, last); - prev->size -= deltaSize; - } else { - unlinkFreeMem(alloc, last); - /* reduce size of last free chunk */ - last->size -= deltaSize; - /* now list of free chunk is potentially no more ordered */ - updateFreeList(alloc, last); - } - } + if(alloc->sbrkSize > size) + return CM_NO_MORE_MEMORY; - alloc->size = size; + alloc->maxSize = size; - if (cmIntensiveCheckState) { + if (cmIntensiveCheckState) cm_MM_RA_checkAllocator(alloc); - } return CM_OK; } @@ -251,13 +196,40 @@ PUBLIC t_memory_handle cm_MM_Alloc( } } + // Try to increase sbrkSize through maxSize + aligned_offset = ALIGN_VALUE(MAX((alloc->offset + alloc->sbrkSize), seg_offset), (memAlignment + 1)); + + aligned_end = aligned_offset + size; + + if ((aligned_end <= seg_end) + && aligned_end <= (alloc->offset + alloc->maxSize) + && aligned_offset >= seg_offset + && aligned_offset >= (alloc->offset + alloc->sbrkSize)) + { + /* If that fit requirement, create a new free chunk at the end of current allocator */ + chunk = allocChunk(); + + /* Update chunk size */ + chunk->offset = alloc->offset + alloc->sbrkSize; // offset start at end of current allocator + chunk->size = aligned_end - chunk->offset; + chunk->alloc = alloc; + + /* Chain it with latest chunk */ + linkChunk(alloc, alloc->lastChunk, chunk); + + /* Increase sbrkSize to end of this new chunk */ + alloc->sbrkSize += chunk->size; + + goto foundNew; + } + return INVALID_MEMORY_HANDLE; found: - /* Remove chunk from free list */ unlinkFreeMem(alloc, chunk); +foundNew: //create an empty chunk before the allocated one if (chunk->offset < aligned_offset) { chunk = splitChunk(alloc, chunk, aligned_offset, FREE_CHUNK_BEFORE); @@ -279,21 +251,45 @@ found: cm_MM_RA_checkAllocator(alloc); } - chunk->alloc = alloc; return (t_memory_handle) chunk; } //caution - if successfull, the chunk offset will be aligned with seg_offset //caution++ the offset of the allocated chunk changes implicitly -PUBLIC t_memory_handle cm_MM_Realloc( +PUBLIC t_cm_error cm_MM_Realloc( t_cm_allocator_desc* alloc, const t_cm_size size, const t_uint32 offset, - const t_cm_memory_alignment memAlignment, - const t_memory_handle handle) + t_memory_handle *handle) { - t_cm_chunk *chunk = (t_cm_chunk*)handle; + t_cm_chunk *chunk = (t_cm_chunk*)*handle; + t_uint32 oldOffset = chunk->offset; + t_uint32 oldSize = chunk->size; + t_uint32 oldDomainId = chunk->domainId; + t_uint16 userData = chunk->userData; + + cm_MM_Free(alloc, *handle); + + *handle = cm_MM_Alloc(alloc, size, CM_MM_ALIGN_NONE, offset, size, oldDomainId); + + if(*handle == INVALID_MEMORY_HANDLE) + { + *handle = cm_MM_Alloc(alloc, oldSize, CM_MM_ALIGN_NONE, oldOffset, oldSize, oldDomainId); + + CM_ASSERT(*handle != INVALID_MEMORY_HANDLE); + + chunk = (t_cm_chunk*)*handle; + chunk->userData = userData; + return CM_NO_MORE_MEMORY; + } + + chunk = (t_cm_chunk*)*handle; + chunk->userData = userData; + + return CM_OK; + +#if 0 /* check reallocation is related to this chunk! */ CM_ASSERT(chunk->offset <= (offset + size)); CM_ASSERT(offset <= (chunk->offset + chunk->size)); @@ -311,12 +307,20 @@ PUBLIC t_memory_handle cm_MM_Realloc( } } - /* check if extend high, note as above */ + /* check if extend high, extend sbrk if necessary */ if ( (offset + size) > (chunk->offset + chunk->size)) { - if ((chunk->next == 0) - ||(chunk->next->status != MEM_FREE) - ||( (chunk->next->offset + chunk->next->size) < (offset + size))) { - return INVALID_MEMORY_HANDLE; + if(chunk->next == 0) + { + // check if allocator can be extended to maxSize + if((offset + size) > (alloc->offset + alloc->maxSize)) + return INVALID_MEMORY_HANDLE; + } + else + { + if ((chunk->next->status != MEM_FREE) + ||( (chunk->next->offset + chunk->next->size) < (offset + size))) { + return INVALID_MEMORY_HANDLE; + } } } @@ -324,90 +328,63 @@ PUBLIC t_memory_handle cm_MM_Realloc( return INVALID_MEMORY_HANDLE; -#if 0 - /* extend low - * all conditions should have been checked - * this must not fail - */ - if (offset < chunk->offset) { - t_cm_chunk *tmp = splitChunk(alloc, chunk->prev, offset, FREE_CHUNK_BEFORE); //tmp = chunk->prev - CM_ASSERT(tmp); - tmp->status = MEM_USED; - tmp->prev->status = MEM_FREE; - mergeChunk(alloc, tmp, chunk); - if ((tmp->prev->prev != 0) - && (tmp->prev->prev->status == MEM_FREE)) { - mergeChunk(alloc, tmp->prev->prev, tmp->prev); - } - chunk = tmp; - } - - /* extend high */ - if ( (offset + size) > (chunk->offset + chunk->size)) { - t_cm_chunk *tmp = splitChunk(alloc, chunk->next, offset + size, FREE_CHUNK_AFTER); //tmp = chunk->next->next - CM_ASSERT(tmp); - tmp->status = MEM_USED; - mergeChunk(alloc, chunk, tmp); - if ((tmp->next->next != 0) - && (tmp->next->next->status == MEM_FREE)) { - mergeChunk(alloc, tmp->next, tmp->next->next); - } - } - - /* reduce top */ - if ((offset + size) < (chunk->offset + chunk->size)) { - t_cm_chunk *tmp = splitChunk(alloc, chunk, offset + size, FREE_CHUNK_AFTER); //tmp = chunk, chunk = result - CM_ASSERT(tmp); - tmp->status = MEM_USED; - tmp->next->status = MEM_FREE; - if ((tmp->next->next != 0) - && (tmp->next->next->status == MEM_FREE)) { - mergeChunk(alloc, tmp->next, tmp->next->next); - } - } - - /* reduce bottom */ - if (offset > chunk->offset) { - t_cm_chunk *tmp = splitChunk(alloc, chunk, offset, FREE_CHUNK_BEFORE); //tmp->next = chunk, tmp = result - CM_ASSERT(tmp); - tmp->status = MEM_USED; - tmp->prev->status = MEM_FREE; - if ((tmp->prev->prev != 0) - &&(tmp->prev->prev->status == MEM_FREE)) { - mergeChunk(alloc, tmp->prev->prev, tmp->prev); - } - chunk = tmp; - } -#else /* extend low * all conditions should have been checked * this must not fail */ if (offset < chunk->offset) { t_uint32 delta = chunk->prev->offset + chunk->prev->size - offset; - CM_ASSERT(chunk->prev->status == MEM_FREE); //TODO, juraj, already checked - unlinkFreeMem(alloc, chunk->prev); - chunk->prev->size -= delta; + t_cm_chunk *prev = chunk->prev; + chunk->offset -= delta; chunk->size += delta; - updateFreeList(alloc, chunk->prev); + + CM_ASSERT(prev->status == MEM_FREE); //TODO, juraj, already checked + unlinkFreeMem(alloc, prev); + prev->size -= delta; + if(prev->size == 0) + { + unlinkChunk(alloc, prev); + freeChunk(prev); + } else { + updateFreeList(alloc, prev); + } } /* extend high */ if ( (offset + size) > (chunk->offset + chunk->size)) { t_uint32 delta = size - chunk->size; - CM_ASSERT(chunk->next->status == MEM_FREE); //TODO, juraj, already checked - unlinkFreeMem(alloc, chunk->next); + t_cm_chunk *next = chunk->next; + chunk->size += delta; - chunk->next->offset += delta; - chunk->next->size -= delta; - updateFreeList(alloc, chunk->next); + + if(next == 0) + { + alloc->sbrkSize += delta; + } else { + CM_ASSERT(next->status == MEM_FREE); + unlinkFreeMem(alloc, next); + next->offset += delta; + next->size -= delta; + if(next->size == 0) + { + unlinkChunk(alloc, next); + freeChunk(next); + } else { + updateFreeList(alloc, next); + } + } } /* reduce top */ if ((offset + size) < (chunk->offset + chunk->size)) { - if (chunk->next->status == MEM_FREE) { - t_uint32 delta = chunk->size - size; + t_uint32 delta = chunk->size - size; + + if(chunk->next == 0) { + alloc->sbrkSize -= delta; + chunk->size -= delta; + + } else if (chunk->next->status == MEM_FREE) { unlinkFreeMem(alloc, chunk->next); chunk->size -= delta; chunk->next->offset -= delta; @@ -435,10 +412,11 @@ PUBLIC t_memory_handle cm_MM_Realloc( tmp->prev->status = MEM_FREE; } } -#endif + cm_MM_RA_checkAllocator(alloc); return (t_memory_handle)chunk; +#endif } PUBLIC void cm_MM_Free(t_cm_allocator_desc* alloc, t_memory_handle memHandle) @@ -453,19 +431,58 @@ PUBLIC void cm_MM_Free(t_cm_allocator_desc* alloc, t_memory_handle memHandle) chunk->status = MEM_FREE; chunk->domainId = 0x0; + // Invariant: Current chunk is free but not in free list + /* Check if the previous chunk is free */ - if((chunk->prev != 0) && (chunk->prev->status == MEM_FREE)) { - chunk = chunk->prev; //chunk, ie. chunk->next, will be freed - mergeChunk(alloc, chunk, chunk->next); + if((chunk->prev != 0) && (chunk->prev->status == MEM_FREE)) + { + t_cm_chunk* prev = chunk->prev; + + // Remove chunk to be freed from memory list + unlinkChunk(alloc, chunk); + + // Remove previous from free list + unlinkFreeMem(alloc, prev); + + // Update previous size + prev->size += chunk->size; + + freeChunk(chunk); + + chunk = prev; } /* Check if the next chunk is free */ - if((chunk->next != 0) && (chunk->next->status == MEM_FREE)) { - mergeChunk(alloc, chunk, chunk->next); + if((chunk->next != 0) && (chunk->next->status == MEM_FREE)) + { + t_cm_chunk* next = chunk->next; + + // Remove next from memory list + unlinkChunk(alloc, next); + + // Remove next from free list + unlinkFreeMem(alloc, next); + + // Update previous size + chunk->size += next->size; + + freeChunk(next); } - unlinkFreeMem(alloc, chunk); - updateFreeList(alloc, chunk); + if(chunk->next == 0) + { + // If we are the last one, decrease sbrkSize + alloc->sbrkSize -= chunk->size; + + unlinkChunk(alloc, chunk); + freeChunk(chunk); + + } + else + { + // Add it in free list + updateFreeList(alloc, chunk); + } if (cmIntensiveCheckState) { cm_MM_RA_checkAllocator(alloc); @@ -475,6 +492,7 @@ PUBLIC void cm_MM_Free(t_cm_allocator_desc* alloc, t_memory_handle memHandle) PUBLIC t_cm_error cm_MM_GetAllocatorStatus(t_cm_allocator_desc* alloc, t_uint32 offset, t_uint32 size, t_cm_allocator_status *pStatus) { t_cm_chunk* chunk = alloc->chunks; + t_uint32 sbrkFree = alloc->maxSize - alloc->sbrkSize; t_uint8 min_free_size_updated = FALSE; /* Init status */ @@ -484,14 +502,13 @@ PUBLIC t_cm_error cm_MM_GetAllocatorStatus(t_cm_allocator_desc* alloc, t_uint32 pStatus->global.minimum_free_size = 0xFFFFFFFF; pStatus->global.accumulate_free_memory = 0; pStatus->global.accumulate_used_memory = 0; - pStatus->global.size = alloc->size; + pStatus->global.size = alloc->maxSize; pStatus->domain.maximum_free_size = 0; pStatus->domain.minimum_free_size = 0xFFFFFFFF; pStatus->domain.accumulate_free_memory = 0; pStatus->domain.accumulate_used_memory = 0; pStatus->domain.size= size; - //TODO, juraj, get allocator status for a domain /* Parse all chunks */ while(chunk != 0) { @@ -521,6 +538,17 @@ PUBLIC t_cm_error cm_MM_GetAllocatorStatus(t_cm_allocator_desc* alloc, t_uint32 chunk = chunk->next; } + /* Accumulate free space between sbrkSize and maxSize */ + pStatus->global.accumulate_free_memory += sbrkFree; + if (sbrkFree > 0) + pStatus->global.free_block_number++; + if (pStatus->global.maximum_free_size < sbrkFree) + pStatus->global.maximum_free_size = sbrkFree; + if (pStatus->global.minimum_free_size > sbrkFree) { + pStatus->global.minimum_free_size = sbrkFree; + min_free_size_updated = TRUE; + } + /* Put max free size to min free size */ if (min_free_size_updated == FALSE) { pStatus->global.minimum_free_size = pStatus->global.maximum_free_size; @@ -542,7 +570,7 @@ PUBLIC t_uint32 cm_MM_GetSize(t_memory_handle memHandle) PUBLIC t_uint32 cm_MM_GetAllocatorSize(t_cm_allocator_desc* alloc) { - return alloc->size; + return alloc->maxSize; } PUBLIC void cm_MM_SetMemoryHandleUserData(t_memory_handle memHandle, t_uint16 userData) @@ -565,24 +593,29 @@ PUBLIC void cm_MM_GetMemoryHandleUserData(t_memory_handle memHandle, t_uint16 *p static void cm_MM_RA_checkAllocator(t_cm_allocator_desc* alloc) { t_cm_chunk *chunk = alloc->chunks; - t_cm_chunk *first = chunk; - t_cm_chunk *last = chunk; t_uint32 size = 0; int i; + CM_ASSERT(alloc->sbrkSize <= alloc->maxSize); + while(chunk != 0) { + if(chunk == alloc->chunks) + CM_ASSERT(chunk->prev == 0); + if(chunk == alloc->lastChunk) + CM_ASSERT(chunk->next == 0); + CM_ASSERT(chunk->alloc == alloc); if (chunk->next != 0) { CM_ASSERT(!((chunk->status == MEM_FREE) && (chunk->next->status == MEM_FREE))); //two free adjacent blocks CM_ASSERT(chunk->offset < chunk->next->offset); //offsets reverted - last = chunk->next; + CM_ASSERT(chunk->offset + chunk->size == chunk->next->offset); // Not hole in allocator } size += chunk->size; chunk = chunk->next; } - CM_ASSERT(size == alloc->size); + CM_ASSERT(size == alloc->sbrkSize); for(i = 0; i < BINS; i++) { @@ -591,73 +624,11 @@ static void cm_MM_RA_checkAllocator(t_cm_allocator_desc* alloc) if (chunk->next_free_mem != 0) { CM_ASSERT(chunk->size <= chunk->next_free_mem->size); //free list not ordered } - CM_ASSERT(!(chunk->prev == 0 && (chunk != first))); //chunk not linked properly - CM_ASSERT(!(chunk->next == 0 && (chunk != last))); //chunk not linked property chunk = chunk->next_free_mem; } } } -#if 0 -static void cm_MM_RA_checkAlloc(t_cm_allocator_desc* alloc, t_uint32 size, t_uint32 align, t_uint32 min, t_uint32 max) -{ - t_cm_chunk *chunk = alloc->chunks; - - while(chunk != 0) { - if (chunk->status == MEM_USED) { - chunk = chunk->next; - continue; - } - if (chunk->size < size) { - chunk = chunk->next; - continue; - } - - if (min < chunk->offset) { - t_uint32 aligned_offset = ALIGN_VALUE(chunk->offset, align + 1); - t_uint32 aligned_end = aligned_offset + size; - if ((aligned_offset + size <= chunk->offset + chunk->size) - && (chunk->offset + chunk->size <= aligned_end)){ - break; - } - } - - if (min >= chunk->offset) { - t_uint32 aligned_offset = ALIGN_VALUE(min, align + 1); - t_uint32 aligned_end = aligned_offset + size; - if ((aligned_offset + size <= chunk->offset + chunk->size) - && (chunk->offset + chunk->size <= aligned_end)) { - break; - } - } - - chunk = chunk->next; - } - - CM_ASSERT(chunk == 0); -} -#endif - -/***************************************************************************/ -/* - * cm_mm_ra_getLastChunk - * param handle : Handle of the allocator - * return : last - * - * Free all chunk in the allocator - * Free allocator descriptor - * - */ -/***************************************************************************/ -static t_cm_chunk* cm_MM_RA_getLastChunk(t_cm_allocator_desc* alloc) -{ - t_cm_chunk* pChunk = alloc->chunks; - - while(pChunk->next != 0) {pChunk = pChunk->next;} - - return pChunk; -} - PUBLIC void cm_MM_DumpMemory(t_cm_allocator_desc* alloc, t_uint32 start, t_uint32 end) { t_cm_chunk *chunk = alloc->chunks; @@ -669,7 +640,7 @@ PUBLIC void cm_MM_DumpMemory(t_cm_allocator_desc* alloc, t_uint32 start, t_uint3 || ((chunk->offset > start) && (chunk->offset + chunk->size < end)) || ((chunk->offset < start) && (chunk->offset + chunk->size > end))) { - LOG_INTERNAL(0, "ALLOCATOR chunk 0x%08x -> 0x%08x: status:%s, domainId: 0x%x\n", + LOG_INTERNAL(0, "ALLOCATOR chunk [0x%08x -> 0x%08x[: status:%s, domainId: 0x%x\n", chunk->offset, chunk->offset + chunk->size, chunk->status?"FREE":"USED", diff --git a/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator_utils.c b/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator_utils.c index 5c19d3e9b5e..4e800376dbb 100644 --- a/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator_utils.c +++ b/drivers/staging/nmf-cm/cm/engine/memory/src/remote_allocator_utils.c @@ -4,6 +4,7 @@ * License terms: GNU General Public License (GPL) version 2. */ #include +#include /***************************************************************************/ /* @@ -15,18 +16,29 @@ * */ /***************************************************************************/ -PUBLIC void linkChunk(t_cm_chunk* prev, t_cm_chunk* add) +PUBLIC void linkChunk(t_cm_allocator_desc* alloc, t_cm_chunk* prev, t_cm_chunk* add) { - /* Link previous */ - add->prev = prev; - add->next = prev->next; + // Link previous + if(prev == 0) + { + add->next = alloc->chunks; + alloc->chunks = add; + } + else + { + add->prev = prev; + add->next = prev->next; + prev->next = add; + } - /* Link next */ - if (prev->next != 0) + // Link next + if(add->next == 0) { - prev->next->prev = add; + // Link at the end + alloc->lastChunk = add; } - prev->next = add; + else + add->next->prev = add; } /***************************************************************************/ @@ -39,24 +51,28 @@ PUBLIC void linkChunk(t_cm_chunk* prev, t_cm_chunk* add) * */ /***************************************************************************/ -PUBLIC void unlinkChunk(t_cm_allocator_desc* alloc ,t_cm_chunk* current) +PUBLIC void unlinkChunk(t_cm_allocator_desc* alloc, t_cm_chunk* current) { - /* Unlink previous */ - if (current->prev !=0) - { + /* Link previous with next */ + if (current->prev != 0) current->prev->next = current->next; - } - - /* Unlink next */ - if (current->next !=0) + else { - current->next->prev= current->prev; + CM_ASSERT(alloc->chunks == current); + + // We remove the first, update chunks + alloc->chunks = current->next; } - /* Update first pointer */ - if (alloc ->chunks == current) + /* Link next with previous */ + if(current->next != 0) + current->next->prev= current->prev; + else { - alloc ->chunks = current->next; + CM_ASSERT(alloc->lastChunk == current); + + // We remove the last, update lastChunk + alloc->lastChunk = current->prev; } } @@ -194,42 +210,6 @@ PUBLIC void updateFreeList(t_cm_allocator_desc* alloc , t_cm_chunk* chunk) } -/***************************************************************************/ -/* - * mergeChunk - * param allocHandle : Allocator handle - * param merged_chunk : Pointer on merged chunk - * param destroy : Pointer on chunk to destroy - * - * Link and destroy merged chunks - * - */ -/***************************************************************************/ -PUBLIC void mergeChunk(t_cm_allocator_desc* alloc,t_cm_chunk *merged_chunk, t_cm_chunk *destroy) -{ - /* Assign offset to the merged */ - /* assume chunks ordered! - if (merged_chunk->offset > destroy->offset) { - merged_chunk->offset = destroy->offset; - } - */ - - /* Remove chunk */ - unlinkChunk(alloc, destroy); - unlinkFreeMem(alloc, destroy); - - if (merged_chunk->status == MEM_FREE) - unlinkFreeMem(alloc, merged_chunk); - - /* Update size */ - merged_chunk->size += destroy->size; - - if (merged_chunk->status == MEM_FREE) - updateFreeList(alloc, merged_chunk); - - freeChunk(destroy); -} - /***************************************************************************/ /* * splitChunk @@ -262,7 +242,7 @@ PUBLIC t_cm_chunk* splitChunk(t_cm_allocator_desc* alloc ,t_cm_chunk *chunk, new_chunk->alloc = alloc; chunk->size = offset - chunk->offset; - linkChunk(chunk, new_chunk); + linkChunk(alloc, chunk, new_chunk); unlinkFreeMem(alloc, free); updateFreeList(alloc, free); 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 8d95436e796..e2f6e8dec81 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 @@ -14,6 +14,7 @@ #include #include +#include /*! * \brief Identifier of a trace channel (id in [0..255]) @@ -43,6 +44,15 @@ typedef t_uint8 t_nmf_osal_sync_error; #define SEM_TIMEOUT_NORMAL 3000 #define SEM_TIMEOUT_DEBUG 300000 +struct osal_debug_operations { + void (*component_create)(t_component_instance *component); + void (*component_destroy)(t_component_instance *component); + void (*domain_create)(t_cm_domain_id id); + void (*domain_destroy)(t_cm_domain_id id); +}; + +extern struct osal_debug_operations osal_debug_ops; + /*! * \brief Description of the Scheduling part of the OS Adaptation Layer * diff --git a/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/src/os_adaptation_layer.c b/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/src/os_adaptation_layer.c index 9beb60dea18..380692e3cd8 100644 --- a/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/src/os_adaptation_layer.c +++ b/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/src/os_adaptation_layer.c @@ -4,10 +4,12 @@ * License terms: GNU General Public License (GPL) version 2. */ #include +#include t_nmf_osal_sync_handle lockHandleApi; t_nmf_osal_sync_handle lockHandleCom; t_nmf_osal_sem_handle semHandle; +struct osal_debug_operations osal_debug_ops; /****************/ /* Generic part */ @@ -15,17 +17,20 @@ t_nmf_osal_sem_handle semHandle; PUBLIC t_cm_error cm_OSAL_Init(void) { - /* create locks */ - lockHandleApi = OSAL_CreateLock(); - if (lockHandleApi == 0) {return CM_INVALID_PARAMETER;} - lockHandleCom = OSAL_CreateLock(); + /* create locks */ + lockHandleApi = OSAL_CreateLock(); + if (lockHandleApi == 0) {return CM_INVALID_PARAMETER;} + lockHandleCom = OSAL_CreateLock(); if (lockHandleCom == 0) {return CM_INVALID_PARAMETER;} - /* create semaphore */ + /* create semaphore */ semHandle = OSAL_CreateSemaphore(0); if (semHandle == 0) {return CM_INVALID_PARAMETER;} - return CM_OK; + /* init to zero */ + cm_MemSet(&osal_debug_ops, 0, sizeof(osal_debug_ops)); + + return CM_OK; } PUBLIC void cm_OSAL_Destroy(void) diff --git a/drivers/staging/nmf-cm/cm/engine/perfmeter/src/mpcload.c b/drivers/staging/nmf-cm/cm/engine/perfmeter/src/mpcload.c index b157103934d..193d155b97b 100644 --- a/drivers/staging/nmf-cm/cm/engine/perfmeter/src/mpcload.c +++ b/drivers/staging/nmf-cm/cm/engine/perfmeter/src/mpcload.c @@ -10,6 +10,8 @@ #include #include +#include + #define PERFMETER_MAX_RETRIES 32 #define PERFMETER_DATA_WORD_NB 7 @@ -96,9 +98,10 @@ PUBLIC t_cm_error cm_PFM_allocatePerfmeterDataMemory(t_nmf_core_id coreId, t_cm_ t_mpcLoad *pMpcLoad = (t_mpcLoad *) &mpcLoad_i[coreId]; pMpcLoad->perfmeterDataHandle = cm_DM_Alloc(domainId, SDRAM_EXT24, PERFMETER_DATA_WORD_NB, CM_MM_ALIGN_WORD, TRUE); - if (pMpcLoad->perfmeterDataHandle == INVALID_MEMORY_HANDLE) + if (pMpcLoad->perfmeterDataHandle == INVALID_MEMORY_HANDLE) { error = CM_NO_MORE_MEMORY; - else { + ERROR("CM_NO_MORE_MEMORY: Unable to allocate perfmeter\n", 0, 0, 0, 0, 0, 0); + } else { t_uint32 mmdspAddr; pMpcLoad->perfmeterDataAddr = cm_DSP_GetHostLogicalAddress(pMpcLoad->perfmeterDataHandle); diff --git a/drivers/staging/nmf-cm/cm/engine/power_mgt/inc/power.h b/drivers/staging/nmf-cm/cm/engine/power_mgt/inc/power.h index 1ca1b314833..942805df2f3 100644 --- a/drivers/staging/nmf-cm/cm/engine/power_mgt/inc/power.h +++ b/drivers/staging/nmf-cm/cm/engine/power_mgt/inc/power.h @@ -18,10 +18,12 @@ typedef enum { - NORMAL_PWR_MODE = 0x1, //!< Normal mode - DISABLE_PWR_MODE = 0x2 //!< Disable mode - CM Power management is disabled. CM Power domain are always enabled and the EEs are loaded by default + DISABLE_PWR_MODE = 0x0, //!< Disable mode - CM Power management is disabled. CM Power domain are always enabled and the EEs are loaded by default + NORMAL_PWR_MODE = 0x1 //!< Normal mode } t_nmf_power_mode; +extern t_nmf_power_mode powerMode; + PUBLIC t_cm_error cm_PWR_Init(void); void cm_PWR_SetMode(t_nmf_power_mode aMode); t_nmf_power_mode cm_PWR_GetMode(void); 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 5b206bfb82d..37ba11314f9 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 @@ -29,7 +29,7 @@ static t_uint32 _pwrMPCMemoryCountT[NB_CORE_IDS]; // ------------------------------------------------------------------------------- // Internal data to store the global Power Manager mode (see cm_PWR_Init fct) // ------------------------------------------------------------------------------- -static t_nmf_power_mode _pwrMode = NORMAL_PWR_MODE; +t_nmf_power_mode powerMode = NORMAL_PWR_MODE; // ------------------------------------------------------------------------------- // cm_PWR_Init @@ -52,12 +52,12 @@ PUBLIC t_cm_error cm_PWR_Init(void) // ------------------------------------------------------------------------------- void cm_PWR_SetMode(t_nmf_power_mode aMode) { - _pwrMode = aMode; + powerMode = aMode; } t_nmf_power_mode cm_PWR_GetMode() { - return _pwrMode; + return powerMode; } t_uint32 cm_PWR_GetMPCMemoryCount(t_nmf_core_id coreId) diff --git a/drivers/staging/nmf-cm/cm/engine/repository_mgt/src/repository_mgt.c b/drivers/staging/nmf-cm/cm/engine/repository_mgt/src/repository_mgt.c index 176a965be22..f6ccb4a9992 100644 --- a/drivers/staging/nmf-cm/cm/engine/repository_mgt/src/repository_mgt.c +++ b/drivers/staging/nmf-cm/cm/engine/repository_mgt/src/repository_mgt.c @@ -18,6 +18,7 @@ #include +#undef NHASH #define NHASH 157 //Use a prime number! #define MULT 17 @@ -144,10 +145,10 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetRequiredComponentFiles( if((error = cm_checkValidServer(compServer, providedItfServerName, &itfProvide)) == CM_OK) { - cm_StringCopy(type, itfProvide.server->template->provides[itfProvide.provideIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringCopy(type, itfProvide.server->Template->provides[itfProvide.provideIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); cm_StringCopy(fileList[0], "_sk.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[0], itfProvide.server->template->provides[itfProvide.provideIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[0], itfProvide.server->Template->provides[itfProvide.provideIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); } } break; @@ -160,11 +161,11 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetRequiredComponentFiles( if((error = cm_checkValidClient(compClient, requiredItfClientName, &itfRequire, &bindable)) == CM_OK) { - cm_StringCopy(type, itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); - *methodNumber = itfRequire.client->template->requires[itfRequire.requireIndex].interface->methodNumber; + cm_StringCopy(type, itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + *methodNumber = itfRequire.client->Template->requires[itfRequire.requireIndex].interface->methodNumber; cm_StringCopy(fileList[0], "_st.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[0], itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[0], itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); } }; break; @@ -179,18 +180,18 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetRequiredComponentFiles( compServer, providedItfServerName, &itfRequire, &itfProvide, &bindable)) == CM_OK) { - if(compClient->template->dspId != compServer->template->dspId) + if(compClient->Template->dspId != compServer->Template->dspId) { cm_StringCopy(fileList[0], "_sk.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[0], itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[0], itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); cm_StringCopy(fileList[1], "_st.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[1], itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[1], itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); } else { cm_StringCopy(fileList[0], "_ev.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[0], itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[0], itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); } } }; break; @@ -207,7 +208,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_ENGINE_GetRequiredComponentFiles( &itfRequire, &itfProvide, &bindable)) == CM_OK) { cm_StringCopy(fileList[0], "_tr.", MAX_INTERFACE_TYPE_NAME_LENGTH); - cm_StringConcatenate(fileList[0], itfRequire.client->template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); + cm_StringConcatenate(fileList[0], itfRequire.client->Template->requires[itfRequire.requireIndex].interface->type, MAX_INTERFACE_TYPE_NAME_LENGTH); } }; 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 832b9f28756..8a4d499ce41 100644 --- a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c +++ b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c @@ -59,15 +59,15 @@ static t_component_instance* getCorrespondingInstance( return instance; } - for(i = 0; i < instance->template->requireNumber; i++) { - int nb = instance->template->requires[i].collectionSize, j; + for(i = 0; i < instance->Template->requireNumber; i++) { + int nb = instance->Template->requires[i].collectionSize, j; for(j = 0; j < nb; j++) { if(instance->interfaceReferences[i][j].instance != NULL && instance->interfaceReferences[i][j].instance != (t_component_instance *)NMF_HOST_COMPONENT && instance->interfaceReferences[i][j].instance != (t_component_instance *)NMF_VOID_COMPONENT && instance->interfaceReferences[i][j].instance->thisAddress == panicThis) { - *itfName = instance->template->requires[i].name; + *itfName = instance->Template->requires[i].name; *instHandle = ENTRY2HANDLE(instance, k); return instance; } @@ -181,8 +181,8 @@ PUBLIC EXPORT_SHARED t_cm_error CM_getServiceDescription( if(instance != 0) { - cm_DSP_GetDspAddress(instance->memories[instance->template->codeMemory->id], &DspAddress); - cm_DSP_GetDspMemoryHandleSize(instance->memories[instance->template->codeMemory->id], &DspSize); + cm_DSP_GetDspAddress(instance->memories[instance->Template->codeMemory->id], &DspAddress); + cm_DSP_GetDspMemoryHandleSize(instance->memories[instance->Template->codeMemory->id], &DspSize); } if(DspAddress <= srcDescr->u.panic.info.mpc.panicInfo1 && @@ -206,7 +206,7 @@ PUBLIC EXPORT_SHARED t_cm_error CM_getServiceDescription( if(instance != 0) { LOG_INTERNAL(0, "Error: Component=%s<%s>\n", - instance->pathname, instance->template->name, 0, 0, 0, 0); + instance->pathname, instance->Template->name, 0, 0, 0, 0); } // We don't set rtos/commonpart/serviceReason = MPC_SERVICE_NONE, since we don't want the diff --git a/drivers/staging/nmf-cm/cm/engine/trace/src/trace.c b/drivers/staging/nmf-cm/cm/engine/trace/src/trace.c index ac948c767b4..4620bc0fd07 100644 --- a/drivers/staging/nmf-cm/cm/engine/trace/src/trace.c +++ b/drivers/staging/nmf-cm/cm/engine/trace/src/trace.c @@ -72,11 +72,11 @@ void cm_TRC_traceLoadMap( trace.header.v = HEADER(TRACE_TYPE_COMPONENT, sizeof(trace)); trace.command = (t_uint16)command; - trace.domainId = (t_uint16)component->template->dspId + 1; + trace.domainId = (t_uint16)component->Template->dspId + 1; trace.componentContext = (t_uint32)component->thisAddress; trace.componentUserContext = (t_uint32)component; cm_StringCopy((char*)trace.componentLocalName, component->pathname, MAX_COMPONENT_NAME_LENGTH); - cm_StringCopy((char*)trace.componentTemplateName, component->template->name, MAX_TEMPLATE_NAME_LENGTH); + cm_StringCopy((char*)trace.componentTemplateName, component->Template->name, MAX_TEMPLATE_NAME_LENGTH); writeN((struct t_nmfTraceChannelHeader*)&trace); @@ -90,12 +90,12 @@ void cm_TRC_traceLoadMap( */ tracemethod.header.v = HEADER(TRACE_TYPE_METHOD, sizeof(tracemethod)); - tracemethod.domainId = (t_uint16)component->template->dspId + 1; + tracemethod.domainId = (t_uint16)component->Template->dspId + 1; tracemethod.componentContext = (t_uint32)component->thisAddress; - for(i = 0; i < component->template->provideNumber; i++) + for(i = 0; i < component->Template->provideNumber; i++) { - t_interface_provide* provide = &component->template->provides[i]; + t_interface_provide* provide = &component->Template->provides[i]; for(j = 0; j < provide->collectionSize; j++) { @@ -133,7 +133,7 @@ void cm_TRC_traceBinding( } else { - trace.clientDomainId = (t_uint16)clientComponent->template->dspId + 1; + trace.clientDomainId = (t_uint16)clientComponent->Template->dspId + 1; trace.clientComponentContext = (t_uint32)clientComponent->thisAddress; } if(requiredItfName != NULL) @@ -153,7 +153,7 @@ void cm_TRC_traceBinding( } else { - trace.serverDomainId = (t_uint16)serverComponent->template->dspId + 1; + trace.serverDomainId = (t_uint16)serverComponent->Template->dspId + 1; trace.serverComponentContext = (t_uint32)serverComponent->thisAddress; } if(providedItfName != NULL) diff --git a/drivers/staging/nmf-cm/cm/engine/utils/src/string.c b/drivers/staging/nmf-cm/cm/engine/utils/src/string.c index 0ed6fb3a214..89058d5825a 100644 --- a/drivers/staging/nmf-cm/cm/engine/utils/src/string.c +++ b/drivers/staging/nmf-cm/cm/engine/utils/src/string.c @@ -14,6 +14,7 @@ #include #include +#undef NHASH #define NHASH 257 //Use a prime number! #define MULT 17 @@ -29,6 +30,7 @@ struct t_linkedstring static struct t_linkedstring *list[NHASH]; +#undef myoffsetof #define myoffsetof(st, m) \ ((int) ( (char *)&((st *)(0))->m - (char *)0 )) diff --git a/drivers/staging/nmf-cm/cm_debug.c b/drivers/staging/nmf-cm/cm_debug.c new file mode 100644 index 00000000000..bf3fa422208 --- /dev/null +++ b/drivers/staging/nmf-cm/cm_debug.c @@ -0,0 +1,838 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Pierre Peiffer for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +#include + +#include "osal-kernel.h" +#include "cm_debug.h" + +#ifdef CONFIG_DEBUG_FS + +static struct dentry *cm_dir; /* nmf-cm/ */ +static struct dentry *proc_dir; /* nmf-cm/proc/ */ +static struct dentry *core_dir; /* nmf-cm/dsp/ */ +static struct dentry *domain_dir; /* nmf-cm/domains/ */ + +/* components data managment */ +struct cm_debug_component_cooky { + struct dentry *comp_file; /* entry in nmf-cm/dsp/sxa/components/ */ + struct dentry *proc_link; /* entry in nmf-cm/proc/ */ +}; + +static ssize_t component_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { + t_component_instance *component = file->f_dentry->d_inode->i_private; + char buf[640]; + int ret=0; + + OSAL_LOCK_API(); + if ((component != NULL) && (component->dbgCooky != NULL)) { + char nb_i[16] = ""; + int i; + + if (component->Template->classe == SINGLETON) + snprintf(nb_i, sizeof(nb_i), " (%d)", + component->Template->numberOfInstance); + + ret = snprintf(buf, sizeof(buf), + "Name:\t\t%s <%s>\n" + "Class:\t\t%s%s\n" + "State:\t\t%s\n" + "Priority:\t%u\n" + "Domain:\t\t%u\n\n" + "Memory : Physical address Logical address" + " DSP address Size\n" + "---------------------------------------------" + "-----------------------------\n", + component->pathname, + component->Template->name, + component->Template->classe == COMPONENT ? + "Component" : + (component->Template->classe == SINGLETON ? + "Singleton" : + (component->Template->classe == FIRMWARE ? + "Firmware" : + "?")), + nb_i, + component->state == STATE_RUNNABLE ? "Runnable" : + (component->state == STATE_STOPPED ? "Sopped" : + "None"), + (unsigned)component->priority, + component->domainId + ); + + for (i=0; imemories[i]) { + t_cm_system_address addr; + t_uint32 dspAddr, dspSize; + cm_DSP_GetHostSystemAddress( + component->memories[i], &addr); + cm_DSP_GetDspAddress( + component->memories[i], &dspAddr); + cm_DSP_GetDspMemoryHandleSize( + component->memories[i], &dspSize); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "%-10s: %p-%p %p-%p %p-%p %8lu\n", + MMDSP_getMappingById(i)->memoryName, + (void *)addr.physical, + (void *)addr.physical + + component->memories[i]->size-1, + (void *)addr.logical, + (void *)addr.logical + + component->memories[i]->size-1, + (void *)dspAddr, + (void *)dspAddr + dspSize - 1, + component->memories[i]->size); + } + } + } + + OSAL_UNLOCK_API(); + return simple_read_from_buffer(userbuf, count, ppos, buf, ret); +} + +static const struct file_operations component_fops = { + .read = component_read, +}; + +static void cm_debug_component_create(t_component_instance *component) +{ + char tmp[12+MAX_COMPONENT_NAME_LENGTH]; + struct cm_debug_component_cooky *cooky; + struct mpcConfig *mpc; + mpc = &osalEnv.mpc[COREIDX(component->Template->dspId)]; + + cooky = OSAL_Alloc_Zero(sizeof(*cooky)); + if (cooky == NULL) + return; + + component->dbgCooky = cooky; + sprintf(tmp, "%s-%08x", component->pathname, + (unsigned int)component->instance); + cooky->comp_file = debugfs_create_file(tmp, S_IRUSR|S_IRGRP, + mpc->comp_dir, + component, &component_fops); + if (IS_ERR(cooky->comp_file)) { + if (PTR_ERR(cooky->comp_file) != -ENODEV) + pr_info("CM: Can't create dsp/%s/components/%s" + "debugfs file: %ld\n", + mpc->name, + tmp, + PTR_ERR(cooky->comp_file)); + cooky->comp_file = NULL; + } else { + char target_lnk[40+MAX_COMPONENT_NAME_LENGTH]; + sprintf(target_lnk, "../../../dsp/%s/components/%s-%08x", + mpc->name, + component->pathname, + (unsigned int)component->instance); + + /* Some firmware, like Executive Engine, do not belong + to any process */ + if (domainDesc[component->domainId].client == current->tgid) { + struct list_head* head; + struct cm_process_priv *entry = NULL; + /* Search the entry for the calling process */ + list_for_each(head, &process_list) { + entry = list_entry(head, + struct cm_process_priv, + entry); + if (entry->pid == current->tgid) + break; + } + + if (entry) { + cooky->proc_link = debugfs_create_symlink( + tmp, + entry->comp_dir, + target_lnk); + if (IS_ERR(cooky->proc_link)) { + long err = PTR_ERR(cooky->proc_link); + if (err != -ENODEV) + pr_info("CM: Can't create " + "proc/%d/%s " + "debugfs link: %ld\n", + entry->pid, tmp, err); + cooky->proc_link = NULL; + } + } + } + } +} + +static void cm_debug_component_destroy(t_component_instance *component) +{ + struct cm_debug_component_cooky *cooky = component->dbgCooky; + + if (cooky) { + component->dbgCooky = NULL; + debugfs_remove(cooky->proc_link); + debugfs_remove(cooky->comp_file); + OSAL_Free(cooky); + } +} + +/* domain data managment */ +struct cm_debug_domain_cooky { + struct dentry *domain_file; /* entry in nmf-cm/components/ */ + struct dentry *proc_link; /* entry in nmf-cm/proc/ */ + struct dentry *dsp_link; /* entry in nmf-cm/dsp/sxa/domains */ +}; + +static ssize_t domain_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + t_cm_domain_id id = + (t_cm_domain_id)(long)file->f_dentry->d_inode->i_private; + t_cm_domain_desc *domain = &domainDesc[id]; + + char buf[640]; + int ret=0; + + OSAL_LOCK_API(); + if ((cm_DM_CheckDomain(id, DOMAIN_ANY) == CM_OK) + && (domain->domain.coreId != -1) + && (domain->dbgCooky != NULL)) { + t_cm_allocator_status status; + t_uint32 dOffset; + t_uint32 dSize; + if (domain->domain.coreId != ARM_CORE_ID) { + t_cm_domain_info info; + + cm_DM_GetDomainAbsAdresses(id, &info); + cm_DSP_GetInternalMemoriesInfo(id, ESRAM_CODE, + &dOffset, &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(domain->domain.coreId, + ESRAM_CODE), + dOffset, dSize, &status); + ret = snprintf( + buf, sizeof(buf), + "Core:\t%s\n\n" + "Memory : Physical address Logical address" + " Size Free Used\n" + "---------------------------------------------" + "-----------------------------\n" + "ESRAM Code: %08x-%08lx %08x-%08lx\t%8lu %8lu " + "%8lu\n", + osalEnv.mpc[COREIDX(domain->domain.coreId)].name, + (unsigned int)info.esramCode.physical, + domain->domain.esramCode.size ? + info.esramCode.physical + + domain->domain.esramCode.size - 1 : 0, + (unsigned int)info.esramCode.logical, + domain->domain.esramCode.size ? + info.esramCode.logical + + domain->domain.esramCode.size - 1 : 0, + domain->domain.esramCode.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_DSP_GetInternalMemoriesInfo(id, ESRAM_EXT24, + &dOffset, &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(domain->domain.coreId, + ESRAM_EXT24), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "ESRAM Data: %08x-%08lx " + "%08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)info.esramData.physical, + domain->domain.esramData.size ? + info.esramData.physical + + domain->domain.esramData.size - 1 : 0, + (unsigned int)info.esramData.logical, + domain->domain.esramData.size ? + info.esramData.logical + + domain->domain.esramData.size - 1 : 0, + domain->domain.esramData.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_DSP_GetInternalMemoriesInfo(id, SDRAM_CODE, + &dOffset, &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(domain->domain.coreId, + SDRAM_CODE), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "SDRAM Code: %08x-%08lx " + "%08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)info.sdramCode.physical, + domain->domain.sdramCode.size ? + info.sdramCode.physical + + domain->domain.sdramCode.size - 1 : 0, + (unsigned int)info.sdramCode.logical, + domain->domain.sdramCode.size ? + info.sdramCode.logical + + domain->domain.sdramCode.size - 1 : 0, + domain->domain.sdramCode.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_DSP_GetInternalMemoriesInfo(id, SDRAM_EXT24, + &dOffset, &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(domain->domain.coreId, + SDRAM_EXT24), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "SDRAM Data: %08x-%08lx " + "%08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)info.sdramData.physical, + domain->domain.sdramData.size ? + info.sdramData.physical + + domain->domain.sdramData.size - 1 : 0, + (unsigned int)info.sdramData.logical, + domain->domain.sdramData.size ? + info.sdramData.logical + + domain->domain.sdramData.size - 1 : 0, + domain->domain.sdramData.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + } else { + t_cm_system_address addr; + ret = snprintf( + buf, sizeof(buf), + "Core:\tarm\n\n" + "Memory : Physical address Logical " + "address Size Free Used\n" + "---------------------------------------" + "-----------------------------------\n"); + if (domain->domain.esramCode.size) { + cm_DSP_GetDspBaseAddress(ARM_CORE_ID, + ESRAM_CODE, &addr); + cm_DSP_GetInternalMemoriesInfo(id, ESRAM_CODE, + &dOffset, + &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(ARM_CORE_ID, + ESRAM_CODE), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "ESRAM Code: %08x-%08lx " + "%08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + + domain->domain.esramCode.size - 1, + (unsigned int)addr.logical, + addr.logical + + domain->domain.esramCode.size - 1, + domain->domain.esramCode.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + } + if (domain->domain.esramData.size) { + cm_DSP_GetDspBaseAddress(ARM_CORE_ID, + ESRAM_EXT24, &addr); + cm_DSP_GetInternalMemoriesInfo(id, ESRAM_EXT24, + &dOffset, + &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(ARM_CORE_ID, + ESRAM_EXT24), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "ESRAM Data: %08x-%08lx " + "%08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + + domain->domain.esramData.size - 1, + (unsigned int)addr.logical, + addr.logical + + domain->domain.esramData.size - 1, + domain->domain.esramData.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + } + if (domain->domain.sdramCode.size) { + cm_DSP_GetDspBaseAddress(ARM_CORE_ID, + SDRAM_CODE, &addr); + cm_DSP_GetInternalMemoriesInfo(id, SDRAM_CODE, + &dOffset, + &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(ARM_CORE_ID, + SDRAM_CODE), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "SDRAM Code: %08x-%08lx %08x-%08lx\t" + "%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + + domain->domain.sdramCode.size - 1, + (unsigned int)addr.logical, + addr.logical + + domain->domain.sdramCode.size - 1, + domain->domain.sdramCode.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + } + if (domain->domain.sdramData.size) { + cm_DSP_GetDspBaseAddress(ARM_CORE_ID, + SDRAM_EXT24, &addr); + cm_DSP_GetInternalMemoriesInfo(id, SDRAM_EXT24, + &dOffset, + &dSize); + cm_MM_GetAllocatorStatus( + cm_DSP_GetAllocator(ARM_CORE_ID, + SDRAM_EXT24), + dOffset, dSize, &status); + ret += snprintf( + &buf[ret], sizeof(buf)-ret, + "SDRAM Data: %08x-%08lx %08x-%08lx\t" + "%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + + domain->domain.sdramData.size - 1, + (unsigned int)addr.logical, + addr.logical + + domain->domain.sdramData.size - 1, + domain->domain.sdramData.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + } + } + } + OSAL_UNLOCK_API(); + return simple_read_from_buffer(userbuf, count, ppos, buf, ret);; +} + +static const struct file_operations domain_fops = { + .read = domain_read, +}; + +static void cm_debug_domain_create(t_cm_domain_id id) +{ + char tmp[12]; + struct cm_debug_domain_cooky *cooky; + + cooky = OSAL_Alloc_Zero(sizeof(*cooky)); + if (cooky == NULL) + return; + + domainDesc[id].dbgCooky = cooky; + sprintf(tmp, "%u", id); + cooky->domain_file = debugfs_create_file(tmp, S_IRUSR|S_IRGRP, + domain_dir, + (void *)(long)id, + &domain_fops); + if (IS_ERR(cooky->domain_file)) { + if (PTR_ERR(cooky->domain_file) != -ENODEV) + pr_err("CM: Can't create domains/%s debugfs " + "file: %ld\n", tmp, + PTR_ERR(cooky->domain_file)); + cooky->domain_file = NULL; + } else { + char target_lnk[40]; + sprintf(target_lnk, "../../../domains/%u", id); + + if (domainDesc[id].client != NMF_CORE_CLIENT) { + struct list_head* head; + struct cm_process_priv *entry = NULL; + + /* Search the entry for the target process */ + list_for_each(head, &process_list) { + entry = list_entry(head, + struct cm_process_priv, + entry); + if (entry->pid == domainDesc[id].client) + break; + } + + if (entry) { + cooky->proc_link = debugfs_create_symlink( + tmp, + entry->domain_dir, + target_lnk); + if (IS_ERR(cooky->proc_link)) { + long err = PTR_ERR(cooky->proc_link); + if (err != -ENODEV) + pr_err("CM: Can't create " + "proc/%d/domains/%s " + "debugfs link: %ld\n", + entry->pid, tmp, err); + cooky->proc_link = NULL; + } + } + } + if (domainDesc[id].domain.coreId != ARM_CORE_ID) { + cooky->dsp_link = + debugfs_create_symlink( + tmp, + osalEnv.mpc[COREIDX(domainDesc[id].domain.coreId)].domain_dir, + target_lnk); + if (IS_ERR(cooky->dsp_link)) { + if (PTR_ERR(cooky->dsp_link) != -ENODEV) + pr_err("CM: Can't create dsp/%s/domains/%s " + "debugfs link: %ld\n", + osalEnv.mpc[COREIDX(domainDesc[id].domain.coreId)].name, + tmp, + PTR_ERR(cooky->dsp_link)); + cooky->dsp_link = NULL; + } + } + } +} + +static void cm_debug_domain_destroy(t_cm_domain_id id) +{ + struct cm_debug_domain_cooky *cooky = domainDesc[id].dbgCooky; + if (cooky) { + domainDesc[id].dbgCooky = NULL; + debugfs_remove(cooky->proc_link); + debugfs_remove(cooky->dsp_link); + debugfs_remove(cooky->domain_file); + OSAL_Free(cooky); + } +} + +/* proc directory */ +void cm_debug_proc_init(struct cm_process_priv *entry) +{ + char tmp[PROC_NUMBUF]; + sprintf(tmp, "%d", entry->pid); + entry->dir = debugfs_create_dir(tmp, proc_dir); + if (IS_ERR(entry->dir)) { + if (PTR_ERR(entry->dir) != -ENODEV) + pr_info("CM: Can't create proc/%d debugfs directory: " + "%ld\n", entry->pid, PTR_ERR(entry->dir)); + entry->dir = NULL; + return; + } + entry->comp_dir = debugfs_create_dir("components", entry->dir); + if (IS_ERR(entry->comp_dir)) { + if (PTR_ERR(entry->comp_dir) != -ENODEV) + pr_info("CM: Can't create proc/%d/components debugfs " + "directory: %ld\n", entry->pid, + PTR_ERR(entry->comp_dir)); + entry->comp_dir = NULL; + } + entry->domain_dir = debugfs_create_dir("domains", entry->dir); + if (IS_ERR(entry->domain_dir)) { + if (PTR_ERR(entry->domain_dir) != -ENODEV) + pr_info("CM: Can't create proc/%d/domains debugfs " + "directory: %ld\n", entry->pid, + PTR_ERR(entry->domain_dir)); + entry->domain_dir = NULL; + } +} + +/* DSP meminfo */ +static ssize_t meminfo_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + const t_nmf_core_id id = + *(t_nmf_core_id *)file->f_dentry->d_inode->i_private; + char buf[640]; + int ret=0; + t_cm_allocator_status status; + t_cm_system_address addr; + + OSAL_LOCK_API(); + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, ESRAM_CODE), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, ESRAM_CODE, &addr); + ret = snprintf(buf, sizeof(buf), + "Memory : Physical address Logical address Size " + " Free Used\n" + "-------------------------------------------------------" + "-------------------\n" + "ESRAM Code: %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, ESRAM_EXT24), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, ESRAM_EXT24, &addr); + ret += snprintf(&buf[ret], sizeof(buf)-ret, + "ESRAM Data: %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, SDRAM_CODE), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, SDRAM_CODE, &addr); + ret += snprintf(&buf[ret], sizeof(buf)-ret, + "SDRAM Code: %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, SDRAM_EXT24), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, SDRAM_EXT24, &addr); + ret += snprintf(&buf[ret], sizeof(buf)-ret, + "SDRAM Data: %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, INTERNAL_XRAM24), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, INTERNAL_XRAM24, &addr); + ret += snprintf(&buf[ret], sizeof(buf)-ret, + "TCM XRAM : %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + cm_MM_GetAllocatorStatus(cm_DSP_GetAllocator(id, INTERNAL_YRAM24), + 0, 0, &status); + cm_DSP_GetDspBaseAddress(id, INTERNAL_YRAM24, &addr); + ret += snprintf(&buf[ret], sizeof(buf)-ret, + "TCM YRAM : %08x-%08lx %08x-%08lx\t%8lu %8lu %8lu\n", + (unsigned int)addr.physical, + addr.physical + status.global.size - 1, + (unsigned int)addr.logical, + addr.logical + status.global.size - 1, + status.global.size, + status.global.accumulate_free_memory, + status.global.accumulate_used_memory); + + OSAL_UNLOCK_API(); + return simple_read_from_buffer(userbuf, count, ppos, buf, ret);; +} + +static const struct file_operations mem_fops = { + .read = meminfo_read, +}; + +/* ESRAM file operations */ +static int esram_open(struct inode *inode, struct file *file) +{ + int i, err=0; + for (i=0; i=0; i--) + regulator_disable(osalEnv.esram_regulator[i]); + } + + return err; +} + +static int esram_release(struct inode *inode, struct file *file) +{ + int i; + for (i=0; i for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef CM_DEBUG_H +#define CM_DEBUG_H + +#ifdef CONFIG_DEBUG_FS +#include "cmld.h" + +void cm_debug_init(void); +void cm_debug_exit(void); +void cm_debug_proc_init(struct cm_process_priv *entry); +void cm_debug_create_tcm_file(unsigned mpc_index); +void cm_debug_destroy_tcm_file(unsigned mpc_index); +#endif /* CONFIG_DEBUG_FS */ +#endif /* CM_DEBUG_H */ diff --git a/drivers/staging/nmf-cm/cm_service.c b/drivers/staging/nmf-cm/cm_service.c index bc70afe10a0..06cfbc74146 100644 --- a/drivers/staging/nmf-cm/cm_service.c +++ b/drivers/staging/nmf-cm/cm_service.c @@ -31,9 +31,14 @@ DECLARE_TASKLET(cmld_service_tasklet, service_tasklet_func, 0); void dispatch_service_msg(struct osal_msg *msg) { struct list_head *head, *next; - - /* Note: no lock needed to protect the channel_list to protect against list - changes, as the current tasklet is disabled each time we modify the list */ +#ifdef CONFIG_DEBUG_FS + bool dump_flag_to_set = true; +#endif + /* + * Note: no lock needed to protect the channel_list against list + * changes, as the current tasklet is disabled each time we modify + * the list + */ list_for_each_safe(head, next, &channel_list) { struct cm_channel_priv *channelPriv = list_entry(head, struct cm_channel_priv, entry); struct osal_msg *new_msg; @@ -50,6 +55,19 @@ void dispatch_service_msg(struct osal_msg *msg) } memcpy(new_msg, msg, msg_size); plist_node_init(&new_msg->msg_entry, 0); +#ifdef CONFIG_DEBUG_FS + if (user_has_debugfs && dump_flag_to_set + && (new_msg->d.srv.srvType == NMF_SERVICE_PANIC)) { + /* + * The reciever of this message will do the DSP + * memory dump + */ + new_msg->d.srv.srvData.panic.panicSource + |= DEBUGFS_DUMP_FLAG; + dump_flag_to_set = false; + dump_done = false; + } +#endif spin_lock_bh(&channelPriv->bh_lock); plist_add(&new_msg->msg_entry, &channelPriv->messageQueue); spin_unlock_bh(&channelPriv->bh_lock); @@ -77,8 +95,9 @@ static void service_tasklet_func(unsigned long unused) dispatch_service_msg(&msg); /* - * Stop DMA directly before shutdown, to avoid bad sound. - * Should be called after DSP has stopped executing, to avoid the DSP + * Stop DMA directly before shutdown, to avoid + * bad sound. Should be called after DSP has + * stopped executing, to avoid the DSP * re-starting DMA */ if (osalEnv.mpc[i].coreId == SIA_CORE_ID) @@ -90,7 +109,8 @@ static void service_tasklet_func(unsigned long unused) if (CM_ReadMPCString(osalEnv.mpc[i].coreId, desc.u.print.dspAddress, msg, sizeof(msg)) == CM_OK) - printk(msg, desc.u.print.value1, desc.u.print.value2); + printk(msg, desc.u.print.value1, + desc.u.print.value2); break; } default: diff --git a/drivers/staging/nmf-cm/cmioctl.h b/drivers/staging/nmf-cm/cmioctl.h index e1ef2bcb025..96481be38b8 100644 --- a/drivers/staging/nmf-cm/cmioctl.h +++ b/drivers/staging/nmf-cm/cmioctl.h @@ -9,6 +9,10 @@ #ifndef __CMIOCTL_H #define __CMIOCTL_H +#ifndef __KERNEL__ +#define BITS_PER_BYTE 8 +#endif + #include #include #include @@ -17,6 +21,8 @@ #include #include +#define DEBUGFS_ROOT "nmf-cm" +#define DEBUGFS_DUMP_FLAG (1 << (sizeof(t_panic_source)*BITS_PER_BYTE - 1)) enum cmdma_type { CMDMA_MEM_2_PER, @@ -586,6 +592,9 @@ typedef struct{ #define CM_PRIVRESERVEMEMORY _IOW('c', 101, unsigned int) #define CM_PRIV_GETBOARDVERSION _IOR('c', 102, unsigned int) #define CM_PRIV_ISCOMPONENTCACHEEMPTY _IO('c', 103) +#define CM_PRIV_DEBUGFS_READY _IO('c', 104) +#define CM_PRIV_DEBUGFS_WAIT_DUMP _IO('c', 105) +#define CM_PRIV_DEBUGFS_DUMP_DONE _IO('c', 106) enum board_version { U8500_V2 diff --git a/drivers/staging/nmf-cm/cmld.c b/drivers/staging/nmf-cm/cmld.c index d01949c8673..f8fe0d41059 100644 --- a/drivers/staging/nmf-cm/cmld.c +++ b/drivers/staging/nmf-cm/cmld.c @@ -11,10 +11,8 @@ */ #include -#include #include #include -#include #include #include #include @@ -23,13 +21,14 @@ #include #include -#include "cmioctl.h" #include "osal-kernel.h" #include "cmld.h" +#include "cmioctl.h" +#include "cm_debug.h" #include "cm_service.h" #include "cm_dma.h" -#define CMDRIVER_PATCH_VERSION 109 +#define CMDRIVER_PATCH_VERSION 112 #define O_FLUSH 0x1000000 static int cmld_major; @@ -49,19 +48,13 @@ static DEFINE_MUTEX(process_lock); /* lock used to protect previous list */ LIST_HEAD(channel_list); static DEFINE_MUTEX(channel_lock); /* lock used to protect previous list */ -/* Variables used to manage temporary allocation of ESRAM - reserved for DMA and B2R2 + MCDE */ -/* As of now, the reservation is done in RME */ -static int cfgESRAM_ReserveMCDE = 0; -static int cfgESRAM_ReserveDMA = 0; -static int cfgESRAMDmaSize = 4; /* in Kb */ -static int cfgESRAMMcdeSize = 128; /* in Kb */ -module_param(cfgESRAM_ReserveMCDE, bool, S_IRUGO); -module_param(cfgESRAM_ReserveDMA, bool, S_IRUGO); -module_param(cfgESRAMDmaSize, uint, S_IRUGO); -module_param(cfgESRAMMcdeSize, uint, S_IRUGO); -static t_cm_domain_id dmaDomainId, mcdeDomainId; -static t_cm_memory_handle dmaMemoryHdl, mcdeMemoryHdl; +#ifdef CONFIG_DEBUG_FS +/* Debugfs support */ +bool user_has_debugfs = false; +bool dump_done = true; +module_param(dump_done, bool, S_IWUSR|S_IRUGO); +static DECLARE_WAIT_QUEUE_HEAD(dump_waitq); +#endif static inline struct cm_process_priv *getProcessPriv(void) { @@ -95,6 +88,9 @@ static inline struct cm_process_priv *getProcessPriv(void) entry->pid = current->tgid; mutex_lock(&process_lock); list_add(&entry->entry, &process_list); +#ifdef CONFIG_DEBUG_FS + cm_debug_proc_init(entry); +#endif out: mutex_unlock(&process_lock); return entry; @@ -113,11 +109,9 @@ static inline void freeMessages(struct cm_channel_priv* channelPriv) warn = 1; } spin_unlock_bh(&channelPriv->bh_lock); - if (warn) { + if (warn) pr_err("[CM - PID=%d]: Some remaining" " message(s) freed\n", current->tgid); - warn = 0; - } } /* Free all pending memory areas and relative descriptors */ @@ -231,6 +225,10 @@ static void freeProcessPriv(struct kref *ref) pr_err("[CM - PID=%d]: Error while flushing some remaining" " domains: error=%d\n", current->tgid, err); +#ifdef CONFIG_DEBUG_FS + debugfs_remove_recursive(entry->dir); +#endif + /* Free the per-process descriptor */ OSAL_Free(entry); } @@ -288,8 +286,6 @@ static int cmld_release(struct inode *inode, struct file *file) { struct cm_process_priv* procPriv; - BUG_ON(file->private_data == NULL); - /* 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 @@ -364,11 +360,11 @@ static ssize_t cmld_read(struct file *file, char *buf, size_t count, loff_t *ppo if (iminor(file->f_dentry->d_inode) == 0) return -ENOSYS; - BUG_ON(channelPriv == NULL); messageQueue = &channelPriv->messageQueue; if (mutex_lock_killable(&channelPriv->msgQueueLock)) return -ERESTARTSYS; + wait: while (plist_head_empty(messageQueue)) { mutex_unlock(&channelPriv->msgQueueLock); @@ -467,9 +463,8 @@ static int cmld_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); - //channelPriv->closed = CHANNEL_CLOSED; file->f_flags |= O_FLUSH; - wake_up_all(&channelPriv->waitq); + wake_up_interruptible(&channelPriv->waitq); } return 0; } @@ -695,12 +690,18 @@ static long cmld_control_ctl(struct file *file, unsigned int cmd, unsigned long return 0; else return -ENOENT; - - default: { + case CM_PRIV_DEBUGFS_READY: +#ifdef CONFIG_DEBUG_FS + user_has_debugfs = true; +#endif + return 0; + case CM_PRIV_DEBUGFS_DUMP_DONE: + case CM_PRIV_DEBUGFS_WAIT_DUMP: + return 0; + default: pr_err("CM(%s): unsupported command %i\n", __func__, cmd); return -EINVAL; } - } return 0; } @@ -712,7 +713,14 @@ static long cmld_control_ctl(struct file *file, unsigned int cmd, unsigned long */ static long cmld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - BUG_ON(filp->private_data == NULL); +#ifdef CONFIG_DEBUG_FS + if (cmd == CM_PRIV_DEBUGFS_DUMP_DONE) { + dump_done = true; + wake_up_interruptible(&dump_waitq); + return 0; + } else if (wait_event_interruptible(dump_waitq, dump_done)) + return -ERESTARTSYS; +#endif if (iminor(filp->f_dentry->d_inode) == 0) { return cmld_control_ctl(filp, cmd, arg); @@ -756,8 +764,6 @@ static int cmld_mmap(struct file* file, struct vm_area_struct* vma) struct memAreaDesc_t* curr = NULL; unsigned int vma_size = vma->vm_end-vma->vm_start; - BUG_ON(procPriv == NULL); - listHead = &procPriv->memAreaDescList; if (lock_process(procPriv)) return -ERESTARTSYS; @@ -918,7 +924,7 @@ static int configureMpc(unsigned i, t_cfg_allocator_id *dataAllocId) * (see in remapRegions()) and we need to create the segment only at first call. * => we reuse the same allocId for the following MPCs */ - if ((osalEnv.mpc[i].sdramDataL != osalEnv.mpc[0].sdramDataL) + if ((osalEnv.mpc[i].sdram_data.data != osalEnv.mpc[0].sdram_data.data) || *dataAllocId == -1) { err = CM_ENGINE_AddMpcSdramSegment(&dataSegment, dataAllocId, "Data"); if (err != CM_OK) { @@ -1155,62 +1161,9 @@ static int __init cmld_init_module(void) CMDRIVER_PATCH_VERSION); } - /* Reserve DMA and MCDE ESRAM if needed */ - if (cfgESRAM_ReserveDMA) { - t_cm_domain_memory domain = INIT_DOMAIN; - - // Reserve memory used by DMA - domain.coreId = ARM_CORE_ID; - domain.esramData.offset = 0x0; - domain.esramData.size = cfgESRAMDmaSize * ONE_KB; - err = CM_ENGINE_CreateMemoryDomain(NMF_CORE_CLIENT, - &domain, &dmaDomainId); - if (err != CM_OK) { - pr_err("CM: Create DMA/ESRAM domain failed with error code: %d\n", err); - err = -EAGAIN; - goto out_all; - } - - err = CM_ENGINE_AllocMpcMemory(dmaDomainId, - NMF_CORE_CLIENT, - CM_MM_MPC_ESRAM16, - cfgESRAMDmaSize * ONE_KB / 2, - CM_MM_MPC_ALIGN_NONE, - &dmaMemoryHdl); - if (err != CM_OK) { - pr_err("CM: Alloc DMA in ESRAM domain failed with error code: %d\n", err); - err = -EAGAIN; - goto out_all; - } - } - - if (cfgESRAM_ReserveMCDE) { - t_cm_domain_memory domain = INIT_DOMAIN; - - // Reserve memory used by MCDE - domain.coreId = ARM_CORE_ID; - domain.esramData.offset = (cfgESRAMSize - cfgESRAMMcdeSize) * ONE_KB; - domain.esramData.size = cfgESRAMMcdeSize * ONE_KB; - err = CM_ENGINE_CreateMemoryDomain(NMF_CORE_CLIENT, - &domain, &mcdeDomainId); - if (err != CM_OK) { - pr_err("CM: Create MCDE/ESRAM domain failed with error code: %d\n", err); - err = -EAGAIN; - goto out_all; - } - - err = CM_ENGINE_AllocMpcMemory(mcdeDomainId, - NMF_CORE_CLIENT, - CM_MM_MPC_ESRAM16, - cfgESRAMMcdeSize * ONE_KB / 2, - CM_MM_MPC_ALIGN_NONE, - &mcdeMemoryHdl); - if (err != CM_OK) { - pr_err("CM: Alloc MCDE in ESRAM domain failed with error code: %d\n", err); - err = -EAGAIN; - goto out_all; - } - } +#ifdef CONFIG_DEBUG_FS + cm_debug_init(); +#endif /* Configure MPC Cores */ for (i=0; i #include - +#include #include "osal-kernel.h" /* Per-driver environment */ @@ -20,28 +20,28 @@ struct OsalEnvironment osalEnv = { .mpc = { { - .coreId = SVA_CORE_ID, - .name = "sva", - .baseP = (void*)SVA_BASE_ADDR, - .interrupt0 = IRQ_DB8500_SVA, - .interrupt1 = IRQ_DB8500_SVA2, + .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, - .hwmemCode = NULL, - .hwmemData = NULL, + .hwmem_code = NULL, + .hwmem_data = NULL, }, { - .coreId = SIA_CORE_ID, - .name = "sia", - .baseP = (void*)SIA_BASE_ADDR, - .interrupt0 = IRQ_DB8500_SIA, - .interrupt1 = IRQ_DB8500_SIA2, + .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, - .hwmemCode = NULL, - .hwmemData = NULL, + .hwmem_code = NULL, + .hwmem_data = NULL, } }, .esram_regulator = { NULL, NULL}, @@ -79,11 +79,11 @@ DECLARE_MPC_PARAM(SVA, SDRAM_DATA_SIZE, "", 1); DECLARE_MPC_PARAM(SIA, 0, "\n\t\t\t(0 means shared with SVA)", 2); -int cfgCommunicationLocationInSDRAM = 1; +bool cfgCommunicationLocationInSDRAM = true; module_param(cfgCommunicationLocationInSDRAM, bool, S_IRUGO); MODULE_PARM_DESC(cfgCommunicationLocationInSDRAM, "Location of communications (SDRAM or ESRAM)"); -int cfgSemaphoreTypeHSEM = 1; +bool cfgSemaphoreTypeHSEM = true; module_param(cfgSemaphoreTypeHSEM, bool, S_IRUGO); MODULE_PARM_DESC(cfgSemaphoreTypeHSEM, "Semaphore used (HSEM or LSEM)"); @@ -91,6 +91,28 @@ int cfgESRAMSize = ESRAM_SIZE; module_param(cfgESRAMSize, uint, S_IRUGO); MODULE_PARM_DESC(cfgESRAMSize, "Size of ESRAM used in the CM (in Kb)"); +static int set_param_powerMode(const char *val, struct kernel_param *kp) +{ + /* No equals means "set"... */ + if (!val) val = "1"; + + /* One of =[yYnN01] */ + switch (val[0]) { + case 'y': case 'Y': case '1': + CM_ENGINE_SetMode(CM_CMD_DBG_MODE, 0); + break; + case 'n': case 'N': case '0': + CM_ENGINE_SetMode(CM_CMD_DBG_MODE, 1); + break; + default: + return -EINVAL; + } + return 0; +} + +module_param_call(powerMode, set_param_powerMode, param_get_bool, &powerMode, S_IWUSR|S_IRUGO); +MODULE_PARM_DESC(powerMode, "DSP power mode enable"); + int init_config(void) { if (cfgMpcSDRAMCodeSize_SVA == 0 || cfgMpcSDRAMCodeSize_SIA == 0) { @@ -102,14 +124,16 @@ 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].sdramCodeSize = cfgMpcSDRAMCodeSize_SVA * ONE_KB; - osalEnv.mpc[SVA].sdramDataSize = cfgMpcSDRAMDataSize_SVA * ONE_KB; - osalEnv.mpc[SIA].nbYramBanks = cfgMpcYBanks_SIA; - osalEnv.mpc[SIA].eeId = cfgSchedulerTypeHybrid_SIA ? HYBRID_EXECUTIVE_ENGINE : SYNCHRONOUS_EXECUTIVE_ENGINE; - osalEnv.mpc[SIA].sdramCodeSize = cfgMpcSDRAMCodeSize_SIA * ONE_KB; - osalEnv.mpc[SIA].sdramDataSize = cfgMpcSDRAMDataSize_SIA * ONE_KB; + 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 + 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 return 0; } diff --git a/drivers/staging/nmf-cm/configuration.h b/drivers/staging/nmf-cm/configuration.h index a3bc1ca9063..8f1b88bc23f 100644 --- a/drivers/staging/nmf-cm/configuration.h +++ b/drivers/staging/nmf-cm/configuration.h @@ -21,11 +21,6 @@ /** Nomadik embedded Static RAM base address*/ #define ESRAM_BASE (U8500_ESRAM_BASE + 0x10000) // V1/V2 config: 0-64k: secure; -#define HWSEM_BASE U8500_HSEM_BASE - -/** SxA base address */ -#define SVA_BASE_ADDR U8500_SVA_BASE -#define SIA_BASE_ADDR U8500_SIA_BASE /** Nomadik embedded ram size for CM (in Kb) */ #define ESRAM_SIZE 576 @@ -48,8 +43,8 @@ enum { #define SDRAM_CODE_SIZE_SIA (2*ONE_KB) #define SDRAM_DATA_SIZE (8*ONE_KB) -extern int cfgCommunicationLocationInSDRAM; -extern int cfgSemaphoreTypeHSEM; +extern bool cfgCommunicationLocationInSDRAM; +extern bool cfgSemaphoreTypeHSEM; extern int cfgESRAMSize; int init_config(void); diff --git a/drivers/staging/nmf-cm/inc/nmf-def.h b/drivers/staging/nmf-cm/inc/nmf-def.h index 86e28626498..b095eb883f4 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) | (113)) +#define NMF_VERSION ((2 << 16) | (10 << 8) | (114)) /*! * \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 37e680a87a4..12a88923f50 100644 --- a/drivers/staging/nmf-cm/osal-kernel.c +++ b/drivers/staging/nmf-cm/osal-kernel.c @@ -27,6 +27,7 @@ #include "osal-kernel.h" #include "cm_service.h" #include "cmld.h" +#include "cm_debug.h" #include "cm_dma.h" __iomem void *prcmu_base = NULL; @@ -68,15 +69,15 @@ int remapRegions(void) /* Remap DSP base areas */ for (i=0; iesramDesc.systemAddr.logical = (t_cm_logical_address)osalEnv.esram_base; nmfHwMappingDesc->esramDesc.size = cfgESRAMSize*ONE_KB; - nmfHwMappingDesc->hwSemaphoresMappingBaseAddr.physical = HWSEM_BASE; + nmfHwMappingDesc->hwSemaphoresMappingBaseAddr.physical = U8500_HSEM_BASE; nmfHwMappingDesc->hwSemaphoresMappingBaseAddr.logical = (t_cm_logical_address)osalEnv.hwsem_base; return 0; @@ -230,8 +231,8 @@ int getNmfHwMappingDesc(t_nmf_hw_mapping_desc* nmfHwMappingDesc) */ void getMpcSystemAddress(unsigned i, t_cm_system_address* mpcSystemAddress) { - mpcSystemAddress->physical = (t_cm_physical_address)osalEnv.mpc[i].baseP; - mpcSystemAddress->logical = (t_cm_logical_address)osalEnv.mpc[i].baseL; + mpcSystemAddress->physical = (t_cm_physical_address)osalEnv.mpc[i].base_phys; + mpcSystemAddress->logical = (t_cm_logical_address)osalEnv.mpc[i].base.data; } @@ -245,13 +246,13 @@ void getMpcSystemAddress(unsigned i, t_cm_system_address* mpcSystemAddress) */ void getMpcSdramSegments(unsigned i, t_nmf_memory_segment* codeSegment, t_nmf_memory_segment* dataSegment) { - codeSegment->systemAddr.logical = (t_cm_logical_address)osalEnv.mpc[i].sdramCodeL; - codeSegment->systemAddr.physical = osalEnv.mpc[i].sdramCodeP; - codeSegment->size = osalEnv.mpc[i].sdramCodeSize; + codeSegment->systemAddr.logical = (t_cm_logical_address)osalEnv.mpc[i].sdram_code.data; + codeSegment->systemAddr.physical = osalEnv.mpc[i].sdram_code_phys; + codeSegment->size = osalEnv.mpc[i].sdram_code.size; - dataSegment->systemAddr.logical = (t_cm_logical_address)osalEnv.mpc[i].sdramDataL; - dataSegment->systemAddr.physical = osalEnv.mpc[i].sdramDataP; - dataSegment->size = osalEnv.mpc[i].sdramDataSize; + dataSegment->systemAddr.logical = (t_cm_logical_address)osalEnv.mpc[i].sdram_data.data; + dataSegment->systemAddr.physical = osalEnv.mpc[i].sdram_data_phys; + dataSegment->size = osalEnv.mpc[i].sdram_data.size; } #ifdef CM_DEBUG_ALLOC @@ -735,11 +736,21 @@ static int dspload_monitor(void *idx) timer.data = (unsigned long)current; init_timer_deferrable(&timer); +#ifdef CONFIG_DEBUG_FS + mpc->opp_request = current_opp_request; +#endif if (prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char*)mpc->name, current_opp_request)) pr_err("CM Driver: Add QoS failed\n"); + /* + * Wait for 500ms before initializing the counter, + * to let the DSP boot (init of counter will failed if + * DSP is not booted). + */ + schedule_timeout_uninterruptible(msecs_to_jiffies(500)); + /* init counter */ if (CM_GetMpcLoadCounter(mpc->coreId, &mpc->oldLoadCounter) != CM_OK) @@ -768,6 +779,9 @@ static int dspload_monitor(void *idx) &loadCounter) != CM_OK) loadCounter = mpc->oldLoadCounter; +#ifdef CONFIG_DEBUG_FS + mpc->load = +#endif load = computeDspLoad(&mpc->oldLoadCounter, &loadCounter); mpc->oldLoadCounter = loadCounter; @@ -776,6 +790,9 @@ static int dspload_monitor(void *idx) /* check if we must request more opp */ if ((current_opp_request == HALF_OPP) && (load > dspLoadHighThreshold)) { +#ifdef CONFIG_DEBUG_FS + mpc->opp_request = +#endif current_opp_request = FULL_OPP; if (cm_debug_level) pr_info("CM Driver: Request QoS OPP %d for %s\n", @@ -787,6 +804,9 @@ static int dspload_monitor(void *idx) /* check if we can request less opp */ else if ((current_opp_request == FULL_OPP) && (load < dspLoadLowThreshold)) { +#ifdef CONFIG_DEBUG_FS + mpc->opp_request = +#endif current_opp_request = HALF_OPP; if (cm_debug_level) pr_info("CM Driver: Request QoS OPP %d for %s\n", @@ -797,6 +817,9 @@ static int dspload_monitor(void *idx) } } +#ifdef CONFIG_DEBUG_FS + mpc->opp_request = mpc->load = 0; +#endif del_singleshot_timer_sync(&timer); if (cm_debug_level) pr_info("CM Driver: Remove QoS OPP for %s\n", mpc->name); @@ -805,7 +828,7 @@ static int dspload_monitor(void *idx) return 0; } -static int enable_auto_pm = 0; +static int enable_auto_pm = 1; module_param(enable_auto_pm, bool, S_IWUSR|S_IRUGO); /** \ingroup OSAL_IMPLEMENTATION @@ -824,6 +847,9 @@ void OSAL_DisablePwrRessource(t_nmf_power_resource resource, t_uint32 firstParam return; } +#ifdef CONFIG_DEBUG_FS + cm_debug_destroy_tcm_file(idx); +#endif /* Stop the DSP load monitoring */ clear_bit(idx, &running_dsp); if (osalEnv.mpc[idx].monitor_tsk) { @@ -959,6 +985,9 @@ t_cm_error OSAL_EnablePwrRessource(t_nmf_power_resource resource, t_uint32 first "thread: %ld\n", PTR_ERR(osalEnv.mpc[idx].monitor_tsk)); osalEnv.mpc[idx].monitor_tsk = NULL; } +#ifdef CONFIG_DEBUG_FS + cm_debug_create_tcm_file(idx); +#endif break; } case CM_OSAL_POWER_SxA_AUTOIDLE: @@ -1069,25 +1098,25 @@ void OSAL_CleanDCache(t_uint32 startAddr, t_uint32 size) struct mpcConfig *mpc; t_uint32 endAddr = startAddr + size; - if (startAddr >= (u32)osalEnv.mpc[0].sdramCodeL - && endAddr <= (u32)(osalEnv.mpc[0].sdramCodeL - + osalEnv.mpc[0].sdramCodeSize)) { + if (startAddr >= (u32)osalEnv.mpc[0].sdram_code.data + && endAddr <= (u32)(osalEnv.mpc[0].sdram_code.data + + osalEnv.mpc[0].sdram_code.size)) { mpc = &osalEnv.mpc[0]; - } else if (startAddr >= (u32)osalEnv.mpc[1].sdramCodeL - && endAddr <= (u32)(osalEnv.mpc[1].sdramCodeL - + osalEnv.mpc[1].sdramCodeSize)) { + } else if (startAddr >= (u32)osalEnv.mpc[1].sdram_code.data + && endAddr <= (u32)(osalEnv.mpc[1].sdram_code.data + + osalEnv.mpc[1].sdram_code.size)) { mpc = &osalEnv.mpc[1]; } else { /* The code may be in esram, in that case, nothing to do */ return; } - region.offset = startAddr - (u32)mpc->sdramCodeL; + region.offset = startAddr - (u32)mpc->sdram_code.data; region.count = 1; region.start = 0; region.end = size; region.size = size; - hwmem_set_domain(mpc->hwmemCode, HWMEM_ACCESS_READ, + hwmem_set_domain(mpc->hwmem_code, HWMEM_ACCESS_READ, HWMEM_DOMAIN_SYNC, ®ion); /* * The hwmem keep track of region being sync or not. @@ -1095,7 +1124,7 @@ void OSAL_CleanDCache(t_uint32 startAddr, t_uint32 size) * to let following clean being done as expected. Today, * there is no other place to do that in CM Core right now */ - hwmem_set_domain(mpc->hwmemCode, HWMEM_ACCESS_WRITE, + hwmem_set_domain(mpc->hwmem_code, HWMEM_ACCESS_WRITE, HWMEM_DOMAIN_CPU, ®ion); #else dsb(); diff --git a/drivers/staging/nmf-cm/osal-kernel.h b/drivers/staging/nmf-cm/osal-kernel.h index 36baf893fcc..7a3834fec59 100644 --- a/drivers/staging/nmf-cm/osal-kernel.h +++ b/drivers/staging/nmf-cm/osal-kernel.h @@ -7,6 +7,7 @@ #ifndef OSAL_KERNEL_H #define OSAL_KERNEL_H +#include #include #include #include @@ -17,37 +18,55 @@ #include #include #include +/* + * Do not include ELF definition from cm/engine/elf/inc/elfapi.h file + * because it conflicts with definition from linux/elf.h file + */ +#define _CM_ELF_H #include #include #include "configuration.h" -/** Per-MPC configuration structure */ +/* + * Per-MPC configuration structure + * Use struct debugfs_blob_wrapper to store pointer and size of section + * to allow easy re-use of data through debugfs + */ struct mpcConfig { - const t_nmf_core_id coreId; /**< MPC coreId */ - const char *name; /**< MPC name */ - t_uint8 nbYramBanks; /**< number of TCM ram banks to reserve for y memory */ - t_nmf_executive_engine_id eeId; /**< Type of Executive Engine */ - const void *baseP; /**< Physical base address of the MPC */ - void *baseL; /**< Remapped base address of the MPC */ - struct hwmem_alloc *hwmemCode; /**< hwmem code segment */ - u32 sdramCodeP; /**< Physical base address for MPC SDRAM Code region */ - void *sdramCodeL; /**< Remapped base address for MPC SDRAM Code region */ - size_t sdramCodeSize; /**< Size of MPC SDRAM Code region */ - struct hwmem_alloc *hwmemData; /**< hwmem data segment */ - u32 sdramDataP; /**< Physical base address for MPC SDRAM Data region */ - void *sdramDataL; /**< Remapped base address for MPC SDRAM Data region */ - size_t sdramDataSize; /**< Size of MPC SDRAM Data region */ - const unsigned int interrupt0; /**< interrupt line triggered by the MPC, for MPC events (if HSEM not used) */ - const unsigned int interrupt1; /**< interrupt line triggered by the MPC, for PANIC events */ - struct tasklet_struct tasklet; /**< taskket used to process MPC events */ + const t_nmf_core_id coreId; /**< MPC coreId */ + const char *name; /**< MPC name */ + t_uint8 nbYramBanks; /**< number of TCM ram banks to reserve for y memory */ + t_nmf_executive_engine_id eeId; /**< Type of Executive Engine */ + const void *base_phys; /**< Physical base address of the MPC */ + struct debugfs_blob_wrapper base;/**< Remapped base address of the MPC and size of TCM24 */ + struct hwmem_alloc *hwmem_code; /**< hwmem code segment */ + u32 sdram_code_phys; /**< Physical base address for MPC SDRAM Code region */ + struct debugfs_blob_wrapper sdram_code; /**< Remapped base address and size for MPC SDRAM Code */ + struct hwmem_alloc *hwmem_data; /**< hwmem data segment */ + u32 sdram_data_phys; /**< Physical base address for MPC SDRAM Data region */ + struct debugfs_blob_wrapper sdram_data; /**< Remapped base address and size for MPC SDRAM Data */ + const unsigned int interrupt0; /**< interrupt line triggered by the MPC, for MPC events (if HSEM not used) */ + const unsigned int interrupt1; /**< interrupt line triggered by the MPC, for PANIC events */ + struct tasklet_struct tasklet; /**< taskket used to process MPC events */ struct regulator *mmdsp_regulator; /**< mmdsp regulator linked to this MPC */ struct regulator *pipe_regulator; /**< hardware pipe linked to this MPC */ #ifdef CONFIG_HAS_WAKELOCK - struct wake_lock wakelock; /**< wakelock for this MPC to prevent ARM to go in APSLEEP state */ + struct wake_lock wakelock; /**< wakelock for this MPC to prevent ARM to go in APSLEEP state */ #endif - struct task_struct *monitor_tsk;/**< task to monitor the dsp load; */ + struct task_struct *monitor_tsk; /**< task to monitor the dsp load; */ t_cm_mpc_load_counter oldLoadCounter; /**< previous load counter of the DSP */ +#ifdef CONFIG_DEBUG_FS + struct dentry *dir; /**< debugfs dir entry */ + struct dentry *comp_dir; /**< debugfs component dir entry */ + struct dentry *domain_dir; /**< debugfs domain dir entry */ + struct dentry *snapshot_dir; /**< debugfs snapshot dir entry */ + struct dentry *mem_file; /**< debugfs meminfo file entry */ + struct dentry *tcm_file; /**< debugfs meminfo file entry */ + struct dentry *esram_file; /**< debugfs meminfo file entry */ + s8 load; /**< current load of the DSP */ + s8 opp_request; /**< current requested opp of the DSP */ +#endif }; /** Describes current Kernel OSAL environment @@ -63,8 +82,8 @@ struct mpcConfig { struct OsalEnvironment { struct mpcConfig mpc[NB_MPC]; - void* hwsem_base; /** < Remapped base address of the hardware semaphores */ - void* esram_base; /** < Remapped base address for embedded RAM used within the CM */ + void* hwsem_base; /** < Remapped base address of the hardware semaphores */ + void* esram_base; /**< Remapped base address embedded RAM used within the CM */ struct regulator *esram_regulator[NB_ESRAM]; /**< regulator for ESRAM bank 1+2 and 3+4 */ struct prcmu_auto_pm_config dsp_sleep; struct prcmu_auto_pm_config dsp_idle; -- cgit v1.2.3 From 4dc43eb0c79e7af48ce94793f4d9a2b7c839d780 Mon Sep 17 00:00:00 2001 From: psen Date: Mon, 5 Sep 2011 15:05:44 +0530 Subject: NMF CM Build Issue Fixed --- drivers/staging/nmf-cm/cm_debug.c | 1 + drivers/staging/nmf-cm/configuration.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/staging/nmf-cm/configuration.c') diff --git a/drivers/staging/nmf-cm/cm_debug.c b/drivers/staging/nmf-cm/cm_debug.c index 78552c9ce67..cb753ea2593 100644 --- a/drivers/staging/nmf-cm/cm_debug.c +++ b/drivers/staging/nmf-cm/cm_debug.c @@ -5,6 +5,7 @@ */ #include +#include #include "osal-kernel.h" #include "cm_debug.h" diff --git a/drivers/staging/nmf-cm/configuration.c b/drivers/staging/nmf-cm/configuration.c index 898aab94877..b61ab509d94 100644 --- a/drivers/staging/nmf-cm/configuration.c +++ b/drivers/staging/nmf-cm/configuration.c @@ -91,7 +91,7 @@ int cfgESRAMSize = ESRAM_SIZE; module_param(cfgESRAMSize, uint, S_IRUGO); MODULE_PARM_DESC(cfgESRAMSize, "Size of ESRAM used in the CM (in Kb)"); -static int set_param_powerMode(const char *val, struct kernel_param *kp) +static int set_param_powerMode(const char *val, const struct kernel_param *kp) { /* No equals means "set"... */ if (!val) val = "1"; -- cgit v1.2.3 From e302925edc2a78569e1742e523db4b55a3fc4e26 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Fri, 2 Dec 2011 14:30:59 +0100 Subject: nmf-cm: Include module.h after 3.2 update Signed-off-by: Philippe Langlais --- drivers/staging/nmf-cm/cmld.c | 1 + drivers/staging/nmf-cm/configuration.c | 1 + drivers/staging/nmf-cm/osal-kernel.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers/staging/nmf-cm/configuration.c') diff --git a/drivers/staging/nmf-cm/cmld.c b/drivers/staging/nmf-cm/cmld.c index d96ceaa3fe5..7b1061d9d52 100644 --- a/drivers/staging/nmf-cm/cmld.c +++ b/drivers/staging/nmf-cm/cmld.c @@ -10,6 +10,7 @@ * */ +#include #include #include #include diff --git a/drivers/staging/nmf-cm/configuration.c b/drivers/staging/nmf-cm/configuration.c index b61ab509d94..d62bcb45500 100644 --- a/drivers/staging/nmf-cm/configuration.c +++ b/drivers/staging/nmf-cm/configuration.c @@ -10,6 +10,7 @@ * */ +#include #include #include #include diff --git a/drivers/staging/nmf-cm/osal-kernel.c b/drivers/staging/nmf-cm/osal-kernel.c index 0b0eeac4ce3..94aa11fc91c 100644 --- a/drivers/staging/nmf-cm/osal-kernel.c +++ b/drivers/staging/nmf-cm/osal-kernel.c @@ -9,6 +9,7 @@ * Implements NMF OSAL for Linux kernel-space environment */ +#include #include #include #include -- cgit v1.2.3 From 3b3c91a8ba4005fa72bb1e553db7300fce3ffbbb 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 component 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: I351d3b294667116b8b6900ef7292f4a62d911b9a Signed-off-by: Pierre Peiffer Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/35778 Reviewed-by: QABUILD --- .../nmf-cm/cm/engine/api/control/irq_engine.h | 14 +- .../inc/executive_engine_mgt.h | 6 + .../src/executive_engine_mgt.c | 13 + .../os_adaptation_layer/inc/os_adaptation_layer.h | 4 + .../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_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 | 450 ++++++++++++++------- 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 | 3 +- drivers/staging/nmf-cm/ee/api/trace.idt | 31 ++ drivers/staging/nmf-cm/inc/nmf-def.h | 2 +- drivers/staging/nmf-cm/osal-kernel.c | 22 +- drivers/staging/nmf-cm/osal-kernel.h | 5 +- .../nmf-cm/share/communication/inc/nmf_service.h | 1 + 20 files changed, 593 insertions(+), 197 deletions(-) create mode 100644 drivers/staging/nmf-cm/ee/api/trace.idt (limited to 'drivers/staging/nmf-cm/configuration.c') 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/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/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/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_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..17af63ac407 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 121 #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)) @@ -371,7 +263,7 @@ wait: if (block == 0) return -EAGAIN; /* Wait until there is a message to ferry up */ - if (wait_event_interruptible(channelPriv->waitq, ((!plist_head_empty(messageQueue)) || (file->f_flags & O_FLUSH)))) + if (wait_event_killable(channelPriv->waitq, ((!plist_head_empty(messageQueue)) || (file->f_flags & O_FLUSH)))) return -ERESTARTSYS; if (file->f_flags & O_FLUSH) { file->f_flags &= ~O_FLUSH; @@ -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_killable(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_killable(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..53135819f4a 100644 --- a/drivers/staging/nmf-cm/ee/api/panic.idt +++ b/drivers/staging/nmf-cm/ee/api/panic.idt @@ -55,7 +55,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..3c21c6a860f --- /dev/null +++ b/drivers/staging/nmf-cm/ee/api/trace.idt @@ -0,0 +1,31 @@ +/* + * 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..5cb1ec7fcec 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) | (121)) /*! * \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 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..dc9bc8445ac 100644 --- a/drivers/staging/nmf-cm/osal-kernel.h +++ b/drivers/staging/nmf-cm/osal-kernel.h @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef CONFIG_HAS_WAKELOCK #include #endif @@ -24,7 +25,6 @@ */ #define _CM_ELF_H #include -#include #include "configuration.h" @@ -56,6 +56,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 -- cgit v1.2.3 From 1e96d1026edb86c7e6f62dfdfcdcf1110aac1cd7 Mon Sep 17 00:00:00 2001 From: himansh Date: Wed, 9 Nov 2011 16:11:59 +0530 Subject: Revert "U8500 CM: Add support to get DSP OST Trace on ARM" This reverts commit 6cfa5e388f0250764e7b9d11d2c3f141b408a93e. ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson ID: 373198 ST-Ericsson Linux next: NA Change-Id: I0ff4c175c3e1c0c7070b76719e1ad51d390221c9 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/37036 Reviewed-by: Himanshu AGRAWAL Reviewed-by: Swinder Pal SINGH Tested-by: Himanshu AGRAWAL Reviewed-by: Sarvesh SANT --- .../nmf-cm/cm/engine/api/control/irq_engine.h | 14 +- .../inc/executive_engine_mgt.h | 6 - .../src/executive_engine_mgt.c | 13 - .../os_adaptation_layer/inc/os_adaptation_layer.h | 4 - .../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_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 | 450 +++++++-------------- 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 | 3 +- drivers/staging/nmf-cm/ee/api/trace.idt | 31 -- drivers/staging/nmf-cm/inc/nmf-def.h | 2 +- drivers/staging/nmf-cm/osal-kernel.c | 22 +- drivers/staging/nmf-cm/osal-kernel.h | 5 +- .../nmf-cm/share/communication/inc/nmf_service.h | 1 - 20 files changed, 197 insertions(+), 593 deletions(-) delete mode 100644 drivers/staging/nmf-cm/ee/api/trace.idt (limited to 'drivers/staging/nmf-cm/configuration.c') 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 e3974764e91..20313f13256 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,7 +14,6 @@ #include #include #include -#include /*! * \brief MPCs -> HOST communication handler @@ -50,8 +49,7 @@ 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_TRACE = 3 //!< Trace service found + CM_MPC_SERVICE_PRINT = 2 //!< Print service found } t_cm_service_type; //!< Service description type /*! @@ -107,14 +105,4 @@ 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/executive_engine_mgt/inc/executive_engine_mgt.h b/drivers/staging/nmf-cm/cm/engine/executive_engine_mgt/inc/executive_engine_mgt.h index 0894410ae0d..aacffd15a17 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,12 +24,6 @@ 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 4df3d7ee0f5..f2c833ff7dc 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,8 +21,6 @@ #include #include -#include - #include t_ee_state eeState[NB_CORE_IDS]; @@ -132,16 +130,6 @@ 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)); @@ -191,7 +179,6 @@ 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/os_adaptation_layer/inc/os_adaptation_layer.h b/drivers/staging/nmf-cm/cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h index c9ec864795f..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 @@ -44,10 +44,6 @@ 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/trace/inc/xtitrace.h b/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h index 1efd4f1e699..6ab960b69b2 100644 --- a/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h +++ b/drivers/staging/nmf-cm/cm/engine/trace/inc/xtitrace.h @@ -39,12 +39,4 @@ 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 e59d9f8b1ba..9cb1a729a92 100644 --- a/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c +++ b/drivers/staging/nmf-cm/cm/engine/trace/src/panic.c @@ -13,111 +13,6 @@ #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 @@ -244,10 +139,6 @@ 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_debug.c b/drivers/staging/nmf-cm/cm_debug.c index 26446e19cdb..a934aa33e92 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 a2a6ffa5b57..70cf6f37524 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(&channelPriv->waitq); + wake_up_interruptible(&channelPriv->waitq); } } @@ -113,12 +113,6 @@ 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 ca8d664abb4..a687e0206a3 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, curr->tid); + __func__, current->pid, physAddr, (int)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 5f7d5b6a349..96481be38b8 100644 --- a/drivers/staging/nmf-cm/cmioctl.h +++ b/drivers/staging/nmf-cm/cmioctl.h @@ -29,11 +29,9 @@ enum cmdma_type { CMDMA_PER_2_MEM }; -#define CMLD_DEV_NAME \ - { "cm_control", \ - "cm_channel", \ - "cm_sia_trace", \ - "cm_sva_trace", \ +#define CMLD_DEV_NAME \ + { "cm_control", \ + "cm_channel" \ } /* diff --git a/drivers/staging/nmf-cm/cmld.c b/drivers/staging/nmf-cm/cmld.c index 17af63ac407..ef9753de7a4 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 121 +#define CMDRIVER_PATCH_VERSION 117 #define O_FLUSH 0x1000000 static int cmld_major; @@ -233,6 +233,111 @@ 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) @@ -242,16 +347,19 @@ static void freeProcessPriv(struct kref *ref) * \note cfr GetEvent() * \return POSIX error code */ -static ssize_t cmld_channel_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t cmld_read(struct file *file, char *buf, size_t count, loff_t *ppos) { int err = 0; - struct cm_channel_priv* channelPriv = file->private_data; + struct cm_channel_priv* channelPriv = (struct cm_channel_priv*)(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)) @@ -263,7 +371,7 @@ wait: if (block == 0) return -EAGAIN; /* Wait until there is a message to ferry up */ - if (wait_event_killable(channelPriv->waitq, ((!plist_head_empty(messageQueue)) || (file->f_flags & O_FLUSH)))) + if (wait_event_interruptible(channelPriv->waitq, ((!plist_head_empty(messageQueue)) || (file->f_flags & O_FLUSH)))) return -ERESTARTSYS; if (file->f_flags & O_FLUSH) { file->f_flags &= ~O_FLUSH; @@ -351,21 +459,19 @@ out: * * \return POSIX error code */ -static int cmld_channel_flush(struct file *file, fl_owner_t id) +static int cmld_flush(struct file *file, fl_owner_t id) { - struct cm_channel_priv* channelPriv = file->private_data; - file->f_flags |= O_FLUSH; - wake_up(&channelPriv->waitq); + 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); + } return 0; } -static long cmld_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long cmld_channel_ctl(struct file *file, unsigned int cmd, unsigned long arg) { struct cm_channel_priv *channelPriv = file->private_data; -#ifdef CONFIG_DEBUG_FS - if (wait_event_killable(dump_waitq, (!cmld_dump_ongoing))) - return -ERESTARTSYS; -#endif switch(cmd) { /* @@ -374,7 +480,7 @@ static long cmld_channel_ioctl(struct file *file, unsigned int cmd, unsigned lon case CM_BINDCOMPONENTTOCMCORE: return cmld_BindComponentToCMCore(channelPriv, (CM_BindComponentToCMCore_t *)arg); case CM_FLUSHCHANNEL: - return cmld_channel_flush(file, 0); + return cmld_flush(file, 0); default: pr_err("CM(%s): unsupported command %i\n", __func__, cmd); return -EINVAL; @@ -382,18 +488,9 @@ static long cmld_channel_ioctl(struct file *file, unsigned int cmd, unsigned lon return 0; } -static long cmld_control_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long cmld_control_ctl(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_killable(dump_waitq, (!cmld_dump_ongoing))) - return -ERESTARTSYS; -#endif - switch(cmd) { /* * All wrapped CM SYSCALL @@ -598,6 +695,7 @@ static long cmld_control_ioctl(struct file *file, unsigned int cmd, unsigned lon cmld_user_has_debugfs = true; #endif return 0; + case CM_PRIV_DEBUGFS_DUMP_DONE: case CM_PRIV_DEBUGFS_WAIT_DUMP: return 0; default: @@ -608,6 +706,29 @@ static long cmld_control_ioctl(struct file *file, unsigned int cmd, unsigned lon 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) { @@ -634,7 +755,7 @@ static struct vm_operations_struct cmld_remap_vm_ops = { * * \return POSIX error code */ -static int cmld_control_mmap(struct file *file, struct vm_area_struct *vma) +static int cmld_mmap(struct file* file, struct vm_area_struct* vma) { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; struct list_head* listHead; @@ -706,278 +827,6 @@ static int cmld_control_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(): @@ -1033,7 +882,12 @@ 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 17e6c55ff61..4c5a5bed7e6 100644 --- a/drivers/staging/nmf-cm/cmld.h +++ b/drivers/staging/nmf-cm/cmld.h @@ -79,52 +79,6 @@ 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 523874fc586..d62bcb45500 100644 --- a/drivers/staging/nmf-cm/configuration.c +++ b/drivers/staging/nmf-cm/configuration.c @@ -21,30 +21,28 @@ 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, - .trace_read_count = ATOMIC_INIT(0), + .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 = 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), + .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, } }, .esram_regulator = { NULL, NULL}, @@ -127,20 +125,16 @@ 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 f4146dc6117..35072831a13 100644 --- a/drivers/staging/nmf-cm/configuration.h +++ b/drivers/staging/nmf-cm/configuration.h @@ -20,14 +20,12 @@ #endif /* Embedded Static RAM base address */ -/* config: 0-64k: secure */ -#define ESRAM_BASE (U8500_ESRAM_BASE + U8500_ESRAM_DMA_LCPA_OFFSET) +#define ESRAM_BASE (U8500_ESRAM_BASE + 0x10000) // V1/V2 config: 0-64k: secure; /* * 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 53135819f4a..f971fdad8c5 100644 --- a/drivers/staging/nmf-cm/ee/api/panic.idt +++ b/drivers/staging/nmf-cm/ee/api/panic.idt @@ -55,8 +55,7 @@ typedef enum { INTERFACE_NOT_BINDED = 8, USER_PANIC = 9, UNBIND_INTERRUPT = 10, - EVENT_FIFO_IN_USE = 11, - RESERVED_PANIC = 2 //for COMPATIBILITY with previous versions of NMF, to be deprecated + EVENT_FIFO_IN_USE = 11 } t_panic_reasonDescription; /*! diff --git a/drivers/staging/nmf-cm/ee/api/trace.idt b/drivers/staging/nmf-cm/ee/api/trace.idt deleted file mode 100644 index 3c21c6a860f..00000000000 --- a/drivers/staging/nmf-cm/ee/api/trace.idt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 5cb1ec7fcec..e671198f7b9 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) | (121)) +#define NMF_VERSION ((2 << 16) | (10 << 8) | (118)) /*! * \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 e79e35db106..94aa11fc91c 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(&skelwrapper->channelPriv->waitq); + wake_up_interruptible(&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_warn("CM Driver: Failed to init load counter for %s\n", - mpc->name); + pr_err("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_BANK1-1); + secondParam = (firstParam+secondParam-(U8500_ESRAM_BASE+0x20000)-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 /= (2*U8500_ESRAM_BANK_SIZE); + secondParam /= 0x40000; 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_BANK1) + if (firstParam < (U8500_ESRAM_BASE+0x20000)) firstParam = 0; else - firstParam = (firstParam-U8500_ESRAM_BANK1)/(2*U8500_ESRAM_BANK_SIZE); + firstParam = (firstParam-(U8500_ESRAM_BASE+0x20000))/0x40000; /* 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_BANK1-1); + secondParam = (firstParam+secondParam-(U8500_ESRAM_BASE+0x20000)-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 /= (2*U8500_ESRAM_BANK_SIZE); + secondParam /= 0x40000; 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_BANK1) + if (firstParam < (U8500_ESRAM_BASE+0x20000)) firstParam = 0; else - firstParam = (firstParam-U8500_ESRAM_BANK1)/(2*U8500_ESRAM_BANK_SIZE); + firstParam = (firstParam-(U8500_ESRAM_BASE+0x20000))/0x40000; /* 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 dc9bc8445ac..7a71bdd591d 100644 --- a/drivers/staging/nmf-cm/osal-kernel.h +++ b/drivers/staging/nmf-cm/osal-kernel.h @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef CONFIG_HAS_WAKELOCK #include #endif @@ -25,6 +24,7 @@ */ #define _CM_ELF_H #include +#include #include "configuration.h" @@ -56,9 +56,6 @@ 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 71dfc534f97..5ec08434492 100644 --- a/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h +++ b/drivers/staging/nmf-cm/share/communication/inc/nmf_service.h @@ -12,6 +12,5 @@ #define MPC_SERVICE_NONE 0 #define MPC_SERVICE_BOOT 0xB001 #define MPC_SERVICE_PRINT 0x1234 -#define MPC_SERVICE_TRACE 0x789 #endif -- cgit v1.2.3 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 (limited to 'drivers/staging/nmf-cm/configuration.c') 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