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
52t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable);
53
54
55/****************************************/
56/*       static functions               */
57/****************************************/
58
59static volatile bool blockingFlag = FALSE;
60static 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
76static 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
181static 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
199static __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
213static 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
237t_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(uintptr_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
278t_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
319uint32_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
389t_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
442static 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
456t_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
508t_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
621t_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
646t_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
668t_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
680void 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
707uint32_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
727t_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
750t_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))
761t_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