blob: 6ddfd6613190911849d61f5cc98f366953b5e9b8 [file] [log] [blame]
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Prasanna Kumarf6c94ae2013-04-11 20:05:21 -07005 */
6/*===========================================================================
7 EDIT HISTORY FOR FILE
8
9 This section contains comments describing changes made to the module.
10 Notice that changes are listed in reverse chronological order.
11
12 $Header:$ $DateTime: $ $Author: $
13
14 when who what, where, why
15 -------- --- -----------------------------------------------------
16 04/10/13 kumarpra nv parser creation
17===========================================================================*/
18
19#include <linux/string.h>
20#include "wlan_nv.h"
21
22/*
23 * NV stream layer service
24 */
25#include "wlan_nv_stream.h"
26#include "wlan_nv_template_internal.h"
27#include "wlan_nv_parser_internal.h"
28#include "wlan_nv_template_api.h"
29#include "wlan_nv_template_builtin.h"
30
31#define _RECURSIVE_DATA_TABLE_PARSING
32// Recursive/iterative switch !! Default iterative
33#define _RECURSIVE_VERSION
34
35/*
36 * Build process should have created the built-in templates in
37 * "wlan_nv_templateBuiltIn.c"
38 * Include its auto-generated companion header file
39 * "wlan_nv_templateBuiltIn.h"
40 *
41 * The main definitions are
42 * _NV_TEMPLATE_TABLE NvTablesBuiltIn[];
43 *
44 */
45
46/*
47 * Parsing control bitmap
48 */
49tANI_U32 gNVParsingControlLo;
50static int subTableSize;
51static int fieldSize;
52static sHalNv *gpnvData_t;
53/* store enum comparison results*/
54static _ENUM_META_DATA enumMetaDataFromBin[INDEX_ENUM_MAX];
55
56
57/*
58 * This data copy logic ignores the enum or int data types,
59 * but simply copy the whole chunk to the NV data structure
60 */
61typedef struct {
62 int idxSubFromBin;
63 int idxSubBuiltin;
64} _SUBTABLES_QUEUE;
65
66pF_NumElemBasedOnStorageType numElemBasedOnStorageType[] = {
67 numElemSingular, // SINGULAR=0
68 numElemArray1, // ARRAY_1=1
69 numElemArray2, // ARRAY_2=2
70 numElemArray3, // ARRAY_3=3
71};
72
73static int sizeOneElemBasedOnFieldIdBasicDataType[] = {
74 1, // _FIELD_ID_DATA_TYPE_U8 =0
75 4, // _FIELD_ID_DATA_TYPE_U32
76 1, // _FIELD_ID_DATA_TYPE_S8
77 4, // _FIELD_ID_DATA_TYPE_S32
78 2, // _FIELD_ID_DATA_TYPE_U16
79 2, // _FIELD_ID_DATA_TYPE_S16
80};
81
82static _NV_STREAM_BUF nvStream[_NV_STREAM_LEN_MAX];
83static int subTableRd, subTableWr;
84
85#if !defined(_RECURSIVE_VERSION)
86#define _SUBTABLES_MAX 32
87static _SUBTABLES_QUEUE subTablesQueue[_SUBTABLES_MAX];
88#endif
89
90/*==============================================================================
91*
92* Storage for NvTablesFromBin
93*
94*===============================================================================
95*/
96
97/*
98 * Init NvTablesFromBin
99 * All entries are initialized to 0, pointers to NULL
100*/
101
102_NV_TEMPLATE_TABLE NvTablesFromBin[TABLES_MAX][TABLE_ENTRIES_MAX] = {
103 { /* TABLE_LAST*/
104 {{nul}, 0, 0, 0, 0, 0, 0, {nul}},
105 },
106};
107
108static void initNvTablesFromBin(void)
109{
110 int i, j;
111
112 for (i = 0; i < TABLES_MAX; i++) {
113 for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
114 NvTablesFromBin[i][j].fieldName[0] = nul;
115 NvTablesFromBin[i][j].fieldName[1] = nul;
116 NvTablesFromBin[i][j].fieldName[2] = nul;
117 NvTablesFromBin[i][j].fieldId = 0;
118 NvTablesFromBin[i][j].fieldStorageType = 0;
119 NvTablesFromBin[i][j].fieldStorageSize1 = 0;
120 NvTablesFromBin[i][j].fieldStorageSize2 = 0;
121 NvTablesFromBin[i][j].fieldStorageSize3 = 0;
122 NvTablesFromBin[i][j].offset = 0;
123 NvTablesFromBin[i][j].fieldFullName[0] = nul;
124 NvTablesFromBin[i][j].fieldFullName[1] = nul;
125 NvTablesFromBin[i][j].fieldFullName[2] = nul;
126 }
127 }
128
129 return;
130}
131
132/*==============================================================================
133*
134* Storage for NvEnumsFromBin
135*
136* ==============================================================================
137*/
138
139/*
140 * Prepare the NV enum templates storage parsed from nv.bin
141 * They are used later for parsing the nv.bin data
142 * All entries are initialized to 0, pointers to NULL
143 */
144
145_NV_TEMPLATE_ENUM NvEnumsFromBin[INDEX_ENUM_MAX][ENUM_ENTRIES_MAX] = {
146 { /* INDEX_ENUM_LAST */
147 {{nul}, 0, 0, {nul}},
148 },
149};
150
151static void initNvEnumsFromBin(void)
152{
153 int i, j;
154
155 for(i = 0; i < INDEX_ENUM_MAX; i++) {
156 for(j = 0; j < ENUM_ENTRIES_MAX; j++) {
157 NvEnumsFromBin[i][j].enumName[0] = nul;
158 NvEnumsFromBin[i][j].enumName[1] = nul;
159 NvEnumsFromBin[i][j].enumName[2] = nul;
160 NvEnumsFromBin[i][j].enumValue = 0;
161 NvEnumsFromBin[i][j].enumValuePeer = 0xFF;
162 NvEnumsFromBin[i][j].enumFullName[0] = nul;
163 }
164 }
165 return;
166}
167
168
169// =============================================================================
170//
171// Parse template streams
172//
173// =============================================================================
174
175/*
176 * Read nv.bin to extract the template info
177 * _NV_TEMPLATE_TABLE NvTablesFromBin[];
178 */
179
180/*
181 * Parse nv.bin data and extract to the build-in data storage
182 *
183 * There are two outcomes from earlier templates comparison operation.
184 * different or identical
185 * If identical, this operation will most likely take place.
186 * If different,
187 * One is to simply indicate to the user and abort reading the nv.bin data
188 * The other is to continue this operation, and extract the matching entries
189 * in nv.bin
190 */
191
192/*
193 * The template based NV logic:
194 * - the s/w module has the built-in templates
195 * - nv.bin is read one stream at a time, sequentially from beginning to end
196 * - if the stream is an enum stream,
197 * - add to nv.bin template data structure
198 * - compare with the built in template, by the string ID
199 * - if two match, move on
200 * - if not match, indicate mismatch, act based on the global logic
201 * _ selection
202 * - if abort, exit here
203 * - if extract-matching-ones,
204 * - copy the enum from the built-in template over to a separate
205 * _ column
206 * - when the enum comparison is done, all correlated enums have
207 * - a built-in enum value
208 * - all mismtached ones have 0xff
209 * - else if the stream is a table
210 * - add to nv.bin template data structure
211 * - compare with the built-in template, by the field string ID
212 * - if two tables match, move on
213 * - if not match, indicate mismatch and proceed based on the global
214 * - logic selection
215 * - if abort, exit here
216 * - if extract-matching-ones,
217 * - copy the built-in template offset to a separate column
218 * - eles if the stream is a data stream
219 * - parse the data stream based on the accumulated NV templates so far,
220 * - note at this point,
221 * - 1. the accumulated templates may be incomplete, to make up the
222 * - whole NV structure
223 * - 2. some will be "overwritten" by later templates definitions
224 * - that change the earlier templates)
225 * - how to parse?
226 * - based on the nv.bin accumulated templates so far,
227 * - select the table definition from the data stream,
228 * - find the corresponding table template,
229 * - start parsing data based on the template's field string IDs,
230 * - field by field sequentially.
231 * - if the field is a nested table,
232 * - go inside to the next level
233 * - if the field is a basic type,
234 * - copy data of the given size to the offset which is the
235 * - offset in the built-in nv data storage
236 * - end of the logic
237 */
238
239/*----------------------------------------------------------------------------
240 \brief nvParser() - parse nv data provided in input buffer and store
241 \ output in sHalNv
242 \param inputEncodedbuffer, length, sHalNv - ptr to input stream,
243 \param length, sHalNv
244 \return success when successfully decode and copy to sHalNv structure
245 \sa
246-----------------------------------------------------------------------------*/
247
248VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
249 sHalNv *hal_nv)
250{
251 _STREAM_RC streamRc;
252 _NV_STREAM_BUF *pStream = &nvStream[0];
253 tANI_U32 len;
254 _ErrorCode errCode = _OK;
255 VOS_STATUS ret = VOS_STATUS_SUCCESS;
256 gpnvData_t = hal_nv;
257
258 // prepare storages for parsing nv.bin
259 initNvTablesFromBin();
260 initNvEnumsFromBin();
261
262 // init stream read pointer
263 initReadStream(pnvEncodedBuf, nvReadBufSize);
264
265 // get and process streams one by one
266 while (RC_FAIL != (streamRc = NEXT_STREAM(&len, &nvStream[0])) ) {
267 // need to copy, stream layer is freeing it
268 if (len > _NV_STREAM_LEN_MAX) {
269 errCode = _STREAM_NOT_FIT_BUF;
270 goto _error;
271 }
272 // template or data
273 if (IsStreamTemplate(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
274 if (_MIS_MATCH == processNvTemplate(pStream, len)) {
275 if (_FLAG_AND_ABORT(gNVParsingControlLo) ) {
276 errCode = _SW_BIN_MISMATCH;
277 break;
278 }
279 }
280 }
281 else {
282 processNvData(pStream, len);
283 }
284 }
285
286_error:
287 if (_OK != errCode) {
288 ret = VOS_STATUS_E_INVAL;
289 }
290
291 // all done
292 return ret;
293}
294
295static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream,
296 int len)
297{
298 // Table or enum
299 if (IsTemplateStreamTable(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
300 return processNvTemplateTable(pStream, len);
301 }
302 else {
303 return processNvTemplateEnum(pStream, len);
304 }
305}
306
307/* -----------------------------------------------------------------------------
308 *
309 * Parse one table template stream in nv.bin
310 * The length of table templates varies, based on the field ID class,
311 * field size type
312 */
313
314static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream,
315 int len)
316{
317 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
318 char tableNameFromBin[_TABLE_NAME_LEN +1];
319 int tableIdxFromBin;
320
321 // construct the template table in the NvTablesFromBin
322 memset((void*)tableNameFromBin, '\0', (size_t) (_TABLE_NAME_LEN +1));
323 tableIdxFromBin = constructATemplateTable(pStream, len, tableNameFromBin);
324
325 // fetch the table name from the first entry, the Table of all tables
326 // search for the corresponding table in NvDataBuiltIn
327 if (tableIdxFromBin) {
328 rc = compareWithBuiltinTable(tableIdxFromBin, tableNameFromBin);
329 }
330 // done
331 return rc;
332}
333
334static int getOffsetFromBuiltIn(char *tableNameFromBin)
335{
336 int offset = _OFFSET_NOT_SET;
337 int i;
338
339 _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
340 // search NvTablesBuiltIn for the same string named table, and its idx
341 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
342 if (nul == pTableBuiltin[0][i].fieldName[0]) {
343 break;
344 }
345 if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
346 offset = pTableBuiltin[0][i].offset;
347 break;
348 }
349 }
350 return offset;
351}
352
353/*
354 * Construct a table template in the NvTablesFromBin
355 * it returns the newly constructed table, for comparison with NvTablesBuiltIn
356 */
357static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len,
358 char *tableStrName)
359{
360 int pos = 0;
361 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
362 int tableIdx, entryIdx;
363 int i;
364 _ErrorCode errCode = _OK;
365
366 tableIdx = (pStream[_NV_BIN_STREAM_TABLE_ID_BYTE] &
367 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
368
369 if (IsIdxTableOfAllTables(tableIdx)) {
370 }
371 else {
372 // find the string name of the table
373 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
374 if (nul == pTable[0][i].fieldName[0]) {
375 break;
376 }
377 if ((pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ==
378 tableIdx) {
379 strlcpy(tableStrName, pTable[0][i].fieldName, (_TABLE_NAME_LEN +1));
380 break;
381 }
382 }
383 if (TABLE_ENTRIES_MAX == i) {
384 // if string name not found, don't know what to do
385 errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
386 goto _error;
387 }
388 }
389
390 // check if the table is already populated
391 if (nul != pTable[tableIdx][0].fieldName[0]) { // there is data in that enty
392 // tbd: decision logic based on Parsing Control (bitmap)
393 }
394
395 // overwrite table entry, tableIdx
396 pos = _TABLE_FIELDS_POS;
397 entryIdx = 0;
398 while (pos < len) {
399 if (!(pos <= (len - _TABLE_FIELD_MIN_LEN))) {
400 // error condition
401 errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
402 break;
403 }
404
405 // populate the entry
406 memset(pTable[tableIdx][entryIdx].fieldName, '\0',
407 (size_t) (_TABLE_NAME_LEN + 1));
408 memset(pTable[tableIdx][entryIdx].fieldFullName, '\0',
409 (size_t) (_TABLE_FIELD_FULL_NAME_LEN + 1));
410 pTable[tableIdx][entryIdx].fieldName[0] = pStream[pos++];
411 pTable[tableIdx][entryIdx].fieldName[1] = pStream[pos++];
412 pTable[tableIdx][entryIdx].fieldId = pStream[pos++];
413 pTable[tableIdx][entryIdx].fieldStorageType = pStream[pos++];
414 pTable[tableIdx][entryIdx].fieldStorageSize1 = 0;
415 pTable[tableIdx][entryIdx].fieldStorageSize2 = 0;
416 pTable[tableIdx][entryIdx].fieldStorageSize3 = 0;
417 pTable[tableIdx][entryIdx].offset =
418 getOffsetFromBuiltIn(pTable[tableIdx][entryIdx].fieldName);
419
420 if (SINGULAR ==
421 _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
422 }
423 else if (ARRAY_1 ==
424 _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
425 pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
426 }
427 else if (ARRAY_2 ==
428 _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
429 pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
430 pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
431 }
432 else if (ARRAY_3 ==
433 _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
434 pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
435 pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
436 pTable[tableIdx][entryIdx].fieldStorageSize3 = pStream[pos++];
437 }
438 //
439 entryIdx++;
440 }
441
442_error:
443 if (_OK != errCode) {
444 }
445
446 // all done
447 return tableIdx;
448}
449
450/* -----------------------------------------------------------------------------
451 *
452 * Table Compare logic:
453 *
454 * 1. the fields need to be in the same order. Looping through fields doesn't
455 * guarantee order.
456 * 2. whenever mismatch occurs in this "same-order" comparison, flag.
457 * 3. If extract matching entries' option is selected, proceed to nv.bin table
458 * and extract data.
459 *
460 * Note
461 * "compareWithBuiltinTable" is the initiating point.
462 * "compare2Tables" is the top level compare logic.
463 * it is naturally implemented as a recursive call, but out of stack
464 * overflow concern,
465 * it is also implemented as an iterative loop.
466 *
467 */
468
469static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin,
470 char *tableNameFromBin)
471{
472 int i;
473 _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
474 int tableIdxBuiltin = 0;
475 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
476 _ErrorCode errCode = _OK;
477
478 // search NvTablesBuiltIn for the same string named table, and its idx
479 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
480 if (nul == pTableBuiltin[0][i].fieldName[0]) {
481 break;
482 }
483 if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
484 tableIdxBuiltin = (pTableBuiltin[0][i].fieldId &
485 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
486 break;
487 }
488 }
489
490 // compare and copy values
491 if (!tableIdxBuiltin) {
492 errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
493 rc = _MIS_MATCH;
494 }
495 else {
496 subTableRd = 0;
497 subTableWr = 0;
498
499 // fire the comparison logic
500 if (_MIS_MATCH == compare2Tables(idxFromBin, tableIdxBuiltin)) {
501 rc = _MIS_MATCH;
502 }
503
504 // for iterative version
505 // return code (rc) should only be set to _MIS_MATCH when it happens at
506 // least once
507#if !defined(_RECURSIVE_VERSION)
508 {
509 int idxSubFromBin, idxSubBuiltin;
510 while (subTableRd != subTableWr) {
511 idxSubFromBin = subTablesQueue[subTableRd].idxSubFromBin;
512 idxSubBuiltin = subTablesQueue[subTableRd].idxSubBuiltin;
513 if (_MIS_MATCH == compare2Tables(idxSubFromBin, idxSubBuiltin)) {
514 rc = _MIS_MATCH;
515 }
516 // increment read pointer
517 subTableRd = (subTableRd+1) % _SUBTABLES_MAX;
518 }
519 }
520#endif //#if !defined(_RECURSIVE_VERSION)
521 }
522
523//_error:
524 if (_OK != errCode) {
525 //printf("Error %d \n", errCode);
526 }
527
528 //
529 return rc;
530}
531
532static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin)
533{
534 int i, j;
535 _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX];
536 _NV_TEMPLATE_TABLE (*pTableFromBin)[TABLE_ENTRIES_MAX];
537 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
538
539 pTableBuiltIn = NvTablesBuiltIn;
540 pTableFromBin = NvTablesFromBin;
541
542 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
543 if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) ||
544 // end of table occurs in either table
545 (nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
546 // end of table occurs in either table
547 if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) &&
548 (nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
549 rc = _MATCH;
550 }
551 else {
552 rc = _MIS_MATCH;
553
554 for (j=0; j<TABLE_ENTRIES_MAX; j++) {
555 if (nul == pTableBuiltIn[idxBuiltin][j].fieldName[0]) {
556 // end of bin table
557 break;
558 }
559 if (!strcmp(
560 (const char*) pTableBuiltIn[idxBuiltin][j].fieldName,
561 (const char*) pTableFromBin[idxFromBin][i].fieldName)) {
562 // found matching field in bin table
563 // DO NOT check return code, it's already a mismatch
564 compare2FieldsAndCopyFromBin(
565 &(pTableBuiltIn[idxBuiltin][j]),
566 &(pTableFromBin[idxFromBin][i]), idxBuiltin,
567 idxFromBin);
568 break;
569 }
570 }
571 }
572 break; // end of table, either table, condition
573 }
574 else {
575 if (!strcmp(pTableBuiltIn[idxBuiltin][i].fieldName,
576 pTableFromBin[idxFromBin][i].fieldName)) {
577 // two field names match
578 if (_MATCH == compare2FieldsAndCopyFromBin(
579 &(pTableBuiltIn[idxBuiltin][i]),
580 &(pTableFromBin[idxFromBin][i]),
581 idxBuiltin, idxFromBin)) {
582 rc = _MATCH;
583 }
584 else {
585 rc = _MIS_MATCH;
586 if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
587 break;
588 }
589 }
590 }
591 else {
592 rc = _MIS_MATCH;
593 if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
594 break;
595 }
596 // else
597 // loop through the WHOLE bin tables, looking for a matching field.
598 // this would take care of both cases where bin table field is
599 // either "ahead" or "behind"
600 for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
601 // end of bin table
602 if (nul == pTableFromBin[idxBuiltin][j].fieldName[0]) {
603 break;
604 }
605 if (!strcmp(pTableBuiltIn[idxBuiltin][j].fieldName,
606 pTableFromBin[idxFromBin][i].fieldName)) {
607 // found matching field in bin table
608 // DO NOT check return code, it's already a mismatch
609 compare2FieldsAndCopyFromBin(&(pTableBuiltIn[idxBuiltin][j]),
610 &(pTableFromBin[idxFromBin][i]), idxBuiltin, idxFromBin);
611 break;
612 }
613 }
614 }
615 }
616 }
617
618 return rc;
619}
620
621static _NV_TEMPLATE_PROCESS_RC compare2FieldsAndCopyFromBin(
622 _NV_TEMPLATE_TABLE*pTableBuiltIn,
623 _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
624{
625 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
626
627 // Verified already the fieldNames match
628 // fieldId type matching?
629 /*
630 * If it's a simple type, simple comparison, ==,after mask out the data type
631 * else if it's a table, need to compare 2 tables, don't call recursively
632 */
633 if (_MIS_MATCH == compare2FieldIDType(pTableBuiltIn, pTableFromBin,
634 idxBuiltin, idxFromBin)) {
635 rc = _MIS_MATCH;
636 goto _end;
637 }
638 // storage type matching?
639 // If it's SINGULAR, simple == comparison
640 // else if it's ARRAY_n, besides check ARRAY_n equal, check sizes
641 // if sizes are Index_int, simple comparison
642 // else if sizes are INDEX_ENUM, need to loop through enums
643 //
644 if (_MIS_MATCH == compare2FieldStorageTypeAndSizes(pTableBuiltIn,
645 pTableFromBin, idxBuiltin, idxFromBin)) {
646 rc = _MIS_MATCH;
647 goto _end;
648 }
649
650 // all matched, copy offset over
651 rc = _MATCH;
652 pTableFromBin->offset = pTableBuiltIn->offset;
653
654_end:
655 return rc;
656}
657
658static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType(
659 _NV_TEMPLATE_TABLE *pTableBuiltIn,
660 _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
661{
662 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
663
664 if (IsFieldTypeBasicData(pTableBuiltIn->fieldId)) {
665 if (pTableBuiltIn->fieldId == pTableFromBin->fieldId) {
666 rc = _MATCH;
667 }
668 else {
669 rc = _MIS_MATCH;
670 }
671 }
672 else { // field is a table
673 int idxSubBuiltin = pTableBuiltIn->fieldId &
674 FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
675 int idxSubFromBin = pTableFromBin->fieldId &
676 FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
677#if defined(_RECURSIVE_VERSION)
678 rc = compare2Tables(idxSubFromBin, idxSubBuiltin);
679#else
680 {
681 subTablesQueue[subTableWr].idxSubFromBin = idxSubFromBin;
682 subTablesQueue[subTableWr].idxSubBuiltin = idxSubBuiltin;
683 subTableWr = (subTableWr +1) % _SUBTABLES_MAX;
684 }
685#endif //#if defined(_RECURSIVE_VERSION)
686 }
687
688 return rc;
689}
690
691
692static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes(
693 _NV_TEMPLATE_TABLE *pTableBuiltIn,
694 _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltIn, int idxFromBin)
695{
696 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
697
698 if (_STORAGE_TYPE(pTableBuiltIn->fieldStorageType) ==
699 _STORAGE_TYPE(pTableFromBin->fieldStorageType)) {
700 if (SINGULAR == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
701 rc = _MATCH;
702 }
703 else if (ARRAY_1 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
704 if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
705 _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
706 pTableBuiltIn->fieldStorageType),
707 _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
708 pTableFromBin->fieldStorageType),
709 pTableBuiltIn->fieldStorageSize1,
710 pTableFromBin->fieldStorageSize1)) ) {
711
712 rc = _MATCH;
713 }
714 }
715 else if (ARRAY_2 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
716 if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
717 _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
718 pTableBuiltIn->fieldStorageType),
719 _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
720 pTableFromBin->fieldStorageType),
721 pTableBuiltIn->fieldStorageSize1,
722 pTableFromBin->fieldStorageSize1)) &&
723 (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
724 _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
725 pTableBuiltIn->fieldStorageType),
726 _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
727 pTableFromBin->fieldStorageType),
728 pTableBuiltIn->fieldStorageSize2,
729 pTableFromBin->fieldStorageSize2)) ) {
730 rc = _MATCH;
731 }
732 }
733 else if (ARRAY_3 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
734 if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
735 _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
736 pTableBuiltIn->fieldStorageType),
737 _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
738 pTableFromBin->fieldStorageType),
739 pTableBuiltIn->fieldStorageSize1,
740 pTableFromBin->fieldStorageSize1)) &&
741 (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
742 _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
743 pTableBuiltIn->fieldStorageType),
744 _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
745 pTableFromBin->fieldStorageType),
746 pTableBuiltIn->fieldStorageSize2,
747 pTableFromBin->fieldStorageSize2)) &&
748 (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
749 _STORAGE_SIZE3(pTableBuiltIn->fieldStorageSize3,
750 pTableBuiltIn->fieldStorageType),
751 _STORAGE_SIZE3(pTableFromBin->fieldStorageSize3,
752 pTableFromBin->fieldStorageType),
753 pTableBuiltIn->fieldStorageSize3,
754 pTableFromBin->fieldStorageSize3)) ) {
755 rc = _MATCH;
756 }
757 }
758 }
759 else {
760 rc = _MIS_MATCH;
761 }
762 return rc;
763}
764
765static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn,
766 int idxFromBin, int sizeBuiltIn,
767 int sizeFromBin, tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte)
768{
769 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
770
771 if (IsFieldSizeInt(sizeBuiltInLowByte) &&
772 IsFieldSizeInt(sizeFromBinLowByte)) {
773 if (sizeBuiltIn == sizeFromBin) {
774 rc = _MATCH;
775 }
776 else {
777 rc = _MIS_MATCH;
778 }
779 }
780 else if (!IsFieldSizeInt(sizeBuiltInLowByte) &&
781 !IsFieldSizeInt(sizeFromBinLowByte)) {
782 // enums should have been compared when enum streams are parsed
783 // The implication is that the enum streams should go before tables'
784 rc = enumMetaDataFromBin[idxFromBin].match;
785 }
786 else {
787 rc = _MIS_MATCH;
788 }
789
790 return rc;
791}
792
793/*
794 * ----------------------------------------------------------------------------
795 *
796 * Parse one enum template stream in nv.bin
797 */
798static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream,
799 int len)
800{
801 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
802 char enumStr[_ENUM_NAME_LEN + 1];
803 //_NV_TEMPLATE_ENUM *pEnum;
804 int enumIdx;
805
806 // construct the enum template in the NvEnumsFromBin
807 memset((void*)enumStr, '\0', (size_t) (_ENUM_NAME_LEN + 1));
808 enumIdx = constructATemplateEnum(pStream, len, enumStr);
809
810 // Compare the enum template
811 // also record compare results for later use in the table
812 // templates parsing where
813 // the fields may be indexed by enums
814 // if enumIdx ==0, didn't construct any entry,
815 // (or only the first entry)
816 if (enumIdx) {
817 compareEnumWithBuiltin(enumStr, enumIdx);
818 }
819
820 return rc;
821}
822
823static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin)
824{
825 int i;
826 int enumIdxBuiltin = 0;
827 _NV_TEMPLATE_ENUM (*pEnumBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
828 _ErrorCode errCode = _OK;
829
830 for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
831 if (nul == pEnumBuiltin[0][i].enumName[0]) {
832 break;
833 }
834 if (!strcmp(enumStr, pEnumBuiltin[0][i].enumName)) {
835 enumIdxBuiltin = pEnumBuiltin[0][i].enumValue;
836 break;
837 }
838 }
839 if (!enumIdxBuiltin) {
840 errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
841 return;
842 }
843 else {
844 compare2EnumEntriesAndCopy(enumIdxFromBin, enumIdxBuiltin);
845 }
846
847//_error:
848 if (_OK != errCode) {
849 //printf("Error %d\n", errCode);
850 }
851
852 return;
853}
854
855static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin,
856 int idxBuiltin)
857{
858 int i,j;
859 _NV_TEMPLATE_PROCESS_RC rc = _MATCH;
860 _NV_TEMPLATE_ENUM (*enumsFromBin)[ENUM_ENTRIES_MAX] = NvEnumsFromBin;
861 _NV_TEMPLATE_ENUM (*enumsBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
862
863 // need to go through all enums
864 for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
865 // end conditions: either both reach the end (match),
866 // or one of them reaching the end (mismatch)
867 if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) ||
868 (nul == enumsFromBin[idxFromBin][i].enumName[0])) {
869 if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) &&
870 (nul == enumsFromBin[idxFromBin][i].enumName[0])) {
871 // fully matched
872 rc = _MATCH;
873 break;
874 }
875 else {
876 rc = _MIS_MATCH;
877 for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
878 if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
879 break;
880 }
881 if (!strcmp((const char*)enumsFromBin[idxFromBin][i].enumName,
882 (const char*)enumsBuiltin[idxBuiltin][j].enumName)) {
883 enumsFromBin[idxFromBin][i].enumValuePeer =
884 enumsBuiltin[idxBuiltin][j].enumValue;
885 break;
886 }
887 }
888 break;
889 }
890 }
891 else {
892 if (!strcmp(enumsBuiltin[idxBuiltin][i].enumName,
893 enumsFromBin[idxFromBin][i].enumName)) {
894 // copy builtIn enum value to fromBin
895 enumsFromBin[idxFromBin][i].enumValuePeer =
896 enumsBuiltin[idxBuiltin][i].enumValue;
897 }
898 else {
899 // mismatch, but still loop through the whole enum list
900 // for the "ahead" and "behind" scenarios
901 rc = _MIS_MATCH;
902 for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
903 if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
904 break;
905 }
906 if (!strcmp(enumsFromBin[idxFromBin][i].enumName,
907 enumsBuiltin[idxBuiltin][j].enumName)) {
908 enumsFromBin[idxFromBin][i].enumValuePeer =
909 enumsBuiltin[idxBuiltin][j].enumValue;
910 break;
911 }
912 }
913 }
914 }
915 }
916
917 // record match or mismatch for later data parsing use
918 enumMetaDataFromBin[idxFromBin].match = rc;
919
920 // all done
921 return rc;
922}
923
924static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len,
925 char *enumStr)
926{
927 int pos = 0;
928 _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
929 int enumIdx = 0;
930 int i;
931 int entryIdx;
932 _ErrorCode errCode = _OK;
933
934 enumIdx = (pStream[_NV_BIN_STREAM_ENUM_ID_BYTE] &
935 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
936 pEnum = NvEnumsFromBin;
937
938 // find its string name
939 // the logic:
940 // since the nv.bin doesn't encode the enum string name in the actual enum
941 // stream, only the first "enum of all enums"
942 // has the names of all enums.
943 if (IsIdxEnumOfAllEnums(enumIdx)) {
944 }
945 else {
946 for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
947 if (nul == pEnum[0][i].enumName[0]) {
948 break;
949 }
950 if (pEnum[0][i].enumValue == enumIdx) {
951 strlcpy(enumStr, pEnum[0][i].enumName,(_ENUM_NAME_LEN + 1));
952 break;
953 }
954 }
955 if (ENUM_ENTRIES_MAX == i) {
956 // without a string name, don't know what to do with the enum indexed
957 errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
958 goto _error;
959 }
960 }
961
962 // Found the enum string name, now parsing decision time ...
963 // Is the entry already populated?
964 if (nul != pEnum[enumIdx][0].enumName[0]) { // there is data in that entry
965 // TBD:
966 // the logic here depends on how we support "parsing data based on the
967 // latest template".
968 // one way is to overwrite the template, so the subsequent parsing will
969 // be based on the "latest".
970 // the second way is to "append" the template, and the parsing should
971 // always be based on the "last" of the same name
972 // for simplicity, support the first approach for now.
973 //
974 // the logic:
975 // based on the parsing control (bitmap), we may proceed on overwriting
976 // enums with blind faith that the writing logic is correct,
977 // or ignore the appended.
978 //
979 }
980
981 // overwrite entry, enumIdx
982 pos = _ENUM_START_POS;
983 entryIdx = 0;
984 while (pos < len) {
985 if (!(pos <= (len - _ENUM_MIN_LEN))) {
986 // error condition
987 errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
988 break;
989 }
990
991 // populate the entry
992 memset(pEnum[enumIdx][entryIdx].enumName, '\0',
993 (size_t) (_ENUM_NAME_LEN +1));
994 memset(pEnum[enumIdx][entryIdx].enumFullName, '\0',
995 (size_t) (_ENUM_FULL_NAME_LEN +1));
996 pEnum[enumIdx][entryIdx].enumName[0] = pStream[pos++];
997 pEnum[enumIdx][entryIdx].enumName[1] = pStream[pos++];
998 pEnum[enumIdx][entryIdx].enumValue = pStream[pos++];
999 entryIdx++;
1000 }
1001
1002_error:
1003 if (_OK != errCode) {
1004 //printf("Error %d\n", errCode);
1005 }
1006
1007 // all done
1008 return enumIdx;
1009}
1010
1011/* -----------------------------------------------------------------------------
1012 *
1013 * Process data stream
1014 * The purpose is to copy nv.bin data into built in NV data structure.
1015 * This is the parser function.
1016 *
1017 * Next phase:
1018 * With NV data in the s/w module data structure, nv.bin conforming
1019 * to the new format can be generated. That is the nv.bin generation logic.)
1020 *
1021 * Data stream has the following format
1022 *
1023 * delimiter|streamHeader|tableID|data....|CRC|delimiter
1024 * Note
1025 * 1. delimiters are not present in the stream data, pStream.
1026 * 2. nested tables do NOT have table IDs with them.
1027 *
1028 */
1029// NV data, per built in templates
1030// Recursive table parsing, which is naturally depth-first
1031// If iterative, a bit hard to implement
1032
1033static void parseSubDataTable4Size(int tableIdx, int numElem)
1034{
1035 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1036 int idxSubTable;
1037 int i;
1038 int numSubElem = 0, idx=0;
1039
1040 // "apply" template to data -- parsing the actual NV data,
1041 // so far we have been parsing and building templates
1042 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1043 if (nul == pTable[tableIdx][i].fieldName[0]) {
1044 // data parsing done for this stream
1045 break;
1046 }
1047 if (IsFieldTypeBasicData(pTable[tableIdx][i].fieldId)) {
1048 getBasicDataSize(&(pTable[tableIdx][i]));
1049 }
1050 else {
1051 // number of element
1052 idx =
1053 _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
1054 numSubElem = numElemBasedOnStorageType[idx](
1055 &(pTable[tableIdx][i]), 1);
1056 // get size of the sub-table
1057 idxSubTable = (pTable[tableIdx][i].fieldId &
1058 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1059 // recursive calls for the total size of the subtable
1060 parseSubDataTable4Size(idxSubTable, numSubElem);
1061 }
1062 }
1063 // update subTableSize for the number of elements
1064 subTableSize *= numElem;
1065
1066 return;
1067}
1068
1069static void copyDataToBuiltInFromBin(int tableIdx,int fieldId,
1070 _NV_STREAM_BUF *pStream, int *pos, int addOffset, int tableBaseOffset)
1071{
1072 int i,j,k,storageType;
1073 int idx=0, size1=0, size2=0, size3=0;
1074 int enumIdx1=0, enumIdx2=0, enumIdx3=0, sizeOneElem=0;
1075 int isFirstFieldEnum=0,isSecondFieldEnum=0,isThirdFieldEnum=0;
1076 int index,index1,index2;
1077 int dindex,dindex1,dindex2,totalSize;
1078 int offset=0,sizeBuiltIn,tableIdxBuiltIn,fieldIdBuiltIn;
1079 int idxBuiltIn=0, size1BuiltIn=0, size2BuiltIn=0, size3BuiltIn=0;
1080 int size1Bin=0, size2Bin=0, size3Bin=0, numElemBuiltIn;
1081 int sizeOneElemBuiltIn=0, field;
1082 unsigned char *ptr, *dptr;
1083 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1084 _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
1085
1086 storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
1087 field = pTable[tableIdx][fieldId].fieldId;
1088 sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
1089 FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
1090 sizeBuiltIn = getBuiltInFieldCount(tableIdx,
1091 pTable[tableIdx][fieldId].fieldName,
1092 &tableIdxBuiltIn,&fieldIdBuiltIn,&numElemBuiltIn);
1093
1094 field = pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldId;
1095 sizeOneElemBuiltIn = sizeOneElemBasedOnFieldIdBasicDataType[field &
1096 FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
1097
1098 if (storageType == SINGULAR ) {
1099 ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
1100 dptr = (unsigned char *)&pStream[*pos];
1101
1102 if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
1103 idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
1104 size1Bin = numElemBasedOnStorageType[idx](
1105 &(pTable[tableIdx][fieldId]), 1);
1106 field = pTable[tableIdx][fieldId].fieldId;
1107 sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
1108 FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
1109
1110 idxBuiltIn = _STORAGE_TYPE(
1111 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1112 size1BuiltIn = numElemBasedOnStorageType[idx](
1113 &(pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn]), 0);
1114
1115 size1 = size1Bin;
1116 if (size1 > size1BuiltIn) {
1117 size1 = size1BuiltIn;
1118 }
1119 }
1120 totalSize = size1 * sizeOneElem;
1121
1122 offset = 0;
1123 for (i = 0; i < size1; i++) {
1124 memcpy(&ptr[offset], &dptr[offset], sizeOneElem);
1125 offset = offset + sizeOneElem;
1126 }
1127
1128 *pos = *pos + (size1Bin * sizeOneElem);
1129 }
1130 else {
1131 if (ARRAY_1 == storageType) {
1132 ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
1133 dptr = (unsigned char *)&pStream[*pos];
1134
1135 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1136 pTable[tableIdx][fieldId].fieldStorageType);
1137 size1Bin = getNumElemOutOfStorageSize(idx,
1138 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
1139
1140 idx = _STORAGE_SIZE1(
1141 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1142 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1143
1144 size1BuiltIn = getNumElemOutOfStorageSize(idx,
1145 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
1146
1147 size1 = size1Bin;
1148
1149 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1150 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1151 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1152 isFirstFieldEnum = 1;
1153 }
1154 else {
1155 isFirstFieldEnum = 0;
1156 if (size1 > size1BuiltIn) {
1157 size1 = size1BuiltIn;
1158 }
1159 }
1160
1161 offset = 0;
1162 for (i = 0; i < size1; i++) {
1163 if (isFirstFieldEnum) {
1164 if (NvEnumsFromBin[enumIdx1][i].enumValuePeer != 0xFF) {
1165 index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
1166 dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
1167
1168 index = index * sizeOneElem;
1169 dindex = dindex * sizeOneElem;
1170
1171 memcpy(&ptr[index], &dptr[dindex], sizeOneElem);
1172 }
1173 }
1174 else {
1175 memcpy(&ptr[offset], &dptr[offset], sizeOneElem);
1176 offset = offset + sizeOneElem;
1177 }
1178 }
1179
1180 *pos = *pos + (size1Bin * sizeOneElem);
1181 }
1182 else if (ARRAY_2 == storageType) {
1183 ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
1184 dptr = (unsigned char *)&pStream[*pos];
1185
1186 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1187 pTable[tableIdx][fieldId].fieldStorageType);
1188 size1Bin = getNumElemOutOfStorageSize(idx,
1189 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
1190
1191 idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
1192 pTable[tableIdx][fieldId].fieldStorageType);
1193
1194 size2Bin = getNumElemOutOfStorageSize(idx,
1195 pTable[tableIdx][fieldId].fieldStorageSize2, 1);
1196
1197 idx = _STORAGE_SIZE1(
1198 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1199 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1200
1201 size1BuiltIn = getNumElemOutOfStorageSize(idx,
1202 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
1203
1204 idx = _STORAGE_SIZE2(
1205 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
1206 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1207
1208 size2BuiltIn = getNumElemOutOfStorageSize(idx,
1209 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, 0);
1210
1211 size1 = size1Bin;
1212 size2 = size2Bin;
1213
1214 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1215 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1216 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1217 isFirstFieldEnum = 1;
1218 }
1219 else {
1220 isFirstFieldEnum = 0;
1221 if (size1 > size1BuiltIn) {
1222 size1 = size1BuiltIn;
1223 }
1224 }
1225
1226 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
1227 enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
1228 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1229 isSecondFieldEnum = 1;
1230 }
1231 else {
1232 isSecondFieldEnum = 0;
1233 if (size2 > size2BuiltIn) {
1234 size2 = size2BuiltIn;
1235 }
1236 }
1237
1238 offset = 0;
1239
1240 for (i = 0; i < size1; i++) {
1241 if (isFirstFieldEnum) {
1242 if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
1243 continue;
1244 }
1245
1246 index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
1247 dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
1248 }
1249 else {
1250 index = dindex = i;
1251 }
1252
1253 for (j = 0; j < size2; j++) {
1254 if (isSecondFieldEnum) {
1255 if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
1256 continue;
1257 }
1258
1259 index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
1260 dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
1261 }
1262 else {
1263 index1 = dindex1 = j;
1264 }
1265
1266 memcpy(&ptr[(index1 + index * size2BuiltIn)*sizeOneElem],
1267 &dptr[(dindex1+dindex*size2Bin)*sizeOneElem], sizeOneElem);
1268 offset = offset + sizeOneElem;
1269 }
1270 }
1271
1272 *pos = *pos + size2Bin * size1Bin * sizeOneElem;
1273 }
1274 else if (ARRAY_3 == storageType) {
1275 ptr = (unsigned char*)((int)gpnvData_t + tableBaseOffset + addOffset);
1276 dptr = (unsigned char *)&pStream[*pos];
1277
1278 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1279 pTable[tableIdx][fieldId].fieldStorageType);
1280 size1Bin = getNumElemOutOfStorageSize(idx,
1281 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
1282
1283 idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
1284 pTable[tableIdx][fieldId].fieldStorageType);
1285 size2Bin = getNumElemOutOfStorageSize(idx,
1286 pTable[tableIdx][fieldId].fieldStorageSize2, 1);
1287
1288 idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
1289 pTable[tableIdx][fieldId].fieldStorageType);
1290 size3Bin = getNumElemOutOfStorageSize(idx,
1291 pTable[tableIdx][fieldId].fieldStorageSize3, 1);
1292
1293 idx = _STORAGE_SIZE1(
1294 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1295 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1296
1297 size1BuiltIn = getNumElemOutOfStorageSize(idx,
1298 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1299 0);
1300
1301 idx = _STORAGE_SIZE2(
1302 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
1303 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1304
1305 size2BuiltIn = getNumElemOutOfStorageSize(idx,
1306 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
1307 0);
1308
1309 idx = _STORAGE_SIZE3(
1310 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
1311 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1312
1313 size3BuiltIn = getNumElemOutOfStorageSize(idx,
1314 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
1315 0);
1316
1317 size1 = size1Bin;
1318 size2 = size2Bin;
1319 size3 = size3Bin;
1320
1321 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1322 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1323 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1324 isFirstFieldEnum = 1;
1325 }
1326 else {
1327 isFirstFieldEnum = 0;
1328 if (size1 > size1BuiltIn) {
1329 size1 = size1BuiltIn;
1330 }
1331 }
1332
1333 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
1334 enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
1335 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1336 isSecondFieldEnum = 1;
1337 }
1338 else {
1339 isSecondFieldEnum = 0;
1340 if (size2 > size2BuiltIn) {
1341 size2 = size2BuiltIn;
1342 }
1343 }
1344
1345 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
1346 enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
1347 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1348 isThirdFieldEnum = 1;
1349 }
1350 else {
1351 isThirdFieldEnum = 0;
1352 if (size3 > size3BuiltIn) {
1353 size3 = size3BuiltIn;
1354 }
1355 }
1356
1357 offset = 0;
1358 for (i = 0; i < size1; i++) {
1359 if (isFirstFieldEnum) {
1360 if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
1361 continue;
1362 }
1363
1364 index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
1365 dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
1366 }
1367 else {
1368 index = dindex = i;
1369 }
1370
1371 for (j = 0; j < size2; j++) {
1372 if (isSecondFieldEnum) {
1373 if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
1374 continue;
1375 }
1376
1377 index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
1378 dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
1379 }
1380 else {
1381 index1 = dindex1 = j;
1382 }
1383
1384 for (k = 0; k < size3; k++) {
1385 if (isThirdFieldEnum) {
1386 if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
1387 continue;
1388 }
1389
1390 index2 = NvEnumsFromBin[enumIdx3][k].enumValuePeer;
1391 dindex2 = NvEnumsFromBin[enumIdx3][k].enumValue;
1392 }
1393 else {
1394 index2 = dindex2 = k;
1395 }
1396
1397 memcpy(&ptr[(index2 + (index1 * size2BuiltIn) +
1398 (index * size3BuiltIn * size2BuiltIn)) * sizeOneElem],
1399 &dptr[(dindex2 + (dindex1 * size2Bin) +
1400 (dindex * size3Bin * size2Bin))*sizeOneElem],
1401 sizeOneElem);
1402
1403 offset = offset + sizeOneElem;
1404 }
1405 }
1406 }
1407
1408 *pos = *pos + size1Bin * size2Bin * size3Bin * sizeOneElem;
1409 }
1410 else {
1411 }
1412 }
1413}
1414
1415// search NvTablesBuiltIn for the same string named table, and its idx
1416static int getBuiltInFieldCount (int tableIdxBin, char *tableNameFromBin,
1417 int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElements)
1418{
1419 int i,idx,numElem,tableIdxBuiltin=0,fieldCnt;
1420 _NV_TEMPLATE_TABLE (*pTableBin)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1421 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
1422 int found=0, fieldIndex = 0;
1423
1424 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1425 if (nul == pTableBin[0][i].fieldName[0]) {
1426 break;
1427 }
1428
1429 if ((pTableBin[0][i].fieldId &
1430 FIELD_ID_TABLE_OR_ENUM_IDX_MASK) == tableIdxBin) {
1431 found = 1;
1432 break;
1433 }
1434 }
1435
1436 if (!found) {
1437 return -1;
1438 }
1439
1440 //fieldName index got from tableId from Bin
1441 fieldIndex = i;
1442 found = 0;
1443
1444 for (i=0;i<TABLE_ENTRIES_MAX;i++) {
1445 if (nul == pTable[0][i].fieldName[0]) {
1446 break;
1447 }
1448
1449 if (!strcmp((const char*)pTableBin[0][fieldIndex].fieldName,
1450 (const char*)pTable[0][i].fieldName)) {
1451 found = 1;
1452 break;
1453 }
1454 }
1455
1456 if (!found) {
1457 return -1;
1458 }
1459
1460 //found tableId of builtIn
1461 tableIdxBuiltin = *tblIdBuiltIn =
1462 (pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1463 found = 0;
1464
1465 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1466 if (nul == pTable[tableIdxBuiltin][i].fieldName[0]) {
1467 break;
1468 }
1469
1470 if (!strcmp((const char*)tableNameFromBin,
1471 (const char*)pTable[tableIdxBuiltin][i].fieldName)) {
1472 found = 1;
1473 break;
1474 }
1475 }
1476
1477 if (!found) {
1478 return -1;
1479 }
1480
1481 *fieldIdBuitIn = i;
1482
1483 idx = _STORAGE_TYPE(pTable[tableIdxBuiltin][i].fieldStorageType);
1484 numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdxBuiltin][i]), 0);
1485
1486 fieldSize = 0;
1487 fieldCnt = getFieldCount (tableIdxBuiltin, i, numElem, 0);
1488
1489 *numElements = numElem;
1490
1491 return fieldCnt;
1492}
1493
1494static int getFieldCount(int tableIdx, int fieldId, int numElem, int nvBin)
1495{
1496 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX];
1497 int idxSubTable;
1498 int i, j, storageType, field;
1499 int numSubElem=0, idx =0, size1=0, size2=0, size3=0, sizeOneElem=0;
1500 int enumIdx1=0, enumIdx2=0, enumIdx3=0;
1501
1502 if ( nvBin ) {
1503 pTable = NvTablesFromBin;
1504 }
1505 else {
1506 pTable = NvTablesBuiltIn;
1507 }
1508
1509 storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
1510
1511 if (SINGULAR == storageType) {
1512 if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
1513 idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
1514 size1 = numElemBasedOnStorageType[idx](&(pTable[tableIdx][fieldId]),
1515 nvBin);
1516 }
1517 else {
1518 }
1519 }
1520 else {
1521 if (ARRAY_1 == storageType) {
1522 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1523 pTable[tableIdx][fieldId].fieldStorageType);
1524 size1 = getNumElemOutOfStorageSize(idx,
1525 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
1526
1527 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1528 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1529 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1530 }
1531 }
1532 else if (ARRAY_2 == storageType) {
1533 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1534 pTable[tableIdx][fieldId].fieldStorageType);
1535 size1 = getNumElemOutOfStorageSize(idx,
1536 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
1537
1538 idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
1539 pTable[tableIdx][fieldId].fieldStorageType);
1540
1541 size2 = getNumElemOutOfStorageSize(idx,
1542 pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
1543
1544 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1545 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1546 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1547 }
1548
1549 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
1550 enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
1551 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1552 }
1553 }
1554 else if (ARRAY_3 == storageType) {
1555 idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1556 pTable[tableIdx][fieldId].fieldStorageType);
1557 size1 = getNumElemOutOfStorageSize(idx,
1558 pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
1559
1560 idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
1561 pTable[tableIdx][fieldId].fieldStorageType);
1562 size2 = getNumElemOutOfStorageSize(idx,
1563 pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
1564
1565 idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
1566 pTable[tableIdx][fieldId].fieldStorageType);
1567 size3 = getNumElemOutOfStorageSize(idx,
1568 pTable[tableIdx][fieldId].fieldStorageSize3,nvBin);
1569
1570 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
1571 enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1572 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1573 }
1574
1575 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
1576 enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
1577 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1578 }
1579
1580 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
1581 enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
1582 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1583 }
1584 }
1585 else {
1586 }
1587 }
1588
1589 if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
1590 field = pTable[tableIdx][fieldId].fieldId;
1591 sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
1592 FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
1593 if ( size3 ) {
1594 fieldSize = fieldSize + size3 * size2 * size1 * sizeOneElem;
1595 }
1596 else if ( size2 ) {
1597 fieldSize = fieldSize + size2 * size1 * sizeOneElem;
1598 }
1599 else if ( size1 ) {
1600 fieldSize = fieldSize + size1 * sizeOneElem;
1601 }
1602 else {
1603 }
1604 }
1605 else {
1606 idxSubTable = (pTable[tableIdx][fieldId].fieldId &
1607 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1608
1609 for (j=0; j<numElem; j++) {
1610 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1611 if (nul == pTable[idxSubTable][i].fieldName[0]) {
1612 // data parsing done for this stream
1613 break;
1614 }
1615
1616 idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
1617 numSubElem = numElemBasedOnStorageType[idx](
1618 &(pTable[idxSubTable][i]),nvBin);
1619
1620 getFieldCount(idxSubTable, i, numSubElem, nvBin);
1621 }
1622 }
1623 }
1624
1625 return fieldSize;
1626}
1627
1628static void parseSubDataTableAndCopy(int tableIdx, int numElem, int numElem2,
1629 int numElem3, int fieldId, _NV_STREAM_BUF *pStream, int *pos, int addOffset,
1630 int tableBaseOffset, int localAddOffset)
1631{
1632 int idxSubTable, i, j, l, m, idx1, storageType, fieldCount=0;
1633 int size1BuiltIn, size2BuiltIn, size3BuiltIn;
1634 int tableIdxBuiltIn, fieldIdBuiltIn, numElemBuiltIn, incAddOffset=0;
1635 int totalOffset=0, enumIdx, size1Bin, size2Bin, size3Bin;
1636 int numSubElem, numSubElem2, numSubElem3, sizeBuiltIn=0, idx=0;
1637 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1638 _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
1639
1640 // "apply" template to data -- parsing the actual NV data,
1641 // so far we have been parsing and building templates
1642 if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
1643 // First Entry, same as off addOffset just increment localOffset
1644 if (pTable[tableIdx][fieldId].offset == addOffset) {
1645 totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset;
1646 }
1647 else {
1648 // Multiple Entry next index array, addOffset and localOffset
1649 totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset +
1650 addOffset;
1651 }
1652 copyDataToBuiltInFromBin(tableIdx, fieldId, pStream, pos, totalOffset,
1653 tableBaseOffset);
1654 }
1655 else {
1656 // number of element
1657 // get size of the sub-table
1658 idxSubTable = (pTable[tableIdx][fieldId].fieldId &
1659 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1660
1661 fieldSize = 0;
1662 sizeBuiltIn = getBuiltInFieldCount(tableIdx,
1663 pTable[tableIdx][fieldId].fieldName,
1664 &tableIdxBuiltIn, &fieldIdBuiltIn, &numElemBuiltIn);
1665 incAddOffset = 0;
1666
1667 if (numElemBuiltIn) {
1668 incAddOffset = sizeBuiltIn/numElemBuiltIn;
1669 }
1670
1671 storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
1672
1673 fieldSize = 0;
1674 fieldCount = getFieldCount(tableIdx, fieldId, numElem, 1);
1675
1676 idx1 = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
1677 pTable[tableIdx][fieldId].fieldStorageType);
1678 size1Bin = getNumElemOutOfStorageSize(idx1,
1679 pTable[tableIdx][fieldId].fieldStorageSize1, 1);
1680
1681 for (l=0; l < numElem3; l++) {
1682 if (storageType == ARRAY_3) {
1683 idx1 = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
1684 pTable[tableIdx][fieldId].fieldStorageType);
1685
1686 size3Bin = getNumElemOutOfStorageSize(idx1,
1687 pTable[tableIdx][fieldId].fieldStorageSize3, 1);
1688
1689 fieldSize = 0;
1690 getBuiltInFieldCount(tableIdx,
1691 pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
1692 &fieldIdBuiltIn, &numElemBuiltIn);
1693
1694 idx1 = _STORAGE_SIZE3(
1695 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
1696 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1697 size3BuiltIn = getNumElemOutOfStorageSize(idx1,
1698 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
1699 0);
1700
1701 if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
1702 enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
1703 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1704 if (NvEnumsFromBin[enumIdx][l].enumValuePeer == 0xFF) {
1705 *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
1706 continue;
1707 }
1708 }
1709 else {
1710 if ((l+1) > size3BuiltIn) {
1711 *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
1712 continue;
1713 }
1714 }
1715 }
1716 for (m=0; m < numElem2; m++) {
1717 if (storageType == ARRAY_2) {
1718 idx1 = _STORAGE_SIZE2(
1719 pTable[tableIdx][fieldId].fieldStorageSize2,
1720 pTable[tableIdx][fieldId].fieldStorageType);
1721 size2Bin = getNumElemOutOfStorageSize(idx1,
1722 pTable[tableIdx][fieldId].fieldStorageSize2, 1);
1723
1724 fieldSize = 0;
1725 getBuiltInFieldCount(tableIdx,
1726 pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
1727 &fieldIdBuiltIn, &numElemBuiltIn);
1728
1729 idx1 = _STORAGE_SIZE2(
1730 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
1731 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1732
1733 size2BuiltIn = getNumElemOutOfStorageSize(idx1,
1734 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
1735 0);
1736
1737 if (!IsFieldSizeInt(
1738 pTable[tableIdx][fieldId].fieldStorageSize2)) {
1739 enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
1740 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1741 if (NvEnumsFromBin[enumIdx][m].enumValuePeer == 0xFF) {
1742 *pos = *pos + (fieldCount/size1Bin) * numElem;
1743 continue;
1744 }
1745 }
1746 else {
1747 if ((m+1) > size2BuiltIn) {
1748 *pos = *pos + (fieldCount/size1Bin) * numElem;
1749 continue;
1750 }
1751 }
1752 }
1753 for (j=0; j < numElem; j++) {
1754 if (storageType == ARRAY_1) {
1755 fieldSize = 0;
1756 getBuiltInFieldCount(tableIdx,
1757 pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
1758 &fieldIdBuiltIn, &numElemBuiltIn);
1759
1760 idx1 = _STORAGE_SIZE1(
1761 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1762 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
1763
1764 size1BuiltIn = getNumElemOutOfStorageSize(idx1,
1765 pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
1766 0);
1767
1768 if (!IsFieldSizeInt(
1769 pTable[tableIdx][fieldId].fieldStorageSize1)) {
1770 enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
1771 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
1772 if (NvEnumsFromBin[enumIdx][j].enumValuePeer == 0xFF) {
1773 *pos = *pos + (fieldCount/size1Bin);
1774 continue;
1775 }
1776 }
1777 else {
1778 if ((j+1) > size1BuiltIn) {
1779 *pos = *pos + (fieldCount/size1Bin);
1780 continue;
1781 }
1782 }
1783 }
1784
1785 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1786 if (nul == pTable[idxSubTable][i].fieldName[0]) {
1787 // data parsing done for this stream
1788 break;
1789 }
1790
1791 idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
1792 numSubElem = numElemBasedOnStorageType[idx](
1793 &(pTable[idxSubTable][i]),1);
1794 numSubElem2 = numSubElem3 = 1;
1795
1796 if (idx == ARRAY_1) {
1797 idx1 = _STORAGE_SIZE1(
1798 pTable[idxSubTable][i].fieldStorageSize1,
1799 pTable[idxSubTable][i].fieldStorageType);
1800 numSubElem = getNumElemOutOfStorageSize(idx1,
1801 pTable[idxSubTable][i].fieldStorageSize1, 1);
1802 }
1803 else if (idx == ARRAY_2) {
1804 idx1 = _STORAGE_SIZE1(
1805 pTable[idxSubTable][i].fieldStorageSize1,
1806 pTable[idxSubTable][i].fieldStorageType);
1807 numSubElem = getNumElemOutOfStorageSize(idx1,
1808 pTable[idxSubTable][i].fieldStorageSize1, 1);
1809
1810 idx1 = _STORAGE_SIZE2(
1811 pTable[idxSubTable][i].fieldStorageSize2,
1812 pTable[idxSubTable][i].fieldStorageType);
1813 numSubElem2 = getNumElemOutOfStorageSize(idx1,
1814 pTable[idxSubTable][i].fieldStorageSize2, 1);
1815 }
1816 else if (idx == ARRAY_3) {
1817 idx1 = _STORAGE_SIZE1(
1818 pTable[idxSubTable][i].fieldStorageSize1,
1819 pTable[idxSubTable][i].fieldStorageType);
1820 numSubElem = getNumElemOutOfStorageSize(idx1,
1821 pTable[idxSubTable][i].fieldStorageSize1, 1);
1822
1823 idx1 = _STORAGE_SIZE2(
1824 pTable[idxSubTable][i].fieldStorageSize2,
1825 pTable[idxSubTable][i].fieldStorageType);
1826 numSubElem2 = getNumElemOutOfStorageSize(idx1,
1827 pTable[idxSubTable][i].fieldStorageSize2, 1);
1828
1829 idx1 = _STORAGE_SIZE3(
1830 pTable[idxSubTable][i].fieldStorageSize3,
1831 pTable[idxSubTable][i].fieldStorageType);
1832 numSubElem3 = getNumElemOutOfStorageSize(idx1,
1833 pTable[idxSubTable][i].fieldStorageSize3, 1);
1834 }
1835
1836 if (_OFFSET_NOT_SET != pTable[idxSubTable][i].offset) {
1837 if ( pTable[tableIdx][fieldId].offset == addOffset ) {
1838 parseSubDataTableAndCopy(idxSubTable, numSubElem,
1839 numSubElem2, numSubElem3, i, pStream, pos,
1840 addOffset, tableBaseOffset, localAddOffset);
1841 }
1842 else {
1843 // NOT the first Entry in the table..
1844 if ( !pTable[tableIdx][fieldId].offset ) {
1845 parseSubDataTableAndCopy(idxSubTable, numSubElem,
1846 numSubElem2, numSubElem3, i, pStream, pos,
1847 addOffset, tableBaseOffset, localAddOffset);
1848 }
1849 else {
1850 //First Entry in the the table..
1851 //(Sending parent offset..)
1852 parseSubDataTableAndCopy(idxSubTable, numSubElem,
1853 numSubElem2, numSubElem3, i, pStream, pos,
1854 addOffset, tableBaseOffset,
1855 pTable[tableIdx][fieldId].offset);
1856 }
1857 }
1858 }
1859 else {
1860 fieldSize = 0;
1861 fieldCount = getFieldCount(idxSubTable, i, numSubElem, 1);
1862 *pos += fieldCount;
1863 }
1864 }
1865
1866 localAddOffset = localAddOffset + incAddOffset;
1867 }
1868 }
1869 }
1870 }
1871
1872 return;
1873}
1874
1875static void processNvData(_NV_STREAM_BUF *pStream, int len)
1876{
1877 int tableIdx, pos, idx = 0, addOffset = 0, i;
1878 int numElem = 0, additionalOffset = 0, tableBaseOffset = 0;
1879 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1880
1881 // fetch the table template
1882 pos = 0; // stream header byte is already checked, that's why we are here
1883 pos += _NV_BIN_DATA_STREAM_TABLEID_BYTE;
1884 tableIdx = (pStream[_NV_BIN_DATA_STREAM_TABLEID_BYTE] &
1885 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1886 pos++;
1887
1888 // call the table parsing
1889 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1890 if (nul == pTable[0][i].fieldName[0]) {
1891 break;
1892 }
1893 if (tableIdx == _TABLE_IDX(pTable[0][i].fieldId)) {
1894 // Table base offset, stored in the "table of all tables" (index 0),
1895 // will be added to
1896 // fields relative offset in all tables.
1897 tableBaseOffset = pTable[0][i].offset;
1898
1899 idx = _STORAGE_TYPE(pTable[0][i].fieldStorageType);
1900
1901 // number of element
1902 numElem = numElemBasedOnStorageType[idx](&(pTable[0][i]),1);
1903
1904 // recursive calls for the total size of the subtable, which may
1905 // contain nested tables
1906 subTableSize = 0;
1907 parseSubDataTable4Size(tableIdx, numElem);
1908
1909 // additional offset for EACH subsequent table element
1910 additionalOffset = subTableSize/numElem;
1911
1912 break;
1913 }
1914 }
1915
1916 if (numElem) {
1917 for (i = 0; i < numElem; i++) {
1918 addOffset = (i * additionalOffset);
1919 parseDataTable_new(pStream, &pos, tableIdx, addOffset,
1920 tableBaseOffset);
1921 }
1922 }
1923
1924 // the above recursive data table parser takes care of the nested tables
1925 // all done
1926 return;
1927}
1928
1929static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos, int tableIdx,
1930 int addOffset, int tableBaseOffset)
1931{
1932 _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
1933 int i, idx, fieldCount;
1934 int numElem, numElem2, numElem3, storageType, idxSubTable;
1935
1936 // "apply" template to data -- parsing the actual NV data,
1937 // so far we have been parsing and building templates
1938 for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
1939 if (nul == pTable[tableIdx][i].fieldName[0]) {
1940 // data parsing done for this stream
1941 break;
1942 }
1943
1944 // get size of the sub-table
1945 idxSubTable = (pTable[tableIdx][i].fieldId &
1946 FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
1947
1948 idx = _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
1949
1950 numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdx][i]),1);
1951
1952 addOffset = pTable[tableIdx][i].offset;
1953
1954 fieldSize = 0;
1955 fieldCount = getFieldCount(tableIdx, i, numElem, 1);
1956
1957 numElem2 = numElem3 = 1;
1958
1959 if (idx == ARRAY_1 ) {
1960 storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
1961 pTable[tableIdx][i].fieldStorageType);
1962 numElem = getNumElemOutOfStorageSize(storageType,
1963 pTable[tableIdx][i].fieldStorageSize1, 1);
1964 }
1965 else if (idx == ARRAY_2) {
1966 storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
1967 pTable[tableIdx][i].fieldStorageType);
1968
1969 numElem = getNumElemOutOfStorageSize(storageType,
1970 pTable[tableIdx][i].fieldStorageSize1, 1);
1971
1972 storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
1973 pTable[tableIdx][i].fieldStorageType);
1974
1975 numElem2 = getNumElemOutOfStorageSize(storageType,
1976 pTable[tableIdx][i].fieldStorageSize2, 1);
1977 }
1978 else if (idx == ARRAY_3) {
1979 storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
1980 pTable[tableIdx][i].fieldStorageType);
1981
1982 numElem = getNumElemOutOfStorageSize(storageType,
1983 pTable[tableIdx][i].fieldStorageSize1, 1);
1984
1985 storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
1986 pTable[tableIdx][i].fieldStorageType);
1987
1988 numElem2 = getNumElemOutOfStorageSize(storageType,
1989 pTable[tableIdx][i].fieldStorageSize2, 1);
1990
1991 storageType = _STORAGE_SIZE3(pTable[tableIdx][i].fieldStorageSize3,
1992 pTable[tableIdx][i].fieldStorageType);
1993
1994 numElem3 = getNumElemOutOfStorageSize(storageType,
1995 pTable[tableIdx][i].fieldStorageSize3, 1);
1996 }
1997
1998 if (_OFFSET_NOT_SET != pTable[tableIdx][i].offset) {
1999 parseSubDataTableAndCopy(tableIdx, numElem, numElem2, numElem3, i,
2000 pStream, pos, addOffset, tableBaseOffset, 0);
2001 }
2002 else {
2003 *pos += fieldCount;
2004 }
2005 }
2006}
2007
2008static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry)
2009{
2010 int numElem, sizeOneElem, totalSize;
2011 int idx, idx1;
2012
2013 // number of element
2014 idx = _STORAGE_TYPE(pTableEntry->fieldStorageType);
2015 numElem = numElemBasedOnStorageType[idx](pTableEntry, 1);
2016
2017 // size of each element
2018 idx1 = pTableEntry->fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
2019 sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[idx1];
2020
2021 // total size in bytes
2022 totalSize = numElem * sizeOneElem;
2023
2024 // all done, update global
2025 subTableSize += totalSize;
2026
2027 return;
2028}
2029
2030static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry, int unused)
2031{
2032 return 1;
2033}
2034
2035static int getNumElemOutOfStorageSize(int fieldStorageSize,
2036 uint8 fieldStorageSizeLowByte, int nvBin)
2037{
2038 int ret = 0;
2039 if (IsFieldSizeInt(fieldStorageSizeLowByte)) {
2040 return fieldStorageSize;
2041 }
2042 else {
2043 int maxEnumVal=0, i;
2044 _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
2045 int enumIdx = ((fieldStorageSizeLowByte &
2046 FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
2047
2048 if (nvBin) {
2049 pEnum = NvEnumsFromBin;
2050 }
2051 else {
2052 pEnum = NvEnumsBuiltIn;
2053 }
2054
2055 for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
2056 if (nul == pEnum[enumIdx][i].enumName[0]) {
2057 if ( i == 0 ) {
2058 maxEnumVal = 0;
2059 }
2060 else {
2061 maxEnumVal = pEnum[enumIdx][i-1].enumValue;
2062 }
2063 break;
2064 }
2065 }
2066 ret = (maxEnumVal + 1);
2067 return ret; // +1 to count for 0 to maxEnumVal
2068 }
2069}
2070
2071static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
2072{
2073 int fieldStorageSize = 0;
2074
2075 fieldStorageSize = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
2076 pTableEntry->fieldStorageSize1, pTableEntry->fieldStorageType),
2077 pTableEntry->fieldStorageSize1, nvBin);
2078
2079 return fieldStorageSize;
2080}
2081
2082static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
2083{
2084 int fieldStorageSize1,fieldStorageSize2,fieldStorageSize;
2085
2086 fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
2087 pTableEntry->fieldStorageSize1,
2088 pTableEntry->fieldStorageType),
2089 pTableEntry->fieldStorageSize1, nvBin);
2090
2091 fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
2092 pTableEntry->fieldStorageSize2,
2093 pTableEntry->fieldStorageType),
2094 pTableEntry->fieldStorageSize2, nvBin);
2095
2096 fieldStorageSize = fieldStorageSize1 * fieldStorageSize2;
2097
2098 return fieldStorageSize;
2099}
2100
2101static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
2102{
2103 int fieldStorageSize1,fieldStorageSize2,fieldStorageSize3,fieldStorageSize;
2104
2105 fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
2106 pTableEntry->fieldStorageSize1,
2107 pTableEntry->fieldStorageType),
2108 pTableEntry->fieldStorageSize1, nvBin);
2109
2110 fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
2111 pTableEntry->fieldStorageSize2,
2112 pTableEntry->fieldStorageType),
2113 pTableEntry->fieldStorageSize2, nvBin);
2114
2115 fieldStorageSize3 = getNumElemOutOfStorageSize(_STORAGE_SIZE3(
2116 pTableEntry->fieldStorageSize3,
2117 pTableEntry->fieldStorageType),
2118 pTableEntry->fieldStorageSize3, nvBin);
2119
2120 fieldStorageSize = fieldStorageSize1 * fieldStorageSize2 * fieldStorageSize3;
2121
2122 return fieldStorageSize;
2123}