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;
BmIpcMsgCompletionCB(t_Handle h_Module,uint8_t * p_Msg,uint8_t * p_Reply,uint32_t replyLength,t_Error status)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
BmHandleIpcMsgCB(t_Handle h_Bm,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength)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
CheckBmParameters(t_Bm * p_Bm)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
GenerateThresh(uint32_t val,int roundup)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
BmSetPool(t_Handle h_Bm,uint8_t bpid,uint32_t swdet,uint32_t swdxt,uint32_t hwdet,uint32_t hwdxt)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
BmSetPoolThresholds(t_Handle h_Bm,uint8_t bpid,const uint32_t * thresholds)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
BmUnSetPoolThresholds(t_Handle h_Bm,uint8_t bpid)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
BmGetCounter(t_Handle h_Bm,e_BmInterModuleCounters counter,uint8_t bpid)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
BmGetRevision(t_Handle h_Bm,t_BmRevisionInfo * p_BmRevisionInfo)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
FreeInitResources(t_Bm * p_Bm)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
BM_Config(t_BmParam * p_BmParam)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
BM_Init(t_Handle h_Bm)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
BM_Free(t_Handle h_Bm)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
BM_ConfigException(t_Handle h_Bm,e_BmExceptions exception,bool enable)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
BM_ConfigFbprThreshold(t_Handle h_Bm,uint32_t threshold)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
BM_ErrorIsr(t_Handle h_Bm)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
BM_GetCounter(t_Handle h_Bm,e_BmCounters counter)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
BM_SetException(t_Handle h_Bm,e_BmExceptions exception,bool enable)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
BM_GetRevision(t_Handle h_Bm,t_BmRevisionInfo * p_BmRevisionInfo)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))
BM_DumpRegs(t_Handle h_Bm)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