www.pudn.com > vxworks0108.rar > nvRam.c
/* nvRam.c - byte-oriented NVRAM driver */
/*
modification history
--------------------
01e,07nov02,bm use sync protected enable/disable routines as default
01d,30apr02,bm added sync counter for nvsram enable/disable routines
01c,28aug01,bm adapted for VG4
01b,29oct96,wlf doc: cleanup.
01a,03jun96,dat written.
*/
/*
DESCRIPTION
This driver is for byte-oriented non-volatile RAM (NVRAM). Typical uses
are EEPROMs, static RAM, and any other byte-oriented device.
There are other generic drivers for block-oriented devices like flash memory,
and for boards that have no non-volatile memory at all.
This is boilerplate driver code. It is to be included in source form
into sysLib.c. Macros are used to provide the actual working elements
while this code provides the generic logic.
The following numeric value macros are required:
NV_RAM_ADRS - address of first non-volatile byte
NV_RAM_INTRVL - address interval between bytes
NV_RAM_SIZE - total number of bytes in device
NV_BOOT_OFFSET - Offset to first byte of boot line information
The following procedural macros are used. If not defined by the
specific BSP, then default procedures assuming static RAM with no
special read/write requirements will be used.
NV_RAM_READ(x) - Read and return one byte at offset (x).
NV_RAM_WRITE(x,y) - Write data (y) at offset (x).
NV_RAM_WR_ENBL - procedure to enable writing, if any
NV_RAM_WR_DSBL - procedure to disable writing, if any
*/
#include "type.h"
#include "config.h"
#include "pciConfigLib.h"
#include "vg4.h"
/*
* The nvsram is write protected.
* Use the sync protected routines to handle multiple enable/disable calls from various callers
* correctly.
*/
#ifndef NV_RAM_WR_ENBL
# define NV_RAM_WR_ENBL nvSramWriteEnable();
#endif /*NV_RAM_WR_ENBL*/
#ifndef NV_RAM_WR_DSBL
# define NV_RAM_WR_DSBL nvSramWriteDisable();
#endif /*NV_RAM_WR_DSBL*/
#ifndef NV_RAM_READ
# define NV_RAM_READ(x) \
(*(UCHAR *)((int)NV_RAM_ADRS + ((x) * NV_RAM_INTRVL)))
#endif /*NV_RAM_READ*/
#ifndef NV_RAM_WRITE
# define NV_RAM_WRITE(x,y) \
(*(UCHAR *)((int)NV_RAM_ADRS + ((x) * NV_RAM_INTRVL)) = (y))
#endif /*NV_RAM_WRITE*/
static int sysNvSramEnableCount = 0;
/******************************************************************************
*
* sysNvRamGet - get the contents of non-volatile RAM
*
* This routine copies the contents of non-volatile memory into a specified
* string. The string is terminated with an EOS.
*
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
*
* SEE ALSO: sysNvRamSet()
*/
STATUS sysNvRamGet
(
char *string, /* where to copy non-volatile RAM */
int strLen, /* maximum number of bytes to copy */
int offset /* byte offset into non-volatile RAM */
)
{
offset += NV_BOOT_OFFSET; /* boot line begins at = 0 */
if ( (offset < 0)
|| (strLen < 0)
|| ((offset + strLen) > NV_RAM_SIZE) )
{
return (ERROR);
}
while ( strLen-- )
{
*string = NV_RAM_READ (offset);
string++, offset++;
}
*string = EOS;
return (OK);
}
/*******************************************************************************
*
* sysNvRamSet - write to non-volatile RAM
*
* This routine copies a specified string into non-volatile RAM.
*
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
*
* SEE ALSO: sysNvRamGet()
*/
STATUS sysNvRamSet
(
char *string, /* string to be copied into non-volatile RAM */
int strLen, /* maximum number of bytes to copy */
int offset /* byte offset into non-volatile RAM */
)
{
STATUS result = OK;
offset += NV_BOOT_OFFSET; /* boot line begins at = 0 */
if ( (offset < 0)
|| (strLen < 0)
|| ((offset + strLen) > NV_RAM_SIZE) )
{
return ERROR;
}
NV_RAM_WR_ENBL;
while ( strLen-- )
{
char data;
data = *string; /* avoid any macro side effects */
NV_RAM_WRITE (offset, data);
/* verify data */
if ( NV_RAM_READ (offset) != (UCHAR)data )
{
result = ERROR;
goto exit;
}
string++, offset++;
}
exit:
NV_RAM_WR_DSBL;
return result;
}
/*******************************************************************************
*
* nvSramWriteEnable - enables nvsram write access
*
* This routine will remove the write protection of the onboard nvsram.
* Bit 6 in BCSC register (offset 0x47 in ALI M1543C southbridge) is the write
* control bit (1=write enabled, 0=write protected).
*
* RETURNS: OK, or ERROR if the write protection of the nvsram couldn't be removed
*
* SEE ALSO: nvSramWriteDisable()
*/
STATUS nvSramWriteEnable (void)
{
int lockKey,
count;
STATUS retVal = OK;
/* Increment enable counter. */
lockKey = intLock();
count = sysNvSramEnableCount++;
intUnlock(lockKey);
/*
* Enable write access, if this is the first call to nvSramWriteEnable().
* The nvsram has aleady been enabled, if the counter is greater than 0.
*/
if (count == 0)
{
retVal = pciConfigModifyByte (0, PCI_DEV_NO_M1543C, 0, M1543C_BCSC, 0x40, 0x40);
}
if (OK != retVal)
{
return (ERROR);
}
else
{
return (OK);
}
}
/*******************************************************************************
*
* nvSramWriteDisable - disables nvsram write access
*
* This routine will write protect the onboard nvsram.
* Bit 6 in BCSC register (offset 0x47 in ALI M1543C southbridge) is the write
* control bit (1=write enabled, 0=write protected).
*
* RETURNS: OK, or ERROR if the write protection of the nvsram couldn't be set
*
* SEE ALSO: nvSramWriteEnable()
*/
STATUS nvSramWriteDisable (void)
{
int lockKey,
count;
STATUS retVal = OK;
/* Decrement enable counter, if counter > 0. */
lockKey = intLock();
count = sysNvSramEnableCount;
if (sysNvSramEnableCount > 0)
{
sysNvSramEnableCount--;
}
intUnlock(lockKey);
/* Disable write access, if the counter is zero after decrementing. */
if (count == 1)
{
retVal = pciConfigModifyByte (0, PCI_DEV_NO_M1543C, 0, M1543C_BCSC, 0x40, 0x00);
}
if (OK != retVal)
{
return (ERROR);
}
else
{
return (OK);
}
}
/******************************************************************************
*
* nvSramGet - get the contents of non-volatile RAM
*
* This routine copies the contents of non-volatile memory into a specified
* string. The string is terminated with an EOS.
*
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
*
* SEE ALSO: sysNvRamSet()
*/
STATUS nvSramGet
(
char *string, /* where to copy non-volatile RAM */
int strLen, /* maximum number of bytes to copy */
int offset /* byte offset into non-volatile RAM */
)
{
if ( (offset < 0)
|| (strLen < 0)
|| ((offset + strLen) > NV_RAM_SIZE) )
{
return (ERROR);
}
while ( strLen-- )
{
*string = NV_RAM_READ (offset);
string++, offset++;
}
*string = EOS;
return (OK);
}
/*******************************************************************************
*
* nvSramSet - write to non-volatile RAM
*
* This routine copies a specified string into non-volatile RAM.
*
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
*
* SEE ALSO: nvSramGet()
*/
STATUS nvSramSet
(
char *string, /* string to be copied into non-volatile RAM */
int strLen, /* maximum number of bytes to copy */
int offset /* byte offset into non-volatile RAM */
)
{
STATUS result = OK;
if ( (offset < 0)
|| (strLen < 0)
|| ((offset + strLen) > NV_RAM_SIZE) )
{
return ERROR;
}
NV_RAM_WR_ENBL;
while ( strLen-- )
{
char data;
data = *string; /* avoid any macro side effects */
NV_RAM_WRITE (offset, data);
/* verify data */
if ( NV_RAM_READ (offset) != (UCHAR)data )
{
result = ERROR;
goto exit;
}
string++, offset++;
}
exit:
NV_RAM_WR_DSBL;
return result;
}
/*******************************************************************************
*
* nvSramFill - fill non-volatile RAM with value
*
* This routine fills non-volatile RAM with a specified value.
*
* RETURNS: OK, or ERROR if access is outside the non-volatile RAM range.
*
* SEE ALSO: nvSramSet(), nvSramGet()
*/
STATUS nvSramFill
(
int ch, /* character with which to fill non-volatile RAM */
int nbytes, /* number of bytes to fill */
int offset /* byte offset into non-volatile RAM */
)
{
STATUS result = OK;
if ( (offset < 0)
|| (nbytes < 0)
|| ((offset + nbytes) > NV_RAM_SIZE) )
{
return ERROR;
}
NV_RAM_WR_ENBL;
while ( nbytes-- )
{
NV_RAM_WRITE (offset, ch);
/* verify data */
if ( NV_RAM_READ (offset) != (UCHAR)ch )
{
result = ERROR;
goto exit;
}
offset++;
}
exit:
NV_RAM_WR_DSBL;
return result;
}