📄 dbmflash2.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
-------------------
CacheDb
FlashProgram
SwapFlashSections
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"
/*----------------------------------------------------------------
* Define Local typedefs and defines
*----------------------------------------------------------------*/
typedef struct
{
const uint16 FlashOffset; /* Flash offset, in 16-bit words */
const uint16 *SegIndexP; /* Segment index data pointer */
const uint16 *SegLengthP; /* Segment length data pointer */
uint8 *DataBaseP; /* Data base cache pointer */
uint16 DbTotalSize; /* Data base total size */
uint16 DbMaxSeg; /* Data base maximum segment # */
}DbParamsT;
typedef struct
{
HwdFlashSectionTypeT FlashSection1; /* Flash section in use */
HwdFlashSectionTypeT FlashSection2; /* Alternate flash section */
bool DbChanged; /* Data base changed flag */
bool DbCached; /* Data Base cached flag */
DbParamsT Db[2]; /* Data base parameters */
}FlashDbmT;
typedef uint32 BlkDbSizeT; /* Block data base size */
/*
This value is always written by the dbm to the first word location in
the non-block dbm flash section. It is later used at power up
initialization to determine whether or not the flash section contains
valid data.
*/
#define DBM_MARKER_VALUE 0xCD95
/*---------------------------------------------------------------
* Declare data base 1 (CP) local variables
*----------------------------------------------------------------*/
/* Define CP data base segment length array */
static const uint16 SegLengthCP[] = {DBM_CP_SEGMENT_SIZES};
/* Define CP data base segment index array */
static const uint16 SegIndexCP[] = {DBM_CP_SEGMENT_INDEXES};
/* CP data base cache */
static uint8 DataBaseCP[DBM_CP_CACHE_SIZE];
/*---------------------------------------------------------------
* Declare data base 2 (RF) local variables
*----------------------------------------------------------------*/
/* Define RF data base segment length array */
static const uint16 SegLengthRF[] = {DBM_RF_SEGMENT_SIZES};
/* Define RF data base segment index array */
static const uint16 SegIndexRF[] = {DBM_RF_SEGMENT_INDEXES};
/* RF data base cache */
static uint8 DataBaseRF[DBM_RF_CACHE_SIZE];
/*---------------------------------------------------------------
* Declare DBM local variables
*----------------------------------------------------------------*/
/* Pointer to flash data base structure */
static FlashDbmT *FlashDbmP;
/* Flash data base data structure */
static FlashDbmT FlashDbm =
{
HWD_FLASH_CP_DATA_BASE_SECTION_1, /* One of two flash sections used by DBM */
HWD_FLASH_CP_DATA_BASE_SECTION_2, /* The other flash section used by DBM */
FALSE, /* Data base changed flag */
FALSE, /* Data base cached flag */
DBM_CP_FLASH_OFFSET/sizeof(uint16), /* Flash section offset for CP data base */
&SegIndexCP[0], /* CP data base segment index array */
&SegLengthCP[0], /* CP data base segment length array */
&DataBaseCP[0], /* CP data base cache */
sizeof(DataBaseCP), /* CP data base size */
DBM_MAX_SEG_CP_DB, /* Largest segment supported for CP data base */
DBM_RF_FLASH_OFFSET/sizeof(uint16), /* Flash section offset for RF data base */
&SegIndexRF[0], /* RF data base segment index array */
&SegLengthRF[0], /* RF data base segment length array */
&DataBaseRF[0], /* RF data base cache */
sizeof(DataBaseRF), /* RF data base size */
DBM_MAX_SEG_RF_DB, /* Largest segment supported for RF data base */
};
/* lock DBM Cache NAM & NVM NAM */
static bool NamLock;
/*---------------------------------------------------------------
* Declare function prototypes for local routines in this file
*----------------------------------------------------------------*/
static void CacheDb(void);
static void SwapFlashSections(void);
static void FlashProgram(HwdFlashSectionTypeT FlashSection, uint16 FlashOffset,
uint8 *Source, uint16 ByteCount);
/*****************************************************************************
FUNCTION NAME: DbmInitFlash
DESCRIPTION:
This routine handles Flash based DBM initialization.
PARAMETERS:
None
RETURNED VALUES:
None
*****************************************************************************/
void DbmInitFlash(void)
{
uint16 Section1Marker, Section2Marker;
uint32 DbSize;
/* Point to the data base structure of interest */
FlashDbmP = &FlashDbm;
/* Calculate size of CP data base sector */
DbSize = HwdFlashSectionSize(HWD_FLASH_CP_DATA_BASE_SECTION_1);
/* Compare size of flash sector to the size of the actual data bases (CP & RF)
and declare an error if flash sector size < data base size */
if (DbSize < FlashDbmP->Db[0].DbTotalSize + FlashDbmP->Db[1].DbTotalSize)
MonFault(MON_DBM_FAULT_UNIT, DBM_FLASH_TOO_SMALL_ERR, DbSize, MON_CONTINUE);
/* Two flash sections are used to maintain the data base.
The two sections are alternately selected between writes to flash
in order to minimize impact on system performance due to erase times. */
/* Read the first byte from each of these sections and check if it is
equal to DBM_MARKER_VALUE. If not then that section doesn't contain
valid data and probably should be erased. If it does then the section
contains valid data and should be used accordingly. */
HwdFlashRead(HWD_FLASH_CP_DATA_BASE_SECTION_1, 0, (uint8 *)&Section1Marker, 2);
HwdFlashRead(HWD_FLASH_CP_DATA_BASE_SECTION_2, 0, (uint8 *)&Section2Marker, 2);
/* If both sections contain data then something is wrong,
only 1 section should contain data while the other section should have
been in the erased state. */
if (Section1Marker == DBM_MARKER_VALUE && Section2Marker == DBM_MARKER_VALUE)
MonFault(MON_DBM_FAULT_UNIT, DBM_FLASH_AMBIGUOUS_ERR,
((Section1Marker << 16) | Section2Marker), MON_CONTINUE);
/* Set FlashSection1 to the empty flash sector. FlashSection2
should be set to the flash sector containing data. */
if (Section2Marker == DBM_MARKER_VALUE)
{
FlashDbmP->FlashSection1 = HWD_FLASH_CP_DATA_BASE_SECTION_1;
FlashDbmP->FlashSection2 = HWD_FLASH_CP_DATA_BASE_SECTION_2;
}
else
{
FlashDbmP->FlashSection1 = HWD_FLASH_CP_DATA_BASE_SECTION_2;
FlashDbmP->FlashSection2 = HWD_FLASH_CP_DATA_BASE_SECTION_1;
}
/* Erase flash section 1 since it has been set to empty */
HwdFlashErase(FlashDbmP->FlashSection1);
/* Cache the CP RAM data base from Flash */
CacheDb();
/* 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;
/* 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 the cache */
SysMemset(FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP, 0,
FlashDbmP->Db[RxMsgP->DataBaseId].DbTotalSize);
/* Indicate the cache is unchanged */
FlashDbmP->DbChanged = FALSE;
/*
Write the Marker value to the data base, to be used to indicate
this flash section is "dirty".
(Two byte operations are done because DataBaseP is a byte pointer
and can point to an odd location).
*/
FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[0] = (uint8)(DBM_MARKER_VALUE & 0xff);
FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[1] = (uint8)(DBM_MARKER_VALUE >> 8);
/*
Write the cleared data base and the other data base to flash
*/
FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[0].FlashOffset+1,
&FlashDbmP->Db[0].DataBaseP[2], FlashDbmP->Db[0].DbTotalSize-2);
FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[1].FlashOffset+1,
&FlashDbmP->Db[1].DataBaseP[2], FlashDbmP->Db[1].DbTotalSize-2);
/*
Write the marker value to the flash
*/
FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[0].FlashOffset,
&FlashDbmP->Db[0].DataBaseP[0], 2);
FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[1].FlashOffset,
&FlashDbmP->Db[1].DataBaseP[0], 2);
/* Send ACK in response message */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *)RspMsgP, RspMsgSize);
/*
NOTE: It is important that the flash is erased AFTER the call
to ExeMsgSend to allow higher priority tasks to run while the
flash is being erased. This minimizes the impact of the flash
erasure time on system performance.
*/
HwdFlashErase(FlashDbmP->FlashSection2);
SwapFlashSections();
}
/*****************************************************************************
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -