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