mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
16 KiB
729 lines
16 KiB
/*
|
|
* Copyright (c) 1995 FirePower Systems, Inc.
|
|
* DO NOT DISTRIBUTE without permission
|
|
*
|
|
* $RCSfile: pxenviro.c $
|
|
* $Revision: 1.12 $
|
|
* $Date: 1996/05/18 00:28:50 $
|
|
* $Locker: $
|
|
*/
|
|
|
|
/***********************************************************************
|
|
|
|
|
|
Copyright (c) 1994 MOTOROLA, INC. All Rights Reserved. This file
|
|
contains copyrighted material. Use of this file is restricted
|
|
by the provisions of a Motorola Software License Agreement.
|
|
|
|
File Name:
|
|
PXENVIRO.C
|
|
|
|
Purpose:
|
|
Provides the interface to the PowerPC ARC firmware.
|
|
|
|
Globals:
|
|
none
|
|
|
|
Functions:
|
|
ULONG HalGetEnvironmentVariable();
|
|
ULONG HalSetEnvironmentVariable();
|
|
|
|
History:
|
|
27-Jul-1993 Steve Johns
|
|
Original version
|
|
31-Jan-1994 Steve Johns
|
|
Added checksum logic
|
|
08-Jul-1994 Steve Johns
|
|
Made Environment variable routines PReP compliant
|
|
12-20-94
|
|
Heavly re-written by Sol Kavy at FirePower to
|
|
clean-up the code and properly suppor the Prep spec.
|
|
|
|
|
|
NOTES:
|
|
|
|
The fields in the NVRAM structure follow Big-Endian byte ordering.
|
|
|
|
Each environment variable is stored as an zero-terminated ASCII string:
|
|
|
|
<name>=<value>,0
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
#define USE_SPINLOCKS FALSE
|
|
|
|
#include "halp.h"
|
|
//#include "fpdebug.h"
|
|
#include "arccodes.h"
|
|
#include "eisa.h"
|
|
#include "pxnvrsup.h"
|
|
#include "fpnvram.h"
|
|
|
|
USHORT HalpComputeCrc(VOID);
|
|
|
|
//
|
|
// Debug Define (first paramter is a place holder for future
|
|
// level handling: 1 = Calls, 2 = Routine Info).
|
|
//
|
|
#define NDBG(_lvl, _print)
|
|
|
|
PKSPIN_LOCK NVRAM_Spinlock;
|
|
|
|
#define NVSIZE 4096
|
|
|
|
//
|
|
// Location of the NVRAM registers
|
|
//
|
|
// #include "phsystem.h"
|
|
// extern PVOID HalpIoControlBase;
|
|
#define NVRAM ((PNVRAM_CONTROL) (HalpIoControlBase))
|
|
// #define NVRAM ((PNVRAM_CONTROL) 0xb1000000)
|
|
|
|
//
|
|
// Dummy pointer used to byte get offset information
|
|
//
|
|
PVOID NvramPtr=0;
|
|
#define NVMAP ((PHEADER) NvramPtr)
|
|
|
|
extern BOOLEAN NvramFailure;
|
|
|
|
//
|
|
// Use the routine from fpds1385.c to access the nvram chip. These
|
|
// routines protect their accesses with the appropriate spin locks
|
|
// to make sure the actions are atomic
|
|
//
|
|
|
|
USHORT
|
|
HalpReadNvramUshort(USHORT Index)
|
|
{
|
|
return (HalpDS1385ReadNVRAM(Index) << 8) +
|
|
HalpDS1385ReadNVRAM((USHORT)(Index+1));
|
|
}
|
|
|
|
|
|
ULONG
|
|
HalpReadNvramUlong(USHORT Index)
|
|
{
|
|
ULONG ReturnValue;
|
|
|
|
//
|
|
// Read Big-Endian ULONG value & convert to Little-Endian
|
|
//
|
|
ReturnValue = ((ULONG) HalpReadNvramUshort(Index) << 16) +
|
|
(ULONG) HalpReadNvramUshort((USHORT)(Index+2));
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
VOID
|
|
HalpWriteNvramUshort(USHORT Index,
|
|
USHORT Value)
|
|
{
|
|
//
|
|
// Write USHORT value in Big-Endian
|
|
//
|
|
HalpDS1385WriteNVRAM(Index, (UCHAR) (Value >> 8));
|
|
HalpDS1385WriteNVRAM((USHORT)(Index+1),(UCHAR) Value);
|
|
}
|
|
|
|
|
|
VOID HalpWriteNvramUlong(
|
|
USHORT Index,
|
|
ULONG Value)
|
|
{
|
|
//
|
|
// Write ULONG value in Big-Endian
|
|
//
|
|
HalpWriteNvramUshort(Index, (USHORT) (Value >> 16));
|
|
HalpWriteNvramUshort((USHORT)(Index+2),(USHORT) Value);
|
|
}
|
|
|
|
//
|
|
// DumpNVRAM
|
|
//
|
|
// Description:
|
|
// Used during bring-up to ensure that NVRAM is being handled
|
|
// correctly. Nothing more than a bunch of DbgPrint of NVRAM
|
|
//
|
|
VOID
|
|
DumpNVRAM()
|
|
{
|
|
DbgPrint("HalpIoControlBase is at 0x%x\n", HalpIoControlBase);
|
|
DbgPrint("NVRAM is at 0x%x\n", NVRAM);
|
|
DbgPrint("NvramIndexLo is at 0x%x\n", &(NVRAM->NvramIndexLo));
|
|
DbgPrint("NvramIndexHi is at 0x%x\n", &(NVRAM->NvramIndexHi));
|
|
DbgPrint("NvramData is at 0x%x\n", &(NVRAM->NvramData));
|
|
DbgPrint("NVRAM USHORT Size(%d): %d\n",
|
|
(USHORT)&NVMAP->Size,
|
|
HalpReadNvramUshort((USHORT)&NVMAP->Size));
|
|
DbgPrint("NVRAM UCHAR Version(%d): %d\n",
|
|
(USHORT)&NVMAP->Version,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->Version));
|
|
DbgPrint("NVRAM UCHAR Revision(%d): %d\n",
|
|
(USHORT)&NVMAP->Revision,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->Revision));
|
|
DbgPrint("NVRAM USHORT Crc1(%d): 0x%x\n",
|
|
(USHORT)&NVMAP->Crc1,
|
|
HalpReadNvramUshort((USHORT)&NVMAP->Crc1));
|
|
DbgPrint("NVRAM USHORT Crc2(%d): 0x%x\n",
|
|
(USHORT)&NVMAP->Crc2,
|
|
HalpReadNvramUshort((USHORT)&NVMAP->Crc2));
|
|
DbgPrint("NVRAM UCHAR LastOS(%d): %d\n",
|
|
(USHORT)&NVMAP->LastOS,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->LastOS));
|
|
DbgPrint("NVRAM UCHAR Endian(%d): %d\n",
|
|
(USHORT)&NVMAP->Endian,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->Endian));
|
|
DbgPrint("NVRAM UCHAR OSAreaUsage(%d): %d\n",
|
|
(USHORT)&NVMAP->OSAreaUsage,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->OSAreaUsage));
|
|
DbgPrint("NVRAM UCHAR PMMode(%d): %d\n",
|
|
(USHORT)&NVMAP->PMMode,
|
|
HalpDS1385ReadNVRAM((USHORT)&NVMAP->PMMode));
|
|
DbgPrint("NVRAM ULONG GEAddress(%d): %d\n",
|
|
(USHORT)&NVMAP->GEAddress,
|
|
HalpReadNvramUlong((USHORT)&NVMAP->GEAddress));
|
|
DbgPrint("NVRAM ULONG GELength(%d): %d\n",
|
|
(USHORT)&NVMAP->GELength,
|
|
HalpReadNvramUlong((USHORT)&NVMAP->GELength));
|
|
{
|
|
USHORT StartIndex, LastIndex, Index;
|
|
UCHAR NvramChar;
|
|
BOOLEAN LastNull = TRUE; // Assume it
|
|
|
|
DbgPrint("NVRAM Global Environment Area:\n");
|
|
|
|
StartIndex = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GEAddress));
|
|
LastIndex = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GELength));
|
|
LastIndex += StartIndex - 1;
|
|
for (Index = StartIndex; Index <= LastIndex; Index++) {
|
|
NvramChar = HalpDS1385ReadNVRAM(Index);
|
|
if (NvramChar == '\0') {
|
|
LastNull = TRUE;
|
|
} else {
|
|
if (LastNull == TRUE) {
|
|
DbgPrint("\n[%d]: ", Index);
|
|
}
|
|
DbgPrint("%c", NvramChar);
|
|
LastNull = FALSE;
|
|
}
|
|
}
|
|
DbgPrint("\n");
|
|
}
|
|
|
|
DbgPrint("Checking Our version of CRC");
|
|
DbgPrint("Compute CRC returns 0x%x\n", HalpComputeCrc());
|
|
}
|
|
|
|
UCHAR
|
|
HalpGetEnvironmentInfo(
|
|
OPTIONAL PUSHORT TotalSize,
|
|
OPTIONAL PUSHORT FreeSize,
|
|
OPTIONAL PULONG pCrc)
|
|
{
|
|
USHORT Index;
|
|
USHORT InUse, TotalLength;
|
|
UCHAR DataByte1, DataByte2;
|
|
|
|
NDBG(1, DbgPrint("HalpGetEnvironmentInfo: called\n"););
|
|
|
|
TotalLength = (USHORT) HalpReadNvramUlong((USHORT) &NVMAP->GELength);
|
|
if (TotalSize != NULL)
|
|
*TotalSize = TotalLength;
|
|
|
|
if (FreeSize != NULL) {
|
|
//
|
|
// Compute how much NVRAM is in use
|
|
//
|
|
InUse = 0;
|
|
Index = (USHORT)HalpReadNvramUlong ((USHORT) &NVMAP->GEAddress);
|
|
DataByte1 = HalpDS1385ReadNVRAM(Index++);
|
|
DataByte2 = DataByte1;
|
|
while (DataByte1 | DataByte2) {
|
|
DataByte1 = DataByte2;
|
|
DataByte2 = HalpDS1385ReadNVRAM(Index++);
|
|
InUse++;
|
|
}
|
|
*FreeSize = TotalLength - InUse;
|
|
}
|
|
|
|
if (pCrc != NULL) {
|
|
*pCrc = HalpReadNvramUshort((USHORT) &NVMAP->Crc1);
|
|
}
|
|
return(HalpDS1385ReadNVRAM((USHORT) &NVMAP->Version));
|
|
}
|
|
|
|
//
|
|
// HalpAddByteCrc
|
|
//
|
|
// Description:
|
|
// Use the X^16 + X^12 + X^5 + 1, Polynomial for CRC
|
|
//
|
|
// Input:
|
|
// Stored in NVRAM
|
|
//
|
|
// Output:
|
|
// New Crc Value
|
|
//
|
|
USHORT
|
|
HalpAddByteCrc(USHORT CurrentCrc, USHORT Index)
|
|
{
|
|
UCHAR Byte;
|
|
UCHAR CrcLo, CrcHi;
|
|
USHORT x,y,z;
|
|
|
|
|
|
Byte = HalpDS1385ReadNVRAM(Index);
|
|
CrcLo = CurrentCrc &0xff;
|
|
CrcHi = CurrentCrc >> 8;
|
|
x = (CrcLo << 8) | (CrcHi^Byte);
|
|
y = (CrcHi^Byte) << 8;
|
|
z = ((y >> 12) | (y << 4)) & 0xf00f;
|
|
x = x^z;
|
|
z = ((y << 13) | (y >> 3)) & 0x1fe0;
|
|
x = x^z;
|
|
z = y&0xf000;
|
|
x = x^z;
|
|
z = ((y<<9) | (y>>7)) & 0x1e0;
|
|
x = x^z;
|
|
return(x);
|
|
}
|
|
|
|
//
|
|
// HalpComputeCrc
|
|
//
|
|
// Description:
|
|
// Find the parts that are part of the crc and compute the
|
|
// crc against them.
|
|
//
|
|
// Input:
|
|
// Stored in NVRAM
|
|
//
|
|
// Output:
|
|
//
|
|
USHORT
|
|
HalpComputeCrc(VOID)
|
|
{
|
|
USHORT CurrentCrc = 0xffff;
|
|
USHORT Index, EndIndex;
|
|
|
|
//
|
|
// Loop through different parts computing CRC
|
|
// This is from Size to Revision inclusive
|
|
//
|
|
for (Index = 0; Index <= 3; Index++) {
|
|
CurrentCrc = HalpAddByteCrc(CurrentCrc, Index);
|
|
}
|
|
|
|
//
|
|
// Compute ending offset
|
|
//
|
|
EndIndex = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->OSAreaAddress));
|
|
|
|
//
|
|
// Loop through second half
|
|
// This is from LastOS to OSArea (Note: 9 should be 8; however,
|
|
// IBM screwed up and we are all just going along with it).
|
|
//
|
|
for (Index = 9; Index < EndIndex; Index++) {
|
|
CurrentCrc = HalpAddByteCrc(CurrentCrc, Index);
|
|
}
|
|
return(CurrentCrc);
|
|
}
|
|
|
|
|
|
//
|
|
// HalpUpdateCrc
|
|
//
|
|
// Description:
|
|
// Compute the required Crc value and update the Header. This
|
|
// code only updates crc1.
|
|
//
|
|
VOID
|
|
HalpUpdateCrc()
|
|
{
|
|
ULONG Crc;
|
|
|
|
NDBG(1, DbgPrint("HalpUpdateCrc: called\n"););
|
|
Crc = HalpComputeCrc();
|
|
HalpWriteNvramUshort((USHORT) &NVMAP->Crc1, (USHORT) Crc);
|
|
}
|
|
|
|
//
|
|
// Returns the number of bytes removed
|
|
//
|
|
USHORT
|
|
HalpCompressEnvironmentSpace(IN USHORT StartIndex)
|
|
{
|
|
USHORT Index, BytesRemoved;
|
|
UCHAR PreviousChar, NvramChar;
|
|
|
|
Index = StartIndex+1;
|
|
while(HalpDS1385ReadNVRAM(Index++) != '=') {
|
|
/* Do Nothing */
|
|
}
|
|
while(HalpDS1385ReadNVRAM(Index++) != 0) {
|
|
/* Do Nothing */
|
|
}
|
|
BytesRemoved = Index - StartIndex; // Adjust amount of free space
|
|
|
|
NvramChar = 0;
|
|
//
|
|
// Copy subsequent variables
|
|
//
|
|
do {
|
|
PreviousChar = NvramChar;
|
|
NvramChar = HalpDS1385ReadNVRAM(Index++);
|
|
HalpDS1385WriteNVRAM(StartIndex++, NvramChar);
|
|
} while (PreviousChar | NvramChar);
|
|
|
|
//
|
|
// Make sure unused NVRAM area is zeroed
|
|
//
|
|
for (Index=0; Index <BytesRemoved; Index++) {
|
|
if (Index+StartIndex >= NVSIZE) {
|
|
break;
|
|
}
|
|
HalpDS1385WriteNVRAM((USHORT)(Index+StartIndex), 0);
|
|
}
|
|
return(BytesRemoved);
|
|
}
|
|
|
|
//
|
|
//HalpFindEnviroVar
|
|
// Description:
|
|
// Searches the NVRAM for an environment variable.
|
|
//
|
|
// Parameters:
|
|
// Variable - ptr to the variable to search for.
|
|
//
|
|
// Return value:
|
|
// The NVRAM index where the environment variable's VALUE is stored.
|
|
// Returns 0 if the variable was not found.
|
|
//
|
|
// Assumes NVRAM_Spinlock has already been acquired by the caller.
|
|
//
|
|
USHORT
|
|
HalpFindEnviroVar(IN CHAR *Variable)
|
|
{
|
|
USHORT Index, StartIndex, LastIndex;
|
|
CHAR *VariablePtr, UserChar, NvramChar;
|
|
|
|
NDBG(1, DbgPrint("HalpFindEnviroVar: called for %s\n", Variable););
|
|
|
|
StartIndex = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GEAddress));
|
|
LastIndex = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GELength));
|
|
LastIndex += StartIndex - 1;
|
|
|
|
|
|
//
|
|
// Search the NVRAM for the variable.
|
|
//
|
|
VariablePtr = Variable;
|
|
for (Index = StartIndex ; Index <= LastIndex; ) {
|
|
//
|
|
// Get a character from the NVRAM
|
|
//
|
|
NvramChar = HalpDS1385ReadNVRAM(Index++);
|
|
if (NvramChar == 0) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Are we at the end of the variable name in both the
|
|
// input string and the NVRAM ?
|
|
// If so, then it is an exact match. Return the NVRAM index.
|
|
//
|
|
UserChar = *VariablePtr++;
|
|
if (UserChar == 0 && NvramChar == '=') {
|
|
NDBG(2, DbgPrint("HalpFindEnviroVar: found %s at %d\n",
|
|
Variable, Index););
|
|
return(Index);
|
|
}
|
|
|
|
//
|
|
// Convert variable to UPPER case
|
|
//
|
|
UserChar = (UserChar >= 'a' && UserChar <= 'z') ?
|
|
UserChar-0x20 : UserChar;
|
|
|
|
//
|
|
// Is there a match on this character ?
|
|
//
|
|
|
|
if (UserChar != NvramChar) {
|
|
//
|
|
// No, then skip over this variable in NVRAM and begin
|
|
// search again at start of variable NAME.
|
|
//
|
|
VariablePtr = Variable;
|
|
while (Index <= LastIndex) {
|
|
NvramChar = HalpDS1385ReadNVRAM(Index++);
|
|
if (NvramChar == '=')
|
|
break;
|
|
}
|
|
while (Index <= LastIndex) {
|
|
NvramChar = HalpDS1385ReadNVRAM(Index++);
|
|
if (NvramChar == 0) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// The variable was not found
|
|
//
|
|
NDBG(2, DbgPrint("HalpFindEnviroVar: %s not found\n", Variable););
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// HalGetEnvironmentVariable
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Variables:
|
|
// Supplies a pointer to the zero-terminated, case ASCII string that contains
|
|
// the name of the environment variable to be returned.
|
|
// Length - Supplies the length of the buffer in bytes.
|
|
// Buffer - Supplies a pointer to a buffer that receives the variable value.
|
|
//
|
|
// Return Value:
|
|
// If the variable, the function returns the value ESUCCESS and its
|
|
// value in Buffer. Otherwise, ENOENT is returned.
|
|
//
|
|
ULONG
|
|
HalGetEnvironmentVariable(IN CHAR *Variable,
|
|
IN USHORT Length,
|
|
OUT CHAR *Buffer)
|
|
{
|
|
USHORT Index;
|
|
static DumpNVRAMOnce = FALSE;
|
|
ULONG retVal = ENOENT
|
|
|
|
|
|
NDBG(1, DbgPrint("HalpGetEnvironmentVariable: called\n"););
|
|
|
|
//
|
|
// Check input parameters
|
|
//
|
|
if (!Variable) {
|
|
if (*Variable == 0 || Length < 1 || Buffer == NULL) {
|
|
NDBG(2, DbgPrint("HalpGetEnvironmentVariable: return ENOENT\n"););
|
|
return(retVal);
|
|
}
|
|
}
|
|
|
|
if (!DumpNVRAMOnce) {
|
|
NDBG(2, DumpNVRAM(););
|
|
DumpNVRAMOnce = TRUE;
|
|
}
|
|
|
|
//
|
|
// Grab control of NVRAM
|
|
//
|
|
#if USE_SPINLOCKS
|
|
KIRQL Irql;
|
|
KeAcquireSpinLock(NVRAM_Spinlock, &Irql);
|
|
#endif
|
|
NvramFailure = FALSE;
|
|
|
|
//
|
|
// Get NVRAM index of environment variable
|
|
//
|
|
Index = HalpFindEnviroVar(Variable);
|
|
if (Index == 0) {
|
|
//
|
|
// Environment variable was not found
|
|
//
|
|
#if USE_SPINLOCKS
|
|
KeReleaseSpinLock(NVRAM_Spinlock, Irql);
|
|
#endif
|
|
return(retVal);
|
|
}
|
|
|
|
//
|
|
// Copy the environment variable's value to Buffer
|
|
//
|
|
do {
|
|
*Buffer = HalpDS1385ReadNVRAM(Index++);
|
|
if (*Buffer++ == 0) {
|
|
if (NvramFailure == TRUE) {
|
|
retVal = ENOMEM;
|
|
} else {
|
|
retVal = ESUCCESS;
|
|
}
|
|
#if USE_SPINLOCKS
|
|
KeReleaseSpinLock(NVRAM_Spinlock, Irql);
|
|
#endif
|
|
return(retVal);
|
|
}
|
|
} while (--Length);
|
|
|
|
//
|
|
// Truncate the returned string. The buffer was too short.
|
|
//
|
|
*--Buffer = 0;
|
|
#if USE_SPINLOCKS
|
|
KeReleaseSpinLock(NVRAM_Spinlock, Irql);
|
|
#endif
|
|
return(ENOMEM);
|
|
}
|
|
|
|
//
|
|
// HalSetEnvironmentVariable
|
|
//
|
|
// Parameters:
|
|
// Variable
|
|
// Supplies a pointer to the zero-terminated ASCII string that contains
|
|
// the name of the environment variable to be returned. The string is
|
|
// converted to UPPER CASE.
|
|
//
|
|
// Value
|
|
// Supplies a pointer to the zero-terminated string that contains the new
|
|
// value of the environment variable.
|
|
//
|
|
// There are 4 cases:
|
|
// 1) The environment variable is deleted if Value is a null string.
|
|
// 2) The environment variable does not currently exist. It is appended
|
|
// if there is enough NVRAM available.
|
|
// 3) The environment variable already exists, and the new Value is
|
|
// shorter than the old value.
|
|
// 4) The environment variable already exists, and the new Value is longer than
|
|
// the old value.
|
|
//
|
|
// In all cases the environment space will be compressed after
|
|
// insertion/deletion.
|
|
//
|
|
ULONG
|
|
HalSetEnvironmentVariable(
|
|
IN CHAR *Variable,
|
|
IN CHAR *Value)
|
|
{
|
|
USHORT TotalSize, FreeSize, Index;
|
|
USHORT OldLength, NewLength;
|
|
USHORT StartIndex;
|
|
USHORT i;
|
|
USHORT NameLength, ValueLength;
|
|
CHAR *VariablePtr, *ValuePtr, Char;
|
|
ARC_STATUS ReturnValue;
|
|
|
|
|
|
NDBG(1, DbgPrint("HalSetEnvironmentVariable: called set %s to %s\n",
|
|
Variable, Value););
|
|
|
|
if (Value == NULL) {
|
|
NDBG(2, DbgPrint("HalSetEnvironmentVariable: returning ENOENT\n"););
|
|
return(ENOENT);
|
|
}
|
|
|
|
//
|
|
// Compute length of environment NAME
|
|
//
|
|
VariablePtr = Variable;
|
|
NameLength = 0;
|
|
while (*VariablePtr != 0) {
|
|
NameLength++;
|
|
VariablePtr++;
|
|
}
|
|
|
|
//
|
|
// Compute length of environment VALUE
|
|
//
|
|
ValuePtr = Value;
|
|
ValueLength = 0;
|
|
while (*ValuePtr != 0) {
|
|
ValueLength++;
|
|
ValuePtr++;
|
|
}
|
|
#if USE_SPINLOCKS
|
|
KIRQL Irql;
|
|
KeAcquireSpinLock(NVRAM_Spinlock, &Irql); // Grab control of NVRAM
|
|
#endif
|
|
NvramFailure = FALSE;
|
|
|
|
HalpGetEnvironmentInfo(&TotalSize, &FreeSize, NULL);
|
|
|
|
|
|
// Get index of environment variable
|
|
Index = HalpFindEnviroVar(Variable);
|
|
|
|
ReturnValue = ESUCCESS;
|
|
// Index to start of NAME
|
|
StartIndex = Index-NameLength-1;
|
|
|
|
// DELETE environment variable
|
|
if (ValueLength == 0) {
|
|
if (Index != 0) {
|
|
HalpCompressEnvironmentSpace(StartIndex);
|
|
}
|
|
} else {
|
|
// ADD or REPLACE environment variable
|
|
// Compute # bytes needed to store variable
|
|
NewLength = ValueLength + NameLength + 2;
|
|
|
|
|
|
// REPLACE environment variable.
|
|
// First we see if there is room. If so, delete the current
|
|
// variable & fall through to the code that ADDs a new variable.
|
|
if (Index != 0) {
|
|
// Compute current length of variable
|
|
OldLength = 0;
|
|
i = Index;
|
|
do {
|
|
OldLength++;
|
|
} while (HalpDS1385ReadNVRAM(i++) != 0);
|
|
|
|
// Is there room for the new variable ?
|
|
if (FreeSize-NewLength+OldLength >= 0)
|
|
FreeSize += HalpCompressEnvironmentSpace(StartIndex);
|
|
}
|
|
//
|
|
// ADD environment variable
|
|
//
|
|
|
|
if ((FreeSize-NewLength) >= 0) { // Room for new
|
|
|
|
Index = (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GEAddress));
|
|
Index += (USHORT) HalpReadNvramUlong((USHORT) (&NVMAP->GELength));
|
|
Index -= FreeSize;
|
|
|
|
//
|
|
// Write Variable NVRAM. Convert to UPPER case first.
|
|
//
|
|
while (*Variable != 0) {
|
|
Char = *Variable++;
|
|
//
|
|
// Convert Variable to UPPER case
|
|
//
|
|
Char = (Char >= 'a' && Char <= 'z') ? Char-0x20 : Char;
|
|
HalpDS1385WriteNVRAM(Index++,Char);
|
|
}
|
|
|
|
HalpDS1385WriteNVRAM(Index++,'='); // Write a "="
|
|
|
|
do {
|
|
// Write VALUE to NVRAM
|
|
HalpDS1385WriteNVRAM(Index++,*Value);
|
|
} while (*Value++ != 0);
|
|
|
|
ReturnValue = ESUCCESS;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update NVRAM checksum
|
|
//
|
|
HalpUpdateCrc();
|
|
if (NvramFailure == TRUE) {
|
|
ReturnValue = ENOMEM;
|
|
}
|
|
#if USE_SPINLOCKS
|
|
KeReleaseSpinLock(NVRAM_Spinlock, Irql);
|
|
#endif
|
|
return(ReturnValue);
|
|
}
|
|
|
|
|