/*******************************************************************/ | |
/************************* 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(fmt, args...) fprintf(stderr, fmt, #args) | |
#define DEBUG_INFO(fmt, args...) fprintf(stderr, fmt, #args) | |
#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_1ST_SERIAL_NUMBER , "1ST_SERIAL_NUMBER" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_2ND_SERIAL_NUMBER , "2ND_SERIAL_NUMBER" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_GPN , "GPN" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_MAC_ADDR_MOCA , "MAC_ADDR_MOCA" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_MAC_ADDR_BT , "MAC_ADDR_BT" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_GOOGLE_SSL_PEM , "GOOGLE_SSL_PEM" , HMX_NVRAM_PARTITION_RO, 0}, | |
{NVRAM_FIELD_GOOGLE_SSL_CRT , "GOOGLE_SSL_CRT" , 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_PAIRED_DISK , "PAIRED_DISK" , 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) | |
{ | |
DEBUG_ERR("[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) | |
{ | |
DEBUG_ERR("[HMX_NVRAM_Load] error(%d) loading backup partition (%d)\n", drv_error, partition); | |
} | |
else | |
{ | |
DEBUG_INFO("[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; | |
} | |
/*@}*/ |