1453 lines
23 KiB
C
1453 lines
23 KiB
C
/*++
|
|
|
|
Copyright (c) 1994, 1995 Digital Equipment Corporation
|
|
|
|
Module Name:
|
|
|
|
nvram.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the new non-volatile RAM API. The new API
|
|
supports a cache interface and is layered on top of the old
|
|
Halp*NVRamBuffer() abstraction.
|
|
|
|
Author:
|
|
|
|
Dave Richards 12-Jan-1995
|
|
|
|
Environment:
|
|
|
|
Executes in kernel mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "arccodes.h"
|
|
#include "halp.h"
|
|
#include "nvram.h"
|
|
|
|
//
|
|
// Global data structures.
|
|
//
|
|
|
|
BOOLEAN HalpNVRamCacheIsValid = FALSE;
|
|
BOOLEAN HalpNVRamRegion0IsValid;
|
|
BOOLEAN HalpNVRamRegion1IsValid;
|
|
UCHAR HalpNVRamCache[NVR_LENGTH];
|
|
BOOLEAN HalpNVRamCacheIsDirty;
|
|
ULONG HalpNVRamCacheDirtyLo = NVR_LENGTH - 1;
|
|
ULONG HalpNVRamCacheDirtyHi = 0;
|
|
|
|
BOOLEAN
|
|
HalpIsNVRamCacheValid(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function fills the NVRAM cache (if the current contents are
|
|
not valid).
|
|
|
|
This function should not be called outside this module.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the cache represents the contents
|
|
of NVRAM.
|
|
|
|
--*/
|
|
{
|
|
ARC_STATUS Status;
|
|
|
|
//
|
|
// If the NVRAM cache is valid, return success.
|
|
//
|
|
|
|
if (HalpNVRamCacheIsValid) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Read the NVRAM contents into the cache.
|
|
//
|
|
|
|
Status = HalpReadNVRamBuffer(
|
|
HalpNVRamCache,
|
|
HalpCMOSRamBase,
|
|
NVR_LENGTH
|
|
);
|
|
|
|
//
|
|
// If we were unable to fill the cache, return failure.
|
|
//
|
|
|
|
if (Status != ESUCCESS) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// The cache is valid.
|
|
//
|
|
|
|
HalpNVRamCacheIsValid = TRUE;
|
|
|
|
//
|
|
// The cache is clean.
|
|
//
|
|
|
|
HalpNVRamCacheIsDirty = FALSE;
|
|
HalpNVRamCacheDirtyLo = NVR_LENGTH - 1;
|
|
HalpNVRamCacheDirtyHi = 0;
|
|
|
|
//
|
|
// The validity of regions 0 and 1 is not known.
|
|
//
|
|
|
|
HalpNVRamRegion0IsValid = FALSE;
|
|
HalpNVRamRegion1IsValid = FALSE;
|
|
|
|
//
|
|
// Return success.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpSynchronizeNVRamCache(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function flushes the cache to NVRAM.
|
|
|
|
This function should not be called outside this module.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the contents of the NVRAM cache
|
|
were written to NVRAM.
|
|
|
|
--*/
|
|
{
|
|
ULONG Lo;
|
|
ULONG Hi;
|
|
ARC_STATUS Status;
|
|
|
|
//
|
|
// If the cache is clean, return success.
|
|
//
|
|
|
|
if (!HalpNVRamCacheIsDirty) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Write the dirty portion of the cache back to NVRAM.
|
|
//
|
|
|
|
Lo = HalpNVRamCacheDirtyLo;
|
|
Hi = HalpNVRamCacheDirtyHi;
|
|
|
|
Status = HalpWriteNVRamBuffer(
|
|
(UCHAR *)HalpCMOSRamBase + Lo,
|
|
&HalpNVRamCache[Lo],
|
|
Hi - Lo + 1
|
|
);
|
|
|
|
//
|
|
// If we were unable to flush the cache, return failure.
|
|
//
|
|
|
|
if (Status != ESUCCESS) {
|
|
|
|
//
|
|
// The cache and NVRAM are no longer synchronized!
|
|
//
|
|
|
|
HalpNVRamCacheIsValid = FALSE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// The cache is valid.
|
|
//
|
|
|
|
HalpNVRamCacheIsValid = TRUE;
|
|
|
|
//
|
|
// The cache is clean.
|
|
//
|
|
|
|
HalpNVRamCacheIsDirty = FALSE;
|
|
HalpNVRamCacheDirtyLo = NVR_LENGTH - 1;
|
|
HalpNVRamCacheDirtyHi = 0;
|
|
|
|
//
|
|
// Return success.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
HalpMarkNVRamCacheDirty(
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function marks the NVRAM cache region between Offset and
|
|
Offset + Length - 1 as dirty.
|
|
|
|
This function should not be called outside this module.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG Lo;
|
|
ULONG Hi;
|
|
|
|
//
|
|
// Compute the new lower and upper bounds.
|
|
//
|
|
|
|
Lo = Offset;
|
|
Hi = Offset + Length - 1;
|
|
|
|
if (Lo < HalpNVRamCacheDirtyLo) {
|
|
HalpNVRamCacheDirtyLo = Lo;
|
|
}
|
|
|
|
if (Hi > HalpNVRamCacheDirtyHi) {
|
|
HalpNVRamCacheDirtyHi = Hi;
|
|
}
|
|
|
|
//
|
|
// The cache is dirty.
|
|
//
|
|
|
|
HalpNVRamCacheIsDirty = TRUE;
|
|
}
|
|
|
|
UCHAR
|
|
HalpGetNVRamUchar(
|
|
IN ULONG Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function reads a byte from the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
The offset in NVRAM.
|
|
|
|
Return Value:
|
|
|
|
The byte read from the NVRAM cache.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Read a byte.
|
|
//
|
|
|
|
return HalpNVRamCache[Offset];
|
|
}
|
|
|
|
VOID
|
|
HalpSetNVRamUchar(
|
|
IN ULONG Offset,
|
|
IN UCHAR Data
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes a byte to the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM.
|
|
|
|
Data - The byte written.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Write a byte.
|
|
//
|
|
|
|
HalpNVRamCache[Offset] = Data;
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Offset, sizeof (UCHAR));
|
|
}
|
|
|
|
USHORT
|
|
HalpGetNVRamUshort(
|
|
IN ULONG Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function reads a word from the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
The offset in NVRAM.
|
|
|
|
Return Value:
|
|
|
|
The word read from the NVRAM cache.
|
|
|
|
--*/
|
|
{
|
|
USHORT Data;
|
|
|
|
//
|
|
// Read a short.
|
|
//
|
|
|
|
RtlMoveMemory(&Data, &HalpNVRamCache[Offset], sizeof (USHORT));
|
|
|
|
return Data;
|
|
}
|
|
|
|
VOID
|
|
HalpSetNVRamUshort(
|
|
IN ULONG Offset,
|
|
IN USHORT Data
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes a word to the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM.
|
|
|
|
Data - The word written.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Write a short.
|
|
//
|
|
|
|
RtlMoveMemory(&HalpNVRamCache[Offset], &Data, sizeof (USHORT));
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Offset, sizeof (USHORT));
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamUlong(
|
|
IN ULONG Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function reads a longword from the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
The offset in NVRAM.
|
|
|
|
Return Value:
|
|
|
|
The longword read from the NVRAM cache.
|
|
|
|
--*/
|
|
{
|
|
ULONG Data;
|
|
|
|
//
|
|
// Read a long.
|
|
//
|
|
|
|
RtlMoveMemory(&Data, &HalpNVRamCache[Offset], sizeof (ULONG));
|
|
|
|
return Data;
|
|
}
|
|
|
|
VOID
|
|
HalpSetNVRamUlong(
|
|
IN ULONG Offset,
|
|
IN ULONG Data
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes a longword to the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM.
|
|
|
|
Data - The longword written.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Write a long.
|
|
//
|
|
|
|
RtlMoveMemory(&HalpNVRamCache[Offset], &Data, sizeof (ULONG));
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Offset, sizeof (ULONG));
|
|
}
|
|
|
|
VOID
|
|
HalpMoveMemoryToNVRam(
|
|
IN ULONG Offset,
|
|
IN PVOID Data,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a region of memory to the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM (destination).
|
|
|
|
Data - A memory pointer (source).
|
|
|
|
Length - The length of the region to copy.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Move memory to the NVRAM cache.
|
|
//
|
|
|
|
RtlMoveMemory(&HalpNVRamCache[Offset], Data, Length);
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Offset, Length);
|
|
}
|
|
|
|
VOID
|
|
HalpMoveNVRamToMemory(
|
|
IN PVOID Data,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a portion of the NVRAM cache to memory.
|
|
|
|
Arguments:
|
|
|
|
Data - A memory pointer (destination).
|
|
|
|
Offset - The offset in NVRAM (source).
|
|
|
|
Length - The length of the region to copy.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Move memory from the NVRAM cache.
|
|
//
|
|
|
|
RtlMoveMemory(Data, &HalpNVRamCache[Offset], Length);
|
|
}
|
|
|
|
VOID
|
|
HalpMoveNVRamToNVRam(
|
|
IN ULONG Destination,
|
|
IN ULONG Source,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a one region of the NVRAM cache to another.
|
|
|
|
Arguments:
|
|
|
|
Destination - An offset in NVRAM.
|
|
|
|
Source - An offset in NVRAM.
|
|
|
|
Length - The length of the region to copy.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Move memory within the NVRAM cache.
|
|
//
|
|
|
|
RtlMoveMemory(
|
|
&HalpNVRamCache[Destination],
|
|
&HalpNVRamCache[Source],
|
|
Length
|
|
);
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Destination, Length);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamStringLength(
|
|
IN ULONG Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the length of a '\0'-terminated string in
|
|
the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - A pointer to the beginning of the string in NVRAM.
|
|
|
|
Return Value:
|
|
|
|
An integer value representing the length of the string.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the length of a string in the NVRAM cache.
|
|
//
|
|
|
|
return strlen(&HalpNVRamCache[Offset]);
|
|
}
|
|
|
|
VOID
|
|
HalpMoveMemoryStringToNVRam(
|
|
IN ULONG Offset,
|
|
IN PCHAR Data
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a string to the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM.
|
|
|
|
Data - A pointer to the beginning of the string in memory.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG Length;
|
|
|
|
//
|
|
// Compute the length of the string.
|
|
//
|
|
|
|
Length = strlen(Data);
|
|
|
|
//
|
|
// Move string to NVRAM.
|
|
//
|
|
|
|
HalpMoveMemoryToNVRam(Offset, Data, Length + 1);
|
|
}
|
|
|
|
VOID
|
|
HalpMoveNVRamStringToMemory(
|
|
IN PUCHAR Data,
|
|
IN ULONG Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function copies a string from the NVRAM cache to memory.
|
|
|
|
Arguments:
|
|
|
|
Data - A pointer in memory.
|
|
|
|
Offset - An offset in NVRAM to the string to copy.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG Length;
|
|
|
|
//
|
|
// Compute the length of the string.
|
|
//
|
|
|
|
Length = HalpGetNVRamStringLength(Offset);
|
|
|
|
//
|
|
// Move string to memory.
|
|
//
|
|
|
|
HalpMoveNVRamToMemory(Data, Offset, Length + 1);
|
|
}
|
|
|
|
VOID
|
|
HalpZeroNVRam(
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function zeroes the contents of a region in the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - The offset in NVRAM of the region to zero.
|
|
|
|
Length - The length of the region to zero.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Zero the NVRAM cache.
|
|
//
|
|
|
|
RtlZeroMemory(&HalpNVRamCache[Offset], Length);
|
|
|
|
//
|
|
// Mark the cache as dirty.
|
|
//
|
|
|
|
HalpMarkNVRamCacheDirty(Offset, Length);
|
|
}
|
|
|
|
ULONG
|
|
HalpComputeNVRamChecksum(
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function computes the checksum for a region in the NVRAM cache.
|
|
|
|
Arguments:
|
|
|
|
Offset - An offset in NVRAM.
|
|
|
|
Length - The length of the region to checksum.
|
|
|
|
Return Value:
|
|
|
|
The 32-bit checksum of the region.
|
|
|
|
--*/
|
|
{
|
|
ULONG Checksum;
|
|
ULONG Index;
|
|
|
|
//
|
|
// Compute the checksum.
|
|
//
|
|
|
|
Checksum = 0;
|
|
|
|
for (Index = 0; Index < Length; Index++) {
|
|
Checksum = (Checksum << 1) + HalpGetNVRamUchar(Offset++) +
|
|
(Checksum >> 31 & 0x1);
|
|
}
|
|
|
|
return ~Checksum;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpIsNVRamRegion0Valid(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function fills the NVRAM cache (if necessary) and ascertains
|
|
whether the contents of region 0 of the NVRAM are valid. It verifies
|
|
that the signature, version and checksum are valid.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the contents of the region are valid.
|
|
|
|
--*/
|
|
{
|
|
ULONG Signature;
|
|
UCHAR Version;
|
|
ULONG Checksum1;
|
|
ULONG Checksum2;
|
|
|
|
//
|
|
// If the contents of the NVRAM cache are invalid, return failure.
|
|
//
|
|
|
|
if (!HalpIsNVRamCacheValid()) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If region 0 is valid, return success.
|
|
//
|
|
|
|
if (HalpNVRamRegion0IsValid) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// If the signature is invalid, return failure.
|
|
//
|
|
|
|
Signature = HalpGetNVRamUlong(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Signature)
|
|
);
|
|
|
|
if (Signature != NVR_REGION0_SIGNATURE) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the version is invalid, return failure.
|
|
//
|
|
|
|
Version = HalpGetNVRamUchar(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Version)
|
|
);
|
|
|
|
if (Version == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the checksum is invalid, return failure.
|
|
//
|
|
|
|
Checksum1 = HalpComputeNVRamChecksum(
|
|
NVR_REGION0_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION0, Checksum)
|
|
);
|
|
|
|
Checksum2 = HalpGetNVRamUlong(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Checksum)
|
|
);
|
|
|
|
if (Checksum1 != Checksum2) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Region 0 is valid.
|
|
//
|
|
|
|
HalpNVRamRegion0IsValid = TRUE;
|
|
|
|
//
|
|
// Return success.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpSynchronizeNVRamRegion0(
|
|
IN BOOLEAN RecomputeChecksum
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes the contents of the NVRAM cache region 0
|
|
back to NVRAM and optionally updates the checksum field.
|
|
|
|
Arguments:
|
|
|
|
RecomputeChecksum - Update the checksum?
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the NVRAM was correctly updated.
|
|
|
|
--*/
|
|
{
|
|
ULONG Checksum;
|
|
|
|
//
|
|
// If we are unable to synchronize the NVRAM cache, return failure.
|
|
//
|
|
|
|
if (!HalpSynchronizeNVRamCache()) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If we do not need to re-compute the checksum, return success.
|
|
//
|
|
|
|
if (!RecomputeChecksum) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Re-compute the checksum and store it in NVRAM.
|
|
//
|
|
|
|
Checksum = HalpComputeNVRamChecksum(
|
|
NVR_REGION0_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION0, Checksum)
|
|
);
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Checksum),
|
|
Checksum
|
|
);
|
|
|
|
//
|
|
// Synchronize the NVRAM cache.
|
|
//
|
|
|
|
return HalpSynchronizeNVRamCache();
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpInitializeNVRamRegion0(
|
|
BOOLEAN Synchronize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes the contents of region 0.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the NVRAM was properly initialized.
|
|
|
|
--*/
|
|
{
|
|
ULONG Checksum;
|
|
|
|
//
|
|
// Zero the contents of region 0.
|
|
//
|
|
|
|
HalpZeroNVRam(NVR_REGION0_OFFSET, NVR_REGION0_LENGTH);
|
|
|
|
//
|
|
// Initialize the signature.
|
|
//
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Signature),
|
|
NVR_REGION0_SIGNATURE
|
|
);
|
|
|
|
//
|
|
// Initialize the version.
|
|
//
|
|
|
|
HalpSetNVRamUchar(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Version),
|
|
NVR_REGION0_VERSION
|
|
);
|
|
|
|
//
|
|
// Initialize the directory.
|
|
//
|
|
|
|
HalpSetNVRamUchar(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, DirectoryEntries),
|
|
NVR_REGION0_DIR_SIZE
|
|
);
|
|
|
|
HalpSetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Directory[NVR_REGION0_DIR_FW_CONFIG]),
|
|
(USHORT)FIELD_OFFSET(NVR_REGION0, Opaque[0])
|
|
);
|
|
|
|
HalpSetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Directory[NVR_REGION0_DIR_LANGUAGE]),
|
|
FIELD_OFFSET(NVR_REGION0, Opaque[0]) +
|
|
NVR_FW_CONFIG_LENGTH
|
|
);
|
|
|
|
HalpSetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Directory[NVR_REGION0_DIR_ENVIRONMENT]),
|
|
FIELD_OFFSET(NVR_REGION0, Opaque[0]) +
|
|
NVR_FW_CONFIG_LENGTH +
|
|
NVR_LANGUAGE_LENGTH
|
|
);
|
|
|
|
HalpSetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Directory[NVR_REGION0_DIR_END]),
|
|
FIELD_OFFSET(NVR_REGION0, Checksum)
|
|
);
|
|
|
|
//
|
|
// Re-compute the checksum and store it in NVRAM.
|
|
//
|
|
|
|
Checksum = HalpComputeNVRamChecksum(
|
|
NVR_REGION0_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION0, Checksum)
|
|
);
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0, Checksum),
|
|
Checksum
|
|
);
|
|
|
|
//
|
|
// Synchronize the cache and NVRAM.
|
|
//
|
|
|
|
if (Synchronize) {
|
|
return HalpSynchronizeNVRamRegion0(TRUE);
|
|
}
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamFwConfigOffset(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the NVRAM offset of the firmware configuration
|
|
section in NVRAM.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The offset in NVRAM of the firmware configuration section.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the firmware configuration offset.
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_FW_CONFIG])
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamFwConfigLength(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the length of the firmware configuration
|
|
section of NVRAM.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The length of the firmware configuration section.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the firmware configuration length.
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_FW_CONFIG + 1])
|
|
) -
|
|
HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_FW_CONFIG])
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamLanguageOffset(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the NVRAM offset of the language section.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The NVRAM offset of the language section.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the language offset.
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_LANGUAGE])
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamLanguageLength(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the length of the language section in NVRAM.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The length of the language section.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the language length.
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_LANGUAGE + 1])
|
|
) -
|
|
HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_LANGUAGE])
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamEnvironmentOffset(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the NVRAM offset of the environment section.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The NVRAM offset of the environment section.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the environment offset;
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_ENVIRONMENT])
|
|
);
|
|
}
|
|
|
|
ULONG
|
|
HalpGetNVRamEnvironmentLength(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function returns the length of the environment section.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The length of the environment section in NVRAM.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Return the environment length.
|
|
//
|
|
|
|
return HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_ENVIRONMENT + 1])
|
|
) -
|
|
HalpGetNVRamUshort(
|
|
NVR_REGION0_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION0,
|
|
Directory[NVR_REGION0_DIR_ENVIRONMENT])
|
|
);
|
|
}
|
|
|
|
#if defined(EISA_PLATFORM)
|
|
|
|
BOOLEAN
|
|
HalpIsNVRamRegion1Valid(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function fills the NVRAM cache (if necessary) and ascertains
|
|
whether the contents of region 1 of the NVRAM are valid. It verifies
|
|
that the signature, version and checksum are valid.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the contents of the region are valid.
|
|
|
|
--*/
|
|
{
|
|
ULONG Signature;
|
|
UCHAR Version;
|
|
ULONG Checksum1;
|
|
ULONG Checksum2;
|
|
|
|
//
|
|
// If the contents of the NVRAM cache are invalid, return failure.
|
|
//
|
|
|
|
if (!HalpIsNVRamCacheValid()) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If region 1 is valid, return success.
|
|
//
|
|
|
|
if (HalpNVRamRegion1IsValid) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// If the signature is invalid, return failure.
|
|
//
|
|
|
|
Signature = HalpGetNVRamUlong(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Signature)
|
|
);
|
|
|
|
if (Signature != NVR_REGION1_SIGNATURE) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the version is invalid, return failure.
|
|
//
|
|
|
|
Version = HalpGetNVRamUchar(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Version)
|
|
);
|
|
|
|
if (Version == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the checksum is invalid, return failure.
|
|
//
|
|
|
|
Checksum1 = HalpComputeNVRamChecksum(
|
|
NVR_REGION1_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION1, Checksum)
|
|
);
|
|
|
|
Checksum2 = HalpGetNVRamUlong(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Checksum)
|
|
);
|
|
|
|
if (Checksum1 != Checksum2) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Region 1 is valid.
|
|
//
|
|
|
|
HalpNVRamRegion1IsValid = TRUE;
|
|
|
|
//
|
|
// Return success.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpSynchronizeNVRamRegion1(
|
|
IN BOOLEAN RecomputeChecksum
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function writes the contents of the NVRAM cache region 1
|
|
back to NVRAM and optionally updates the checksum field.
|
|
|
|
Arguments:
|
|
|
|
RecomputeChecksum - Update the checksum?
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the NVRAM was correctly updated.
|
|
|
|
--*/
|
|
{
|
|
ULONG Checksum;
|
|
|
|
//
|
|
// If we are unable to synchronize the NVRAM cache, return failure.
|
|
//
|
|
|
|
if (!HalpSynchronizeNVRamCache()) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If we do not need to re-compute the checksum, return success.
|
|
//
|
|
|
|
if (!RecomputeChecksum) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Re-compute the checksum and store it in NVRAM.
|
|
//
|
|
|
|
Checksum = HalpComputeNVRamChecksum(
|
|
NVR_REGION1_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION1, Checksum)
|
|
);
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Checksum),
|
|
Checksum
|
|
);
|
|
|
|
//
|
|
// Synchronize the NVRAM cache.
|
|
//
|
|
|
|
return HalpSynchronizeNVRamCache();
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpInitializeNVRamRegion1(
|
|
BOOLEAN Synchronize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes the contents of region 1.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A boolean value indicating whether the NVRAM was properly initialized.
|
|
|
|
--*/
|
|
{
|
|
ULONG Checksum;
|
|
|
|
//
|
|
// Zero the contents of region 1.
|
|
//
|
|
|
|
HalpZeroNVRam(NVR_REGION1_OFFSET, NVR_REGION1_LENGTH);
|
|
|
|
//
|
|
// Initialize the signature.
|
|
//
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Signature),
|
|
NVR_REGION1_SIGNATURE
|
|
);
|
|
|
|
//
|
|
// Initialize the version.
|
|
//
|
|
|
|
HalpSetNVRamUchar(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Version),
|
|
NVR_REGION1_VERSION
|
|
);
|
|
|
|
//
|
|
// Re-compute the checksum and store it in NVRAM.
|
|
//
|
|
|
|
Checksum = HalpComputeNVRamChecksum(
|
|
NVR_REGION1_OFFSET,
|
|
FIELD_OFFSET(NVR_REGION1, Checksum)
|
|
);
|
|
|
|
HalpSetNVRamUlong(
|
|
NVR_REGION1_OFFSET +
|
|
FIELD_OFFSET(NVR_REGION1, Checksum),
|
|
Checksum
|
|
);
|
|
|
|
//
|
|
// Synchronize the cache and NVRAM.
|
|
//
|
|
|
|
if (Synchronize) {
|
|
return HalpSynchronizeNVRamRegion1(TRUE);
|
|
}
|
|
}
|
|
|
|
#endif // EISA_PLATFORM
|