📄 dbmflash.c
字号:
/*****************************************************************************
FILE NAME: dbmflash.c
DESCRIPTION:
This file contains the Data Base Manager (DBM) Flash routines.
The DBM maintains a data base in Flash memory allowing data to
survive across power cycles.
PROCEDURES IN THIS SOURCE FILE:
Global Procedures
-------------------
DbmInitFlash
DbmClearFlashDbMsg
DbmReadFlashDbMsg
DbmWriteFlashDbMsg
DbmCacheFlashDbMsg
DbmFlushFlashDbMsg
DbmBlkWriteFlashDbMsg
DbmBlkReadFlashDbMsg
DbmNAMLockUnlockDbMsg
Local Procedures
-------------------
ReadItem
WriteItem
Copyright (c) 1998 - 2002 LSI Logic. All rights reserved. LSI Confidential information.
Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/
#include "dbmapi.h"
#include "dbmdefs.h"
#include "dbmerrs.h"
#include "exeapi.h"
#include "hwddefs.h"
#include "hwdapi.h"
#include "monapi.h"
#include "sysdefs.h"
#include "sysapi.h"
#include "hwdflash.h"
#include "pswapi.h"
#include "iopapi.h"
#include "fsmapi.h"
#include "fsmdataitem.h"
#include "sidbdefs.h"
static bool ReadItem(uint16 type, uint16 id, uint32 offset, void *data, uint32 length);
static bool WriteItem(uint16 type, uint16 id, uint32 offset, void *data, uint32 length);
/*----------------------------------------------------------------
* Define Local typedefs and defines
*----------------------------------------------------------------*/
#define DBM_PATH "vt/dbmfile"
#define DBM_ITEM_CP_TYPE ITEM_DBM_CP_TYPE
#define DBM_ITEM_RF_TYPE ITEM_DBM_RF_TYPE
#define DBM_MAX_WRITE_TRY 3
#define DBM_SLEEP_TICKS 20
#define MAKE_LONG(a,b) ((((long)(a)) << 16) | ((long)(b)))
#define FILE_NAME_SIZE 128
/*---------------------------------------------------------------
* Declare data base 1 (CP) local variables
*----------------------------------------------------------------*/
/* Define CP data base segment length array */
static const uint16 SegLengthCP[] = {DBM_CP_SEGMENT_SIZES};
static uint16 MaxCPSegLength;
/*---------------------------------------------------------------
* Declare data base 2 (RF) local variables
*----------------------------------------------------------------*/
/* Define RF data base segment length array */
static const uint16 SegLengthRF[] = {DBM_RF_SEGMENT_SIZES};
static uint16 MaxRFSegLength;
/*---------------------------------------------------------------*/
/* lock DBM Cache NAM & NVM NAM */
static bool NamLock;
/*****************************************************************************
FUNCTION NAME: DbmInitFlash
DESCRIPTION:
This routine handles Flash based DBM initialization.
PARAMETERS:
None
RETURNED VALUES:
None
*****************************************************************************/
void DbmInitFlash(void)
{
HFSMFILE handle;
uint16 max_len;
uint32 i;
max_len = 0;
for( i = 0; i < DBM_MAX_SEG_CP_DB; i++)
{
if(SegLengthCP[i] > max_len)
max_len = SegLengthCP[i];
}
MaxCPSegLength = max_len + 4;
max_len = 0;
for(i = 0; i < DBM_MAX_SEG_RF_DB; i++)
{
if(SegLengthRF[i] > max_len)
max_len = SegLengthRF[i];
}
MaxRFSegLength = max_len + 4;
handle = FsmOpenDir(DBM_PATH);
if(handle == INVALID_FILE_HANDLE)
{
FsmMakeDir(DBM_PATH);
}
else
{
FsmCloseDir(handle);
}
/* lock DBM Cache NAM & NVM NAM */
NamLock = TRUE;
}
/*****************************************************************************
FUNCTION NAME: DbmClearFlashDbMsg
DESCRIPTION:
This routine handles the clear data base message. When this message
is received the entire cache is cleared. The flash section associated
with the data base is then erased.
PARAMETERS:
MsgDataP - Pointer to message structure
RETURNED VALUES:
None
*****************************************************************************/
void DbmClearFlashDbMsg(void *MsgDataP)
{
DbmClearMsgT *RxMsgP;
DbmClearRspMsgT *RspMsgP;
uint32 RspMsgSize;
uint16 i;
uint16 type;
uint32 maxsize;
bool status;
uint8 *pBuffer;
/* Cast pointer to data base manager clear message structure */
RxMsgP = (DbmClearMsgT *) MsgDataP;
/* Get response message size */
RspMsgSize = sizeof(DbmClearRspMsgT);
/* Allocate memory for response message */
RspMsgP = (DbmClearRspMsgT *)(ExeMsgBufferGet(RspMsgSize));
/* Return data base ID in response message */
RspMsgP->DataBaseId = RxMsgP->DataBaseId;
/* Default to returning ACK in response message */
RspMsgP->AckType = DBM_ACK_TYPE;
/* If NAM is locked & NAM data base clear request ? */
if ((NamLock == TRUE) && (RxMsgP->DataBaseId == DBM_CP_DATA_BASE))
{
/* NACK response */
RspMsgP->AckType = DBM_NACK_TYPE;
/* Send response message back to sender of write message */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *) RspMsgP, RspMsgSize);
/* Declare a Mon Fault */
MonFault(MON_DBM_FAULT_UNIT, DBM_NAM_LOCKED_ERR, 0, MON_CONTINUE);
/* Don't clear cache or flash */
return;
}
/*
* ================================================================
* clear all data.
*/
maxsize = MaxCPSegLength > MaxRFSegLength ? MaxCPSegLength : MaxRFSegLength;
pBuffer = (uint8 *)ExeMsgBufferGet(maxsize);
if(pBuffer == NULL)
{
RspMsgP->AckType = DBM_NACK_TYPE;
/* Send response message back to sender of write message */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *) RspMsgP, RspMsgSize);
/* Declare a Mon Fault */
MonFault(MON_DBM_FAULT_UNIT, DBM_NAM_LOCKED_ERR, 0x55AA, MON_CONTINUE);
/* Don't clear cache or flash */
return;
}
memset(pBuffer, 0, maxsize);
if(RxMsgP->DataBaseId == DBM_CP_DATA_BASE)
{
/* MonPrintf("\n\n clear CP.........\n\n");*/
type = DBM_ITEM_CP_TYPE;
for(i = 0; i < DBM_MAX_SEG_CP_DB; i++)
{
status = WriteItem(type, i, 0, pBuffer, SegLengthCP[i]);
if(!status)
MonFault(MON_DBM_FAULT_UNIT, DBM_WRITE_ERR, MAKE_LONG(type, i), MON_CONTINUE);
}
}
else if(RxMsgP->DataBaseId == DBM_RF_DATA_BASE)
{
/* MonPrintf("\n\n clear RF.........\n\n");*/
type = DBM_ITEM_RF_TYPE;
for(i = 0; i < DBM_MAX_SEG_RF_DB; i++)
{
status = WriteItem(type, i, 0, pBuffer, SegLengthRF[i]);
if(!status)
MonFault(MON_DBM_FAULT_UNIT, DBM_WRITE_ERR, MAKE_LONG(type, i), MON_CONTINUE);
}
}
ExeMsgBufferFree(pBuffer);
/* Send ACK in response message */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *)RspMsgP, RspMsgSize);
}
/*****************************************************************************
FUNCTION NAME: DbmReadFlashDbMsg
DESCRIPTION:
This routine handles the read data base message. When this message
is received data are read from the cache. Data is stored in
segments and this routine creates a data base address from a
segment and offset. Then the amount of data specified in the
command is read from cache.
PARAMETERS:
MsgDataP - Pointer to message structure
RETURNED VALUES:
None
*****************************************************************************/
void DbmReadFlashDbMsg(void *MsgDataP)
{
DbmReadMsgT *RxMsgP;
DbmReadRspMsgT *RspMsgP = NULL;
uint32 MsgSize;
uint16 MaxSeg;
uint16 type;
uint16 Id;
bool status;
uint16 NumBytes;
const uint16 * pSegLength;
/* Cast pointer to read command struct */
RxMsgP = (DbmReadMsgT *) MsgDataP;
MsgSize = sizeof(DbmReadRspMsgT) + RxMsgP->NumBytes - sizeof(RspMsgP->Data);
RspMsgP = (DbmReadRspMsgT *) ExeMsgBufferGet(MsgSize);
if(RspMsgP == NULL)
{
MonPrintf("\nBuffer get failure in DBM read!\n");
return;
}
RspMsgP->DataBaseId = RxMsgP->DataBaseId;
RspMsgP->Address = RxMsgP->Address;
NumBytes = 0;
/* MonPrintf("\n ReadDB: Task Id = %d, Database ID = %x, seg = %x \n",
RxMsgP->RspInfo.TaskId,
RxMsgP->DataBaseId,
RxMsgP->Address.Segment);*/
Id = RxMsgP->Address.Segment;
if(RxMsgP->DataBaseId == DBM_CP_DATA_BASE)
{
type = DBM_ITEM_CP_TYPE;
MaxSeg = DBM_MAX_SEG_CP_DB;
pSegLength = &SegLengthCP[0];
}
else if(RxMsgP->DataBaseId == DBM_RF_DATA_BASE)
{
type = DBM_ITEM_RF_TYPE;
MaxSeg = DBM_MAX_SEG_RF_DB;
pSegLength = &SegLengthRF[0];
}
else
{
MonPrintf("\nDataBaseId error in DBM read\n");
goto exit;
}
/* Range check DB segment address for read */
if (RxMsgP->Address.Segment >= MaxSeg)
{
MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_NUM_ERR, RxMsgP->Address.Segment,
MON_CONTINUE);
goto exit;
}
/* Range check DB segment size for read */
if ((RxMsgP->Address.Offset + RxMsgP->NumBytes) > pSegLength[RxMsgP->Address.Segment])
{
MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_SIZE_ERR, 0, MON_CONTINUE);
goto exit;
}
RspMsgP->NumBytes = RxMsgP->NumBytes;
status = ReadItem(type, Id, RxMsgP->Address.Offset, (void *)(&(RspMsgP->Data[0])), RxMsgP->NumBytes);
if(!status)
{
MonPrintf("\nDBM read failure!\n");
NumBytes = 0;
goto exit;
}
NumBytes = RxMsgP->NumBytes;
exit:
RspMsgP->NumBytes = NumBytes;
/* Send response message back to sender of read command */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *) RspMsgP, MsgSize);
/* MonPrintf("Read Done-------<<<<<<<\n");*/
}
/*****************************************************************************
FUNCTION NAME: DbmWriteFlashDbMsg
DESCRIPTION:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -