summaryrefslogtreecommitdiff
path: root/arch/ppc/kernel
diff options
context:
space:
mode:
authorTom Rini <trini@kernel.crashing.org>2002-07-21 20:07:21 -0700
committerTom Rini <trini@kernel.crashing.org>2002-07-21 20:07:21 -0700
commit25330c6041e9cc68e23541894035afd117d71456 (patch)
treeb638a7b733e80df35d5970eadf82651a1ea90e05 /arch/ppc/kernel
parent4872eaccd9c1926c2e047abd761a1076eb7c4d11 (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/Makefile1
-rw-r--r--arch/ppc/kernel/prep_nvram.c148
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;
+ }
+}
+
+
+