/****************************************************************************** © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc. All rights reserved. This is proprietary source code of Freescale Semiconductor Inc., and its use is subject to the NetComm Device Drivers EULA. The copyright notice above does not evidence any actual or intended publication of such source code. ALTERNATIVELY, redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Freescale Semiconductor nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ /****************************************************************************** @File bm.c @Description BM *//***************************************************************************/ #include "error_ext.h" #include "std_ext.h" #include "string_ext.h" #include "sprint_ext.h" #include "debug_ext.h" #include "mm_ext.h" #include "bm.h" t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable); /****************************************/ /* static functions */ /****************************************/ static volatile bool blockingFlag = FALSE; static void BmIpcMsgCompletionCB(t_Handle h_Module, uint8_t *p_Msg, uint8_t *p_Reply, uint32_t replyLength, t_Error status) { SANITY_CHECK_RETURN(h_Module, E_INVALID_HANDLE); #ifdef DISABLE_SANITY_CHECKS UNUSED(h_Module); #endif /* DISABLE_SANITY_CHECKS */ UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); blockingFlag = FALSE; } static t_Error BmHandleIpcMsgCB(t_Handle h_Bm, uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply, uint32_t *p_ReplyLength) { t_Bm *p_Bm = (t_Bm*)h_Bm; t_BmIpcMsg *p_IpcMsg = (t_BmIpcMsg*)p_Msg; t_BmIpcReply *p_IpcReply = (t_BmIpcReply *)p_Reply; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); #ifdef DISABLE_SANITY_CHECKS UNUSED(msgLength); #endif /* DISABLE_SANITY_CHECKS */ ASSERT_COND(p_IpcMsg); memset(p_IpcReply, 0, (sizeof(uint8_t) * BM_IPC_MAX_REPLY_SIZE)); *p_ReplyLength = 0; switch(p_IpcMsg->msgId) { case (BM_MASTER_IS_ALIVE): *(uint8_t*)p_IpcReply->replyBody = 1; *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); break; case (BM_SET_POOL_THRESH): { t_Error err; t_BmIpcPoolThreshParams ipcPoolThresh; memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams)); if ((err = BmSetPoolThresholds(p_Bm, ipcPoolThresh.bpid, ipcPoolThresh.thresholds)) != E_OK) REPORT_ERROR(MINOR, err, NO_MSG); break; } case (BM_UNSET_POOL_THRESH): { t_Error err; t_BmIpcPoolThreshParams ipcPoolThresh; memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams)); if ((err = BmUnSetPoolThresholds(p_Bm, ipcPoolThresh.bpid)) != E_OK) REPORT_ERROR(MINOR, err, NO_MSG); break; } case (BM_GET_COUNTER): { t_BmIpcGetCounter ipcCounter; uint32_t count; memcpy((uint8_t*)&ipcCounter, p_IpcMsg->msgBody, sizeof(t_BmIpcGetCounter)); count = BmGetCounter(p_Bm, (e_BmInterModuleCounters)ipcCounter.enumId, ipcCounter.bpid); memcpy(p_IpcReply->replyBody, (uint8_t*)&count, sizeof(uint32_t)); *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); break; } case (BM_GET_REVISION): { t_BmRevisionInfo revInfo; t_BmIpcRevisionInfo ipcRevInfo; p_IpcReply->error = (uint32_t)BmGetRevision(h_Bm, &revInfo); ipcRevInfo.majorRev = revInfo.majorRev; ipcRevInfo.minorRev = revInfo.minorRev; memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_BmIpcRevisionInfo)); *p_ReplyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo); break; } case (BM_FORCE_BPID): { t_BmIpcBpidParams ipcBpid; uint32_t tmp; memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams)); tmp = BmBpidGet(p_Bm, TRUE, ipcBpid.bpid); memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t)); *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); break; } case (BM_PUT_BPID): { t_Error err; t_BmIpcBpidParams ipcBpid; memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams)); if ((err = BmBpidPut(p_Bm, ipcBpid.bpid)) != E_OK) REPORT_ERROR(MINOR, err, NO_MSG); break; } default: *p_ReplyLength = 0; RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); } return E_OK; } static t_Error CheckBmParameters(t_Bm *p_Bm) { if ((p_Bm->p_BmDriverParams->partBpidBase + p_Bm->p_BmDriverParams->partNumOfPools) > BM_MAX_NUM_OF_POOLS) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partBpidBase+partNumOfPools out of range!!!")); if (p_Bm->guestId == NCSW_MASTER_ID) { if (!p_Bm->p_BmDriverParams->totalNumOfBuffers) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be larger than '0'!!!")); if (p_Bm->p_BmDriverParams->totalNumOfBuffers > (128*MEGABYTE)) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be equal or smaller than 128M!!!")); if(!p_Bm->f_Exception) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); } return E_OK; } static __inline__ uint32_t GenerateThresh(uint32_t val, int roundup) { uint32_t e = 0; /* co-efficient, exponent */ uint32_t oddbit = 0; while(val > 0xff) { oddbit = val & 1; val >>= 1; e++; if(roundup && oddbit) val++; } return (val | (e << 8)); } static t_Error BmSetPool(t_Handle h_Bm, uint8_t bpid, uint32_t swdet, uint32_t swdxt, uint32_t hwdet, uint32_t hwdxt) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); WRITE_UINT32(p_Bm->p_BmRegs->swdet[bpid], GenerateThresh(swdet, 0)); WRITE_UINT32(p_Bm->p_BmRegs->swdxt[bpid], GenerateThresh(swdxt, 1)); WRITE_UINT32(p_Bm->p_BmRegs->hwdet[bpid], GenerateThresh(hwdet, 0)); WRITE_UINT32(p_Bm->p_BmRegs->hwdxt[bpid], GenerateThresh(hwdxt, 1)); return E_OK; } /****************************************/ /* Inter-Module functions */ /****************************************/ t_Error BmSetPoolThresholds(t_Handle h_Bm, uint8_t bpid, const uint32_t *thresholds) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); if (p_Bm->guestId == NCSW_MASTER_ID) { return BmSetPool(h_Bm, bpid, thresholds[0], thresholds[1], thresholds[2], thresholds[3]); } else if (p_Bm->h_Session) { t_BmIpcMsg msg; t_BmIpcPoolThreshParams ipcPoolThresh; t_Error errCode = E_OK; memset(&msg, 0, sizeof(t_BmIpcMsg)); ipcPoolThresh.bpid = bpid; memcpy(ipcPoolThresh.thresholds, thresholds, sizeof(uintptr_t) * MAX_DEPLETION_THRESHOLDS); msg.msgId = BM_SET_POOL_THRESH; memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams)); if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, (uint8_t*)&msg, sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams), NULL, NULL, NULL, NULL)) != E_OK) RETURN_ERROR(MAJOR, errCode, NO_MSG); return E_OK; } else RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC")); } t_Error BmUnSetPoolThresholds(t_Handle h_Bm, uint8_t bpid) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); if (p_Bm->guestId == NCSW_MASTER_ID) { return BmSetPool(h_Bm, bpid, 0, 0, 0, 0); } else if (p_Bm->h_Session) { t_BmIpcMsg msg; t_BmIpcPoolThreshParams ipcPoolThresh; t_Error errCode = E_OK; memset(&msg, 0, sizeof(t_BmIpcMsg)); memset(&ipcPoolThresh, 0, sizeof(t_BmIpcPoolThreshParams)); ipcPoolThresh.bpid = bpid; msg.msgId = BM_UNSET_POOL_THRESH; memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams)); if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, (uint8_t*)&msg, sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams), NULL, NULL, NULL, NULL)) != E_OK) RETURN_ERROR(MAJOR, errCode, NO_MSG); return E_OK; } else RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC")); } uint32_t BmGetCounter(t_Handle h_Bm, e_BmInterModuleCounters counter, uint8_t bpid) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE, 0); SANITY_CHECK_RETURN_VALUE((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) || (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE, 0); if ((p_Bm->guestId == NCSW_MASTER_ID) || (!p_Bm->h_Session && p_Bm->p_BmRegs)) { switch(counter) { case(e_BM_IM_COUNTERS_POOL_CONTENT): return GET_UINT32(p_Bm->p_BmRegs->content[bpid]); case(e_BM_IM_COUNTERS_POOL_SW_DEPLETION): return GET_UINT32(p_Bm->p_BmRegs->sdcnt[bpid]); case(e_BM_IM_COUNTERS_POOL_HW_DEPLETION): return GET_UINT32(p_Bm->p_BmRegs->hdcnt[bpid]); case(e_BM_IM_COUNTERS_FBPR): return GET_UINT32(p_Bm->p_BmRegs->fbpr_fpc); default: break; } /* should never get here */ ASSERT_COND(FALSE); } else if (p_Bm->h_Session) { t_BmIpcMsg msg; t_BmIpcReply reply; t_BmIpcGetCounter ipcCounter; uint32_t replyLength; uint32_t count; t_Error errCode = E_OK; memset(&msg, 0, sizeof(t_BmIpcMsg)); memset(&reply, 0, sizeof(t_BmIpcReply)); ipcCounter.bpid = bpid; ipcCounter.enumId = (uint32_t)counter; msg.msgId = BM_GET_COUNTER; memcpy(msg.msgBody, &ipcCounter, sizeof(t_BmIpcGetCounter)); replyLength = sizeof(uint32_t) + sizeof(uint32_t); if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, (uint8_t*)&msg, sizeof(msg.msgId) + sizeof(t_BmIpcGetCounter), (uint8_t*)&reply, &replyLength, NULL, NULL)) != E_OK) REPORT_ERROR(MAJOR, errCode, NO_MSG); if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) { REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); errCode = E_INVALID_VALUE; } if (errCode == E_OK) { memcpy((uint8_t*)&count, reply.replyBody, sizeof(uint32_t)); return count; } } else REPORT_ERROR(WARNING, E_NOT_SUPPORTED, ("In 'guest', either IPC or 'baseAddress' is required!")); return 0; } t_Error BmGetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo) { t_Bm *p_Bm = (t_Bm*)h_Bm; uint32_t tmpReg; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER); SANITY_CHECK_RETURN_ERROR((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) || (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE); if ((p_Bm->guestId == NCSW_MASTER_ID) || (!p_Bm->h_Session && p_Bm->p_BmRegs)) { /* read revision register 1 */ tmpReg = GET_UINT32(p_Bm->p_BmRegs->ip_rev_1); p_BmRevisionInfo->majorRev = (uint8_t)((tmpReg & REV1_MAJOR_MASK) >> REV1_MAJOR_SHIFT); p_BmRevisionInfo->minorRev = (uint8_t)((tmpReg & REV1_MINOR_MASK) >> REV1_MINOR_SHIFT); } else if (p_Bm->h_Session) { t_BmIpcMsg msg; t_BmIpcReply reply; t_BmIpcRevisionInfo ipcRevInfo; uint32_t replyLength; t_Error errCode = E_OK; memset(&msg, 0, sizeof(t_BmIpcMsg)); memset(&reply, 0, sizeof(t_BmIpcReply)); msg.msgId = BM_GET_REVISION; replyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo); if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, (uint8_t*)&msg, sizeof(msg.msgId), (uint8_t*)&reply, &replyLength, NULL, NULL)) != E_OK) RETURN_ERROR(MAJOR, errCode, NO_MSG); if (replyLength != (sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo))) RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_BmIpcRevisionInfo)); p_BmRevisionInfo->majorRev = ipcRevInfo.majorRev; p_BmRevisionInfo->minorRev = ipcRevInfo.minorRev; return (t_Error)(reply.error); } else RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("In 'guest', either IPC or 'baseAddress' is required!")); return E_OK; } static void FreeInitResources(t_Bm *p_Bm) { if (p_Bm->p_FbprBase) XX_FreeSmart(p_Bm->p_FbprBase); if (p_Bm->h_Session) XX_IpcFreeSession(p_Bm->h_Session); if (p_Bm->h_BpidMm) MM_Free(p_Bm->h_BpidMm); } /****************************************/ /* API Init unit functions */ /****************************************/ t_Handle BM_Config(t_BmParam *p_BmParam) { t_Bm *p_Bm; SANITY_CHECK_RETURN_VALUE(p_BmParam, E_INVALID_HANDLE, NULL); p_Bm = (t_Bm *)XX_Malloc(sizeof(t_Bm)); if (!p_Bm) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM obj!!!")); return NULL; } memset(p_Bm, 0, sizeof(t_Bm)); p_Bm->p_BmDriverParams = (t_BmDriverParams *)XX_Malloc(sizeof(t_BmDriverParams)); if (!p_Bm->p_BmDriverParams) { XX_Free(p_Bm); REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm driver parameters")); return NULL; } memset(p_Bm->p_BmDriverParams, 0, sizeof(t_BmDriverParams)); p_Bm->guestId = p_BmParam->guestId; p_Bm->p_BmDriverParams->partNumOfPools = p_BmParam->partNumOfPools; p_Bm->p_BmDriverParams->partBpidBase = p_BmParam->partBpidBase; p_Bm->p_BmRegs = (t_BmRegs *)UINT_TO_PTR(p_BmParam->baseAddress); if (p_Bm->guestId == NCSW_MASTER_ID) { p_Bm->exceptions = DEFAULT_exceptions; p_Bm->f_Exception = p_BmParam->f_Exception; p_Bm->h_App = p_BmParam->h_App; p_Bm->errIrq = p_BmParam->errIrq; p_Bm->p_BmDriverParams->totalNumOfBuffers = p_BmParam->totalNumOfBuffers; p_Bm->p_BmDriverParams->fbprMemPartitionId = p_BmParam->fbprMemPartitionId; p_Bm->p_BmDriverParams->fbprThreshold = DEFAULT_fbprThreshold; p_Bm->p_BmDriverParams->liodn = p_BmParam->liodn; } /* build the BM partition IPC address */ memset(p_Bm->moduleName, 0, MODULE_NAME_SIZE); if(Sprint (p_Bm->moduleName, "BM_0_%d",p_Bm->guestId) != (p_Bm->guestId<10 ? 6:7)) { XX_Free(p_Bm->p_BmDriverParams); XX_Free(p_Bm); REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); return NULL; } return p_Bm; } t_Error BM_Init(t_Handle h_Bm) { t_Bm *p_Bm = (t_Bm *)h_Bm; t_Error err; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); CHECK_INIT_PARAMETERS(p_Bm, CheckBmParameters); if (p_Bm->p_BmDriverParams->partNumOfPools) if (MM_Init(&p_Bm->h_BpidMm, p_Bm->p_BmDriverParams->partBpidBase, p_Bm->p_BmDriverParams->partNumOfPools) != E_OK) { FreeInitResources(p_Bm); RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("BM-BPIDS-MEM partition!!!")); } if (p_Bm->guestId == NCSW_MASTER_ID) { uint64_t phyAddr; t_BmRevisionInfo revInfo; uint32_t dsSize, exp; BmGetRevision(p_Bm, &revInfo); DBG(TRACE, ("Bman ver:%02x,%02x", revInfo.majorRev, revInfo.minorRev)); WRITE_UINT32(p_Bm->p_BmRegs->liodnr, (uint16_t)p_Bm->p_BmDriverParams->liodn); /* FBPR memory */ dsSize = (uint32_t)(p_Bm->p_BmDriverParams->totalNumOfBuffers * (FBPR_ENTRY_SIZE / 8)); LOG2(dsSize, exp); if (!POWER_OF_2(dsSize)) (exp++); dsSize = (uint32_t)(1 << exp); if (dsSize < (4*KILOBYTE)) { dsSize = (4*KILOBYTE); LOG2(dsSize, exp); } p_Bm->p_FbprBase = XX_MallocSmart(dsSize, (int)p_Bm->p_BmDriverParams->fbprMemPartitionId, dsSize); if (!p_Bm->p_FbprBase) { FreeInitResources(p_Bm); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FBPR obj!!!")); } phyAddr = XX_VirtToPhys(p_Bm->p_FbprBase); WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bare, ((uint32_t)(phyAddr >> 32) & 0xffff)); WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bar, (uint32_t)phyAddr); WRITE_UINT32(p_Bm->p_BmRegs->fbpr_ar, (exp - 1)); WRITE_UINT32(p_Bm->p_BmRegs->fbpr_fp_lwit, p_Bm->p_BmDriverParams->fbprThreshold); WRITE_UINT32(p_Bm->p_BmRegs->err_isr, p_Bm->exceptions); WRITE_UINT32(p_Bm->p_BmRegs->err_ier, p_Bm->exceptions); WRITE_UINT32(p_Bm->p_BmRegs->err_isdr, 0x0); if (p_Bm->errIrq != NO_IRQ) { XX_SetIntr(p_Bm->errIrq, BM_ErrorIsr, p_Bm); XX_EnableIntr(p_Bm->errIrq); } if ((err = XX_IpcRegisterMsgHandler(p_Bm->moduleName, BmHandleIpcMsgCB, p_Bm, BM_IPC_MAX_REPLY_SIZE)) != E_OK) { FreeInitResources(p_Bm); RETURN_ERROR(MAJOR, err, NO_MSG); } } else /* guest mode */ { char masterModuleName[MODULE_NAME_SIZE]; memset(masterModuleName, 0, MODULE_NAME_SIZE); if(Sprint (masterModuleName, "BM_0_%d", NCSW_MASTER_ID) != (NCSW_MASTER_ID<10 ? 6:7)) { FreeInitResources(p_Bm); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); } p_Bm->h_Session = XX_IpcInitSession(masterModuleName, p_Bm->moduleName); if (p_Bm->h_Session) { t_BmIpcMsg msg; uint8_t isMasterAlive = 0; t_BmIpcReply reply; uint32_t replyLength; memset(&msg, 0, sizeof(t_BmIpcMsg)); memset(&reply, 0, sizeof(t_BmIpcReply)); msg.msgId = BM_MASTER_IS_ALIVE; replyLength = sizeof(uint32_t) + sizeof(uint8_t); do { blockingFlag = TRUE; if ((err = XX_IpcSendMessage(p_Bm->h_Session, (uint8_t*)&msg, sizeof(msg.msgId), (uint8_t*)&reply, &replyLength, BmIpcMsgCompletionCB, p_Bm)) != E_OK) REPORT_ERROR(MAJOR, err, NO_MSG); while(blockingFlag) ; if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); isMasterAlive = *(uint8_t*)(reply.replyBody); } while (!isMasterAlive); } } XX_Free(p_Bm->p_BmDriverParams); p_Bm->p_BmDriverParams = NULL; return E_OK; } t_Error BM_Free(t_Handle h_Bm) { t_Bm *p_Bm = (t_Bm *)h_Bm; if (!p_Bm) return ERROR_CODE(E_INVALID_HANDLE); if (p_Bm->guestId == NCSW_MASTER_ID) { XX_IpcUnregisterMsgHandler(p_Bm->moduleName); if (p_Bm->errIrq != NO_IRQ) { XX_DisableIntr(p_Bm->errIrq); XX_FreeIntr(p_Bm->errIrq); } } FreeInitResources(p_Bm); if(p_Bm->p_BmDriverParams) XX_Free(p_Bm->p_BmDriverParams); XX_Free(p_Bm); return E_OK; } t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable) { t_Bm *p_Bm = (t_Bm*)h_Bm; uint32_t bitMask = 0; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); GET_EXCEPTION_FLAG(bitMask, exception); if(bitMask) { if (enable) p_Bm->exceptions |= bitMask; else p_Bm->exceptions &= ~bitMask; } else RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); return E_OK; } t_Error BM_ConfigFbprThreshold(t_Handle h_Bm, uint32_t threshold) { t_Bm *p_Bm = (t_Bm *)h_Bm; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); p_Bm->p_BmDriverParams->fbprThreshold = threshold; return E_OK; } void BM_ErrorIsr(t_Handle h_Bm) { t_Bm *p_Bm = (t_Bm *)h_Bm; uint32_t tmpReg; SANITY_CHECK_RETURN(p_Bm, E_INVALID_HANDLE); if (p_Bm->guestId != NCSW_MASTER_ID) { REPORT_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); return; } tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_isr); tmpReg &= GET_UINT32(p_Bm->p_BmRegs->err_ier); WRITE_UINT32(p_Bm->p_BmRegs->err_isr, tmpReg); if (tmpReg & BM_EX_INVALID_COMMAND) p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_INVALID_COMMAND); if (tmpReg & BM_EX_FBPR_THRESHOLD) p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_FBPR_THRESHOLD); if (tmpReg & BM_EX_MULTI_ECC) p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_MULTI_ECC); if (tmpReg & BM_EX_SINGLE_ECC) p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_SINGLE_ECC); } uint32_t BM_GetCounter(t_Handle h_Bm, e_BmCounters counter) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0); SANITY_CHECK_RETURN_VALUE(!p_Bm->p_BmDriverParams, E_INVALID_STATE, 0); switch(counter) { case(e_BM_COUNTERS_FBPR): return BmGetCounter(p_Bm, e_BM_IM_COUNTERS_FBPR, 0); default: break; } /* should never get here */ ASSERT_COND(FALSE); return 0; } t_Error BM_SetException(t_Handle h_Bm, e_BmExceptions exception, bool enable) { t_Bm *p_Bm = (t_Bm*)h_Bm; uint32_t tmpReg, bitMask = 0; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); if (p_Bm->guestId != NCSW_MASTER_ID) RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); BM_ConfigException(p_Bm, exception, enable); tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_ier); if(enable) tmpReg |= bitMask; else tmpReg &= ~bitMask; WRITE_UINT32(p_Bm->p_BmRegs->err_ier, tmpReg); return E_OK; } t_Error BM_GetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo) { t_Bm *p_Bm = (t_Bm*)h_Bm; SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER); return BmGetRevision(p_Bm, p_BmRevisionInfo); } #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) t_Error BM_DumpRegs(t_Handle h_Bm) { t_Bm *p_Bm = (t_Bm *)h_Bm; DECLARE_DUMP; if (p_Bm->guestId != NCSW_MASTER_ID) RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_Bm->p_BmDriverParams, E_INVALID_STATE); DUMP_SUBTITLE(("\n")); DUMP_TITLE(p_Bm->p_BmRegs, ("BmRegs Regs")); DUMP_ARR(p_Bm->p_BmRegs, swdet); DUMP_ARR(p_Bm->p_BmRegs, hwdet); DUMP_ARR(p_Bm->p_BmRegs, swdxt); DUMP_ARR(p_Bm->p_BmRegs, hwdxt); DUMP_ARR(p_Bm->p_BmRegs, sdcnt); DUMP_ARR(p_Bm->p_BmRegs, hdcnt); DUMP_ARR(p_Bm->p_BmRegs, content); DUMP_ARR(p_Bm->p_BmRegs, hdptr); DUMP_VAR(p_Bm->p_BmRegs,fbpr_fpc); DUMP_VAR(p_Bm->p_BmRegs,fbpr_fp_lwit); DUMP_ARR(p_Bm->p_BmRegs, cmd_pm_cfg); DUMP_ARR(p_Bm->p_BmRegs, fl_pm_cfg); DUMP_VAR(p_Bm->p_BmRegs, ecsr); DUMP_VAR(p_Bm->p_BmRegs, ecir); DUMP_VAR(p_Bm->p_BmRegs, eadr); DUMP_ARR(p_Bm->p_BmRegs, edata); DUMP_VAR(p_Bm->p_BmRegs,sbet); DUMP_VAR(p_Bm->p_BmRegs,efcr); DUMP_VAR(p_Bm->p_BmRegs,efar); DUMP_VAR(p_Bm->p_BmRegs,sbec0); DUMP_VAR(p_Bm->p_BmRegs,sbec1); DUMP_VAR(p_Bm->p_BmRegs,ip_rev_1); DUMP_VAR(p_Bm->p_BmRegs,ip_rev_2); DUMP_VAR(p_Bm->p_BmRegs,fbpr_bare); DUMP_VAR(p_Bm->p_BmRegs,fbpr_bar); DUMP_VAR(p_Bm->p_BmRegs,fbpr_ar); DUMP_VAR(p_Bm->p_BmRegs,srcidr); DUMP_VAR(p_Bm->p_BmRegs,liodnr); DUMP_VAR(p_Bm->p_BmRegs,err_isr); DUMP_VAR(p_Bm->p_BmRegs,err_ier); DUMP_VAR(p_Bm->p_BmRegs,err_isdr); DUMP_VAR(p_Bm->p_BmRegs,err_iir); DUMP_VAR(p_Bm->p_BmRegs,err_ifr); return E_OK; } #endif /* (defined(DEBUG_ERRORS) && ... */