/*
 * arch/ppc/kernel/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;
	}
}
