1 /****************************************************************************** 2 3 � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc. 4 All rights reserved. 5 6 This is proprietary source code of Freescale Semiconductor Inc., 7 and its use is subject to the NetComm Device Drivers EULA. 8 The copyright notice above does not evidence any actual or intended 9 publication of such source code. 10 11 ALTERNATIVELY, redistribution and use in source and binary forms, with 12 or without modification, are permitted provided that the following 13 conditions are met: 14 * Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 * Redistributions in binary form must reproduce the above copyright 17 notice, this list of conditions and the following disclaimer in the 18 documentation and/or other materials provided with the distribution. 19 * Neither the name of Freescale Semiconductor nor the 20 names of its contributors may be used to endorse or promote products 21 derived from this software without specific prior written permission. 22 23 THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 35 36 **************************************************************************/ 37 /****************************************************************************** 38 @File bm.c 39 40 @Description BM 41 *//***************************************************************************/ 42 #include "error_ext.h" 43 #include "std_ext.h" 44 #include "string_ext.h" 45 #include "sprint_ext.h" 46 #include "debug_ext.h" 47 #include "mm_ext.h" 48 49 #include "bm.h" 50 51 52 t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable); 53 54 55 /****************************************/ 56 /* static functions */ 57 /****************************************/ 58 59 static volatile bool blockingFlag = FALSE; 60 static void BmIpcMsgCompletionCB(t_Handle h_Module, 61 uint8_t *p_Msg, 62 uint8_t *p_Reply, 63 uint32_t replyLength, 64 t_Error status) 65 { 66 SANITY_CHECK_RETURN(h_Module, E_INVALID_HANDLE); 67 68 #ifdef DISABLE_SANITY_CHECKS 69 UNUSED(h_Module); 70 #endif /* DISABLE_SANITY_CHECKS */ 71 UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); 72 73 blockingFlag = FALSE; 74 } 75 76 static t_Error BmHandleIpcMsgCB(t_Handle h_Bm, 77 uint8_t *p_Msg, 78 uint32_t msgLength, 79 uint8_t *p_Reply, 80 uint32_t *p_ReplyLength) 81 { 82 t_Bm *p_Bm = (t_Bm*)h_Bm; 83 t_BmIpcMsg *p_IpcMsg = (t_BmIpcMsg*)p_Msg; 84 t_BmIpcReply *p_IpcReply = (t_BmIpcReply *)p_Reply; 85 86 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 87 SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); 88 89 #ifdef DISABLE_SANITY_CHECKS 90 UNUSED(msgLength); 91 #endif /* DISABLE_SANITY_CHECKS */ 92 93 ASSERT_COND(p_IpcMsg); 94 95 memset(p_IpcReply, 0, (sizeof(uint8_t) * BM_IPC_MAX_REPLY_SIZE)); 96 *p_ReplyLength = 0; 97 98 switch(p_IpcMsg->msgId) 99 { 100 case (BM_MASTER_IS_ALIVE): 101 *(uint8_t*)p_IpcReply->replyBody = 1; 102 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); 103 break; 104 case (BM_SET_POOL_THRESH): 105 { 106 t_Error err; 107 t_BmIpcPoolThreshParams ipcPoolThresh; 108 109 memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams)); 110 if ((err = BmSetPoolThresholds(p_Bm, 111 ipcPoolThresh.bpid, 112 ipcPoolThresh.thresholds)) != E_OK) 113 REPORT_ERROR(MINOR, err, NO_MSG); 114 break; 115 } 116 case (BM_UNSET_POOL_THRESH): 117 { 118 t_Error err; 119 t_BmIpcPoolThreshParams ipcPoolThresh; 120 121 memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams)); 122 if ((err = BmUnSetPoolThresholds(p_Bm, 123 ipcPoolThresh.bpid)) != E_OK) 124 REPORT_ERROR(MINOR, err, NO_MSG); 125 break; 126 } 127 case (BM_GET_COUNTER): 128 { 129 t_BmIpcGetCounter ipcCounter; 130 uint32_t count; 131 132 memcpy((uint8_t*)&ipcCounter, p_IpcMsg->msgBody, sizeof(t_BmIpcGetCounter)); 133 count = BmGetCounter(p_Bm, 134 (e_BmInterModuleCounters)ipcCounter.enumId, 135 ipcCounter.bpid); 136 memcpy(p_IpcReply->replyBody, (uint8_t*)&count, sizeof(uint32_t)); 137 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); 138 break; 139 } 140 case (BM_GET_REVISION): 141 { 142 t_BmRevisionInfo revInfo; 143 t_BmIpcRevisionInfo ipcRevInfo; 144 145 p_IpcReply->error = (uint32_t)BmGetRevision(h_Bm, &revInfo); 146 ipcRevInfo.majorRev = revInfo.majorRev; 147 ipcRevInfo.minorRev = revInfo.minorRev; 148 memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_BmIpcRevisionInfo)); 149 *p_ReplyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo); 150 break; 151 } 152 case (BM_FORCE_BPID): 153 { 154 t_BmIpcBpidParams ipcBpid; 155 uint32_t tmp; 156 157 memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams)); 158 tmp = BmBpidGet(p_Bm, TRUE, ipcBpid.bpid); 159 memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t)); 160 *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); 161 break; 162 } 163 case (BM_PUT_BPID): 164 { 165 t_Error err; 166 t_BmIpcBpidParams ipcBpid; 167 168 memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams)); 169 if ((err = BmBpidPut(p_Bm, ipcBpid.bpid)) != E_OK) 170 REPORT_ERROR(MINOR, err, NO_MSG); 171 break; 172 } 173 default: 174 *p_ReplyLength = 0; 175 RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); 176 } 177 178 return E_OK; 179 } 180 181 static t_Error CheckBmParameters(t_Bm *p_Bm) 182 { 183 if ((p_Bm->p_BmDriverParams->partBpidBase + p_Bm->p_BmDriverParams->partNumOfPools) > BM_MAX_NUM_OF_POOLS) 184 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partBpidBase+partNumOfPools out of range!!!")); 185 186 if (p_Bm->guestId == NCSW_MASTER_ID) 187 { 188 if (!p_Bm->p_BmDriverParams->totalNumOfBuffers) 189 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be larger than '0'!!!")); 190 if (p_Bm->p_BmDriverParams->totalNumOfBuffers > (128*MEGABYTE)) 191 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be equal or smaller than 128M!!!")); 192 if(!p_Bm->f_Exception) 193 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); 194 } 195 196 return E_OK; 197 } 198 199 static __inline__ uint32_t GenerateThresh(uint32_t val, int roundup) 200 { 201 uint32_t e = 0; /* co-efficient, exponent */ 202 uint32_t oddbit = 0; 203 while(val > 0xff) { 204 oddbit = val & 1; 205 val >>= 1; 206 e++; 207 if(roundup && oddbit) 208 val++; 209 } 210 return (val | (e << 8)); 211 } 212 213 static t_Error BmSetPool(t_Handle h_Bm, 214 uint8_t bpid, 215 uint32_t swdet, 216 uint32_t swdxt, 217 uint32_t hwdet, 218 uint32_t hwdxt) 219 { 220 t_Bm *p_Bm = (t_Bm*)h_Bm; 221 222 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 223 SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); 224 225 WRITE_UINT32(p_Bm->p_BmRegs->swdet[bpid], GenerateThresh(swdet, 0)); 226 WRITE_UINT32(p_Bm->p_BmRegs->swdxt[bpid], GenerateThresh(swdxt, 1)); 227 WRITE_UINT32(p_Bm->p_BmRegs->hwdet[bpid], GenerateThresh(hwdet, 0)); 228 WRITE_UINT32(p_Bm->p_BmRegs->hwdxt[bpid], GenerateThresh(hwdxt, 1)); 229 230 return E_OK; 231 } 232 233 /****************************************/ 234 /* Inter-Module functions */ 235 /****************************************/ 236 237 t_Error BmSetPoolThresholds(t_Handle h_Bm, uint8_t bpid, const uint32_t *thresholds) 238 { 239 t_Bm *p_Bm = (t_Bm*)h_Bm; 240 241 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 242 SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); 243 244 if (p_Bm->guestId == NCSW_MASTER_ID) 245 { 246 return BmSetPool(h_Bm, 247 bpid, 248 thresholds[0], 249 thresholds[1], 250 thresholds[2], 251 thresholds[3]); 252 } 253 else if (p_Bm->h_Session) 254 { 255 t_BmIpcMsg msg; 256 t_BmIpcPoolThreshParams ipcPoolThresh; 257 t_Error errCode = E_OK; 258 259 memset(&msg, 0, sizeof(t_BmIpcMsg)); 260 ipcPoolThresh.bpid = bpid; 261 memcpy(ipcPoolThresh.thresholds, thresholds, sizeof(uint32_t) * MAX_DEPLETION_THRESHOLDS); 262 msg.msgId = BM_SET_POOL_THRESH; 263 memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams)); 264 if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, 265 (uint8_t*)&msg, 266 sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams), 267 NULL, 268 NULL, 269 NULL, 270 NULL)) != E_OK) 271 RETURN_ERROR(MAJOR, errCode, NO_MSG); 272 return E_OK; 273 } 274 else 275 RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC")); 276 } 277 278 t_Error BmUnSetPoolThresholds(t_Handle h_Bm, uint8_t bpid) 279 { 280 t_Bm *p_Bm = (t_Bm*)h_Bm; 281 282 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 283 SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE); 284 285 if (p_Bm->guestId == NCSW_MASTER_ID) 286 { 287 return BmSetPool(h_Bm, 288 bpid, 289 0, 290 0, 291 0, 292 0); 293 } 294 else if (p_Bm->h_Session) 295 { 296 t_BmIpcMsg msg; 297 t_BmIpcPoolThreshParams ipcPoolThresh; 298 t_Error errCode = E_OK; 299 300 memset(&msg, 0, sizeof(t_BmIpcMsg)); 301 memset(&ipcPoolThresh, 0, sizeof(t_BmIpcPoolThreshParams)); 302 ipcPoolThresh.bpid = bpid; 303 msg.msgId = BM_UNSET_POOL_THRESH; 304 memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams)); 305 if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, 306 (uint8_t*)&msg, 307 sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams), 308 NULL, 309 NULL, 310 NULL, 311 NULL)) != E_OK) 312 RETURN_ERROR(MAJOR, errCode, NO_MSG); 313 return E_OK; 314 } 315 else 316 RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC")); 317 } 318 319 uint32_t BmGetCounter(t_Handle h_Bm, e_BmInterModuleCounters counter, uint8_t bpid) 320 { 321 t_Bm *p_Bm = (t_Bm*)h_Bm; 322 323 SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0); 324 SANITY_CHECK_RETURN_VALUE(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE, 0); 325 SANITY_CHECK_RETURN_VALUE((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) || 326 (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE, 0); 327 328 if ((p_Bm->guestId == NCSW_MASTER_ID) || 329 (!p_Bm->h_Session && p_Bm->p_BmRegs)) 330 { 331 switch(counter) 332 { 333 case(e_BM_IM_COUNTERS_POOL_CONTENT): 334 return GET_UINT32(p_Bm->p_BmRegs->content[bpid]); 335 case(e_BM_IM_COUNTERS_POOL_SW_DEPLETION): 336 return GET_UINT32(p_Bm->p_BmRegs->sdcnt[bpid]); 337 case(e_BM_IM_COUNTERS_POOL_HW_DEPLETION): 338 return GET_UINT32(p_Bm->p_BmRegs->hdcnt[bpid]); 339 case(e_BM_IM_COUNTERS_FBPR): 340 return GET_UINT32(p_Bm->p_BmRegs->fbpr_fpc); 341 default: 342 break; 343 } 344 /* should never get here */ 345 ASSERT_COND(FALSE); 346 } 347 else if (p_Bm->h_Session) 348 { 349 t_BmIpcMsg msg; 350 t_BmIpcReply reply; 351 t_BmIpcGetCounter ipcCounter; 352 uint32_t replyLength; 353 uint32_t count; 354 t_Error errCode = E_OK; 355 356 memset(&msg, 0, sizeof(t_BmIpcMsg)); 357 memset(&reply, 0, sizeof(t_BmIpcReply)); 358 ipcCounter.bpid = bpid; 359 ipcCounter.enumId = (uint32_t)counter; 360 msg.msgId = BM_GET_COUNTER; 361 memcpy(msg.msgBody, &ipcCounter, sizeof(t_BmIpcGetCounter)); 362 replyLength = sizeof(uint32_t) + sizeof(uint32_t); 363 if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, 364 (uint8_t*)&msg, 365 sizeof(msg.msgId) + sizeof(t_BmIpcGetCounter), 366 (uint8_t*)&reply, 367 &replyLength, 368 NULL, 369 NULL)) != E_OK) 370 REPORT_ERROR(MAJOR, errCode, NO_MSG); 371 if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) 372 { 373 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 374 errCode = E_INVALID_VALUE; 375 } 376 if (errCode == E_OK) 377 { 378 memcpy((uint8_t*)&count, reply.replyBody, sizeof(uint32_t)); 379 return count; 380 } 381 } 382 else 383 REPORT_ERROR(WARNING, E_NOT_SUPPORTED, 384 ("In 'guest', either IPC or 'baseAddress' is required!")); 385 386 return 0; 387 } 388 389 t_Error BmGetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo) 390 { 391 t_Bm *p_Bm = (t_Bm*)h_Bm; 392 uint32_t tmpReg; 393 394 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 395 SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER); 396 SANITY_CHECK_RETURN_ERROR((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) || 397 (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE); 398 399 if ((p_Bm->guestId == NCSW_MASTER_ID) || 400 (!p_Bm->h_Session && p_Bm->p_BmRegs)) 401 { 402 /* read revision register 1 */ 403 tmpReg = GET_UINT32(p_Bm->p_BmRegs->ip_rev_1); 404 p_BmRevisionInfo->majorRev = (uint8_t)((tmpReg & REV1_MAJOR_MASK) >> REV1_MAJOR_SHIFT); 405 p_BmRevisionInfo->minorRev = (uint8_t)((tmpReg & REV1_MINOR_MASK) >> REV1_MINOR_SHIFT); 406 } 407 else if (p_Bm->h_Session) 408 { 409 t_BmIpcMsg msg; 410 t_BmIpcReply reply; 411 t_BmIpcRevisionInfo ipcRevInfo; 412 uint32_t replyLength; 413 t_Error errCode = E_OK; 414 415 memset(&msg, 0, sizeof(t_BmIpcMsg)); 416 memset(&reply, 0, sizeof(t_BmIpcReply)); 417 msg.msgId = BM_GET_REVISION; 418 replyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo); 419 if ((errCode = XX_IpcSendMessage(p_Bm->h_Session, 420 (uint8_t*)&msg, 421 sizeof(msg.msgId), 422 (uint8_t*)&reply, 423 &replyLength, 424 NULL, 425 NULL)) != E_OK) 426 RETURN_ERROR(MAJOR, errCode, NO_MSG); 427 if (replyLength != (sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo))) 428 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 429 430 memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_BmIpcRevisionInfo)); 431 p_BmRevisionInfo->majorRev = ipcRevInfo.majorRev; 432 p_BmRevisionInfo->minorRev = ipcRevInfo.minorRev; 433 return (t_Error)(reply.error); 434 } 435 else 436 RETURN_ERROR(WARNING, E_NOT_SUPPORTED, 437 ("In 'guest', either IPC or 'baseAddress' is required!")); 438 439 return E_OK; 440 } 441 442 static void FreeInitResources(t_Bm *p_Bm) 443 { 444 if (p_Bm->p_FbprBase) 445 XX_FreeSmart(p_Bm->p_FbprBase); 446 if (p_Bm->h_Session) 447 XX_IpcFreeSession(p_Bm->h_Session); 448 if (p_Bm->h_BpidMm) 449 MM_Free(p_Bm->h_BpidMm); 450 } 451 452 /****************************************/ 453 /* API Init unit functions */ 454 /****************************************/ 455 456 t_Handle BM_Config(t_BmParam *p_BmParam) 457 { 458 t_Bm *p_Bm; 459 460 SANITY_CHECK_RETURN_VALUE(p_BmParam, E_INVALID_HANDLE, NULL); 461 462 p_Bm = (t_Bm *)XX_Malloc(sizeof(t_Bm)); 463 if (!p_Bm) 464 { 465 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM obj!!!")); 466 return NULL; 467 } 468 memset(p_Bm, 0, sizeof(t_Bm)); 469 470 p_Bm->p_BmDriverParams = (t_BmDriverParams *)XX_Malloc(sizeof(t_BmDriverParams)); 471 if (!p_Bm->p_BmDriverParams) 472 { 473 XX_Free(p_Bm); 474 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm driver parameters")); 475 return NULL; 476 } 477 memset(p_Bm->p_BmDriverParams, 0, sizeof(t_BmDriverParams)); 478 479 p_Bm->guestId = p_BmParam->guestId; 480 p_Bm->p_BmDriverParams->partNumOfPools = p_BmParam->partNumOfPools; 481 p_Bm->p_BmDriverParams->partBpidBase = p_BmParam->partBpidBase; 482 p_Bm->p_BmRegs = (t_BmRegs *)UINT_TO_PTR(p_BmParam->baseAddress); 483 484 if (p_Bm->guestId == NCSW_MASTER_ID) 485 { 486 p_Bm->exceptions = DEFAULT_exceptions; 487 p_Bm->f_Exception = p_BmParam->f_Exception; 488 p_Bm->h_App = p_BmParam->h_App; 489 p_Bm->errIrq = p_BmParam->errIrq; 490 p_Bm->p_BmDriverParams->totalNumOfBuffers = p_BmParam->totalNumOfBuffers; 491 p_Bm->p_BmDriverParams->fbprMemPartitionId = p_BmParam->fbprMemPartitionId; 492 p_Bm->p_BmDriverParams->fbprThreshold = DEFAULT_fbprThreshold; 493 p_Bm->p_BmDriverParams->liodn = p_BmParam->liodn; 494 495 } 496 /* build the BM partition IPC address */ 497 memset(p_Bm->moduleName, 0, MODULE_NAME_SIZE); 498 if(Sprint (p_Bm->moduleName, "BM_0_%d",p_Bm->guestId) != (p_Bm->guestId<10 ? 6:7)) 499 { 500 XX_Free(p_Bm->p_BmDriverParams); 501 XX_Free(p_Bm); 502 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 503 return NULL; 504 } 505 return p_Bm; 506 } 507 508 t_Error BM_Init(t_Handle h_Bm) 509 { 510 t_Bm *p_Bm = (t_Bm *)h_Bm; 511 t_Error err; 512 513 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 514 SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); 515 516 CHECK_INIT_PARAMETERS(p_Bm, CheckBmParameters); 517 518 if (p_Bm->p_BmDriverParams->partNumOfPools) 519 if (MM_Init(&p_Bm->h_BpidMm, p_Bm->p_BmDriverParams->partBpidBase, p_Bm->p_BmDriverParams->partNumOfPools) != E_OK) 520 { 521 FreeInitResources(p_Bm); 522 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("BM-BPIDS-MEM partition!!!")); 523 } 524 525 if (p_Bm->guestId == NCSW_MASTER_ID) 526 { 527 uint64_t phyAddr; 528 t_BmRevisionInfo revInfo; 529 uint32_t dsSize, exp; 530 531 BmGetRevision(p_Bm, &revInfo); 532 DBG(TRACE, ("Bman ver:%02x,%02x", revInfo.majorRev, revInfo.minorRev)); 533 534 WRITE_UINT32(p_Bm->p_BmRegs->liodnr, (uint16_t)p_Bm->p_BmDriverParams->liodn); 535 536 /* FBPR memory */ 537 dsSize = (uint32_t)(p_Bm->p_BmDriverParams->totalNumOfBuffers * (FBPR_ENTRY_SIZE / 8)); 538 LOG2(dsSize, exp); 539 if (!POWER_OF_2(dsSize)) (exp++); 540 dsSize = (uint32_t)(1 << exp); 541 if (dsSize < (4*KILOBYTE)) 542 { 543 dsSize = (4*KILOBYTE); 544 LOG2(dsSize, exp); 545 } 546 p_Bm->p_FbprBase = XX_MallocSmart(dsSize, (int)p_Bm->p_BmDriverParams->fbprMemPartitionId, dsSize); 547 if (!p_Bm->p_FbprBase) 548 { 549 FreeInitResources(p_Bm); 550 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FBPR obj!!!")); 551 } 552 phyAddr = XX_VirtToPhys(p_Bm->p_FbprBase); 553 WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bare, ((uint32_t)(phyAddr >> 32) & 0xffff)); 554 WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bar, (uint32_t)phyAddr); 555 WRITE_UINT32(p_Bm->p_BmRegs->fbpr_ar, (exp - 1)); 556 557 WRITE_UINT32(p_Bm->p_BmRegs->fbpr_fp_lwit, p_Bm->p_BmDriverParams->fbprThreshold); 558 WRITE_UINT32(p_Bm->p_BmRegs->err_isr, p_Bm->exceptions); 559 WRITE_UINT32(p_Bm->p_BmRegs->err_ier, p_Bm->exceptions); 560 WRITE_UINT32(p_Bm->p_BmRegs->err_isdr, 0x0); 561 if (p_Bm->errIrq != NO_IRQ) 562 { 563 XX_SetIntr(p_Bm->errIrq, BM_ErrorIsr, p_Bm); 564 XX_EnableIntr(p_Bm->errIrq); 565 } 566 567 if ((err = XX_IpcRegisterMsgHandler(p_Bm->moduleName, BmHandleIpcMsgCB, p_Bm, BM_IPC_MAX_REPLY_SIZE)) != E_OK) 568 { 569 FreeInitResources(p_Bm); 570 RETURN_ERROR(MAJOR, err, NO_MSG); 571 } 572 } 573 else /* guest mode */ 574 { 575 char masterModuleName[MODULE_NAME_SIZE]; 576 577 memset(masterModuleName, 0, MODULE_NAME_SIZE); 578 if(Sprint (masterModuleName, "BM_0_%d", NCSW_MASTER_ID) != (NCSW_MASTER_ID<10 ? 6:7)) 579 { 580 FreeInitResources(p_Bm); 581 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 582 } 583 584 p_Bm->h_Session = XX_IpcInitSession(masterModuleName, p_Bm->moduleName); 585 if (p_Bm->h_Session) 586 { 587 t_BmIpcMsg msg; 588 uint8_t isMasterAlive = 0; 589 t_BmIpcReply reply; 590 uint32_t replyLength; 591 592 memset(&msg, 0, sizeof(t_BmIpcMsg)); 593 memset(&reply, 0, sizeof(t_BmIpcReply)); 594 msg.msgId = BM_MASTER_IS_ALIVE; 595 replyLength = sizeof(uint32_t) + sizeof(uint8_t); 596 do 597 { 598 blockingFlag = TRUE; 599 if ((err = XX_IpcSendMessage(p_Bm->h_Session, 600 (uint8_t*)&msg, 601 sizeof(msg.msgId), 602 (uint8_t*)&reply, 603 &replyLength, 604 BmIpcMsgCompletionCB, 605 p_Bm)) != E_OK) 606 REPORT_ERROR(MAJOR, err, NO_MSG); 607 while(blockingFlag) ; 608 if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) 609 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 610 isMasterAlive = *(uint8_t*)(reply.replyBody); 611 } while (!isMasterAlive); 612 } 613 } 614 615 XX_Free(p_Bm->p_BmDriverParams); 616 p_Bm->p_BmDriverParams = NULL; 617 618 return E_OK; 619 } 620 621 t_Error BM_Free(t_Handle h_Bm) 622 { 623 t_Bm *p_Bm = (t_Bm *)h_Bm; 624 625 if (!p_Bm) 626 return ERROR_CODE(E_INVALID_HANDLE); 627 628 if (p_Bm->guestId == NCSW_MASTER_ID) 629 { 630 XX_IpcUnregisterMsgHandler(p_Bm->moduleName); 631 if (p_Bm->errIrq != NO_IRQ) 632 { 633 XX_DisableIntr(p_Bm->errIrq); 634 XX_FreeIntr(p_Bm->errIrq); 635 } 636 } 637 FreeInitResources(p_Bm); 638 639 if(p_Bm->p_BmDriverParams) 640 XX_Free(p_Bm->p_BmDriverParams); 641 642 XX_Free(p_Bm); 643 return E_OK; 644 } 645 646 t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable) 647 { 648 t_Bm *p_Bm = (t_Bm*)h_Bm; 649 uint32_t bitMask = 0; 650 651 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 652 SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); 653 654 GET_EXCEPTION_FLAG(bitMask, exception); 655 if(bitMask) 656 { 657 if (enable) 658 p_Bm->exceptions |= bitMask; 659 else 660 p_Bm->exceptions &= ~bitMask; 661 } 662 else 663 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); 664 665 return E_OK; 666 } 667 668 t_Error BM_ConfigFbprThreshold(t_Handle h_Bm, uint32_t threshold) 669 { 670 t_Bm *p_Bm = (t_Bm *)h_Bm; 671 672 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 673 SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE); 674 675 p_Bm->p_BmDriverParams->fbprThreshold = threshold; 676 677 return E_OK; 678 } 679 680 void BM_ErrorIsr(t_Handle h_Bm) 681 { 682 t_Bm *p_Bm = (t_Bm *)h_Bm; 683 uint32_t tmpReg; 684 685 SANITY_CHECK_RETURN(p_Bm, E_INVALID_HANDLE); 686 687 if (p_Bm->guestId != NCSW_MASTER_ID) 688 { 689 REPORT_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); 690 return; 691 } 692 693 tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_isr); 694 tmpReg &= GET_UINT32(p_Bm->p_BmRegs->err_ier); 695 WRITE_UINT32(p_Bm->p_BmRegs->err_isr, tmpReg); 696 697 if (tmpReg & BM_EX_INVALID_COMMAND) 698 p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_INVALID_COMMAND); 699 if (tmpReg & BM_EX_FBPR_THRESHOLD) 700 p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_FBPR_THRESHOLD); 701 if (tmpReg & BM_EX_MULTI_ECC) 702 p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_MULTI_ECC); 703 if (tmpReg & BM_EX_SINGLE_ECC) 704 p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_SINGLE_ECC); 705 } 706 707 uint32_t BM_GetCounter(t_Handle h_Bm, e_BmCounters counter) 708 { 709 t_Bm *p_Bm = (t_Bm*)h_Bm; 710 711 SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0); 712 SANITY_CHECK_RETURN_VALUE(!p_Bm->p_BmDriverParams, E_INVALID_STATE, 0); 713 714 switch(counter) 715 { 716 case(e_BM_COUNTERS_FBPR): 717 return BmGetCounter(p_Bm, e_BM_IM_COUNTERS_FBPR, 0); 718 default: 719 break; 720 } 721 /* should never get here */ 722 ASSERT_COND(FALSE); 723 724 return 0; 725 } 726 727 t_Error BM_SetException(t_Handle h_Bm, e_BmExceptions exception, bool enable) 728 { 729 t_Bm *p_Bm = (t_Bm*)h_Bm; 730 uint32_t tmpReg, bitMask = 0; 731 732 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 733 734 if (p_Bm->guestId != NCSW_MASTER_ID) 735 RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); 736 737 BM_ConfigException(p_Bm, exception, enable); 738 739 tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_ier); 740 741 if(enable) 742 tmpReg |= bitMask; 743 else 744 tmpReg &= ~bitMask; 745 WRITE_UINT32(p_Bm->p_BmRegs->err_ier, tmpReg); 746 747 return E_OK; 748 } 749 750 t_Error BM_GetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo) 751 { 752 t_Bm *p_Bm = (t_Bm*)h_Bm; 753 754 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 755 SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER); 756 757 return BmGetRevision(p_Bm, p_BmRevisionInfo); 758 } 759 760 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 761 t_Error BM_DumpRegs(t_Handle h_Bm) 762 { 763 t_Bm *p_Bm = (t_Bm *)h_Bm; 764 765 DECLARE_DUMP; 766 767 if (p_Bm->guestId != NCSW_MASTER_ID) 768 RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only")); 769 770 SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE); 771 SANITY_CHECK_RETURN_ERROR(!p_Bm->p_BmDriverParams, E_INVALID_STATE); 772 773 DUMP_SUBTITLE(("\n")); 774 775 DUMP_TITLE(p_Bm->p_BmRegs, ("BmRegs Regs")); 776 777 DUMP_ARR(p_Bm->p_BmRegs, swdet); 778 DUMP_ARR(p_Bm->p_BmRegs, hwdet); 779 DUMP_ARR(p_Bm->p_BmRegs, swdxt); 780 DUMP_ARR(p_Bm->p_BmRegs, hwdxt); 781 DUMP_ARR(p_Bm->p_BmRegs, sdcnt); 782 DUMP_ARR(p_Bm->p_BmRegs, hdcnt); 783 DUMP_ARR(p_Bm->p_BmRegs, content); 784 DUMP_ARR(p_Bm->p_BmRegs, hdptr); 785 786 DUMP_VAR(p_Bm->p_BmRegs,fbpr_fpc); 787 DUMP_VAR(p_Bm->p_BmRegs,fbpr_fp_lwit); 788 789 DUMP_ARR(p_Bm->p_BmRegs, cmd_pm_cfg); 790 DUMP_ARR(p_Bm->p_BmRegs, fl_pm_cfg); 791 DUMP_VAR(p_Bm->p_BmRegs, ecsr); 792 DUMP_VAR(p_Bm->p_BmRegs, ecir); 793 DUMP_VAR(p_Bm->p_BmRegs, eadr); 794 DUMP_ARR(p_Bm->p_BmRegs, edata); 795 DUMP_VAR(p_Bm->p_BmRegs,sbet); 796 DUMP_VAR(p_Bm->p_BmRegs,efcr); 797 DUMP_VAR(p_Bm->p_BmRegs,efar); 798 DUMP_VAR(p_Bm->p_BmRegs,sbec0); 799 DUMP_VAR(p_Bm->p_BmRegs,sbec1); 800 DUMP_VAR(p_Bm->p_BmRegs,ip_rev_1); 801 DUMP_VAR(p_Bm->p_BmRegs,ip_rev_2); 802 DUMP_VAR(p_Bm->p_BmRegs,fbpr_bare); 803 DUMP_VAR(p_Bm->p_BmRegs,fbpr_bar); 804 DUMP_VAR(p_Bm->p_BmRegs,fbpr_ar); 805 DUMP_VAR(p_Bm->p_BmRegs,srcidr); 806 DUMP_VAR(p_Bm->p_BmRegs,liodnr); 807 DUMP_VAR(p_Bm->p_BmRegs,err_isr); 808 DUMP_VAR(p_Bm->p_BmRegs,err_ier); 809 DUMP_VAR(p_Bm->p_BmRegs,err_isdr); 810 DUMP_VAR(p_Bm->p_BmRegs,err_iir); 811 DUMP_VAR(p_Bm->p_BmRegs,err_ifr); 812 813 return E_OK; 814 } 815 #endif /* (defined(DEBUG_ERRORS) && ... */ 816