diff options
| author | Tom Rini <trini@kernel.crashing.org> | 2002-07-21 20:07:21 -0700 |
|---|---|---|
| committer | Tom Rini <trini@kernel.crashing.org> | 2002-07-21 20:07:21 -0700 |
| commit | 25330c6041e9cc68e23541894035afd117d71456 (patch) | |
| tree | b638a7b733e80df35d5970eadf82651a1ea90e05 /arch/ppc/kernel | |
| parent | 4872eaccd9c1926c2e047abd761a1076eb7c4d11 (diff) | |
PPC32: Allow Motorola machines with PPCBUG to get their boot args from NVRAM.
Diffstat (limited to 'arch/ppc/kernel')
| -rw-r--r-- | arch/ppc/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/ppc/kernel/prep_nvram.c | 148 |
2 files changed, 149 insertions, 0 deletions
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 3a8e5d1930b7..0c92373f434f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_PCI) += pci.o ifneq ($(CONFIG_PPC_ISERIES),y) obj-$(CONFIG_PCI) += pci-dma.o endif +obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_TAU) += temp.o diff --git a/arch/ppc/kernel/prep_nvram.c b/arch/ppc/kernel/prep_nvram.c new file mode 100644 index 000000000000..7d8c7e7e91e1 --- /dev/null +++ b/arch/ppc/kernel/prep_nvram.c @@ -0,0 +1,148 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * 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/segment.h> +#include <asm/io.h> +#include <asm/processor.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 prep_nvram_read_val(int addr) +{ + outb(addr, PREP_NVRAM_AS0); + outb(addr>>8, PREP_NVRAM_AS1); + return inb(PREP_NVRAM_DATA); +} + +void __prep 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++; + } +} + +__prep +char __prep *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; +} + +__prep +char __prep *prep_nvram_first_var(void) +{ + if (nvram->Header.GELength == 0) { + return NULL; + } else { + return (((char *)nvram) + + ((unsigned int) nvram->Header.GEAddress)); + } +} + +__prep +char __prep *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; + } +} + + + |
