blob: 499158bb61f4e0dd8043523fffd5ab8d8db3d1c9 [file] [log] [blame]
/*******************************************************************/
/************************* File Description ************************/
/*******************************************************************/
/* File Name: $Workfile: hmx_uprade_nvram.c $
* Version: $Revision: 1.0 $
* Original Author: Yang Hyun Uk $
* Current Author: $Author: huyang@humaxdigital.com $
* Date: $Date: 2011.11.07
* File Description: Humax Upgrade APIs
* Module:
* Remarks:
*/
/**
* @defgroup NVRAM APIs for Upgrade Module
* @ingroup UPGRADE
*/
/**
* @author Hyunuk Yang(huyang@humaxdigital.com)
* @date 07 Nov 2011
*/
/**
* @note
* Copyright (C) 2011 Humax Corporation. All Rights Reserved. <br>
* This software is the confidential and proprietary information
* of Humax Corporation. You may not use or distribute this software
* except in compliance with the terms and conditions of any applicable license
* agreement in writing between Humax Corporation and you.
*/
/*@{*/
/**
* @file hmx_upgrade_nvram.c
*/
/*******************************************************************/
/**************************** Header Files *************************/
/*******************************************************************/
/* Start Including Header Files */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lib_queue.h"
#include "hmx_upgrade_nvram.h"
/* End Including Headers */
/*******************************************************************/
/****************************** define *****************************/
/*******************************************************************/
#define NVRAM_TYPE_LEN 1
#define NVRAM_RECORD_LENG_LEN 4
#define NVRAM_NAME_LENG_LEN 1
#define NVRAM_DATA_LENG_LEN 4
#define MAX_NAME_LEN (256)
#define MAX_DATA_LEN (256*1024)
#define MAX_FIELD_LEN (MAX_DATA_LEN+MAX_NAME_LEN*2)
#define NVRAM_TLV_TYPE_END 0x00
#define NVRAM_TLV_TYPE_ENV 0x01
#define get8bit(q) (unsigned char)((q)[0])
#define get32bit(q) (unsigned int)(((*(unsigned char *)(q)) << 24) | (*((unsigned char *)(q)+1) << 16) | (*((unsigned char *)(q)+2) << 8) | (*((unsigned char *)(q)+3)) )
#define DEBUG_ERR printf
#define DEBUG_INFO printf
#define UNUSED(x) (void)(x)
#define MAX_NVRAM_FILENAME_LENGTH 32
#define SEM_Get(x) (void)(x)
#define SEM_Release(x) (void)(x)
#define NVRAM_RO_OFFSET 0x0
#define NVRAM_RO_SIZE 0x00100000
#define NVRAM_RW_OFFSET ( NVRAM_RO_OFFSET + NVRAM_RO_SIZE )
#define NVRAM_RW_SIZE 0x00040000
#define NVRAM_RWB_OFFSET ( NVRAM_RW_OFFSET + NVRAM_RW_SIZE)
#define NVRAM_RWB_SIZE 0x00020000
#define RAW_FS_OFFSET ( NVRAM_RWB_OFFSET + NVRAM_RWB_SIZE)
#define RAW_FS_SIZE 0x00020000
/* End #define */
/*******************************************************************/
/****************************** typedef ****************************/
/*******************************************************************/
/* Start typedef */
typedef struct NVRAM_EVNVAR_t{
queue_t qb;
unsigned int recLen;
unsigned char *name;
unsigned char nameLen;
unsigned char *value;
unsigned int valueLen;
} NVRAM_EVNVAR_T;
typedef struct HMX_NVRAM_MAP_t
{
NVRAM_FIELD_T type;
unsigned char szFileName[MAX_NVRAM_FILENAME_LENGTH];
HMX_NVRAM_PARTITION_E storePartition;
unsigned int defaultSize;
} HMX_NVRAM_FIELD_INFO_T;
HMX_NVRAM_FIELD_INFO_T s_nvramFieldInfo[] =
{
{NVRAM_FIELD_SYSTEM_ID , "SYSTEM_ID" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_SFLASH , "SFLASH" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_SERIAL_NO , "SERIAL_NO" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_DTCP_KEY , "DTCP_KEY" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_CI_PLUS_KEY , "CI_PLUS_KEY" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_MAC_ADDR , "MAC_ADDR" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_HDCP_KEY , "HDCP_KEY" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_PARING_DATA , "PARING_DATA" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_CM_SERIAL_NO , "CM_SERIAL_NO" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_CM_MAC_ADDR , "CM_MAC_ADDR" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_CM_MAC_ADDR_ANOTHER , "CM_MAC_ADDR_ANOTHER" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_IRDETO_BBCB , "IRDETO_BBCB" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_IRDETO_CPCB , "IRDETO_CPCB" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_IRDETO_CPCB_ENCRYPTED, "IRDETO_CPCB_ENCRYPTED" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_PRIVATE , "PRAVATE" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_CSC_KEY , "CSC_KEY" , HMX_NVRAM_PARTITION_RO, 0},
{NVRAM_FIELD_LOADER_VER , "LOADER_VER" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_APP_VER , "APP_VER" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_LANGUAGE , "LANGUAGE" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TV_STANDARD , "TV_STANDARD" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_SCART_RGB , "SCART_RGB" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_HD_RESOULTION , "HD_RESOULTION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_FIELD_RATE , "FIELD_RATE" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_FLAG1 , "OTA_FLAG1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_FLAG2 , "OTA_FLAG2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_FLAG3 , "OTA_FLAG3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_TYPE1 , "OTA_TYPE1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_TYPE2 , "OTA_TYPE2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_TYPE3 , "OTA_TYPE3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_TYPE1 , "CH_TYPE1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_TYPE2 , "CH_TYPE2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_TYPE3 , "CH_TYPE3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TUNER_ID1 , "TUNER_ID1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TUNER_ID2 , "TUNER_ID2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TUNER_ID3 , "TUNER_ID3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ANTENA_POWER1 , "ANTENA_POWER1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ANTENA_POWER2 , "ANTENA_POWER2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ANTENA_POWER3 , "ANTENA_POWER3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ES_PID1 , "ES_PID1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ES_PID2 , "ES_PID2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ES_PID3 , "ES_PID3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TRANSACTION_ID1 , "TRANSACTION_ID1" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TRANSACTION_ID2 , "TRANSACTION_ID2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_TRANSACTION_ID3 , "TRANSACTION_ID3" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_APP_VERSION , "APP_VERSION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTALDR_VERSION , "OTALDR_VERSION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CUR_OTAIMAGE_VERSION , "CUR_OTAIMAGE_VERSION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OAD_VERSION , "OAD_VERSION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_NET_IP_CONFIG , "NET_IP_CONFIG" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_NET_IP_SETTING , "NET_IP_SETTING" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_RCU_CUSTOM_CODE , "RCU_CUSTOM_CODE" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_RCU_CUSTOM_CODE2 , "RCU_CUSTOM_CODE2" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_PANEL_DISPLAY , "PANEL_DISPLAY" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_PANEL_DIMMING , "PANEL_DIMMING" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ASPECT_RATIO , "ASPECT_RATIO" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_COUNTRY_CODE , "COUNTRY_CODE" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_USAGE_ID , "USAGE_ID" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_INFO_S , "CH_INFO_S" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_INFO_T , "CH_INFO_T" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_CH_INFO_C , "CH_INFO_C" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OTA_FTP_INFO , "FTP_OTA_INFO" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_NET_PORTAL_IP , "NET_PORTAL_IP" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_NET_DOWN_PATH , "NET_DOWN_PATH" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_LOADER_VERSION , "LOADER_VERSION" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_OSD_DISPLAY , "OSD_DISPLAY" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ACTIVATED_KERNEL_NUM, "ACTIVATED_KERNEL_NUM" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_MTD_TYPE_FOR_KERNEL , "MTD_TYPE_FOR_KERNEL" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_ACTIVATED_KERNEL_NAME , "ACTIVATED_KERNEL_NAME" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_EXTRA_KERNEL_OPT , "EXTRA_KERNEL_OPT" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_PLATFORM_NAME , "PLATFORM_NAME" , HMX_NVRAM_PARTITION_RW, 0},
{NVRAM_FIELD_BIN8K , "BIN8K" , HMX_NVRAM_PARTITION_RW, 0x2000},
{NVRAM_FIELD_RAWFS , "RAWFS" , HMX_NVRAM_PARTITION_W_RAWFS, RAW_FS_SIZE},
{NVRAM_FIELD_DUMMY , "DUMMY" , HMX_NVRAM_PARTITION_RW, 0}
};
/* End typedef */
/*******************************************************************/
/************************ global variables *************************/
/*******************************************************************/
/* Start global variable */
static queue_t s_nvram_envvars[HMX_NVRAM_PARTITION_MAX] = {
{&s_nvram_envvars[0],&s_nvram_envvars[0]},
{&s_nvram_envvars[1],&s_nvram_envvars[1]},
{&s_nvram_envvars[2],&s_nvram_envvars[2]},
};
static unsigned int s_nvram_offset[HMX_NVRAM_PARTITION_MAX] = {
NVRAM_RO_OFFSET,
NVRAM_RW_OFFSET,
RAW_FS_OFFSET
};
static unsigned int s_nvram_backup_offset[HMX_NVRAM_PARTITION_MAX] = {
0,
NVRAM_RWB_OFFSET,
0
};
static unsigned int s_nvram_size[HMX_NVRAM_PARTITION_MAX] = {
NVRAM_RO_SIZE,
NVRAM_RW_SIZE,
RAW_FS_SIZE
};
/* End global variable */
/*******************************************************************/
/************************ static variables *************************/
/*******************************************************************/
/* Start static variable */
static unsigned long s_nvramSema;
/* End static variable */
/*******************************************************************/
/************************ static funtions **************************/
/*******************************************************************/
/* *********************************************************************0
* HMX_NVRAM_Read(buffer,offset,length)0
* 0
* Read data from the NVRAM device0
*
* Input parameters:
* buffer - destination buffer
* offset - offset of data to read
* length - number of bytes to read
*
* Return value:
* number of bytes read, or <0 if error occured
********************************************************************* */
static int drv_NVRAM_Read(unsigned char *buffer,unsigned int offset,unsigned int length)
{
DRV_Error drv_error;
drv_error = HMX_UPGRADE_NVRAM_Read(offset, buffer, length);
if (drv_error != 0)
{
return -1;
}
return length;
}
/* *********************************************************************
* HMX_NVRAM_Write(buffer,offset,length)
*
* Write data to the NVRAM device
*
* Input parameters:
* buffer - source buffer
* offset - offset of data to write
* length - number of bytes to write
*
* Return value:
* number of bytes written, or -1 if error occured
********************************************************************* */
static int drv_NVRAM_Write(unsigned char *buffer,unsigned int offset,unsigned int length)
{
DRV_Error drv_error;
drv_error = HMX_UPGRADE_NVRAM_Write(offset, buffer, length);
if (drv_error != 0)
{
return -1;
}
return length;
}
/* *********************************************************************
* HMX_NVRAM_FindEnv(name)
*
* Locate an environment variable in the in-memory list
*
* Input parameters:
* name - name of env var to find
*
* Return value:
* NVRAM_EVNVAR_T pointer, or NULL if not found
********************************************************************* */
static NVRAM_EVNVAR_T *drv_NVRAM_FindEnv(HMX_NVRAM_PARTITION_E partition, const unsigned char *name)
{
queue_t *qb;
NVRAM_EVNVAR_T *env;
for (qb = s_nvram_envvars[partition].q_next; qb != &s_nvram_envvars[partition]; qb = qb->q_next)
{
env = (NVRAM_EVNVAR_T *) qb;
if (strcmp((char*)env->name, (char*)name) == 0)
break;
}
if (qb == &s_nvram_envvars[partition])
return NULL;
return (NVRAM_EVNVAR_T *) qb;
}
/* *********************************************************************
* HMX_NVRAM_ScanDir(idx,name,namelen,val,vallen)
*
* Enumerate environment variables. This routine locates
* the nth environment variable and copies its name and value
* to user buffers.
*
* The namelen and vallen variables must be preinitialized to
* the maximum size of the output buffer.
*
* Input parameters:
* idx - variable index to find (starting with zero)
* name,namelen - name buffer and length
* val,vallen - value buffer and length
*
* Return value:
* 0 if ok
* else error code
********************************************************************* */
static DRV_Error drv_NVRAM_ScanDir(HMX_NVRAM_PARTITION_E partition, unsigned int idx, unsigned char *name, unsigned int *namelen, unsigned char *val, unsigned int *vallen)
{
queue_t *qb;
NVRAM_EVNVAR_T *env;
for (qb = s_nvram_envvars[partition].q_next; qb != &s_nvram_envvars[partition]; qb = qb->q_next) {
if (idx == 0)
break;
idx--;
}
if (qb == &s_nvram_envvars[partition])
{
return DRV_ERR;
}
env = (NVRAM_EVNVAR_T *) qb;
if (name != NULL)
{
strncpy((char*)name, (char*)env->name, env->nameLen);
name[env->nameLen] = 0;
}
*namelen = env->nameLen;
if (val != NULL)
{
memcpy(val, env->value, env->valueLen);
}
*vallen = env->valueLen;
return DRV_OK;
}
/* *********************************************************************
* HMX_NVRAM_Delete(name)
*
* Delete an environment variable
*
* Input parameters:
* name - environment variable to delete
*
* Return value:
* 0 if ok
* else error code
********************************************************************* */
static DRV_Error drv_NVRAM_Delete(HMX_NVRAM_PARTITION_E partition, const unsigned char *name)
{
NVRAM_EVNVAR_T *env;
env = drv_NVRAM_FindEnv(partition, name);
if (env == NULL)
{
return DRV_ERR;
}
q_dequeue((queue_t *) env);
free(env);
return DRV_OK;
}
/* *********************************************************************
* HMX_NVRAM_GetEnv(name)
*
* Retrieve the value of an environment variable
*
* Input parameters:
* name - name of environment variable to find
*
* Return value:
* value, or NULL if variable is not found
********************************************************************* */
static DRV_Error drv_NVRAM_GetEnv(HMX_NVRAM_PARTITION_E partition, const unsigned char *name, const unsigned int offset, unsigned char *value, unsigned int readLen)
{
NVRAM_EVNVAR_T *env;
unsigned int len;
memset(value, 0, readLen);
env = drv_NVRAM_FindEnv(partition, name);
if (env != NULL)
{
if (readLen > env->valueLen - offset)
len = env->valueLen - offset;
else
len = readLen;
memcpy(value, env->value+offset, len);
}
return DRV_OK;
}
/* *********************************************************************
* HMX_NVRAM_GetLength(name)
*
* Retrieve the value of an environment variable
*
* Input parameters:
* name - name of environment variable to find
*
* Return value:
* value, or NULL if variable is not found
********************************************************************* */
static DRV_Error drv_NVRAM_GetLength(HMX_NVRAM_PARTITION_E partition, const unsigned char *name, unsigned int *pLen)
{
NVRAM_EVNVAR_T *env;
env = drv_NVRAM_FindEnv(partition, name);
if (env != NULL)
{
*pLen = env->valueLen;
return DRV_OK;
}
return DRV_ERR_INVALID_PARAMETER;
}
/* *********************************************************************
* HMX_NVRAM_SetEnv(name,value,flags)
*
* Set the value of an environment variable
*
* Input parameters:
* name - name of variable
* value - value of variable
* flags - flags for variable (ENV_FLG_xxx)
*
* Return value:
* 0 if ok
* else error code
********************************************************************* */
static DRV_Error drv_NVRAM_SetEnv(HMX_NVRAM_PARTITION_E partition, const unsigned char *name, unsigned char *value, unsigned int valueLen)
{
NVRAM_EVNVAR_T *env;
unsigned int namelen;
env = drv_NVRAM_FindEnv(partition, name);
if (env)
{
q_dequeue((queue_t *) env);
free(env);
}
namelen = strlen((char*)name);
env = malloc(sizeof(NVRAM_EVNVAR_T) + namelen + 1 + valueLen);
if (!env)
{
return DRV_ERR_OUTOFMEMORY;
}
env->name = (unsigned char *) (env+1);
env->value = env->name + namelen + 1;
env->nameLen = namelen;
env->valueLen = valueLen;
env->recLen = (NVRAM_NAME_LENG_LEN + namelen + NVRAM_DATA_LENG_LEN + valueLen);
strncpy((char*)env->name, (char*)name, namelen);
env->name[namelen] = 0;
memcpy(env->value, value, valueLen);
q_enqueue(&s_nvram_envvars[partition],(queue_t *) env);
return DRV_OK;
}
/* *********************************************************************
* HMX_NVRAM_Load()
*
* Load the environment from the NVRAM device.
*
* Input parameters:
* nothing
*
* Return value:
* 0 if ok
* else error code
********************************************************************* */
static DRV_Error drv_NVRAM_LoadByAddress(HMX_NVRAM_PARTITION_E partition, unsigned int address, unsigned int size)
{
unsigned int nvram_size;
unsigned char *buffer;
unsigned char *ptr;
unsigned int recLen;
unsigned int recType;
unsigned int offset;
unsigned int retval;
unsigned char fileName[MAX_NAME_LEN];
unsigned char nameLen;
unsigned int dataLen;
nvram_size = size;
buffer = malloc(MAX_FIELD_LEN);
if (buffer == NULL)
{
return DRV_ERR_OUTOFMEMORY;
}
ptr = buffer;
offset = 0;
retval = DRV_OK;
/* Read the record type and length */
if (drv_NVRAM_Read(ptr,offset+address,NVRAM_TYPE_LEN) != NVRAM_TYPE_LEN)
{
retval = DRV_ERR_EXTERNAL_ERROR;
goto error;
}
while ((*ptr != NVRAM_TLV_TYPE_END) && (nvram_size > NVRAM_TYPE_LEN))
{
/* Adjust pointer for TLV type */
recType = get8bit(ptr);
nvram_size -= NVRAM_TYPE_LEN;
offset += NVRAM_TYPE_LEN;
if (recType != NVRAM_TLV_TYPE_ENV)
{
retval = DRV_ERR_EVENT_INITIALIZATION;
goto error;
}
/* Read the record type and length - 16 bits, MSB first */
if (drv_NVRAM_Read(ptr, offset+address, NVRAM_RECORD_LENG_LEN) != NVRAM_RECORD_LENG_LEN)
{
retval = DRV_ERR_EXTERNAL_ERROR;
goto error;
}
recLen = get32bit(ptr);
nvram_size -= NVRAM_RECORD_LENG_LEN;
offset += NVRAM_RECORD_LENG_LEN;
if (recLen > MAX_FIELD_LEN)
{
retval = DRV_ERR_EVENT_INITIALIZATION;
goto error;
}
if (recLen > nvram_size)
{
retval = DRV_ERR_EVENT_INITIALIZATION;
goto error; /* should not happen, bad NVRAM */
}
/* Read the TLV data */
if (drv_NVRAM_Read(ptr,offset+address,recLen) != (int)recLen)
{
retval = DRV_ERR_EXTERNAL_ERROR;
goto error;
}
nameLen = get8bit(ptr);
ptr += NVRAM_NAME_LENG_LEN;
if (nameLen)
{
memcpy(fileName, ptr, nameLen);
}
fileName[nameLen] = 0;
ptr += nameLen;
dataLen = get32bit(ptr);
ptr += NVRAM_DATA_LENG_LEN;
if (dataLen > MAX_DATA_LEN)
{
retval = DRV_ERR_EVENT_INITIALIZATION;
goto error;
}
if (recLen != (NVRAM_NAME_LENG_LEN + nameLen + NVRAM_DATA_LENG_LEN + dataLen))
{
retval = DRV_ERR_EVENT_INITIALIZATION;
goto error;
}
drv_NVRAM_SetEnv(partition, fileName, ptr, dataLen);
nvram_size -= (unsigned int)recLen;
offset += recLen;
/* Read the next record type */
ptr = buffer;
if (drv_NVRAM_Read(ptr,offset+address, NVRAM_TYPE_LEN) != NVRAM_TYPE_LEN)
{
retval = DRV_ERR_EXTERNAL_ERROR;
goto error;
}
}
error:
free(buffer);
return retval;
}
static DRV_Error drv_NVRAM_Load(HMX_NVRAM_PARTITION_E partition)
{
DRV_Error drv_error;
drv_error = drv_NVRAM_LoadByAddress(partition, s_nvram_offset[partition], s_nvram_size[partition]);
if (drv_error != DRV_OK)
{
printf("[HMX_NVRAM_Load] error(%d) loading partition (%d)\n", drv_error, partition);
if (s_nvram_backup_offset[partition] != 0)
{
drv_error = drv_NVRAM_LoadByAddress(partition, s_nvram_backup_offset[partition], s_nvram_size[partition]);
if (drv_error != DRV_OK)
{
printf("[HMX_NVRAM_Load] error(%d) loading backup partition (%d)\n", drv_error, partition);
}
else
{
printf("[HMX_NVRAM_Load] load OK loading backup partition (%d)\n", partition);
}
}
}
return drv_error;
}
/* *********************************************************************
* HMX_NVRAM_Save()
*
* Write the environment to the NVRAM device.
*
* Input parameters:
* nothing
*
* Return value:
* 0 if ok, else error code
********************************************************************* */
static DRV_Error drv_NVRAM_Save(HMX_NVRAM_PARTITION_E partition)
{
unsigned int nvram_size;
unsigned char *buffer;
unsigned char *buffer_end;
unsigned char *ptr;
queue_t *qb;
NVRAM_EVNVAR_T *env;
unsigned char namelen;
unsigned int valuelen;
unsigned int recLen;
nvram_size = s_nvram_size[partition];
buffer = malloc(nvram_size);
if (buffer == NULL)
{
return DRV_ERR_OUTOFMEMORY;
}
buffer_end = buffer + nvram_size - 1;
ptr = buffer;
for (qb = s_nvram_envvars[partition].q_next; qb != &s_nvram_envvars[partition]; qb = qb->q_next)
{
env = (NVRAM_EVNVAR_T *) qb;
namelen = env->nameLen;
valuelen = env->valueLen;
recLen = env->recLen;
if ((ptr + NVRAM_TYPE_LEN + NVRAM_RECORD_LENG_LEN + recLen) > buffer_end)
{
break;
}
*ptr++ = NVRAM_TLV_TYPE_ENV; /* TLV record type */
*ptr++ = (recLen>>24) & 0xFF; /* TLV record length */
*ptr++ = (recLen>>16) & 0xFF; /* TLV record length */
*ptr++ = (recLen>>8) & 0xFF; /* TLV record length */
*ptr++ = (recLen>>0) & 0xFF; /* TLV record length */
*ptr++ = (namelen>>0) & 0xFF; /* NAME record length */
memcpy(ptr, env->name, namelen); /* NAME record data */
ptr += namelen;
*ptr++ = (valuelen>>24) & 0xFF; /* VALUE record length */
*ptr++ = (valuelen>>16) & 0xFF; /* VALUE record length */
*ptr++ = (valuelen>>8) & 0xFF; /* VALUE record length */
*ptr++ = (valuelen>>0) & 0xFF; /* VALUE record length */
memcpy(ptr,env->value, valuelen);
ptr += valuelen;
}
*ptr++ = NVRAM_TLV_TYPE_END;
nvram_size = drv_NVRAM_Write(buffer,0+s_nvram_offset[partition],ptr-buffer);
if (s_nvram_backup_offset[partition] != 0)
{
drv_NVRAM_Write(buffer,0+s_nvram_backup_offset[partition],ptr-buffer);
}
free(buffer);
return (nvram_size == (unsigned int)(ptr-buffer)) ? DRV_OK : DRV_ERR_EXTERNAL_ERROR;
}
static unsigned int NVRAM_SWAP32(unsigned int A)
{
return ((A << 24) | ((A << 8) & 0xFF0000) | ((A >> 8) & 0xFF00) |(A >> 24));
}
static unsigned long s_nvramSema;
static DRV_Error drv_NVRAM_GetFieldInfo(const NVRAM_FIELD_T type, HMX_NVRAM_PARTITION_E *pPartition, unsigned char *pszFileName, unsigned int *defaultSize)
{
int i;
SEM_Get(s_nvramSema);
for (i=0;;i++)
{
if (NVRAM_FIELD_DUMMY == s_nvramFieldInfo[i].type)
break;
if (type != s_nvramFieldInfo[i].type)
continue;
strncpy((char*)pszFileName, (char*)(s_nvramFieldInfo[i].szFileName), MAX_NVRAM_FILENAME_LENGTH);
*pPartition = s_nvramFieldInfo[i].storePartition;
*defaultSize = s_nvramFieldInfo[i].defaultSize;
SEM_Release(s_nvramSema);
return DRV_OK;
}
SEM_Release(s_nvramSema);
return 1;
}
DRV_Error HMX_NVRAM_Init(void)
{
drv_NVRAM_Load(HMX_NVRAM_PARTITION_RO);
drv_NVRAM_Load(HMX_NVRAM_PARTITION_RW);
return DRV_OK;
}
DRV_Error HMX_NVRAM_Write(HMX_NVRAM_PARTITION_E partition, unsigned char *pName, unsigned int offset, unsigned char *pValue, unsigned int ulSize)
{
DRV_Error drv_error;
UNUSED(offset);
SEM_Get(s_nvramSema);
drv_error = drv_NVRAM_SetEnv(partition, pName, pValue, ulSize);
drv_error = drv_NVRAM_Save(partition);
SEM_Release(s_nvramSema);
return drv_error;
}
DRV_Error HMX_NVRAM_Read(HMX_NVRAM_PARTITION_E partition, unsigned char *pName, unsigned int offset, unsigned char *pValue, unsigned int ulSize)
{
DRV_Error drv_error;
SEM_Get(s_nvramSema);
memset(pValue, 0, ulSize);
drv_error = drv_NVRAM_GetEnv(partition, pName, offset, pValue, ulSize);
SEM_Release(s_nvramSema);
return drv_error;
}
DRV_Error HMX_NVRAM_GetField(NVRAM_FIELD_T field, unsigned int offset, void *data, int nDataSize)
{
DRV_Error errCode = DRV_ERR;
unsigned char szFileName[MAX_NVRAM_FILENAME_LENGTH];
HMX_NVRAM_PARTITION_E partition;
int nvramHandle;
unsigned int defaultSize;
if( data == NULL || field == NVRAM_FIELD_DUMMY )
{
return 2;
}
errCode = drv_NVRAM_GetFieldInfo(field, &partition, szFileName, &defaultSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_GetField] field(%d) error(%08X) : HMX_NVRAM_GetFieldInfo\n", field, errCode);
return errCode;
}
switch (partition)
{
case HMX_NVRAM_PARTITION_W_RAWFS :
break;
case HMX_NVRAM_PARTITION_RO :
case HMX_NVRAM_PARTITION_RW :
if (defaultSize == 0)
{
errCode = HMX_NVRAM_Read(partition, szFileName, offset, data, nDataSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_GetField] field(%d)-%s error(%08X) : HMX_NVRAM_Read\n", field, szFileName, errCode);
return errCode;
}
if (field == NVRAM_FIELD_SYSTEM_ID && errCode == 0)
{
*((unsigned int*)data) = NVRAM_SWAP32((unsigned int)*(unsigned int*)data);
}
}
else
{
unsigned char *pBuf;
pBuf = malloc(defaultSize);
if (pBuf == NULL)
{
DEBUG_ERR("[HMX_NVRAM_GetField] malloc\n");
return 3;
}
errCode = HMX_NVRAM_Read(partition, szFileName, 0, pBuf, defaultSize);
if (errCode != DRV_OK)
{
memset(pBuf, 0, defaultSize);
}
memcpy(data, pBuf + offset, nDataSize);
free(pBuf);
}
break;
default :
DEBUG_ERR("[HMX_NVRAM_GetField] DI_ERR_INVALID_PARAM field(%d)-%s error(%08X) : HMX_NVRAM_Write\n", field, szFileName, errCode);
return 2;
}
return errCode;
}
DRV_Error HMX_NVRAM_SetField(NVRAM_FIELD_T field, unsigned int offset, void *data, int nDataSize)
{
DRV_Error errCode = DRV_ERR;
unsigned char szFileName[MAX_NVRAM_FILENAME_LENGTH];
HMX_NVRAM_PARTITION_E partition;
int nvramHandle;
unsigned int defaultSize;
unsigned char *pBuf;
unsigned int systemId;
if( data == NULL || field == NVRAM_FIELD_DUMMY )
{
return 2;
}
pBuf = malloc(nDataSize);
if (pBuf == NULL)
{
return 5;
}
errCode = HMX_NVRAM_GetField(field, offset, pBuf, nDataSize);
if (errCode == DRV_OK)
{
if (memcmp(pBuf, data, nDataSize) == 0)
{
free(pBuf);
return 0;
}
}
free(pBuf);
errCode = drv_NVRAM_GetFieldInfo(field, &partition, szFileName, &defaultSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_SetField] error(%08X) : HMX_NVRAM_GetFieldInfo, field (%d)\n", errCode, field);
return errCode;
}
switch (partition)
{
case HMX_NVRAM_PARTITION_W_RAWFS :
errCode = DRV_NANDFLASH_GetNvramHandle(&nvramHandle);
if (errCode != DRV_OK)
{
return errCode;
}
errCode = DRV_FLASH_Write(s_nvram_offset[HMX_NVRAM_PARTITION_W_RAWFS] + offset, data, nDataSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_SetField] field(%d)-%s error(%08X) : HMX_NVRAM_Write\n", field, szFileName, errCode);
return errCode;
}
break;
case HMX_NVRAM_PARTITION_RO :
case HMX_NVRAM_PARTITION_RW :
if (defaultSize == 0)
{
if (field == NVRAM_FIELD_SYSTEM_ID && errCode == 0)
{
systemId = NVRAM_SWAP32((unsigned int)*(unsigned int*)data);
data = (void*)&systemId;
}
errCode = HMX_NVRAM_Write(partition, szFileName, 0, data, nDataSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_SetField] field(%d)-%s error(%08X) : HMX_NVRAM_Write\n", field, szFileName, errCode);
return errCode;
}
}
else
{
unsigned char *pBuf;
pBuf = malloc(defaultSize);
if (pBuf == NULL)
{
DEBUG_ERR("[HMX_NVRAM_SetField] malloc\n");
return 3;
}
errCode = HMX_NVRAM_Read(partition, szFileName, 0, pBuf, defaultSize);
if (errCode != DRV_OK)
{
memset(pBuf, 0, defaultSize);
}
memcpy(pBuf + offset, data, nDataSize);
errCode = HMX_NVRAM_Write(partition, szFileName, 0, pBuf, defaultSize);
free(pBuf);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_SetField] field(%d)-%s error(%08X) : HMX_NVRAM_Write\n", field, szFileName, errCode);
return errCode;
}
}
break;
default :
DEBUG_ERR("[HMX_NVRAM_SetField] DI_ERR_INVALID_PARAM field(%d)-%s error(%08X) : HMX_NVRAM_Write\n", field, szFileName, errCode);
return 1;
}
return errCode;
}
DRV_Error HMX_NVRAM_GetLength(NVRAM_FIELD_T field, int *pLen)
{
DRV_Error errCode = DRV_ERR;
unsigned char szFileName[MAX_NVRAM_FILENAME_LENGTH];
HMX_NVRAM_PARTITION_E partition;
int nvramHandle;
unsigned int defaultSize;
unsigned char *pBuf;
if( pLen == NULL)
{
return 2;
}
*pLen = 0;
errCode = drv_NVRAM_GetFieldInfo(field, &partition, szFileName, &defaultSize);
if (errCode != DRV_OK)
{
DEBUG_ERR("[HMX_NVRAM_GetLength] error(%08X) : HMX_NVRAM_GetFieldInfo, field (%d)\n", errCode, field);
return errCode;
}
errCode = drv_NVRAM_GetLength(partition, szFileName, pLen);
return DRV_OK;
}
DRV_Error HMX_NVRAM_Remove(HMX_NVRAM_PARTITION_E partition, unsigned char *pName)
{
int result;
SEM_Get(s_nvramSema);
result = drv_NVRAM_Delete(partition, pName);
if (result == 0)
{
result = drv_NVRAM_Save(partition);
}
SEM_Release(s_nvramSema);
return result;
}
DRV_Error HMX_NVRAM_Dump(unsigned char* pucBuffer, unsigned int uiLen, unsigned int uiAlign)
{
unsigned int uiIndex;
unsigned int skip;
skip = 1;
for (uiIndex=0 ; uiIndex<uiLen ; uiIndex++)
{
if (uiAlign!=0 && (uiIndex%uiAlign)==0)
{
if (skip == 0)
{
printf("\n");
}
else
skip = 0;
}
printf("%02X ", *(pucBuffer+uiIndex));
}
printf("\n");
return DRV_OK;
}
DRV_Error HMX_NVRAM_Dir(void)
{
char name[80];
char *value;
int nameLen, valueLen;
int idx;
value = malloc(MAX_DATA_LEN);
if (value == NULL)
{
return DRV_ERR_OUTOFMEMORY;
}
SEM_Get(s_nvramSema);
printf("ROM Name Value\n");
printf("-------------------- --------------------------------------------------\n");
for (idx=0;;idx++)
{
if (drv_NVRAM_ScanDir(HMX_NVRAM_PARTITION_RO, idx, (unsigned char*)name, (unsigned int*)&nameLen, (unsigned char*)value, (unsigned int*)&valueLen) != DRV_OK)
break;
printf("%20s ", name);
(void)HMX_NVRAM_Dump((unsigned char*)value, valueLen, 16);
}
printf("-------------------- --------------------------------------------------\n");
printf("\n");
printf("Variable Name Value\n");
printf("-------------------- --------------------------------------------------\n");
for (idx=0;;idx++)
{
if (drv_NVRAM_ScanDir(HMX_NVRAM_PARTITION_RW, idx, (unsigned char*)name, (unsigned int*)&nameLen, (unsigned char*)value, (unsigned int*)&valueLen) != DRV_OK)
break;
printf("%20s ", name);
(void)HMX_NVRAM_Dump((unsigned char*)value, valueLen, 16);
}
printf("-------------------- --------------------------------------------------\n");
free(value);
SEM_Release(s_nvramSema);
return DRV_OK;
}
/*@}*/