| /*******************************************************************/ |
| /************************* 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 "hnvram_dlist.h" |
| #include "hmx_upgrade_nvram.h" |
| /* End Including Headers */ |
| |
| |
| /*******************************************************************/ |
| /****************************** define *****************************/ |
| /*******************************************************************/ |
| /* Start #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 { |
| dlist_hdr_t dlist_hdr; |
| 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_SERIAL_NO, "SERIAL_NO", 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_DTCP_KEY, "DTCP_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_HW_VER, "HW_VER", HMX_NVRAM_PARTITION_RO, 0}, |
| {NVRAM_FIELD_LOADER_VERSION, "LOADER_VERSION", 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_PARTITION_VER, "PARTITION_VER", HMX_NVRAM_PARTITION_RW, 0}, |
| {NVRAM_FIELD_DUMMY, "DUMMY", HMX_NVRAM_PARTITION_RW, 0} |
| }; |
| /* End typedef */ |
| |
| /*******************************************************************/ |
| /************************ global variables *************************/ |
| /*******************************************************************/ |
| /* Start global variable */ |
| static dlist_hdr_t s_nvram_envvars[HMX_NVRAM_PARTITION_MAX] = { |
| DLIST_INIT(s_nvram_envvars[0]), |
| DLIST_INIT(s_nvram_envvars[1]), |
| DLIST_INIT(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) |
| { |
| dlist_hdr_t *entry; |
| NVRAM_EVNVAR_T *env; |
| |
| DLIST_FOR_EACH(&s_nvram_envvars[partition], entry) { |
| env = (NVRAM_EVNVAR_T *) entry; |
| if (strcmp((char*)env->name, (char*)name) == 0) |
| break; |
| } |
| |
| if (entry == &s_nvram_envvars[partition]) |
| return NULL; |
| |
| return (NVRAM_EVNVAR_T *) entry; |
| } |
| |
| /* ********************************************************************* |
| * 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) |
| { |
| dlist_hdr_t *entry; |
| NVRAM_EVNVAR_T *env; |
| |
| DLIST_FOR_EACH(&s_nvram_envvars[partition], entry) { |
| if (idx == 0) |
| break; |
| idx--; |
| } |
| |
| if (entry == &s_nvram_envvars[partition]) { |
| return DRV_ERR; |
| } |
| env = (NVRAM_EVNVAR_T *) entry; |
| |
| 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; |
| } |
| |
| dlist_del((dlist_hdr_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) { |
| dlist_del((dlist_hdr_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); |
| |
| dlist_add(&s_nvram_envvars[partition], (dlist_hdr_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; |
| dlist_hdr_t *entry; |
| 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; |
| |
| DLIST_FOR_EACH(&s_nvram_envvars[partition], entry) { |
| env = (NVRAM_EVNVAR_T *) entry; |
| |
| 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; |
| } |
| |
| void HMX_NVRAM_Print_Separator(void) { |
| printf("-------------------- " |
| "--------------------------------------------------\n"); |
| } |
| |
| 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"); |
| HMX_NVRAM_Print_Separator(); |
| |
| 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); |
| } |
| HMX_NVRAM_Print_Separator(); |
| |
| printf("\n"); |
| |
| printf("Variable Name Value\n"); |
| HMX_NVRAM_Print_Separator(); |
| |
| 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); |
| } |
| HMX_NVRAM_Print_Separator(); |
| |
| free(value); |
| |
| SEM_Release(s_nvramSema); |
| return DRV_OK; |
| } |
| |
| /*@}*/ |