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