Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/ncsw/Peripherals/BM/bm.c
48375 views
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
817