Logo Search packages:      
Sourcecode: linux version File versions  Download package

prep_nvram.c

/*
 * Copyright (C) 1998  Corey Minyard
 *
 * This reads the NvRAM on PReP compliant machines (generally from IBM or
 * Motorola).  Motorola kept the format of NvRAM in their ROM, PPCBUG, the
 * same, long after they had stopped producing PReP compliant machines.  So
 * this code is useful in those cases as well.
 *
 */
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/ioport.h>

#include <asm/sections.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/prep_nvram.h>

static char nvramData[MAX_PREP_NVRAM];
static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];

unsigned char prep_nvram_read_val(int addr)
{
      outb(addr, PREP_NVRAM_AS0);
      outb(addr>>8, PREP_NVRAM_AS1);
      return inb(PREP_NVRAM_DATA);
}

void prep_nvram_write_val(int           addr,
                    unsigned char val)
{
      outb(addr, PREP_NVRAM_AS0);
      outb(addr>>8, PREP_NVRAM_AS1);
      outb(val, PREP_NVRAM_DATA);
}

void __init init_prep_nvram(void)
{
      unsigned char *nvp;
      int  i;
      int  nvramSize;

      /*
       * The following could fail if the NvRAM were corrupt but
       * we expect the boot firmware to have checked its checksum
       * before boot
       */
      nvp = (char *) &nvram->Header;
      for (i=0; i<sizeof(HEADER); i++)
      {
            *nvp = ppc_md.nvram_read_val(i);
            nvp++;
      }

      /*
       * The PReP NvRAM may be any size so read in the header to
       * determine how much we must read in order to get the complete
       * GE area
       */
      nvramSize=(int)nvram->Header.GEAddress+nvram->Header.GELength;
      if(nvramSize>MAX_PREP_NVRAM)
      {
            /*
             * NvRAM is too large
             */
            nvram->Header.GELength=0;
            return;
      }

      /*
       * Read the remainder of the PReP NvRAM
       */
      nvp = (char *) &nvram->GEArea[0];
      for (i=sizeof(HEADER); i<nvramSize; i++)
      {
            *nvp = ppc_md.nvram_read_val(i);
            nvp++;
      }
}

char *prep_nvram_get_var(const char *name)
{
      char *cp;
      int  namelen;

      namelen = strlen(name);
      cp = prep_nvram_first_var();
      while (cp != NULL) {
            if ((strncmp(name, cp, namelen) == 0)
                && (cp[namelen] == '='))
            {
                  return cp+namelen+1;
            }
            cp = prep_nvram_next_var(cp);
      }

      return NULL;
}

char *prep_nvram_first_var(void)
{
        if (nvram->Header.GELength == 0) {
            return NULL;
      } else {
            return (((char *)nvram)
                  + ((unsigned int) nvram->Header.GEAddress));
      }
}

char *prep_nvram_next_var(char *name)
{
      char *cp;


      cp = name;
      while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
             && (*cp != '\0'))
      {
            cp++;
      }

      /* Skip over any null characters. */
      while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
             && (*cp == '\0'))
      {
            cp++;
      }

      if ((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength) {
            return cp;
      } else {
            return NULL;
      }
}

Generated by  Doxygen 1.6.0   Back to index