summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/mips/jxenvir.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/fw/mips/jxenvir.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/fw/mips/jxenvir.c')
-rw-r--r--private/ntos/fw/mips/jxenvir.c502
1 files changed, 502 insertions, 0 deletions
diff --git a/private/ntos/fw/mips/jxenvir.c b/private/ntos/fw/mips/jxenvir.c
new file mode 100644
index 000000000..50738f922
--- /dev/null
+++ b/private/ntos/fw/mips/jxenvir.c
@@ -0,0 +1,502 @@
+#if defined(JAZZ)
+
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ jxenvir.c
+
+Abstract:
+
+ This module implements the ARC firmware Environment Variable functions as
+ described in the Advanced Risc Computing Specification (Revision 1.00),
+ section 3.3.3.11, for a MIPS R3000 or R4000 Jazz system.
+
+Author:
+
+ David M. Robinson (davidro) 13-June-1991
+
+
+Revision History:
+
+--*/
+
+#include "fwp.h"
+//
+// Static data.
+//
+
+UCHAR OutputString[MAXIMUM_ENVIRONMENT_VALUE];
+PCHAR VolatileEnvironment;
+
+//
+// Routine prototypes.
+//
+
+VOID
+FwEnvironmentSetChecksum (
+ VOID
+ );
+
+ARC_STATUS
+FwFindEnvironmentVariable (
+ IN PCHAR Variable,
+ OUT PULONG VariableIndex,
+ OUT PULONG ValueIndex
+ );
+
+
+VOID
+FwEnvironmentInitialize (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initializes the environment routine addresses.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Allocate enough memory to load the environment for loaded programs.
+ //
+
+ VolatileEnvironment = FwAllocatePool(LENGTH_OF_ENVIRONMENT);
+
+ //
+ // Initialize the environment routine addresses in the system
+ // parameter block.
+ //
+
+ (PARC_GET_ENVIRONMENT_ROUTINE)SYSTEM_BLOCK->FirmwareVector[GetEnvironmentRoutine] =
+ FwGetEnvironmentVariable;
+ (PARC_SET_ENVIRONMENT_ROUTINE)SYSTEM_BLOCK->FirmwareVector[SetEnvironmentRoutine] =
+ FwSetEnvironmentVariable;
+
+ return;
+}
+
+
+VOID
+FwEnvironmentSetChecksum (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the environment area checksum.
+
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ PUCHAR NvChars;
+ PNV_CONFIGURATION NvConfiguration;
+ ULONG Index;
+ ULONG Checksum;
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
+
+ //
+ // Form checksum from NVRAM data.
+ //
+
+ Checksum = 0;
+ NvChars = (PUCHAR)&NvConfiguration->Environment[0];
+
+ for ( Index = 0 ;
+ Index < LENGTH_OF_ENVIRONMENT;
+ Index++ ) {
+ Checksum += READ_REGISTER_UCHAR( NvChars++ );
+ }
+
+ //
+ // Write environment checksum.
+ //
+
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Checksum2[0],
+ (UCHAR)(Checksum & 0xFF));
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Checksum2[1],
+ (UCHAR)((Checksum >> 8) & 0xFF));
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Checksum2[2],
+ (UCHAR)((Checksum >> 16) & 0xFF));
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Checksum2[3],
+ (UCHAR)(Checksum >> 24));
+}
+
+
+PCHAR
+FwGetEnvironmentVariable (
+ IN PCHAR Variable
+ )
+
+/*++
+
+Routine Description:
+
+ This routine searches (not case sensitive) the non-volatile ram for
+ Variable, and if found returns a pointer to a zero terminated string that
+ contains the value, otherwise a NULL pointer is returned.
+
+
+Arguments:
+
+ Variable - Supplies a zero terminated string containing an environment
+ variable.
+
+Return Value:
+
+ If successful, returns a zero terminated string that is the value of
+ Variable, otherwise NULL is returned.
+
+--*/
+
+{
+ PNV_CONFIGURATION NvConfiguration;
+ ULONG VariableIndex;
+ ULONG ValueIndex;
+ ULONG Outdex;
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
+
+ //
+ // If checksum is wrong, or the variable can't be found, return NULL.
+ //
+
+ if ((FwEnvironmentCheckChecksum() != ESUCCESS) ||
+ (FwFindEnvironmentVariable(Variable, &VariableIndex, &ValueIndex) != ESUCCESS)) {
+ return NULL;
+ }
+
+ //
+ // Copy value to an output string, break on zero terminator or string max.
+ //
+
+ for ( Outdex = 0 ; Outdex < (MAXIMUM_ENVIRONMENT_VALUE - 1) ; Outdex++ ) {
+ if (NvConfiguration->Environment[ValueIndex] == 0) {
+ break;
+ }
+ OutputString[Outdex] =
+ READ_REGISTER_UCHAR( &NvConfiguration->Environment[ValueIndex++] );
+ }
+
+ //
+ // Zero terminate string, and return.
+ //
+
+ OutputString[Outdex] = 0;
+ return OutputString;
+}
+
+
+ARC_STATUS
+FwSetEnvironmentVariable (
+ IN PCHAR Variable,
+ IN PCHAR Value
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets Variable (not case sensitive) to Value.
+
+Arguments:
+
+ Variable - Supplies a zero terminated string containing an environment
+ variable.
+
+ Value - Supplies a zero terminated string containing an environment
+ variable value.
+
+Return Value:
+
+ Returns ESUCCESS if the set completed successfully, otherwise one of
+ the following error codes is returned.
+
+ ENOSPC No space in NVRAM for set operation.
+
+ EIO Invalid Checksum.
+
+--*/
+
+{
+ PNV_CONFIGURATION NvConfiguration;
+ ULONG VariableIndex;
+ ULONG ValueIndex;
+ ULONG TopOfEnvironment;
+ PCHAR String;
+ ULONG Count;
+ CHAR Char;
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
+
+ //
+ // If checksum is wrong, return EIO;
+ //
+
+ if (FwEnvironmentCheckChecksum() != ESUCCESS) {
+ return EIO;
+ }
+
+ //
+ // Determine the top of the environment space by looking for the first
+ // non-null character from the top.
+ //
+
+ TopOfEnvironment = LENGTH_OF_ENVIRONMENT - 1;
+ while (READ_REGISTER_UCHAR( &NvConfiguration->Environment[--TopOfEnvironment]) == 0) {
+ if (TopOfEnvironment == 0) {
+ break;
+ }
+ }
+
+ //
+ // Adjust TopOfEnvironment to the first new character, unless environment
+ // space is empty.
+ //
+
+ if (TopOfEnvironment != 0) {
+ TopOfEnvironment += 2;
+ }
+
+ //
+ // Check to see if the variable already has a value.
+ //
+
+ Count = LENGTH_OF_ENVIRONMENT - TopOfEnvironment;
+
+ if (FwFindEnvironmentVariable(Variable, &VariableIndex, &ValueIndex) == ESUCCESS) {
+
+ //
+ // Count free space, starting with the free area at the top and adding
+ // the old variable value.
+ //
+
+ for ( String = &NvConfiguration->Environment[ValueIndex] ;
+ READ_REGISTER_UCHAR( String ) != 0 ;
+ String++ ) {
+ Count++;
+ }
+
+ //
+ // Determine if free area is large enough to handle new value, if not
+ // return error.
+ //
+
+ for ( String = Value ; *String != 0 ; String++ ) {
+ if (Count-- == 0) {
+ return ENOSPC;
+ }
+ }
+
+ //
+ // Move ValueIndex to the end of the value and compress strings.
+ //
+
+ while(READ_REGISTER_UCHAR( &NvConfiguration->Environment[ValueIndex++]) != 0) {
+ }
+
+ while (ValueIndex < TopOfEnvironment ) {
+ Char = READ_REGISTER_UCHAR( &NvConfiguration->Environment[ValueIndex++] );
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Environment[VariableIndex++], Char);
+ }
+
+ //
+ // Adjust new top of environment.
+ //
+
+ TopOfEnvironment = VariableIndex;
+
+ //
+ // Zero to the end.
+ //
+
+ while (VariableIndex < LENGTH_OF_ENVIRONMENT) {
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Environment[VariableIndex++],
+ 0);
+ }
+
+ //
+ // Variable is new.
+ //
+
+ } else {
+
+ //
+ // Determine if free area is large enough to handle new value, if not
+ // return error.
+ //
+
+ for ( String = Value ; *String != 0 ; String++ ) {
+ if (Count-- == 0) {
+ return ENOSPC;
+ }
+ }
+
+ }
+
+ //
+ // If Value is not zero, write new variable and value.
+ //
+
+ if (*Value != 0) {
+
+ //
+ // Write new variable, converting to upper case.
+ //
+
+ while (*Variable != 0) {
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Environment[TopOfEnvironment++],
+ ((*Variable >= 'a') &&
+ (*Variable <= 'z') ?
+ (*Variable - 'a' + 'A') : *Variable));
+ Variable++;
+ }
+
+ //
+ // Write equal sign.
+ //
+
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Environment[TopOfEnvironment++], '=');
+
+ //
+ // Write new value.
+ //
+
+ while (*Value != 0) {
+ WRITE_REGISTER_UCHAR( &NvConfiguration->Environment[TopOfEnvironment++],
+ *Value++);
+ }
+ }
+
+ //
+ // Set checksum.
+ //
+
+ FwEnvironmentSetChecksum();
+
+ return ESUCCESS;
+}
+
+
+ARC_STATUS
+FwFindEnvironmentVariable (
+ IN PCHAR Variable,
+ OUT PULONG VariableIndex,
+ OUT PULONG ValueIndex
+ )
+
+/*++
+
+Routine Description:
+
+ This routine searches (not case sensitive) the non-volatile ram for
+ Variable.
+
+
+Arguments:
+
+ Variable - Supplies a zero terminated string containing an environment
+ variable.
+
+Return Value:
+
+ If successful, returns ESUCCESS, otherwise returns ENOENT.
+
+--*/
+
+{
+ PNV_CONFIGURATION NvConfiguration;
+ PUCHAR String;
+ PUCHAR Environment;
+ ULONG Index;
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_CONFIGURATION;
+
+ //
+ // If Variable is null, return immediately.
+ //
+
+ if (*Variable == 0) {
+ return ENOENT;
+ }
+
+ Environment = NvConfiguration->Environment;
+ Index = 0;
+
+ while (TRUE) {
+
+ //
+ // Set string to beginning of Variable.
+ //
+
+ String = Variable;
+ *VariableIndex = Index;
+
+ //
+ // Search until the end of NVRAM.
+ //
+
+ while ( Index < LENGTH_OF_ENVIRONMENT ) {
+
+ //
+ // Convert to uppercase and break if mismatch.
+ //
+
+ if ( READ_REGISTER_UCHAR( &Environment[Index] ) !=
+ ((*String >= 'a') &&
+ (*String <= 'z') ?
+ (*String - 'a' + 'A') : *String) ) {
+ break;
+ }
+
+ String++;
+ Index++;
+ }
+
+ //
+ // Check to see if we're at the end of the string and the variable,
+ // which means a match.
+ //
+
+ if ((*String == 0) && (READ_REGISTER_UCHAR( &Environment[Index] ) == '=')) {
+ *ValueIndex = ++Index;
+ return ESUCCESS;
+ }
+
+ //
+ // Move index to the start of the next variable.
+ //
+
+ while (READ_REGISTER_UCHAR( &Environment[Index++] ) != 0) {
+ if (Index >= LENGTH_OF_ENVIRONMENT) {
+ return ENOENT;
+ }
+ }
+ }
+}
+#endif
+