📄 nvimnv.c
字号:
Initialize nv error queue for external tasks
DEPENDENCIES
Called once, by NV.C to init buffers
RETURN VALUE
False if init conflict.
SIDE EFFECTS
None.
===========================================================================*/
static boolean nverr_init( void )
{
int i;
static boolean nv_error_initialized = FALSE;
static boolean nv_error_init_in_progress = FALSE;
/* We have allready visited this routine */
if(nv_error_initialized)
{
nv_error_init_in_progress = FALSE;
return TRUE;
}
/* Flag incase multiple paths initing nv at same time. */
if(nv_error_init_in_progress) return FALSE;
nv_error_init_in_progress = TRUE;
/* read up shadow copy of error log */
for(i=0; i< NV_MAX_ERR_LOG; i++)
{
(void) nvimr_read_fixed_array
(
NV_ERR_LOG_I,
(byte) i, /* Item index within its array */
&(nverr_log.external[i].err_count), /* data buffer */
nv_op_get_size(NV_ERR_LOG_I)
);
nverr_log.update_required[i] = FALSE;
}
nverr_log.processing_required = FALSE;
nv_error_initialized = TRUE;
nv_error_init_in_progress = FALSE;
return TRUE;
}
/*===========================================================================
FUNCTION NVERR_UPDATE_LOG
DESCRIPTION
write dirty error log items out to nv.
DEPENDENCIES
nverr_init must have been called.
RETURN VALUE
None.
SIDE EFFECTS
None.
===========================================================================*/
static void nverr_update_log( void )
{
int i; /* loop counter */
word isave; /* save flags for interrupt diasble/enable */
/* If no errors waiting to be saved, get out of here */
if(!nverr_log.processing_required) return;
KICK_WATCHDOG();
/* update internal copy of err_log to write out from */
INTLOCK_SAV( isave ); /* Disable interrupts and save PSW */
(void) memcpy((void *) nverr_log.internal,
(void *) nverr_log.external,
sizeof(nverr_log.internal)); /* data buffer size */
(void) memcpy((void *) nverr_log.update_in_progress,
(void *) nverr_log.update_required,
sizeof(nverr_log.update_in_progress)); /* data buffer size */
for(i=0; i< NV_MAX_ERR_LOG; i++)
{
nverr_log.update_required[i] = FALSE;
}
nverr_log.processing_required = FALSE;
INTFREE_SAV( isave ); /* Restore interrupts (PSW) */
/* write out internal shadow copy of error log */
for(i=0; i< NV_MAX_ERR_LOG; i++)
{
if(nverr_log.update_in_progress[i])
{
MSG_MED("nverr_log entry %d update in progress ", i, 0, 0);
KICK_WATCHDOG();
(void) nvimw_write_fixed_array
(
NV_ERR_LOG_I,
(byte) i, /* Item index within its array */
&(nverr_log.internal[i].err_count), /* data buffer */
nv_op_get_size(NV_ERR_LOG_I)
);
}
}
}
/*===========================================================================
FUNCTION NV_SMS_SIZEOF
DESCRIPTION
When passed the number of SMS message bytes, this function returns
the number of "raw" bytes of in EFS that will be required to store
the SMS message.
DEPENDENCIES
None.
RETURN VALUE
The number of "raw" bytes in EFS required to store the specified
SMS message length.
SIDE EFFECTS
None.
===========================================================================*/
word nv_sms_sizeof
(
word sms_message_size /* Size of sms message data in bytes */
)
{
word n;
/* Translate number of sms message bytes to number of raw bytes */
n = sms_message_size + sizeof(nvi_sms_type);
return n;
} /* nv_sms_sizeof */
#ifdef FEATURE_GWSMS
/*===========================================================================
FUNCTION NV_SMS_GW_SIZEOF
DESCRIPTION
When passed the number of SMS message bytes, this function returns
the number of "raw" bytes of in EFS that will be required to store
the SMS message.
DEPENDENCIES
None.
RETURN VALUE
The number of "raw" bytes in EFS required to store the specified
SMS message length.
SIDE EFFECTS
None.
===========================================================================*/
word nv_sms_gw_sizeof
(
word sms_gw_message_size /* Size of sms message data in bytes */
)
{
word n;
/* Translate number of sms message bytes to number of raw bytes */
n = sms_gw_message_size + sizeof(nvi_sms_gw_type);
return n;
} /* nv_sms_gw_sizeof */
#endif
/*===========================================================================
FUNCTION NV_BUILT
DESCRIPTION
This function will return TRUE once the files are available that simulate
NV storage.
DEPENDENCIES
This is a special use function, normally called by error services
to allow early access to NV, and before the NV task has been started.
The NV Item Manager allows access once file initialization is complete.
RETURN VALUE
TRUE - The NV has been built and direct read/write is allowed
FALSE - The NV has not been built and access is not allowed
SIDE EFFECTS
None.
===========================================================================*/
boolean nv_built (void)
{
return nvi_initialized;
} /* nv_built */
/*===========================================================================
FUNCTION NVIMNV_PEEK_FIXED
DESCRIPTION
This function reads a number of bytes from an EFS file that simulates
the fixed item space in NVM.
DEPENDENCIES
None.
RETURN VALUE
NV_DONE_S if it worked
Others Failure for internal call
SIDE EFFECTS
None
===========================================================================*/
static nv_stat_enum_type nvimnv_peek_fixed
(
nv_cmd_type *cmd_ptr /* Command block */
)
{
word addr; /* Address of peek */
word count;
word length;
nv_stat_enum_type status; /* Status to return */
dword fpos;
nvim_efs_params *fparams;
/* Read from allowed fixed area */
addr = cmd_ptr->data_ptr->peek.address;
count = 0;
status = NV_DONE_S;
while (count < cmd_ptr->data_ptr->peek.length)
{
/* ESN and ESN_CHKSUM are in a permanent file by themselves */
if (addr == FPOS(nvim_0000_contents_type, reserved_dword_1))
{
fparams = nv_op_get_fparams(NV_ESN_I); /* esn EFS info */
fpos = nv_op_get_file_pos(NV_ESN_I); /* file position */
length = nv_op_get_size(NV_ESN_I); /* item byte count */
}
else if (addr == FPOS(nvim_0000_contents_type, reserved_dword_2))
{
fparams = nv_op_get_fparams(NV_ESN_CHKSUM_I); /* esn chksum EFS info */
fpos = nv_op_get_file_pos(NV_ESN_CHKSUM_I); /* file position */
length = nv_op_get_size(NV_ESN_CHKSUM_I); /* item byte count */
}
else
{
/* Read from the reserved data file (nvim_0000_contents_type) */
fparams = nv_op_get_fparams(NV_VERNO_MAJ_I);
fpos = addr; /* file position */
length = cmd_ptr->data_ptr->peek.length - count;
}
status = nvim_read_efs(fparams->rd_handle, /* file handle */
fpos, /* file position */
&cmd_ptr->data_ptr->peek.mem[count], /* data ptr */
length); /* data count */
if (status != NV_DONE_S)
{
ERR("Failed to read from fixed item data file %s",
fparams->fname, 0, 0);
return status;
}
count += length;
addr += length;
}
return status;
}
/*===========================================================================
FUNCTION NV_PEEK
DESCRIPTION
This function reads a number of bytes from a specified location in NVM.
DEPENDENCIES
None.
RETURN VALUE
NV_DONE_S if it worked
NV_BADPARM_S if requested bytes are out of range for NVM, or buffer size
exceeded, or requested bytes are in the secure area.
Others Failure for internal call
SIDE EFFECTS
None
===========================================================================*/
LOCAL nv_stat_enum_type nv_peek
(
nv_cmd_type *cmd_ptr /* Command block */
)
{
word start_addr; /* Start address of peek */
word end_addr; /* End address of peek */
word secure_low_addr; /* Low address of secure area */
word secure_high_addr; /* High address of secure area */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* Check to make sure read length is not too big */
/* and that bytes are not extending beyond NVM. */
if(cmd_ptr->data_ptr->peek.length > NV_MAX_PEEK_SIZE) return NV_BADPARM_S;
start_addr = cmd_ptr->data_ptr->peek.address;
end_addr = start_addr + cmd_ptr->data_ptr->peek.length - 1;
/*lint -e413 */
secure_low_addr = (word) (NVIKLTADDR + FPOS(nvim_0000_contents_type, reserved_word_5));
secure_high_addr = (word) (NVIKLTADDR + FPOS(nvim_0000_contents_type, nv_verno_ext));
/*lint +e413 */
/* Don't allow PEEKing of most of the fixed data area, since it contains */
/* secure data (such as the A-Keys, SSDs, and lock codes). */
/*lint -e568 */
if(!((start_addr <= end_addr) || (start_addr > secure_high_addr)
|| (end_addr < secure_low_addr)))
{
ERR("Illegal peek address, start 0x%x end 0x%x",
start_addr, end_addr, 0);
return NV_BADPARM_S;
}
/* First, check for allowed fixed area */
if (end_addr < secure_low_addr)
{
/* Read from a fixed data file */
return nvimnv_peek_fixed(cmd_ptr);
}
/* Next, check for factory area */
if ((start_addr >= NVD_MAX_OFFSET) &&
(end_addr <= NVD_MAX_OFFSET + NV_FACTORY_RSVD))
{
/* Copy from the static block, latest factory data*/
memcpy((void *) cmd_ptr->data_ptr->peek.mem,
&fact_data[start_addr - NVD_MAX_OFFSET],
cmd_ptr->data_ptr->peek.length);
return NV_DONE_S;
}
/* The fixed and factory areas are the only supported areas */
return NV_BADPARM_S;
} /* nv_peek */
/*===========================================================================
FUNCTION NVIMNV_POKE_FACTORY
DESCRIPTION
This function writes a number of bytes to an EFS file that simulates
the reserved factory space in NVM.
DEPENDENCIES
None.
RETURN VALUE
NV_DONE_S if it worked
Others Failure for internal call
SIDE EFFECTS
None
===========================================================================*/
static nv_stat_enum_type nvimnv_poke_factory
(
nv_cmd_type *cmd_ptr /* Command block */
)
{
word start_addr; /* Start address of peek */
nv_stat_enum_type status; /* Status to return */
/* Get the actual offset into the file */
start_addr = cmd_ptr->data_ptr->peek.address - NVD_MAX_OFFSET;
/* Copy to the static block */
memcpy(&fact_data[start_addr], (void *) cmd_ptr->data_ptr->poke.mem,
cmd_ptr->data_ptr->poke.length);
/* Write data to the factory data file if we have a full block */
if ((start_addr + cmd_ptr->data_ptr->poke.length) == NVIM_FACTORY_DATA_SIZE)
{
status = nvimw_write_factory(fact_data, /* data ptr */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -