linux/arch/ppc/syslib/prep_nvram.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1998  Corey Minyard
   3 *
   4 * This reads the NvRAM on PReP compliant machines (generally from IBM or
   5 * Motorola).  Motorola kept the format of NvRAM in their ROM, PPCBUG, the
   6 * same, long after they had stopped producing PReP compliant machines.  So
   7 * this code is useful in those cases as well.
   8 *
   9 */
  10#include <linux/init.h>
  11#include <linux/delay.h>
  12#include <linux/slab.h>
  13#include <linux/ioport.h>
  14
  15#include <asm/sections.h>
  16#include <asm/io.h>
  17#include <asm/machdep.h>
  18#include <asm/prep_nvram.h>
  19
  20static char nvramData[MAX_PREP_NVRAM];
  21static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
  22
  23unsigned char prep_nvram_read_val(int addr)
  24{
  25        outb(addr, PREP_NVRAM_AS0);
  26        outb(addr>>8, PREP_NVRAM_AS1);
  27        return inb(PREP_NVRAM_DATA);
  28}
  29
  30void prep_nvram_write_val(int           addr,
  31                          unsigned char val)
  32{
  33        outb(addr, PREP_NVRAM_AS0);
  34        outb(addr>>8, PREP_NVRAM_AS1);
  35        outb(val, PREP_NVRAM_DATA);
  36}
  37
  38void __init init_prep_nvram(void)
  39{
  40        unsigned char *nvp;
  41        int  i;
  42        int  nvramSize;
  43
  44        /*
  45         * The following could fail if the NvRAM were corrupt but
  46         * we expect the boot firmware to have checked its checksum
  47         * before boot
  48         */
  49        nvp = (char *) &nvram->Header;
  50        for (i=0; i<sizeof(HEADER); i++)
  51        {
  52                *nvp = ppc_md.nvram_read_val(i);
  53                nvp++;
  54        }
  55
  56        /*
  57         * The PReP NvRAM may be any size so read in the header to
  58         * determine how much we must read in order to get the complete
  59         * GE area
  60         */
  61        nvramSize=(int)nvram->Header.GEAddress+nvram->Header.GELength;
  62        if(nvramSize>MAX_PREP_NVRAM)
  63        {
  64                /*
  65                 * NvRAM is too large
  66                 */
  67                nvram->Header.GELength=0;
  68                return;
  69        }
  70
  71        /*
  72         * Read the remainder of the PReP NvRAM
  73         */
  74        nvp = (char *) &nvram->GEArea[0];
  75        for (i=sizeof(HEADER); i<nvramSize; i++)
  76        {
  77                *nvp = ppc_md.nvram_read_val(i);
  78                nvp++;
  79        }
  80}
  81
  82char *prep_nvram_get_var(const char *name)
  83{
  84        char *cp;
  85        int  namelen;
  86
  87        namelen = strlen(name);
  88        cp = prep_nvram_first_var();
  89        while (cp != NULL) {
  90                if ((strncmp(name, cp, namelen) == 0)
  91                    && (cp[namelen] == '='))
  92                {
  93                        return cp+namelen+1;
  94                }
  95                cp = prep_nvram_next_var(cp);
  96        }
  97
  98        return NULL;
  99}
 100
 101char *prep_nvram_first_var(void)
 102{
 103        if (nvram->Header.GELength == 0) {
 104                return NULL;
 105        } else {
 106                return (((char *)nvram)
 107                        + ((unsigned int) nvram->Header.GEAddress));
 108        }
 109}
 110
 111char *prep_nvram_next_var(char *name)
 112{
 113        char *cp;
 114
 115
 116        cp = name;
 117        while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
 118               && (*cp != '\0'))
 119        {
 120                cp++;
 121        }
 122
 123        /* Skip over any null characters. */
 124        while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
 125               && (*cp == '\0'))
 126        {
 127                cp++;
 128        }
 129
 130        if ((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength) {
 131                return cp;
 132        } else {
 133                return NULL;
 134        }
 135}
 136