blob: 7317c361a5551c6d708c425c19ff133e229065a6 [file] [log] [blame]
/*
* Copyright (c) 2014 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*===========================================================================
EDIT HISTORY FOR FILE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
$Header:$ $DateTime: $ $Author: $
when who what, where, why
-------- --- -----------------------------------------------------
04/10/13 kumarpra nv parser creation
===========================================================================*/
#include <linux/string.h>
#include "wlan_nv.h"
/*
* NV stream layer service
*/
#include "wlan_nv_stream.h"
#include "wlan_nv_template_internal.h"
#include "wlan_nv_parser_internal.h"
#include "wlan_nv_template_api.h"
#include "wlan_nv_template_builtin.h"
extern void vos_mem_copy( void *pDst, const void *pSrc, unsigned int numBytes );
#define _RECURSIVE_DATA_TABLE_PARSING
// Recursive/iterative switch !! Default iterative
#define _RECURSIVE_VERSION
/*
* Build process should have created the built-in templates in
* "wlan_nv_templateBuiltIn.c"
* Include its auto-generated companion header file
* "wlan_nv_templateBuiltIn.h"
*
* The main definitions are
* _NV_TEMPLATE_TABLE NvTablesBuiltIn[];
*
*/
/*
* Parsing control bitmap
*/
tANI_U32 gNVParsingControlLo;
static int subTableSize;
static int fieldSize;
static sHalNv *gpnvData_t;
/* store enum comparison results*/
static _ENUM_META_DATA enumMetaDataFromBin[INDEX_ENUM_MAX];
/*
* This data copy logic ignores the enum or int data types,
* but simply copy the whole chunk to the NV data structure
*/
typedef struct {
int idxSubFromBin;
int idxSubBuiltin;
} _SUBTABLES_QUEUE;
pF_NumElemBasedOnStorageType numElemBasedOnStorageType[] = {
numElemSingular, // SINGULAR=0
numElemArray1, // ARRAY_1=1
numElemArray2, // ARRAY_2=2
numElemArray3, // ARRAY_3=3
};
static int sizeOneElemBasedOnFieldIdBasicDataType[] = {
1, // _FIELD_ID_DATA_TYPE_U8 =0
4, // _FIELD_ID_DATA_TYPE_U32
1, // _FIELD_ID_DATA_TYPE_S8
4, // _FIELD_ID_DATA_TYPE_S32
2, // _FIELD_ID_DATA_TYPE_U16
2, // _FIELD_ID_DATA_TYPE_S16
};
static _NV_STREAM_BUF nvStream[_NV_STREAM_LEN_MAX];
static int subTableRd, subTableWr;
#if !defined(_RECURSIVE_VERSION)
#define _SUBTABLES_MAX 32
static _SUBTABLES_QUEUE subTablesQueue[_SUBTABLES_MAX];
#endif
/*==============================================================================
*
* Storage for NvTablesFromBin
*
*===============================================================================
*/
/*
* Init NvTablesFromBin
* All entries are initialized to 0, pointers to NULL
*/
_NV_TEMPLATE_TABLE NvTablesFromBin[TABLES_MAX][TABLE_ENTRIES_MAX] = {
{ /* TABLE_LAST*/
{{nul}, 0, 0, 0, 0, 0, 0, {nul}},
},
};
static void initNvTablesFromBin(void)
{
int i, j;
for (i = 0; i < TABLES_MAX; i++) {
for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
NvTablesFromBin[i][j].fieldName[0] = nul;
NvTablesFromBin[i][j].fieldName[1] = nul;
NvTablesFromBin[i][j].fieldName[2] = nul;
NvTablesFromBin[i][j].fieldId = 0;
NvTablesFromBin[i][j].fieldStorageType = 0;
NvTablesFromBin[i][j].fieldStorageSize1 = 0;
NvTablesFromBin[i][j].fieldStorageSize2 = 0;
NvTablesFromBin[i][j].fieldStorageSize3 = 0;
NvTablesFromBin[i][j].offset = 0;
NvTablesFromBin[i][j].fieldFullName[0] = nul;
NvTablesFromBin[i][j].fieldFullName[1] = nul;
NvTablesFromBin[i][j].fieldFullName[2] = nul;
}
}
return;
}
/*==============================================================================
*
* Storage for NvEnumsFromBin
*
* ==============================================================================
*/
/*
* Prepare the NV enum templates storage parsed from nv.bin
* They are used later for parsing the nv.bin data
* All entries are initialized to 0, pointers to NULL
*/
_NV_TEMPLATE_ENUM NvEnumsFromBin[INDEX_ENUM_MAX][ENUM_ENTRIES_MAX] = {
{ /* INDEX_ENUM_LAST */
{{nul}, 0, 0, {nul}},
},
};
static void initNvEnumsFromBin(void)
{
int i, j;
for(i = 0; i < INDEX_ENUM_MAX; i++) {
for(j = 0; j < ENUM_ENTRIES_MAX; j++) {
NvEnumsFromBin[i][j].enumName[0] = nul;
NvEnumsFromBin[i][j].enumName[1] = nul;
NvEnumsFromBin[i][j].enumName[2] = nul;
NvEnumsFromBin[i][j].enumValue = 0;
NvEnumsFromBin[i][j].enumValuePeer = 0xFF;
NvEnumsFromBin[i][j].enumFullName[0] = nul;
}
}
return;
}
// =============================================================================
//
// Parse template streams
//
// =============================================================================
/*
* Read nv.bin to extract the template info
* _NV_TEMPLATE_TABLE NvTablesFromBin[];
*/
/*
* Parse nv.bin data and extract to the build-in data storage
*
* There are two outcomes from earlier templates comparison operation.
* different or identical
* If identical, this operation will most likely take place.
* If different,
* One is to simply indicate to the user and abort reading the nv.bin data
* The other is to continue this operation, and extract the matching entries
* in nv.bin
*/
/*
* The template based NV logic:
* - the s/w module has the built-in templates
* - nv.bin is read one stream at a time, sequentially from beginning to end
* - if the stream is an enum stream,
* - add to nv.bin template data structure
* - compare with the built in template, by the string ID
* - if two match, move on
* - if not match, indicate mismatch, act based on the global logic
* _ selection
* - if abort, exit here
* - if extract-matching-ones,
* - copy the enum from the built-in template over to a separate
* _ column
* - when the enum comparison is done, all correlated enums have
* - a built-in enum value
* - all mismtached ones have 0xff
* - else if the stream is a table
* - add to nv.bin template data structure
* - compare with the built-in template, by the field string ID
* - if two tables match, move on
* - if not match, indicate mismatch and proceed based on the global
* - logic selection
* - if abort, exit here
* - if extract-matching-ones,
* - copy the built-in template offset to a separate column
* - eles if the stream is a data stream
* - parse the data stream based on the accumulated NV templates so far,
* - note at this point,
* - 1. the accumulated templates may be incomplete, to make up the
* - whole NV structure
* - 2. some will be "overwritten" by later templates definitions
* - that change the earlier templates)
* - how to parse?
* - based on the nv.bin accumulated templates so far,
* - select the table definition from the data stream,
* - find the corresponding table template,
* - start parsing data based on the template's field string IDs,
* - field by field sequentially.
* - if the field is a nested table,
* - go inside to the next level
* - if the field is a basic type,
* - copy data of the given size to the offset which is the
* - offset in the built-in nv data storage
* - end of the logic
*/
/*----------------------------------------------------------------------------
\brief nvParser() - parse nv data provided in input buffer and store
\ output in sHalNv
\param inputEncodedbuffer, length, sHalNv - ptr to input stream,
\param length, sHalNv
\return success when successfully decode and copy to sHalNv structure
\sa
-----------------------------------------------------------------------------*/
VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize,
sHalNv *hal_nv)
{
_STREAM_RC streamRc;
_NV_STREAM_BUF *pStream = &nvStream[0];
tANI_U32 len;
_ErrorCode errCode = _OK;
VOS_STATUS ret = VOS_STATUS_SUCCESS;
gpnvData_t = hal_nv;
// prepare storages for parsing nv.bin
initNvTablesFromBin();
initNvEnumsFromBin();
// init stream read pointer
initReadStream(pnvEncodedBuf, nvReadBufSize);
// get and process streams one by one
while (RC_FAIL != (streamRc = NEXT_STREAM(&len, &nvStream[0])) ) {
// need to copy, stream layer is freeing it
if (len > _NV_STREAM_LEN_MAX) {
errCode = _STREAM_NOT_FIT_BUF;
goto _error;
}
// template or data
if (IsStreamTemplate(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
if (_MIS_MATCH == processNvTemplate(pStream, len)) {
if (_FLAG_AND_ABORT(gNVParsingControlLo) ) {
errCode = _SW_BIN_MISMATCH;
break;
}
}
}
else {
processNvData(pStream, len);
}
}
_error:
if (_OK != errCode) {
ret = VOS_STATUS_E_INVAL;
}
// all done
return ret;
}
static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream,
int len)
{
// Table or enum
if (IsTemplateStreamTable(pStream[_NV_BIN_STREAM_HEADER_BYTE])) {
return processNvTemplateTable(pStream, len);
}
else {
return processNvTemplateEnum(pStream, len);
}
}
/* -----------------------------------------------------------------------------
*
* Parse one table template stream in nv.bin
* The length of table templates varies, based on the field ID class,
* field size type
*/
static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream,
int len)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
char tableNameFromBin[_TABLE_NAME_LEN +1];
int tableIdxFromBin;
// construct the template table in the NvTablesFromBin
memset((void*)tableNameFromBin, '\0', (size_t) (_TABLE_NAME_LEN +1));
tableIdxFromBin = constructATemplateTable(pStream, len, tableNameFromBin);
// fetch the table name from the first entry, the Table of all tables
// search for the corresponding table in NvDataBuiltIn
if (tableIdxFromBin) {
rc = compareWithBuiltinTable(tableIdxFromBin, tableNameFromBin);
}
// done
return rc;
}
static int getOffsetFromBuiltIn(char *tableNameFromBin)
{
int offset = _OFFSET_NOT_SET;
int i;
_NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
// search NvTablesBuiltIn for the same string named table, and its idx
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTableBuiltin[0][i].fieldName[0]) {
break;
}
if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
offset = pTableBuiltin[0][i].offset;
break;
}
}
return offset;
}
/*
* Construct a table template in the NvTablesFromBin
* it returns the newly constructed table, for comparison with NvTablesBuiltIn
*/
static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len,
char *tableStrName)
{
int pos = 0;
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
int tableIdx, entryIdx;
int i;
_ErrorCode errCode = _OK;
tableIdx = (pStream[_NV_BIN_STREAM_TABLE_ID_BYTE] &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
if (IsIdxTableOfAllTables(tableIdx)) {
}
else {
// find the string name of the table
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[0][i].fieldName[0]) {
break;
}
if ((pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ==
tableIdx) {
strlcpy(tableStrName, pTable[0][i].fieldName, (_TABLE_NAME_LEN +1));
break;
}
}
if (TABLE_ENTRIES_MAX == i) {
// if string name not found, don't know what to do
errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
goto _error;
}
}
// check if the table is already populated
if (nul != pTable[tableIdx][0].fieldName[0]) { // there is data in that enty
// tbd: decision logic based on Parsing Control (bitmap)
}
// overwrite table entry, tableIdx
pos = _TABLE_FIELDS_POS;
entryIdx = 0;
while (pos < len) {
if (!(pos <= (len - _TABLE_FIELD_MIN_LEN))) {
// error condition
errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
break;
}
// populate the entry
memset(pTable[tableIdx][entryIdx].fieldName, '\0',
(size_t) (_TABLE_NAME_LEN + 1));
memset(pTable[tableIdx][entryIdx].fieldFullName, '\0',
(size_t) (_TABLE_FIELD_FULL_NAME_LEN + 1));
pTable[tableIdx][entryIdx].fieldName[0] = pStream[pos++];
pTable[tableIdx][entryIdx].fieldName[1] = pStream[pos++];
pTable[tableIdx][entryIdx].fieldId = pStream[pos++];
pTable[tableIdx][entryIdx].fieldStorageType = pStream[pos++];
pTable[tableIdx][entryIdx].fieldStorageSize1 = 0;
pTable[tableIdx][entryIdx].fieldStorageSize2 = 0;
pTable[tableIdx][entryIdx].fieldStorageSize3 = 0;
pTable[tableIdx][entryIdx].offset =
getOffsetFromBuiltIn(pTable[tableIdx][entryIdx].fieldName);
if (SINGULAR ==
_STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
}
else if (ARRAY_1 ==
_STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
}
else if (ARRAY_2 ==
_STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
}
else if (ARRAY_3 ==
_STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) {
pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++];
pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++];
pTable[tableIdx][entryIdx].fieldStorageSize3 = pStream[pos++];
}
//
entryIdx++;
}
_error:
if (_OK != errCode) {
}
// all done
return tableIdx;
}
/* -----------------------------------------------------------------------------
*
* Table Compare logic:
*
* 1. the fields need to be in the same order. Looping through fields doesn't
* guarantee order.
* 2. whenever mismatch occurs in this "same-order" comparison, flag.
* 3. If extract matching entries' option is selected, proceed to nv.bin table
* and extract data.
*
* Note
* "compareWithBuiltinTable" is the initiating point.
* "compare2Tables" is the top level compare logic.
* it is naturally implemented as a recursive call, but out of stack
* overflow concern,
* it is also implemented as an iterative loop.
*
*/
static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin,
char *tableNameFromBin)
{
int i;
_NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
int tableIdxBuiltin = 0;
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
_ErrorCode errCode = _OK;
// search NvTablesBuiltIn for the same string named table, and its idx
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTableBuiltin[0][i].fieldName[0]) {
break;
}
if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) {
tableIdxBuiltin = (pTableBuiltin[0][i].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
break;
}
}
// compare and copy values
if (!tableIdxBuiltin) {
errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES;
rc = _MIS_MATCH;
}
else {
subTableRd = 0;
subTableWr = 0;
// fire the comparison logic
if (_MIS_MATCH == compare2Tables(idxFromBin, tableIdxBuiltin)) {
rc = _MIS_MATCH;
}
// for iterative version
// return code (rc) should only be set to _MIS_MATCH when it happens at
// least once
#if !defined(_RECURSIVE_VERSION)
{
int idxSubFromBin, idxSubBuiltin;
while (subTableRd != subTableWr) {
idxSubFromBin = subTablesQueue[subTableRd].idxSubFromBin;
idxSubBuiltin = subTablesQueue[subTableRd].idxSubBuiltin;
if (_MIS_MATCH == compare2Tables(idxSubFromBin, idxSubBuiltin)) {
rc = _MIS_MATCH;
}
// increment read pointer
subTableRd = (subTableRd+1) % _SUBTABLES_MAX;
}
}
#endif //#if !defined(_RECURSIVE_VERSION)
}
//_error:
if (_OK != errCode) {
//printf("Error %d \n", errCode);
}
//
return rc;
}
static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin)
{
int i, j;
_NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX];
_NV_TEMPLATE_TABLE (*pTableFromBin)[TABLE_ENTRIES_MAX];
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
pTableBuiltIn = NvTablesBuiltIn;
pTableFromBin = NvTablesFromBin;
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) ||
// end of table occurs in either table
(nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
// end of table occurs in either table
if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) &&
(nul == pTableFromBin[idxFromBin][i].fieldName[0])) {
rc = _MATCH;
}
else {
rc = _MIS_MATCH;
for (j=0; j<TABLE_ENTRIES_MAX; j++) {
if (nul == pTableBuiltIn[idxBuiltin][j].fieldName[0]) {
// end of bin table
break;
}
if (!strcmp(
(const char*) pTableBuiltIn[idxBuiltin][j].fieldName,
(const char*) pTableFromBin[idxFromBin][i].fieldName)) {
// found matching field in bin table
// DO NOT check return code, it's already a mismatch
compare2FieldsAndCopyFromBin(
&(pTableBuiltIn[idxBuiltin][j]),
&(pTableFromBin[idxFromBin][i]), idxBuiltin,
idxFromBin);
break;
}
}
}
break; // end of table, either table, condition
}
else {
if (!strcmp(pTableBuiltIn[idxBuiltin][i].fieldName,
pTableFromBin[idxFromBin][i].fieldName)) {
// two field names match
if (_MATCH == compare2FieldsAndCopyFromBin(
&(pTableBuiltIn[idxBuiltin][i]),
&(pTableFromBin[idxFromBin][i]),
idxBuiltin, idxFromBin)) {
rc = _MATCH;
}
else {
rc = _MIS_MATCH;
if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
break;
}
}
}
else {
rc = _MIS_MATCH;
if ( _FLAG_AND_ABORT(gNVParsingControlLo) ) {
break;
}
// else
// loop through the WHOLE bin tables, looking for a matching field.
// this would take care of both cases where bin table field is
// either "ahead" or "behind"
for (j = 0; j < TABLE_ENTRIES_MAX; j++) {
// end of bin table
if (nul == pTableFromBin[idxBuiltin][j].fieldName[0]) {
break;
}
if (!strcmp(pTableBuiltIn[idxBuiltin][j].fieldName,
pTableFromBin[idxFromBin][i].fieldName)) {
// found matching field in bin table
// DO NOT check return code, it's already a mismatch
compare2FieldsAndCopyFromBin(&(pTableBuiltIn[idxBuiltin][j]),
&(pTableFromBin[idxFromBin][i]), idxBuiltin, idxFromBin);
break;
}
}
}
}
}
return rc;
}
static _NV_TEMPLATE_PROCESS_RC compare2FieldsAndCopyFromBin(
_NV_TEMPLATE_TABLE*pTableBuiltIn,
_NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
// Verified already the fieldNames match
// fieldId type matching?
/*
* If it's a simple type, simple comparison, ==,after mask out the data type
* else if it's a table, need to compare 2 tables, don't call recursively
*/
if (_MIS_MATCH == compare2FieldIDType(pTableBuiltIn, pTableFromBin,
idxBuiltin, idxFromBin)) {
rc = _MIS_MATCH;
goto _end;
}
// storage type matching?
// If it's SINGULAR, simple == comparison
// else if it's ARRAY_n, besides check ARRAY_n equal, check sizes
// if sizes are Index_int, simple comparison
// else if sizes are INDEX_ENUM, need to loop through enums
//
if (_MIS_MATCH == compare2FieldStorageTypeAndSizes(pTableBuiltIn,
pTableFromBin, idxBuiltin, idxFromBin)) {
rc = _MIS_MATCH;
goto _end;
}
// all matched, copy offset over
rc = _MATCH;
pTableFromBin->offset = pTableBuiltIn->offset;
_end:
return rc;
}
static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType(
_NV_TEMPLATE_TABLE *pTableBuiltIn,
_NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
if (IsFieldTypeBasicData(pTableBuiltIn->fieldId)) {
if (pTableBuiltIn->fieldId == pTableFromBin->fieldId) {
rc = _MATCH;
}
else {
rc = _MIS_MATCH;
}
}
else { // field is a table
int idxSubBuiltin = pTableBuiltIn->fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
int idxSubFromBin = pTableFromBin->fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
#if defined(_RECURSIVE_VERSION)
rc = compare2Tables(idxSubFromBin, idxSubBuiltin);
#else
{
subTablesQueue[subTableWr].idxSubFromBin = idxSubFromBin;
subTablesQueue[subTableWr].idxSubBuiltin = idxSubBuiltin;
subTableWr = (subTableWr +1) % _SUBTABLES_MAX;
}
#endif //#if defined(_RECURSIVE_VERSION)
}
return rc;
}
static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes(
_NV_TEMPLATE_TABLE *pTableBuiltIn,
_NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltIn, int idxFromBin)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
if (_STORAGE_TYPE(pTableBuiltIn->fieldStorageType) ==
_STORAGE_TYPE(pTableFromBin->fieldStorageType)) {
if (SINGULAR == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
rc = _MATCH;
}
else if (ARRAY_1 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize1,
pTableFromBin->fieldStorageSize1)) ) {
rc = _MATCH;
}
}
else if (ARRAY_2 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize1,
pTableFromBin->fieldStorageSize1)) &&
(_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize2,
pTableFromBin->fieldStorageSize2)) ) {
rc = _MATCH;
}
}
else if (ARRAY_3 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) {
if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE1(pTableFromBin->fieldStorageSize1,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize1,
pTableFromBin->fieldStorageSize1)) &&
(_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE2(pTableFromBin->fieldStorageSize2,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize2,
pTableFromBin->fieldStorageSize2)) &&
(_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin,
_STORAGE_SIZE3(pTableBuiltIn->fieldStorageSize3,
pTableBuiltIn->fieldStorageType),
_STORAGE_SIZE3(pTableFromBin->fieldStorageSize3,
pTableFromBin->fieldStorageType),
pTableBuiltIn->fieldStorageSize3,
pTableFromBin->fieldStorageSize3)) ) {
rc = _MATCH;
}
}
}
else {
rc = _MIS_MATCH;
}
return rc;
}
static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn,
int idxFromBin, int sizeBuiltIn,
int sizeFromBin, tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
if (IsFieldSizeInt(sizeBuiltInLowByte) &&
IsFieldSizeInt(sizeFromBinLowByte)) {
if (sizeBuiltIn == sizeFromBin) {
rc = _MATCH;
}
else {
rc = _MIS_MATCH;
}
}
else if (!IsFieldSizeInt(sizeBuiltInLowByte) &&
!IsFieldSizeInt(sizeFromBinLowByte)) {
// enums should have been compared when enum streams are parsed
// The implication is that the enum streams should go before tables'
rc = enumMetaDataFromBin[idxFromBin].match;
}
else {
rc = _MIS_MATCH;
}
return rc;
}
/*
* ----------------------------------------------------------------------------
*
* Parse one enum template stream in nv.bin
*/
static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream,
int len)
{
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
char enumStr[_ENUM_NAME_LEN + 1];
//_NV_TEMPLATE_ENUM *pEnum;
int enumIdx;
// construct the enum template in the NvEnumsFromBin
memset((void*)enumStr, '\0', (size_t) (_ENUM_NAME_LEN + 1));
enumIdx = constructATemplateEnum(pStream, len, enumStr);
// Compare the enum template
// also record compare results for later use in the table
// templates parsing where
// the fields may be indexed by enums
// if enumIdx ==0, didn't construct any entry,
// (or only the first entry)
if (enumIdx) {
compareEnumWithBuiltin(enumStr, enumIdx);
}
return rc;
}
static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin)
{
int i;
int enumIdxBuiltin = 0;
_NV_TEMPLATE_ENUM (*pEnumBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
_ErrorCode errCode = _OK;
for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
if (nul == pEnumBuiltin[0][i].enumName[0]) {
break;
}
if (!strcmp(enumStr, pEnumBuiltin[0][i].enumName)) {
enumIdxBuiltin = pEnumBuiltin[0][i].enumValue;
break;
}
}
if (!enumIdxBuiltin) {
errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
return;
}
else {
compare2EnumEntriesAndCopy(enumIdxFromBin, enumIdxBuiltin);
}
//_error:
if (_OK != errCode) {
//printf("Error %d\n", errCode);
}
return;
}
static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin,
int idxBuiltin)
{
int i,j;
_NV_TEMPLATE_PROCESS_RC rc = _MATCH;
_NV_TEMPLATE_ENUM (*enumsFromBin)[ENUM_ENTRIES_MAX] = NvEnumsFromBin;
_NV_TEMPLATE_ENUM (*enumsBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn;
// need to go through all enums
for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
// end conditions: either both reach the end (match),
// or one of them reaching the end (mismatch)
if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) ||
(nul == enumsFromBin[idxFromBin][i].enumName[0])) {
if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) &&
(nul == enumsFromBin[idxFromBin][i].enumName[0])) {
// fully matched
rc = _MATCH;
break;
}
else {
rc = _MIS_MATCH;
for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
break;
}
if (!strcmp((const char*)enumsFromBin[idxFromBin][i].enumName,
(const char*)enumsBuiltin[idxBuiltin][j].enumName)) {
enumsFromBin[idxFromBin][i].enumValuePeer =
enumsBuiltin[idxBuiltin][j].enumValue;
break;
}
}
break;
}
}
else {
if (!strcmp(enumsBuiltin[idxBuiltin][i].enumName,
enumsFromBin[idxFromBin][i].enumName)) {
// copy builtIn enum value to fromBin
enumsFromBin[idxFromBin][i].enumValuePeer =
enumsBuiltin[idxBuiltin][i].enumValue;
}
else {
// mismatch, but still loop through the whole enum list
// for the "ahead" and "behind" scenarios
rc = _MIS_MATCH;
for (j = 0; j < ENUM_ENTRIES_MAX; j++) {
if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) {
break;
}
if (!strcmp(enumsFromBin[idxFromBin][i].enumName,
enumsBuiltin[idxBuiltin][j].enumName)) {
enumsFromBin[idxFromBin][i].enumValuePeer =
enumsBuiltin[idxBuiltin][j].enumValue;
break;
}
}
}
}
}
// record match or mismatch for later data parsing use
enumMetaDataFromBin[idxFromBin].match = rc;
// all done
return rc;
}
static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len,
char *enumStr)
{
int pos = 0;
_NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
int enumIdx = 0;
int i;
int entryIdx;
_ErrorCode errCode = _OK;
enumIdx = (pStream[_NV_BIN_STREAM_ENUM_ID_BYTE] &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
pEnum = NvEnumsFromBin;
// find its string name
// the logic:
// since the nv.bin doesn't encode the enum string name in the actual enum
// stream, only the first "enum of all enums"
// has the names of all enums.
if (IsIdxEnumOfAllEnums(enumIdx)) {
}
else {
for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
if (nul == pEnum[0][i].enumName[0]) {
break;
}
if (pEnum[0][i].enumValue == enumIdx) {
strlcpy(enumStr, pEnum[0][i].enumName,(_ENUM_NAME_LEN + 1));
break;
}
}
if (ENUM_ENTRIES_MAX == i) {
// without a string name, don't know what to do with the enum indexed
errCode = _ENUM_NOT_FOUND_IN_BUILT_IN;
goto _error;
}
}
// Found the enum string name, now parsing decision time ...
// Is the entry already populated?
if (nul != pEnum[enumIdx][0].enumName[0]) { // there is data in that entry
// TBD:
// the logic here depends on how we support "parsing data based on the
// latest template".
// one way is to overwrite the template, so the subsequent parsing will
// be based on the "latest".
// the second way is to "append" the template, and the parsing should
// always be based on the "last" of the same name
// for simplicity, support the first approach for now.
//
// the logic:
// based on the parsing control (bitmap), we may proceed on overwriting
// enums with blind faith that the writing logic is correct,
// or ignore the appended.
//
}
// overwrite entry, enumIdx
pos = _ENUM_START_POS;
entryIdx = 0;
while (pos < len) {
if (!(pos <= (len - _ENUM_MIN_LEN))) {
// error condition
errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR;
break;
}
// populate the entry
memset(pEnum[enumIdx][entryIdx].enumName, '\0',
(size_t) (_ENUM_NAME_LEN +1));
memset(pEnum[enumIdx][entryIdx].enumFullName, '\0',
(size_t) (_ENUM_FULL_NAME_LEN +1));
pEnum[enumIdx][entryIdx].enumName[0] = pStream[pos++];
pEnum[enumIdx][entryIdx].enumName[1] = pStream[pos++];
pEnum[enumIdx][entryIdx].enumValue = pStream[pos++];
entryIdx++;
}
_error:
if (_OK != errCode) {
//printf("Error %d\n", errCode);
}
// all done
return enumIdx;
}
/* -----------------------------------------------------------------------------
*
* Process data stream
* The purpose is to copy nv.bin data into built in NV data structure.
* This is the parser function.
*
* Next phase:
* With NV data in the s/w module data structure, nv.bin conforming
* to the new format can be generated. That is the nv.bin generation logic.)
*
* Data stream has the following format
*
* delimiter|streamHeader|tableID|data....|CRC|delimiter
* Note
* 1. delimiters are not present in the stream data, pStream.
* 2. nested tables do NOT have table IDs with them.
*
*/
// NV data, per built in templates
// Recursive table parsing, which is naturally depth-first
// If iterative, a bit hard to implement
static void parseSubDataTable4Size(int tableIdx, int numElem)
{
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
int idxSubTable;
int i;
int numSubElem = 0, idx=0;
// "apply" template to data -- parsing the actual NV data,
// so far we have been parsing and building templates
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[tableIdx][i].fieldName[0]) {
// data parsing done for this stream
break;
}
if (IsFieldTypeBasicData(pTable[tableIdx][i].fieldId)) {
getBasicDataSize(&(pTable[tableIdx][i]));
}
else {
// number of element
idx =
_STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
numSubElem = numElemBasedOnStorageType[idx](
&(pTable[tableIdx][i]), 1);
// get size of the sub-table
idxSubTable = (pTable[tableIdx][i].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
// recursive calls for the total size of the subtable
parseSubDataTable4Size(idxSubTable, numSubElem);
}
}
// update subTableSize for the number of elements
subTableSize *= numElem;
return;
}
static void copyDataToBuiltInFromBin(int tableIdx,int fieldId,
_NV_STREAM_BUF *pStream, int *pos, int addOffset, int tableBaseOffset)
{
int i,j,k,storageType;
int idx=0, size1=0, size2=0, size3=0;
int enumIdx1=0, enumIdx2=0, enumIdx3=0, sizeOneElem=0;
int isFirstFieldEnum=0,isSecondFieldEnum=0,isThirdFieldEnum=0;
int index,index1,index2;
int dindex,dindex1,dindex2,totalSize;
int offset=0,sizeBuiltIn,tableIdxBuiltIn,fieldIdBuiltIn;
int idxBuiltIn=0, size1BuiltIn=0, size2BuiltIn=0, size3BuiltIn=0;
int size1Bin=0, size2Bin=0, size3Bin=0, numElemBuiltIn;
int sizeOneElemBuiltIn=0, field;
unsigned char *ptr, *dptr;
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
_NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
field = pTable[tableIdx][fieldId].fieldId;
sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
sizeBuiltIn = getBuiltInFieldCount(tableIdx,
pTable[tableIdx][fieldId].fieldName,
&tableIdxBuiltIn,&fieldIdBuiltIn,&numElemBuiltIn);
field = pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldId;
sizeOneElemBuiltIn = sizeOneElemBasedOnFieldIdBasicDataType[field &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
if (storageType == SINGULAR ) {
ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset;
dptr = (unsigned char *)&pStream[*pos];
if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
size1Bin = numElemBasedOnStorageType[idx](
&(pTable[tableIdx][fieldId]), 1);
field = pTable[tableIdx][fieldId].fieldId;
sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
idxBuiltIn = _STORAGE_TYPE(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size1BuiltIn = numElemBasedOnStorageType[idx](
&(pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn]), 0);
size1 = size1Bin;
if (size1 > size1BuiltIn) {
size1 = size1BuiltIn;
}
}
totalSize = size1 * sizeOneElem;
offset = 0;
for (i = 0; i < size1; i++) {
vos_mem_copy(&ptr[offset], &dptr[offset], sizeOneElem);
offset = offset + sizeOneElem;
}
*pos = *pos + (size1Bin * sizeOneElem);
}
else {
if (ARRAY_1 == storageType) {
ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset;
dptr = (unsigned char *)&pStream[*pos];
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1, 1);
idx = _STORAGE_SIZE1(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size1BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
size1 = size1Bin;
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isFirstFieldEnum = 1;
}
else {
isFirstFieldEnum = 0;
if (size1 > size1BuiltIn) {
size1 = size1BuiltIn;
}
}
offset = 0;
for (i = 0; i < size1; i++) {
if (isFirstFieldEnum) {
if (NvEnumsFromBin[enumIdx1][i].enumValuePeer != 0xFF) {
index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
index = index * sizeOneElem;
dindex = dindex * sizeOneElem;
vos_mem_copy(&ptr[index], &dptr[dindex], sizeOneElem);
}
}
else {
vos_mem_copy(&ptr[offset], &dptr[offset], sizeOneElem);
offset = offset + sizeOneElem;
}
}
*pos = *pos + (size1Bin * sizeOneElem);
}
else if (ARRAY_2 == storageType) {
ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset;
dptr = (unsigned char *)&pStream[*pos];
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1, 1);
idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
pTable[tableIdx][fieldId].fieldStorageType);
size2Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize2, 1);
idx = _STORAGE_SIZE1(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size1BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0);
idx = _STORAGE_SIZE2(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size2BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, 0);
size1 = size1Bin;
size2 = size2Bin;
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isFirstFieldEnum = 1;
}
else {
isFirstFieldEnum = 0;
if (size1 > size1BuiltIn) {
size1 = size1BuiltIn;
}
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isSecondFieldEnum = 1;
}
else {
isSecondFieldEnum = 0;
if (size2 > size2BuiltIn) {
size2 = size2BuiltIn;
}
}
offset = 0;
for (i = 0; i < size1; i++) {
if (isFirstFieldEnum) {
if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
continue;
}
index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
}
else {
index = dindex = i;
}
for (j = 0; j < size2; j++) {
if (isSecondFieldEnum) {
if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
continue;
}
index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
}
else {
index1 = dindex1 = j;
}
vos_mem_copy(&ptr[(index1 + index * size2BuiltIn)*sizeOneElem],
&dptr[(dindex1+dindex*size2Bin)*sizeOneElem], sizeOneElem);
offset = offset + sizeOneElem;
}
}
*pos = *pos + size2Bin * size1Bin * sizeOneElem;
}
else if (ARRAY_3 == storageType) {
ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset;
dptr = (unsigned char *)&pStream[*pos];
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1, 1);
idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
pTable[tableIdx][fieldId].fieldStorageType);
size2Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize2, 1);
idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
pTable[tableIdx][fieldId].fieldStorageType);
size3Bin = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize3, 1);
idx = _STORAGE_SIZE1(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size1BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
0);
idx = _STORAGE_SIZE2(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size2BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
0);
idx = _STORAGE_SIZE3(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size3BuiltIn = getNumElemOutOfStorageSize(idx,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
0);
size1 = size1Bin;
size2 = size2Bin;
size3 = size3Bin;
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isFirstFieldEnum = 1;
}
else {
isFirstFieldEnum = 0;
if (size1 > size1BuiltIn) {
size1 = size1BuiltIn;
}
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isSecondFieldEnum = 1;
}
else {
isSecondFieldEnum = 0;
if (size2 > size2BuiltIn) {
size2 = size2BuiltIn;
}
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
isThirdFieldEnum = 1;
}
else {
isThirdFieldEnum = 0;
if (size3 > size3BuiltIn) {
size3 = size3BuiltIn;
}
}
offset = 0;
for (i = 0; i < size1; i++) {
if (isFirstFieldEnum) {
if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) {
continue;
}
index = NvEnumsFromBin[enumIdx1][i].enumValuePeer;
dindex = NvEnumsFromBin[enumIdx1][i].enumValue;
}
else {
index = dindex = i;
}
for (j = 0; j < size2; j++) {
if (isSecondFieldEnum) {
if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
continue;
}
index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer;
dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue;
}
else {
index1 = dindex1 = j;
}
for (k = 0; k < size3; k++) {
if (isThirdFieldEnum) {
if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) {
continue;
}
index2 = NvEnumsFromBin[enumIdx3][k].enumValuePeer;
dindex2 = NvEnumsFromBin[enumIdx3][k].enumValue;
}
else {
index2 = dindex2 = k;
}
vos_mem_copy(&ptr[(index2 + (index1 * size2BuiltIn) +
(index * size3BuiltIn * size2BuiltIn)) * sizeOneElem],
&dptr[(dindex2 + (dindex1 * size2Bin) +
(dindex * size3Bin * size2Bin))*sizeOneElem],
sizeOneElem);
offset = offset + sizeOneElem;
}
}
}
*pos = *pos + size1Bin * size2Bin * size3Bin * sizeOneElem;
}
else {
}
}
}
// search NvTablesBuiltIn for the same string named table, and its idx
static int getBuiltInFieldCount (int tableIdxBin, char *tableNameFromBin,
int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElements)
{
int i,idx,numElem,tableIdxBuiltin=0,fieldCnt;
_NV_TEMPLATE_TABLE (*pTableBin)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
int found=0, fieldIndex = 0;
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTableBin[0][i].fieldName[0]) {
break;
}
if ((pTableBin[0][i].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK) == tableIdxBin) {
found = 1;
break;
}
}
if (!found) {
return -1;
}
//fieldName index got from tableId from Bin
fieldIndex = i;
found = 0;
for (i=0;i<TABLE_ENTRIES_MAX;i++) {
if (nul == pTable[0][i].fieldName[0]) {
break;
}
if (!strcmp((const char*)pTableBin[0][fieldIndex].fieldName,
(const char*)pTable[0][i].fieldName)) {
found = 1;
break;
}
}
if (!found) {
return -1;
}
//found tableId of builtIn
tableIdxBuiltin = *tblIdBuiltIn =
(pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
found = 0;
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[tableIdxBuiltin][i].fieldName[0]) {
break;
}
if (!strcmp((const char*)tableNameFromBin,
(const char*)pTable[tableIdxBuiltin][i].fieldName)) {
found = 1;
break;
}
}
if (!found) {
return -1;
}
*fieldIdBuitIn = i;
idx = _STORAGE_TYPE(pTable[tableIdxBuiltin][i].fieldStorageType);
numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdxBuiltin][i]), 0);
fieldSize = 0;
fieldCnt = getFieldCount (tableIdxBuiltin, i, numElem, 0);
*numElements = numElem;
return fieldCnt;
}
static int getFieldCount(int tableIdx, int fieldId, int numElem, int nvBin)
{
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX];
int idxSubTable;
int i, j, storageType, field;
int numSubElem=0, idx =0, size1=0, size2=0, size3=0, sizeOneElem=0;
int enumIdx1=0, enumIdx2=0, enumIdx3=0;
if ( nvBin ) {
pTable = NvTablesFromBin;
}
else {
pTable = NvTablesBuiltIn;
}
storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
if (SINGULAR == storageType) {
if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
size1 = numElemBasedOnStorageType[idx](&(pTable[tableIdx][fieldId]),
nvBin);
}
else {
}
}
else {
if (ARRAY_1 == storageType) {
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
}
else if (ARRAY_2 == storageType) {
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
pTable[tableIdx][fieldId].fieldStorageType);
size2 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
}
else if (ARRAY_3 == storageType) {
idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize1,nvBin);
idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2,
pTable[tableIdx][fieldId].fieldStorageType);
size2 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize2,nvBin);
idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
pTable[tableIdx][fieldId].fieldStorageType);
size3 = getNumElemOutOfStorageSize(idx,
pTable[tableIdx][fieldId].fieldStorageSize3,nvBin);
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) {
enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
}
}
else {
}
}
if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
field = pTable[tableIdx][fieldId].fieldId;
sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK];
if ( size3 ) {
fieldSize = fieldSize + size3 * size2 * size1 * sizeOneElem;
}
else if ( size2 ) {
fieldSize = fieldSize + size2 * size1 * sizeOneElem;
}
else if ( size1 ) {
fieldSize = fieldSize + size1 * sizeOneElem;
}
else {
}
}
else {
idxSubTable = (pTable[tableIdx][fieldId].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
for (j=0; j<numElem; j++) {
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[idxSubTable][i].fieldName[0]) {
// data parsing done for this stream
break;
}
idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
numSubElem = numElemBasedOnStorageType[idx](
&(pTable[idxSubTable][i]),nvBin);
getFieldCount(idxSubTable, i, numSubElem, nvBin);
}
}
}
return fieldSize;
}
static void parseSubDataTableAndCopy(int tableIdx, int numElem, int numElem2,
int numElem3, int fieldId, _NV_STREAM_BUF *pStream, int *pos, int addOffset,
int tableBaseOffset, int localAddOffset)
{
int idxSubTable, i, j, l, m, idx1, storageType, fieldCount=0;
int size1BuiltIn, size2BuiltIn, size3BuiltIn;
int tableIdxBuiltIn, fieldIdBuiltIn, numElemBuiltIn, incAddOffset=0;
int totalOffset=0, enumIdx, size1Bin, size2Bin, size3Bin;
int numSubElem, numSubElem2, numSubElem3, sizeBuiltIn=0, idx=0;
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
_NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn;
// "apply" template to data -- parsing the actual NV data,
// so far we have been parsing and building templates
if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) {
// First Entry, same as off addOffset just increment localOffset
if (pTable[tableIdx][fieldId].offset == addOffset) {
totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset;
}
else {
// Multiple Entry next index array, addOffset and localOffset
totalOffset = localAddOffset + pTable[tableIdx][fieldId].offset +
addOffset;
}
copyDataToBuiltInFromBin(tableIdx, fieldId, pStream, pos, totalOffset,
tableBaseOffset);
}
else {
// number of element
// get size of the sub-table
idxSubTable = (pTable[tableIdx][fieldId].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
fieldSize = 0;
sizeBuiltIn = getBuiltInFieldCount(tableIdx,
pTable[tableIdx][fieldId].fieldName,
&tableIdxBuiltIn, &fieldIdBuiltIn, &numElemBuiltIn);
incAddOffset = 0;
if (numElemBuiltIn) {
incAddOffset = sizeBuiltIn/numElemBuiltIn;
}
storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType);
fieldSize = 0;
fieldCount = getFieldCount(tableIdx, fieldId, numElem, 1);
idx1 = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1,
pTable[tableIdx][fieldId].fieldStorageType);
size1Bin = getNumElemOutOfStorageSize(idx1,
pTable[tableIdx][fieldId].fieldStorageSize1, 1);
for (l=0; l < numElem3; l++) {
if (storageType == ARRAY_3) {
idx1 = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3,
pTable[tableIdx][fieldId].fieldStorageType);
size3Bin = getNumElemOutOfStorageSize(idx1,
pTable[tableIdx][fieldId].fieldStorageSize3, 1);
fieldSize = 0;
getBuiltInFieldCount(tableIdx,
pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
&fieldIdBuiltIn, &numElemBuiltIn);
idx1 = _STORAGE_SIZE3(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size3BuiltIn = getNumElemOutOfStorageSize(idx1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3,
0);
if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) {
enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize3 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
if (NvEnumsFromBin[enumIdx][l].enumValuePeer == 0xFF) {
*pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
continue;
}
}
else {
if ((l+1) > size3BuiltIn) {
*pos = *pos + (fieldCount/size1Bin) * numElem * numElem2;
continue;
}
}
}
for (m=0; m < numElem2; m++) {
if (storageType == ARRAY_2) {
idx1 = _STORAGE_SIZE2(
pTable[tableIdx][fieldId].fieldStorageSize2,
pTable[tableIdx][fieldId].fieldStorageType);
size2Bin = getNumElemOutOfStorageSize(idx1,
pTable[tableIdx][fieldId].fieldStorageSize2, 1);
fieldSize = 0;
getBuiltInFieldCount(tableIdx,
pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
&fieldIdBuiltIn, &numElemBuiltIn);
idx1 = _STORAGE_SIZE2(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size2BuiltIn = getNumElemOutOfStorageSize(idx1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2,
0);
if (!IsFieldSizeInt(
pTable[tableIdx][fieldId].fieldStorageSize2)) {
enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize2 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
if (NvEnumsFromBin[enumIdx][m].enumValuePeer == 0xFF) {
*pos = *pos + (fieldCount/size1Bin) * numElem;
continue;
}
}
else {
if ((m+1) > size2BuiltIn) {
*pos = *pos + (fieldCount/size1Bin) * numElem;
continue;
}
}
}
for (j=0; j < numElem; j++) {
if (storageType == ARRAY_1) {
fieldSize = 0;
getBuiltInFieldCount(tableIdx,
pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn,
&fieldIdBuiltIn, &numElemBuiltIn);
idx1 = _STORAGE_SIZE1(
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType);
size1BuiltIn = getNumElemOutOfStorageSize(idx1,
pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1,
0);
if (!IsFieldSizeInt(
pTable[tableIdx][fieldId].fieldStorageSize1)) {
enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize1 &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
if (NvEnumsFromBin[enumIdx][j].enumValuePeer == 0xFF) {
*pos = *pos + (fieldCount/size1Bin);
continue;
}
}
else {
if ((j+1) > size1BuiltIn) {
*pos = *pos + (fieldCount/size1Bin);
continue;
}
}
}
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[idxSubTable][i].fieldName[0]) {
// data parsing done for this stream
break;
}
idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType);
numSubElem = numElemBasedOnStorageType[idx](
&(pTable[idxSubTable][i]),1);
numSubElem2 = numSubElem3 = 1;
if (idx == ARRAY_1) {
idx1 = _STORAGE_SIZE1(
pTable[idxSubTable][i].fieldStorageSize1,
pTable[idxSubTable][i].fieldStorageType);
numSubElem = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize1, 1);
}
else if (idx == ARRAY_2) {
idx1 = _STORAGE_SIZE1(
pTable[idxSubTable][i].fieldStorageSize1,
pTable[idxSubTable][i].fieldStorageType);
numSubElem = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize1, 1);
idx1 = _STORAGE_SIZE2(
pTable[idxSubTable][i].fieldStorageSize2,
pTable[idxSubTable][i].fieldStorageType);
numSubElem2 = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize2, 1);
}
else if (idx == ARRAY_3) {
idx1 = _STORAGE_SIZE1(
pTable[idxSubTable][i].fieldStorageSize1,
pTable[idxSubTable][i].fieldStorageType);
numSubElem = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize1, 1);
idx1 = _STORAGE_SIZE2(
pTable[idxSubTable][i].fieldStorageSize2,
pTable[idxSubTable][i].fieldStorageType);
numSubElem2 = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize2, 1);
idx1 = _STORAGE_SIZE3(
pTable[idxSubTable][i].fieldStorageSize3,
pTable[idxSubTable][i].fieldStorageType);
numSubElem3 = getNumElemOutOfStorageSize(idx1,
pTable[idxSubTable][i].fieldStorageSize3, 1);
}
if (_OFFSET_NOT_SET != pTable[idxSubTable][i].offset) {
if ( pTable[tableIdx][fieldId].offset == addOffset ) {
parseSubDataTableAndCopy(idxSubTable, numSubElem,
numSubElem2, numSubElem3, i, pStream, pos,
addOffset, tableBaseOffset, localAddOffset);
}
else {
// NOT the first Entry in the table..
if ( !pTable[tableIdx][fieldId].offset ) {
parseSubDataTableAndCopy(idxSubTable, numSubElem,
numSubElem2, numSubElem3, i, pStream, pos,
addOffset, tableBaseOffset, localAddOffset);
}
else {
//First Entry in the the table..
//(Sending parent offset..)
parseSubDataTableAndCopy(idxSubTable, numSubElem,
numSubElem2, numSubElem3, i, pStream, pos,
addOffset, tableBaseOffset,
pTable[tableIdx][fieldId].offset);
}
}
}
else {
fieldSize = 0;
fieldCount = getFieldCount(idxSubTable, i, numSubElem, 1);
*pos += fieldCount;
}
}
localAddOffset = localAddOffset + incAddOffset;
}
}
}
}
return;
}
static void processNvData(_NV_STREAM_BUF *pStream, int len)
{
int tableIdx, pos, idx = 0, addOffset = 0, i;
int numElem = 0, additionalOffset = 0, tableBaseOffset = 0;
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
// fetch the table template
pos = 0; // stream header byte is already checked, that's why we are here
pos += _NV_BIN_DATA_STREAM_TABLEID_BYTE;
tableIdx = (pStream[_NV_BIN_DATA_STREAM_TABLEID_BYTE] &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
pos++;
// call the table parsing
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[0][i].fieldName[0]) {
break;
}
if (tableIdx == _TABLE_IDX(pTable[0][i].fieldId)) {
// Table base offset, stored in the "table of all tables" (index 0),
// will be added to
// fields relative offset in all tables.
tableBaseOffset = pTable[0][i].offset;
idx = _STORAGE_TYPE(pTable[0][i].fieldStorageType);
// number of element
numElem = numElemBasedOnStorageType[idx](&(pTable[0][i]),1);
// recursive calls for the total size of the subtable, which may
// contain nested tables
subTableSize = 0;
parseSubDataTable4Size(tableIdx, numElem);
// additional offset for EACH subsequent table element
additionalOffset = subTableSize/numElem;
break;
}
}
if (numElem) {
for (i = 0; i < numElem; i++) {
addOffset = (i * additionalOffset);
parseDataTable_new(pStream, &pos, tableIdx, addOffset,
tableBaseOffset);
}
}
// the above recursive data table parser takes care of the nested tables
// all done
return;
}
static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos, int tableIdx,
int addOffset, int tableBaseOffset)
{
_NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin;
int i, idx, fieldCount;
int numElem, numElem2, numElem3, storageType, idxSubTable;
// "apply" template to data -- parsing the actual NV data,
// so far we have been parsing and building templates
for (i = 0; i < TABLE_ENTRIES_MAX; i++) {
if (nul == pTable[tableIdx][i].fieldName[0]) {
// data parsing done for this stream
break;
}
// get size of the sub-table
idxSubTable = (pTable[tableIdx][i].fieldId &
FIELD_ID_TABLE_OR_ENUM_IDX_MASK);
idx = _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType);
numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdx][i]),1);
addOffset = pTable[tableIdx][i].offset;
fieldSize = 0;
fieldCount = getFieldCount(tableIdx, i, numElem, 1);
numElem2 = numElem3 = 1;
if (idx == ARRAY_1 ) {
storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
pTable[tableIdx][i].fieldStorageType);
numElem = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize1, 1);
}
else if (idx == ARRAY_2) {
storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
pTable[tableIdx][i].fieldStorageType);
numElem = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize1, 1);
storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
pTable[tableIdx][i].fieldStorageType);
numElem2 = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize2, 1);
}
else if (idx == ARRAY_3) {
storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1,
pTable[tableIdx][i].fieldStorageType);
numElem = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize1, 1);
storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2,
pTable[tableIdx][i].fieldStorageType);
numElem2 = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize2, 1);
storageType = _STORAGE_SIZE3(pTable[tableIdx][i].fieldStorageSize3,
pTable[tableIdx][i].fieldStorageType);
numElem3 = getNumElemOutOfStorageSize(storageType,
pTable[tableIdx][i].fieldStorageSize3, 1);
}
if (_OFFSET_NOT_SET != pTable[tableIdx][i].offset) {
parseSubDataTableAndCopy(tableIdx, numElem, numElem2, numElem3, i,
pStream, pos, addOffset, tableBaseOffset, 0);
}
else {
*pos += fieldCount;
}
}
}
static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry)
{
int numElem, sizeOneElem, totalSize;
int idx, idx1;
// number of element
idx = _STORAGE_TYPE(pTableEntry->fieldStorageType);
numElem = numElemBasedOnStorageType[idx](pTableEntry, 1);
// size of each element
idx1 = pTableEntry->fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK;
sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[idx1];
// total size in bytes
totalSize = numElem * sizeOneElem;
// all done, update global
subTableSize += totalSize;
return;
}
static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry, int unused)
{
return 1;
}
static int getNumElemOutOfStorageSize(int fieldStorageSize,
uint8 fieldStorageSizeLowByte, int nvBin)
{
int ret = 0;
if (IsFieldSizeInt(fieldStorageSizeLowByte)) {
return fieldStorageSize;
}
else {
int maxEnumVal=0, i;
_NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX];
int enumIdx = ((fieldStorageSizeLowByte &
FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB);
if (nvBin) {
pEnum = NvEnumsFromBin;
}
else {
pEnum = NvEnumsBuiltIn;
}
for (i = 0; i < ENUM_ENTRIES_MAX; i++) {
if (nul == pEnum[enumIdx][i].enumName[0]) {
if ( i == 0 ) {
maxEnumVal = 0;
}
else {
maxEnumVal = pEnum[enumIdx][i-1].enumValue;
}
break;
}
}
ret = (maxEnumVal + 1);
return ret; // +1 to count for 0 to maxEnumVal
}
}
static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
{
int fieldStorageSize = 0;
fieldStorageSize = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
pTableEntry->fieldStorageSize1, pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize1, nvBin);
return fieldStorageSize;
}
static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
{
int fieldStorageSize1,fieldStorageSize2,fieldStorageSize;
fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
pTableEntry->fieldStorageSize1,
pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize1, nvBin);
fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
pTableEntry->fieldStorageSize2,
pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize2, nvBin);
fieldStorageSize = fieldStorageSize1 * fieldStorageSize2;
return fieldStorageSize;
}
static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin)
{
int fieldStorageSize1,fieldStorageSize2,fieldStorageSize3,fieldStorageSize;
fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1(
pTableEntry->fieldStorageSize1,
pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize1, nvBin);
fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2(
pTableEntry->fieldStorageSize2,
pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize2, nvBin);
fieldStorageSize3 = getNumElemOutOfStorageSize(_STORAGE_SIZE3(
pTableEntry->fieldStorageSize3,
pTableEntry->fieldStorageType),
pTableEntry->fieldStorageSize3, nvBin);
fieldStorageSize = fieldStorageSize1 * fieldStorageSize2 * fieldStorageSize3;
return fieldStorageSize;
}