xref: /freebsd/sys/contrib/ncsw/Peripherals/BM/bm.c (revision f81cdf24ba5436367377f7c8e8f51f6df2a75ca7)
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