summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr98mp/mips/jxenvirv.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halr98mp/mips/jxenvirv.c')
-rw-r--r--private/ntos/nthals/halr98mp/mips/jxenvirv.c818
1 files changed, 818 insertions, 0 deletions
diff --git a/private/ntos/nthals/halr98mp/mips/jxenvirv.c b/private/ntos/nthals/halr98mp/mips/jxenvirv.c
new file mode 100644
index 000000000..5e9446d73
--- /dev/null
+++ b/private/ntos/nthals/halr98mp/mips/jxenvirv.c
@@ -0,0 +1,818 @@
+#pragma comment(exestr, "@(#) jxenvirv.c 1.8 94/12/06 15:07:37 nec")
+/*++
+
+Copyright (c) 1991-1994 Microsoft Corporation
+
+Module Name:
+
+ jxenvirv.c
+
+Abstract:
+
+ This module implements the HAL get and set environment variable routines
+ for a MIPS system.
+
+Author:
+
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+--*/
+/*
+ * Original source: Build Number 1.612
+ *
+ * Modify for R98(MIPS/R4400)
+ *
+ ***********************************************************************
+ * K001 94.5/31 (Tue) N.Kugimoto
+ * Del No Map TLB. & nvram base define -->def.h
+ * Add Nvram write enable
+ * K002 94/6/10 (Fri) N.Kugimoto
+ * Chg Compile err del.
+ * K003 94/8/29 (Mon) N.Kugimoto
+ * -1 BUG HalpUnmapNvram() stsr register write value bug.
+ * -2 Chg HalpMapNvram() stsr register write value is absolute.
+ * K004 94/10/11 N.Kugimoto
+ * H/W Work Around. NVRAM can't write protect!!.
+ * K005 94/12/06 N.Kugimoto
+ * Add ESM Interface
+ * -2 Miss ;; -->,
+ */
+
+#include "halp.h"
+#include "arccodes.h"
+#include "jazznvr.h"
+#include "string.h"
+
+//
+// Define base address at which to map NVRAM.
+//
+#if !defined(_R98_) // K001
+#define NVRAM_MEMORY_BASE PTE_BASE
+#endif
+//
+// Define local upcase macro.
+//
+
+#define UpCase(c) ((c) >= 'a' && (c) <= 'z' ? (c) - ('a' - 'A') : (c))
+
+KIRQL
+HalpMapNvram (
+ IN PENTRYLO SavedPte
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to map the NVRAM into the address space of
+ the current process.
+
+Arguments:
+
+ SavedPte - Supplies a pointer to an array which receives the old NVRAM
+ PTE values.
+
+Return Value:
+
+ The previous IRQL is returned as the function value.
+
+--*/
+
+{
+
+ KIRQL OldIrql;
+#if defined(_R98_) // K001
+ //
+ // Nvram Write enable
+ // K002
+ WRITE_REGISTER_ULONG(
+ &( PMC_CONTROL1 )->STSR.Long,
+ STSR_NVWINH_ENABLE //K003-2
+ );
+
+#else // K001
+ ENTRYLO NvramPte;
+ PENTRYLO PtePointer;
+
+ //
+ // Construct a PTE to map NVRAM into the address space of the current
+ // process.
+ //
+
+ NvramPte.X1 = 0;
+ NvramPte.PFN = NVRAM_PHYSICAL_BASE >> PAGE_SHIFT;
+ NvramPte.G = 0;
+ NvramPte.V = 1;
+ NvramPte.D = 1;
+
+#if defined(R3000)
+
+ NvramPte.N = 1;
+
+#endif
+
+#if defined(R4000)
+
+ NvramPte.C = UNCACHED_POLICY;
+
+#endif
+
+ //
+ // Raise IRQL to the highest level, flush the TB, map the NVRAM into
+ // the address space of the current process, and return the previous
+ // IRQL.
+ //
+
+ PtePointer = (PENTRYLO)PDE_BASE;
+#endif // _R98_
+
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+#if !defined(_R98_)
+ SavedPte[0] = PtePointer[0];
+ SavedPte[1] = PtePointer[1];
+ KeFlushCurrentTb();
+ PtePointer[0] = NvramPte;
+ NvramPte.PFN += 1;
+ PtePointer[1] = NvramPte;
+#endif //_R98_
+ return OldIrql;
+}
+
+VOID
+HalpUnmapNvram (
+ IN PENTRYLO SavedPte,
+ IN KIRQL OldIrql
+ )
+
+/*++
+
+Routine Description:
+
+ This function is called to unmap the NVRAM from the address space of
+ the current process.
+
+Arguments:
+
+ SavedPte - Supplies a pointer to an array which contains the old NVRAM
+ PTE values.
+
+ OldIrql - Supplies the previous IRQL value.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+#if defined(_R98_) // K001
+#if 0 //K004 vvvvv
+ //
+ // Nvram write disable
+ // K002
+ WRITE_REGISTER_ULONG(
+ &( PMC_CONTROL1 )->STSR.Long,
+ STSR_NVWINH_DISABLE //K003-1
+ );
+
+#endif //K004 ^^^^^
+#else
+ PENTRYLO PtePointer;
+ //
+ // Restore the previous mapping for the current process, flush the TB,
+ // and lower IRQL to its previous level.
+ //
+
+ PtePointer = (PENTRYLO)PDE_BASE;
+ KeFlushCurrentTb();
+ PtePointer[0] = SavedPte[0];
+ PtePointer[1] = SavedPte[1];
+#endif //_R98_
+ KeLowerIrql(OldIrql);
+ return;
+}
+
+ARC_STATUS
+HalpEnvironmentCheckChecksum (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine checks the NVRAM environment area checksum.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ ESUCCESS is returned if the checksum matches. Otherwise, EIO is returned.
+
+--*/
+
+{
+
+ ULONG Checksum1;
+ ULONG Checksum2;
+ PUCHAR Environment;
+ ULONG Index;
+ PNV_CONFIGURATION NvConfiguration;
+
+ //
+ // Compute the NVRAM environment area checksum.
+ //
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_MEMORY_BASE;
+ Environment = &NvConfiguration->Environment[0];
+ Checksum1 = 0;
+ for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
+ Checksum1 += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
+ }
+
+ //
+ // Merge the checksum bytes from the NVRAM and compare to computed value.
+ //
+
+ Checksum2 = (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[0]) |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[1]) << 8 |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[2]) << 16 |
+ (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[3]) << 24;
+
+ //
+ // If the checksum mismatches, then return an I/O error. Otherwise,
+ // return a success status.
+ //
+
+ if (Checksum1 != Checksum2) {
+ return EIO;
+
+ } else {
+ return ESUCCESS;
+ }
+}
+
+VOID
+HalpEnvironmentSetChecksum (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets the NVRAM environment area checksum.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Checksum;
+ PUCHAR Environment;
+ ULONG Index;
+ PNV_CONFIGURATION NvConfiguration;
+
+ //
+ // Compute the NVRAM environment area checksum.
+ //
+
+ NvConfiguration = (PNV_CONFIGURATION)NVRAM_MEMORY_BASE;
+ Environment = &NvConfiguration->Environment[0];
+ Checksum = 0;
+ for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
+ Checksum += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
+ }
+
+ //
+ // Write the NVRAM environment area 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));
+
+ return;
+}
+
+ARC_STATUS
+HalpFindEnvironmentVariable (
+ IN PCHAR Variable,
+ OUT PULONG VariableIndex,
+ OUT PULONG ValueIndex
+ )
+
+/*++
+
+Routine Description:
+
+ This routine performs a case insensitive search of the NVRAM environment
+ area for the specified variable name.
+
+ N.B. The NVRAM must be mapped before this routine is called.
+
+
+Arguments:
+
+ Variable - Supplies a pointer to a zero terminated string containing an
+ environment variable name.
+
+Return Value:
+
+ ESUCCESS is returned if the specified variable name is located. Otherwise,
+ ENOENT is returned.
+
+--*/
+
+{
+
+ PUCHAR Environment;
+ ULONG Index;
+ PUCHAR Name;
+
+ //
+ // If the variable name is null, then return no entry found.
+ //
+
+ if (*Variable == 0) {
+ return ENOENT;
+ }
+
+ //
+ // Search the environment section of the NVRAM for a variable name match.
+ //
+
+ Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];
+ Index = 0;
+ do {
+
+ //
+ // Set name to the beginning of the variable name and record the
+ // current index value.
+ //
+
+ Name = Variable;
+ *VariableIndex = Index;
+
+ //
+ // Search until the end of the current environment variable, the
+ // end of the specified variable name, or the end of the NVRAM is
+ // reached.
+ //
+
+ while ((Index < LENGTH_OF_ENVIRONMENT) &&
+ (READ_REGISTER_UCHAR(&Environment[Index]) != 0) && (*Name != 0)) {
+ if (READ_REGISTER_UCHAR(&Environment[Index]) != UpCase(*Name)) {
+ break;
+ }
+
+ Name += 1;
+ Index += 1;
+ }
+
+ //
+ // Check for a match which is signified by the end of the variable
+ // name and the equal separator in the current environment variable.
+ //
+
+ if ((*Name == 0) && (READ_REGISTER_UCHAR(&Environment[Index]) == '=')) {
+ *ValueIndex = Index + 1;
+ return ESUCCESS;
+ }
+
+ //
+ // Advance to the start of the next variable.
+ //
+
+ while ((Index < LENGTH_OF_ENVIRONMENT) &&
+ (READ_REGISTER_UCHAR(&Environment[Index]) != 0)) {
+ Index += 1;
+ }
+
+ Index += 1;
+ } while (Index < LENGTH_OF_ENVIRONMENT);
+
+ return ENOENT;
+}
+
+ARC_STATUS
+HalGetEnvironmentVariable (
+ IN PCHAR Variable,
+ IN USHORT Length,
+ OUT PCHAR Buffer
+ )
+
+/*++
+
+Routine Description:
+
+ This function locates an environment variable and returns its value.
+
+Arguments:
+
+ Variable - Supplies a pointer to a zero terminated environment variable
+ name.
+
+ Length - Supplies the length of the value buffer in bytes.
+
+ Buffer - Supplies a pointer to a buffer that receives the variable value.
+
+Return Value:
+
+ ESUCCESS is returned if the enviroment variable is located. Otherwise,
+ ENOENT is returned.
+
+--*/
+
+{
+
+ PUCHAR Environment;
+ ULONG Index;
+ KIRQL OldIrql;
+ ENTRYLO SavedPte[2];
+ ARC_STATUS Status;
+ ULONG ValueIndex;
+ ULONG VariableIndex;
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+
+ //
+ // If the checksum does not match or the specified variable cannot
+ // be located, then set the status to no entry found. Otherwise, copy
+ // the respective variable value to the specified output buffer.
+ //
+
+ Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];
+ if ((HalpEnvironmentCheckChecksum() != ESUCCESS) ||
+ (HalpFindEnvironmentVariable(Variable,
+ &VariableIndex,
+ &ValueIndex) != ESUCCESS)) {
+
+ Status = ENOENT;
+
+ } else {
+
+ //
+ // Copy the specified value to the output buffer.
+ //
+
+ for (Index = 0; Index < Length; Index += 1) {
+ *Buffer = READ_REGISTER_UCHAR(&Environment[ValueIndex]);
+ if (*Buffer == 0) {
+ break;
+ }
+
+ Buffer += 1;
+ ValueIndex += 1;
+ }
+
+ //
+ // If the length terminated the loop, then return not enough memory.
+ // Otherwise, return success.
+ //
+
+ if (Index == Length) {
+ Status = ENOMEM;
+
+ } else {
+ Status = ESUCCESS;
+ }
+ }
+
+ //
+ // Unmap the NVRAM from the address space of the current process and
+ // return the function status.
+ //
+
+ HalpUnmapNvram(&SavedPte[0], OldIrql);
+ return Status;
+}
+
+ARC_STATUS
+HalSetEnvironmentVariable (
+ IN PCHAR Variable,
+ IN PCHAR Value
+ )
+
+/*++
+
+Routine Description:
+
+ This function creates an environment variable with the specified value.
+
+Arguments:
+
+ Variable - Supplies a pointer to an environment variable name.
+
+ Value - Supplies a pointer to the environment variable value.
+
+Return Value:
+
+ ESUCCESS is returned if the environment variable is created. Otherwise,
+ ENOMEM is returned.
+
+--*/
+
+{
+
+ UCHAR Character;
+ PUCHAR Environment;
+ KIRQL OldIrql;
+ ENTRYLO SavedPte[2];
+ ARC_STATUS Status;
+ ULONG TopIndex;
+ ULONG VariableIndex;
+ ULONG VariableLength;
+ ULONG ValueEnd;
+ ULONG ValueIndex;
+ ULONG ValueLength;
+
+ //
+ // Map the NVRAM into the address space of the current process.
+ //
+
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+ Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];
+
+ //
+ // If the checksum does not match, then set status to an I/O error.
+ //
+
+ if (HalpEnvironmentCheckChecksum() != ESUCCESS) {
+ Status = EIO;
+ goto Unmap;
+ }
+
+ //
+ // Determine the top of the environment area by scanning backwards until
+ // the a non-null character is found or the beginning of the environment
+ // area is reached.
+ //
+
+ for (TopIndex = (LENGTH_OF_ENVIRONMENT - 1); TopIndex > 0; TopIndex -= 1) {
+ if (READ_REGISTER_UCHAR(&Environment[TopIndex]) != '\0') {
+ break;
+ }
+ }
+
+ //
+ // If the environment area contains any data, then adjust the top index
+ // to the first free byte.
+ //
+
+ if (TopIndex != 0) {
+ TopIndex += 2;
+ }
+
+ //
+ // Compute the length of the variable name and the variable value.
+ //
+
+ VariableLength = strlen(Variable) + 1;
+ ValueLength = strlen(Value) + 1;
+
+ //
+ // Check to determine if the specified variable is currently defined.
+ //
+
+ if (HalpFindEnvironmentVariable(Variable,
+ &VariableIndex,
+ &ValueIndex) == ESUCCESS) {
+
+ //
+ // The specified variable is currently defined. Determine the end
+ // of the variable value by scanning forward to the zero termination
+ // byte.
+ //
+
+ ValueEnd = ValueIndex;
+ while (READ_REGISTER_UCHAR(&Environment[ValueEnd]) != '\0') {
+ ValueEnd += 1;
+ }
+
+ ValueEnd += 1;
+
+ //
+ // If there is enough free space for the new variable value, then
+ // remove the current variable name and value from the environment
+ // area, insert the new variable value at the end of the environment
+ // if it is not null, and set the status to success. Otherwise, set
+ // the status to no space available.
+ //
+
+ if ((ValueEnd - ValueIndex + LENGTH_OF_ENVIRONMENT - TopIndex) >= ValueLength) {
+ while (ValueEnd != TopIndex) {
+ Character = READ_REGISTER_UCHAR(&Environment[ValueEnd]);
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], Character);
+ ValueEnd += 1;
+ VariableIndex += 1;
+ }
+
+ ValueIndex = VariableIndex;
+ while (ValueIndex != TopIndex) {
+ WRITE_REGISTER_UCHAR(&Environment[ValueIndex], '\0');
+ ValueIndex += 1;
+ }
+
+ //
+ // If the new variable value is not null, then copy the variable
+ // name and the variable value into the enviroment area.
+ //
+
+ if (*Value != '\0') {
+
+ //
+ // copy the variable name to the environment area.
+ //
+
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], UpCase(*Variable));
+ VariableIndex += 1;
+ Variable += 1;
+ } while (*Variable != '\0');
+
+ //
+ // Insert separator character and copy variable value to the
+ // environment area.
+ //
+
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], '=');
+ VariableIndex += 1;
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[VariableIndex], *Value);
+ VariableIndex += 1;
+ Value += 1;
+ } while (*Value != '\0');
+ }
+
+ Status = ESUCCESS;
+
+ } else {
+ Status = ENOSPC;
+ }
+
+ } else {
+
+ //
+ // The specified variable does not currently have a value. If the
+ // specified variable is null or has no value, then set the status
+ // to success. Otherwise, if the free area is not large enough to
+ // hold the new variable name and its value, then set the status to
+ // no space available. Otherwise, insert the variable name and value
+ // at the end of the environment area and set the status to success.
+ //
+
+ if ((*Variable == '\0') || (*Value == '\0')) {
+ Status = ESUCCESS;
+
+ } else if ((LENGTH_OF_ENVIRONMENT - TopIndex) <
+ (VariableLength + ValueLength)) {
+ Status = ENOSPC;
+
+ } else {
+
+ //
+ // copy the variable name to the environment area.
+ //
+
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], UpCase(*Variable));
+ TopIndex += 1;
+ Variable += 1;
+ } while (*Variable != '\0');
+
+ //
+ // Insert separator character and copy variable value to the
+ // environment area.
+ //
+
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], '=');
+ TopIndex += 1;
+ do {
+ WRITE_REGISTER_UCHAR(&Environment[TopIndex], *Value);
+ TopIndex += 1;
+ Value += 1;
+ } while (*Value != '\0');
+
+ Status = ESUCCESS;
+ }
+ }
+
+ //
+ // Compute the new checksum and write to the environment area.
+ //
+
+ HalpEnvironmentSetChecksum();
+
+ //
+ // Unmap the NVRAM from the address space of the current process.
+ //
+
+Unmap:
+ HalpUnmapNvram(&SavedPte[0], OldIrql);
+ return Status;
+}
+
+
+
+#if defined(_R98_) //K005 Start VVVVV
+
+BOOLEAN
+HalNvramWrite(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Write Byte Count
+ PVOID Buffer // Pointer Of Buffer Write to NVRAM
+){
+ // Write into NVRAM
+ return HalpNvramReadWrite(Offset,Count,Buffer,1);
+}
+
+BOOLEAN
+HalNvramRead(
+ ULONG Offset, // Offset Of ESM NVRAM
+ ULONG Count, // Read Byte Count
+ PVOID Buffer // Pointer Of Buffer Read From NVRAM
+){
+ // Read From NVRAM
+ return HalpNvramReadWrite(Offset,Count,Buffer,0);
+}
+
+BOOLEAN
+HalpNvramReadWrite(
+ ULONG Offset, // Read/Write offset of ESM NVRAM
+ ULONG Count, // Read/Write Byte Count
+ PVOID Buffer, // read/Write Pointer
+ ULONG Write // Operation
+){
+
+ ENTRYLO SavedPte[2];
+ KIRQL OldIrql;
+ ULONG i;
+ //
+ // Check is addr . So decrement 1
+ //
+ if(
+ Offset >=0 &&
+ Count >=0 &&
+ NVRAM_ESM_BASE+Offset <=NVRAM_ESM_END &&
+ NVRAM_ESM_BASE+Offset+Count-1 <=NVRAM_ESM_END
+
+ ){
+
+ if(Write){
+ OldIrql = HalpMapNvram(&SavedPte[0]);
+ for(i=0;i<Count;i++){
+ WRITE_REGISTER_UCHAR((PUCHAR)(NVRAM_ESM_BASE+Offset+i),((PUCHAR)Buffer)[i]);
+ }
+ HalpUnmapNvram(&SavedPte[0], OldIrql);
+ }else{
+ for(i=0;i<Count;i++){
+ ((PUCHAR)Buffer)[i] =READ_REGISTER_UCHAR((PUCHAR)(NVRAM_ESM_BASE+Offset+i));
+
+ }
+ }
+
+ return TRUE;
+
+ }else{
+
+ //
+ // It is no ESM NVRAM Erea.
+ return FALSE;
+ }
+
+}
+
+//K005 End ^^^^^
+#endif