Newer bootloader from netbsd. This should work with non MCG Firmworks
authorrahnds <rahnds@openbsd.org>
Wed, 30 Apr 1997 14:33:59 +0000 (14:33 +0000)
committerrahnds <rahnds@openbsd.org>
Wed, 30 Apr 1997 14:33:59 +0000 (14:33 +0000)
openfirmware.

12 files changed:
sys/arch/powerpc/stand/ofwboot/Locore.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/Makefile [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/alloc.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/boot.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/cache.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/net.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/netif_of.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/ofdev.c [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/ofdev.h [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/ofwmagic.S [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/openfirm.h [new file with mode: 0644]
sys/arch/powerpc/stand/ofwboot/version [new file with mode: 0644]

diff --git a/sys/arch/powerpc/stand/ofwboot/Locore.c b/sys/arch/powerpc/stand/ofwboot/Locore.c
new file mode 100644 (file)
index 0000000..4887605
--- /dev/null
@@ -0,0 +1,477 @@
+/*     $NetBSD: Locore.c,v 1.1 1997/04/16 20:29:11 thorpej Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <lib/libsa/stand.h>
+#include <powerpc/stand/ofwboot/openfirm.h>
+
+/*
+#include "machine/cpu.h"
+*/
+
+static int (*openfirmware)(void *);
+
+static void setup __P((void));
+
+#ifdef XCOFF_GLUE
+asm (".text; .globl _entry; _entry: .long _start,0,0");
+#endif
+
+__dead void
+_start(vpd, res, openfirm, arg, argl)
+       void *vpd;
+       int res;
+       int (*openfirm)(void *);
+       char *arg;
+       int argl;
+{
+       extern char etext[];
+
+#ifdef FIRMWORKSBUGS
+       syncicache((void *)RELOC, etext - (char *)RELOC);
+#endif
+       openfirmware = openfirm;        /* Save entry to Open Firmware */
+       setup();
+       main(arg, argl);
+       exit();
+}
+
+__dead void
+_rtt()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+       } args = {
+               "exit",
+               0,
+               0
+       };
+
+       openfirmware(&args);
+       while (1);                      /* just in case */
+}
+
+int
+OF_finddevice(name)
+       char *name;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *device;
+               int phandle;
+       } args = {
+               "finddevice",
+               1,
+               1,
+       };      
+       
+       args.device = name;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_instance_to_package(ihandle)
+       int ihandle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               int phandle;
+       } args = {
+               "instance-to-package",
+               1,
+               1,
+       };
+       
+       args.ihandle = ihandle;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.phandle;
+}
+
+int
+OF_getprop(handle, prop, buf, buflen)
+       int handle;
+       char *prop;
+       void *buf;
+       int buflen;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *prop;
+               void *buf;
+               int buflen;
+               int size;
+       } args = {
+               "getprop",
+               4,
+               1,
+       };
+       
+       args.phandle = handle;
+       args.prop = prop;
+       args.buf = buf;
+       args.buflen = buflen;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.size;
+}
+
+#ifdef __notyet__      /* Has a bug on FirePower */
+int
+OF_setprop(handle, prop, buf, len)
+       int handle;
+       char *prop;
+       void *buf;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int phandle;
+               char *prop;
+               void *buf;
+               int len;
+               int size;
+       } args = {
+               "setprop",
+               4,
+               1,
+       };
+       
+       args.phandle = handle;
+       args.prop = prop;
+       args.buf = buf;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.size;
+}
+#endif
+
+int
+OF_open(dname)
+       char *dname;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               char *dname;
+               int handle;
+       } args = {
+               "open",
+               1,
+               1,
+       };
+       
+       args.dname = dname;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.handle;
+}
+
+void
+OF_close(handle)
+       int handle;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+       } args = {
+               "close",
+               1,
+               0,
+       };
+       
+       args.handle = handle;
+       openfirmware(&args);
+}
+
+int
+OF_write(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "write",
+               3,
+               1,
+       };
+
+       args.ihandle = handle;
+       args.addr = addr;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.actual;
+}
+
+int
+OF_read(handle, addr, len)
+       int handle;
+       void *addr;
+       int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ihandle;
+               void *addr;
+               int len;
+               int actual;
+       } args = {
+               "read",
+               3,
+               1,
+       };
+
+       args.ihandle = handle;
+       args.addr = addr;
+       args.len = len;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.actual;
+}
+
+int
+OF_seek(handle, pos)
+       int handle;
+       u_quad_t pos;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int handle;
+               int poshi;
+               int poslo;
+               int status;
+       } args = {
+               "seek",
+               3,
+               1,
+       };
+       
+       args.handle = handle;
+       args.poshi = (int)(pos >> 32);
+       args.poslo = (int)pos;
+       if (openfirmware(&args) == -1)
+               return -1;
+       return args.status;
+}
+
+void *
+OF_claim(virt, size, align)
+       void *virt;
+       u_int size;
+       u_int align;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+               u_int align;
+               void *baseaddr;
+       } args = {
+               "claim",
+               3,
+               1,
+       };
+
+#ifdef FIRMWORKSBUGS
+       /*
+        * Bug with Firmworks OFW
+        */
+       if (virt)
+               return virt;
+#endif
+       args.virt = virt;
+       args.size = size;
+       args.align = align;
+       if (openfirmware(&args) == -1)
+               return (void *)-1;
+       return args.baseaddr;
+}
+
+void
+OF_release(virt, size)
+       void *virt;
+       u_int size;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+       } args = {
+               "release",
+               2,
+               0,
+       };
+       
+       args.virt = virt;
+       args.size = size;
+       openfirmware(&args);
+}
+
+int
+OF_milliseconds()
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               int ms;
+       } args = {
+               "milliseconds",
+               0,
+               1,
+       };
+       
+       openfirmware(&args);
+       return args.ms;
+}
+
+#ifdef __notyet__
+void
+OF_chain(virt, size, entry, arg, len)
+       void *virt;
+       u_int size;
+       void (*entry)();
+       void *arg;
+       u_int len;
+{
+       static struct {
+               char *name;
+               int nargs;
+               int nreturns;
+               void *virt;
+               u_int size;
+               void (*entry)();
+               void *arg;
+               u_int len;
+       } args = {
+               "chain",
+               5,
+               0,
+       };
+
+       args.virt = virt;
+       args.size = size;
+       args.entry = entry;
+       args.arg = arg;
+       args.len = len;
+       openfirmware(&args);
+}
+#else
+void
+OF_chain(virt, size, entry, arg, len)
+       void *virt;
+       u_int size;
+       void (*entry)();
+       void *arg;
+       u_int len;
+{
+       /*
+        * This is a REALLY dirty hack till the firmware gets this going
+        */
+       OF_release(virt, size);
+       entry(0, 0, openfirmware, arg, len);
+}
+#endif
+
+static int stdin;
+static int stdout;
+
+static void
+setup()
+{
+       int chosen;
+       
+       if ((chosen = OF_finddevice("/chosen")) == -1)
+               _rtt();
+       if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) != sizeof(stdin)
+           || OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) !=
+           sizeof(stdout))
+               _rtt();
+}
+
+void
+putchar(c)
+       int c;
+{
+       char ch = c;
+
+       if (c == '\n')
+               putchar('\r');
+       OF_write(stdout, &ch, 1);
+}
+
+int
+getchar()
+{
+       unsigned char ch;
+       int l;
+
+       while ((l = OF_read(stdin, &ch, 1)) != 1)
+               if (l != -2)
+                       return -1;
+       return ch;
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/Makefile b/sys/arch/powerpc/stand/ofwboot/Makefile
new file mode 100644 (file)
index 0000000..9cc424b
--- /dev/null
@@ -0,0 +1,54 @@
+#      $NetBSD: Makefile,v 1.2 1997/04/17 07:46:24 thorpej Exp $
+
+S=     ${.CURDIR}/../../../..
+R=../
+
+PROG=          ofwboot
+SRCS=          Locore.c boot.c ofdev.c net.c netif_of.c alloc.c cache.c
+.PATH:         ${S}/arch/powerpc/powerpc
+SRCS+=         ofwmagic.S
+#CFLAGS+=      -DDEBUG -DNETIF_DEBUG
+NOMAN=
+STRIPFLAG=
+BINMODE=       444
+OBJCOPY?=      objcopy
+SAREL=
+BINDIR=         /usr/mdec
+
+NEWVERSWHAT=   "OpenFirmware Boot"
+
+# For now...
+RELOC=         20000
+
+ENTRY=         _start
+
+CPPFLAGS+=     -I. -I${.CURDIR}/../../.. -I${.CURDIR}/../../../..
+CPPFLAGS+=     -DRELOC=0x${RELOC}
+CPPFLAGS+=     -DFIRMWORKSBUGS
+CPPFLAGS+=     -DPOWERPC_BOOT_ELF
+CPPFLAGS+=     -DXCOFF_GLUE            # for booting PCI Powermacs
+
+### find out what to use for libkern
+KERN_AS=       library
+.include "${S}/lib/libkern/Makefile.inc"
+LIBKERN=       ${KERNLIB}
+
+### find out what to use for libz
+Z_AS=          library
+.include "${S}/lib/libz/Makefile.inc"
+LIBZ=          ${ZLIB}
+
+### find out what to use for libsa
+SA_AS=         library
+SAMISCMAKEFLAGS= SA_USE_CREAD=yes
+.include "${S}/lib/libsa/Makefile.inc"
+LIBSA=         ${SALIB}
+
+${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
+       ${LD} -X -Ttext ${RELOC} -e ${ENTRY} -o ${PROG} \
+           ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
+#      mv ${PROG} ${PROG}.elf
+#      ${OBJCOPY} --input-target=elf32-powerpc \
+#          --output-target=xcoff-powermac ${PROG}.elf ${PROG}.xcf
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/powerpc/stand/ofwboot/alloc.c b/sys/arch/powerpc/stand/ofwboot/alloc.c
new file mode 100644 (file)
index 0000000..2349861
--- /dev/null
@@ -0,0 +1,217 @@
+/*     $NetBSD: alloc.c,v 1.1 1997/04/16 20:29:16 thorpej Exp $        */
+
+/*
+ * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
+ * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
+ * Copyright (c) 1996
+ *     Matthias Drochner.  All rights reserved.
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Dynamic memory allocator suitable for use with OpenFirmware.
+ *
+ * Compile options:
+ *
+ *     ALLOC_TRACE     enable tracing of allocations/deallocations
+ *
+ *     ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than
+ *                     the default best-fit algorithm.
+ *
+ *     DEBUG           enable debugging sanity checks.
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#include <lib/libsa/stand.h>
+
+#include <powerpc/stand/ofwboot/openfirm.h>
+
+/*
+ * Each block actually has ALIGN(struct ml) + ALIGN(size) bytes allocated
+ * to it, as follows:
+ *
+ * 0 ... (sizeof(struct ml) - 1)
+ *     allocated or unallocated: holds size of user-data part of block.
+ *
+ * sizeof(struct ml) ... (ALIGN(sizeof(struct ml)) - 1)
+ *     allocated: unused
+ *     unallocated: depends on packing of struct fl
+ *
+ * ALIGN(sizeof(struct ml)) ... (ALIGN(sizeof(struct ml)) +
+ *   ALIGN(data size) - 1)
+ *     allocated: user data
+ *     unallocated: depends on packing of struct fl
+ *
+ * 'next' is only used when the block is unallocated (i.e. on the free list).
+ * However, note that ALIGN(sizeof(struct ml)) + ALIGN(data size) must
+ * be at least 'sizeof(struct fl)', so that blocks can be used as structures
+ * when on the free list.
+ */
+
+/*
+ * Memory lists.
+ */
+struct ml {
+       unsigned        size;
+       LIST_ENTRY(ml)  list;
+};
+
+/* XXX - this is from NetBSD  */
+#define LIST_HEAD_INITIALIZER(head) { NULL }
+
+LIST_HEAD(, ml) freelist = LIST_HEAD_INITIALIZER(freelist);
+LIST_HEAD(, ml) allocatedlist = LIST_HEAD_INITIALIZER(allocatedlist);
+
+#define        OVERHEAD        ALIGN(sizeof (struct ml))       /* shorthand */
+
+void *
+alloc(size)
+       unsigned size;
+{
+       struct ml *f, *bestf;
+       unsigned bestsize = 0xffffffff; /* greater than any real size */
+       char *help;
+       int failed;
+
+#ifdef ALLOC_TRACE
+       printf("alloc(%u)", size);
+#endif
+
+       /*
+        * Account for overhead now, so that we don't get an
+        * "exact fit" which doesn't have enough space.
+        */
+       size = ALIGN(size) + OVERHEAD;
+
+#ifdef ALLOC_FIRST_FIT
+       /* scan freelist */
+       for (f = freelist.lh_first; f != NULL && f->size < size;
+           f = f->list.le_next)
+               /* noop */ ;
+       bestf = f;
+       failed = (bestf == (struct fl *)0);
+#else
+       /* scan freelist */
+       f = freelist.lh_first;
+       while (f != NULL) {
+               if (f->size >= size) {
+                       if (f->size == size)    /* exact match */
+                               goto found;
+
+                       if (f->size < bestsize) {
+                               /* keep best fit */
+                               bestf = f;
+                               bestsize = f->size;
+                       }
+               }
+               f = f->list.le_next;
+       }
+
+       /* no match in freelist if bestsize unchanged */
+       failed = (bestsize == 0xffffffff);
+#endif
+
+       if (failed) {   /* nothing found */
+               /*
+                * Allocate memory from the OpenFirmware, rounded
+                * to page size, and record the chunk size.
+                */
+               size = roundup(size, NBPG);
+               help = OF_claim(0, size, NBPG);
+               if (help == (char *)-1)
+                       panic("alloc: out of memory");
+
+               f = (struct ml *)help;
+               f->size = size;
+#ifdef ALLOC_TRACE
+               printf("=%lx (new chunk size %u)\n",
+                   (u_long)(help + OVERHEAD), f->f_size);
+#endif
+               goto out;
+       }
+
+       /* we take the best fit */
+       f = bestf;
+
+ found:
+       /* remove from freelist */
+       LIST_REMOVE(f, list);
+       help = (char *)f;
+#ifdef ALLOC_TRACE
+       printf("=%lx (origsize %u)\n", (u_long)(help + OVERHEAD), f->size);
+#endif
+ out:
+       /* place on allocated list */
+       LIST_INSERT_HEAD(&allocatedlist, f, list);
+       return (help + OVERHEAD);
+}
+
+void
+free(ptr, size)
+       void *ptr;
+       unsigned size;  /* only for consistenct check */
+{
+       register struct ml *a = (struct ml *)((char*)ptr - OVERHEAD);
+
+#ifdef ALLOC_TRACE
+       printf("free(%lx, %u) (origsize %u)\n", (u_long)ptr, size, a->size);
+#endif
+#ifdef DEBUG
+       if (size > a->size)
+               printf("free %u bytes @%lx, should be <=%u\n",
+                   size, (u_long)ptr, a->size);
+#endif
+
+       /* Remove from allocated list, place on freelist. */
+       LIST_REMOVE(a, list);
+       LIST_INSERT_HEAD(&freelist, a, list);
+}
+
+void
+freeall()
+{
+#ifdef __notyet__              /* Firmware bug ?! */
+       struct ml *m;
+
+       /* Release chunks on freelist... */
+       while ((m = freelist.lh_first) != NULL) {
+               LIST_REMOVE(m, list);
+               OF_release(m, m->size);
+       }
+
+       /* ...and allocated list. */
+       while ((m = allocatedlist.lh_first) != NULL) {
+               LIST_REMOVE(m, list);
+               OF_release(m, m->size);
+       }
+#endif /* __notyet__ */
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/boot.c b/sys/arch/powerpc/stand/ofwboot/boot.c
new file mode 100644 (file)
index 0000000..2da4a5f
--- /dev/null
@@ -0,0 +1,492 @@
+/*     $NetBSD: boot.c,v 1.1 1997/04/16 20:29:17 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * ELF support derived from NetBSD/alpha's boot loader, written
+ * by Christopher G. Demetriou.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * First try for the boot code
+ *
+ * Input syntax is:
+ *     [promdev[{:|,}partition]]/[filename] [flags]
+ */
+
+#define        ELFSIZE         32              /* We use 32-bit ELF. */
+
+#include <lib/libkern/libkern.h>
+#include <lib/libsa/stand.h>
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_elf.h>
+#include <sys/reboot.h>
+#include <sys/disklabel.h>
+
+#include <machine/cpu.h>
+/*
+#include <machine/machine_type.h>
+*/
+
+#include <powerpc/stand/ofwboot/ofdev.h>
+#include <powerpc/stand/ofwboot/openfirm.h>
+
+char bootdev[128];
+char bootfile[128];
+int boothowto;
+int debug;
+
+#ifdef POWERPC_BOOT_ELF
+int    elf_exec __P((int, Elf32_Ehdr *, u_int32_t *, void **));
+#endif
+
+#ifdef POWERPC_BOOT_AOUT
+int    aout_exec __P((int, struct exec *, u_int32_t *, void **));
+#endif
+
+static void
+prom2boot(dev)
+       char *dev;
+{
+       char *cp, *lp = 0;
+       int handle;
+       char devtype[16];
+       
+       for (cp = dev; *cp; cp++)
+               if (*cp == ':')
+                       lp = cp;
+       if (!lp)
+               lp = cp;
+       *lp = 0;
+}
+
+static void
+parseargs(str, howtop)
+       char *str;
+       int *howtop;
+{
+       char *cp;
+
+       /* Allow user to drop back to the PROM. */
+       if (strcmp(str, "exit") == 0)
+               _rtt();
+
+       *howtop = 0;
+       for (cp = str; *cp; cp++)
+               if (*cp == ' ' || *cp == '-')
+                       break;
+       if (!*cp)
+               return;
+       
+       *cp++ = 0;
+       while (*cp) {
+               switch (*cp++) {
+               case 'a':
+                       *howtop |= RB_ASKNAME;
+                       break;
+               case 's':
+                       *howtop |= RB_SINGLE;
+                       break;
+               case 'd':
+                       *howtop |= RB_KDB;
+                       debug = 1;
+                       break;
+               }
+       }
+}
+
+static void
+chain(entry, args, esym)
+       void (*entry)();
+       char *args;
+       void *esym;
+{
+       extern char end[];
+       int l, machine_tag;
+
+       freeall();
+
+       /*
+        * Stash pointer to end of symbol table after the argument
+        * strings.
+        */
+       l = strlen(args) + 1;
+       bcopy(&esym, args + l, sizeof(esym));
+       l += sizeof(esym);
+
+#ifdef __notyet__
+       /*
+        * Tell the kernel we're an OpenFirmware system.
+        */
+       machine_tag = POWERPC_MACHINE_OPENFIRMWARE;
+       bcopy(&machine_tag, args + l, sizeof(machine_tag));
+       l += sizeof(machine_tag);
+#endif
+
+       OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l);
+       panic("chain");
+}
+
+int
+loadfile(fd, args)
+       int fd;
+       char *args;
+{
+       union {
+#ifdef POWERPC_BOOT_AOUT
+               struct exec aout;
+#endif
+#ifdef POWERPC_BOOT_ELF
+               Elf32_Ehdr elf;
+#endif
+       } hdr;
+       int rval;
+       u_int32_t entry;
+       void *esym;
+
+       rval = 1;
+       esym = NULL;
+
+       /* Load the header. */
+       if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+               printf("read header: %s\n", strerror(errno));
+               goto err;
+       }
+
+       /* Determine file type, load kernel. */
+#ifdef POWERPC_BOOT_AOUT
+       if (N_BADMAG(hdr.aout) == 0 && N_GETMID(hdr.aout) == MID_POWERPC) {
+               rval = aout_exec(fd, &hdr.aout, &entry, &esym);
+       } else
+#endif
+#ifdef POWERPC_BOOT_ELF
+       if (IS_ELF(hdr.elf)) {
+               rval = elf_exec(fd, &hdr.elf, &entry, &esym);
+       } else
+#endif
+       {
+               printf("unknown executable format\n");
+       }
+
+       if (rval)
+               goto err;
+
+       printf(" start=0x%x\n", entry);
+
+       close(fd);
+
+       /* XXX this should be replaced w/ a mountroothook. */
+       if (floppyboot) {
+               printf("Please insert root disk and press ENTER ");
+               getchar();
+               printf("\n");
+       }
+
+       chain((void *)entry, args, esym);
+       /* NOTREACHED */
+
+ err:
+       close(fd);
+       return (rval);
+}
+
+#ifdef POWERPC_BOOT_AOUT
+int
+aout_exec(fd, hdr, entryp, esymp)
+       int fd;
+       struct exec *hdr;
+       u_int32_t *entryp;
+       void **esymp;
+{
+       void *addr;
+       int n, *paddr;
+
+       /* Display the load address (entry point) for a.out. */
+       printf("Booting %s @ 0x%lx\n", opened_name, hdr->a_entry);
+       addr = (void *)(hdr->a_entry);
+
+       /*
+        * Determine memory needed for kernel and allocate it from
+        * the firmware.
+        */
+       n = hdr->a_text + hdr->a_data + hdr->a_bss + hdr->a_syms + sizeof(int);
+       if ((paddr = OF_claim(addr, n, 0)) == (int *)-1)
+               panic("cannot claim memory");
+
+       /* Load text. */
+       lseek(fd, N_TXTOFF(*hdr), SEEK_SET);
+       printf("%lu", hdr->a_text);
+       if (read(fd, paddr, hdr->a_text) != hdr->a_text) {
+               printf("read text: %s\n", strerror(errno));
+               return (1);
+       }
+       syncicache((void *)paddr, hdr->a_text);
+
+       /* Load data. */
+       printf("+%lu", hdr->a_data);
+       if (read(fd, (void *)paddr + hdr->a_text, hdr->a_data) != hdr->a_data) {
+               printf("read data: %s\n", strerror(errno));
+               return (1);
+       }
+
+       /* Zero BSS. */
+       printf("+%lu", hdr->a_bss);
+       bzero((void *)paddr + hdr->a_text + hdr->a_data, hdr->a_bss);
+
+       /* Symbols. */
+       *esymp = paddr;
+       paddr = (int *)((void *)paddr + hdr->a_text + hdr->a_data + hdr->a_bss);
+       *paddr++ = hdr->a_syms;
+       if (hdr->a_syms) {
+               printf(" [%lu", hdr->a_syms);
+               if (read(fd, paddr, hdr->a_syms) != hdr->a_syms) {
+                       printf("read symbols: %s\n", strerror(errno));
+                       return (1);
+               }
+               paddr = (int *)((void *)paddr + hdr->a_syms);
+               if (read(fd, &n, sizeof(int)) != sizeof(int)) {
+                       printf("read symbols: %s\n", strerror(errno));
+                       return (1);
+               }
+               if (OF_claim((void *)paddr, n + sizeof(int), 0) == (void *)-1)
+                       panic("cannot claim memory");
+               *paddr++ = n;
+               if (read(fd, paddr, n - sizeof(int)) != n - sizeof(int)) {
+                       printf("read symbols: %s\n", strerror(errno));
+                       return (1);
+               }
+               printf("+%d]", n - sizeof(int));
+               *esymp = paddr + (n - sizeof(int));
+       }
+
+       *entryp = hdr->a_entry;
+       return (0);
+}
+#endif /* POWERPC_BOOT_AOUT */
+
+#ifdef POWERPC_BOOT_ELF
+int
+elf_exec(fd, elf, entryp, esymp)
+       int fd;
+       Elf32_Ehdr *elf;
+       u_int32_t *entryp;
+       void **esymp;
+{
+       Elf32_Shdr *shp;
+       Elf32_Off off;
+       void *addr;
+       size_t size;
+       int i, first = 1;
+       int n;
+
+       /*
+        * Don't display load address for ELF; it's encoded in
+        * each section.
+        */
+       printf("Booting %s\n", opened_name);
+
+       for (i = 0; i < elf->e_phnum; i++) {
+               Elf32_Phdr phdr;
+               (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
+               if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
+                       printf("read phdr: %s\n", strerror(errno));
+                       return (1);
+               }
+               if (phdr.p_type != PT_LOAD ||
+                   (phdr.p_flags & (PF_W|PF_X)) == 0)
+                       continue;
+
+               /* Read in segment. */
+               printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz,
+                   (u_long)phdr.p_vaddr);
+               (void)lseek(fd, phdr.p_offset, SEEK_SET);
+               if (OF_claim((void *)phdr.p_vaddr, phdr.p_memsz, 0) ==
+                   (void *)-1)
+                       panic("cannot claim memory");
+               if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
+                   phdr.p_filesz) {
+                       printf("read segment: %s\n", strerror(errno));
+                       return (1);
+               }
+               syncicache((void *)phdr.p_vaddr, phdr.p_filesz);
+
+               /* Zero BSS. */
+               if (phdr.p_filesz < phdr.p_memsz) {
+                       printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz,
+                           (u_long)(phdr.p_vaddr + phdr.p_filesz));
+                       bzero(phdr.p_vaddr + phdr.p_filesz,
+                           phdr.p_memsz - phdr.p_filesz);
+               }
+               first = 0;
+       }
+
+       printf(" \n");
+
+#if 0 /* I want to rethink this... --thorpej@netbsd.org */
+       /*
+        * Compute the size of the symbol table.
+        */
+       size = sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
+       shp = addr = alloc(elf->e_shnum * sizeof(Elf32_Shdr));
+       (void)lseek(fd, elf->e_shoff, SEEK_SET);
+       if (read(fd, addr, elf->e_shnum * sizeof(Elf32_Shdr)) !=
+           elf->e_shnum * sizeof(Elf32_Shdr)) {
+               printf("read section headers: %s\n", strerror(errno));
+               return (1);
+       }
+       for (i = 0; i < elf->e_shnum; i++, shp++) {
+               if (shp->sh_type == Elf32_sht_null)
+                       continue;
+               if (shp->sh_type != Elf32_sht_symtab
+                   && shp->sh_type != Elf32_sht_strtab) {
+                       shp->sh_offset = 0; 
+                       shp->sh_type = Elf32_sht_nobits;
+                       continue;
+               }
+               size += shp->sh_size;
+       }
+       shp = addr;
+
+       /*
+        * Reserve memory for the symbols.
+        */
+       if ((addr = OF_claim(0, size, NBPG)) == (void *)-1)
+               panic("no space for symbol table");
+
+       /*
+        * Copy the headers.
+        */
+       elf->e_phoff = 0;
+       elf->e_shoff = sizeof(Elf32_Ehdr);
+       elf->e_phentsize = 0;
+       elf->e_phnum = 0;
+       bcopy(elf, addr, sizeof(Elf32_Ehdr));
+       bcopy(shp, addr + sizeof(Elf32_Ehdr), elf->e_shnum * sizeof(Elf32_Shdr));
+       free(shp, elf->e_shnum * sizeof(Elf32_Shdr));
+       *ssymp = addr;
+
+       /*
+        * Now load the symbol sections themselves.
+        */
+       shp = addr + sizeof(Elf32_Ehdr);
+       addr += sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
+       off = sizeof(Elf32_Ehdr) + (elf->e_shnum * sizeof(Elf32_Shdr));
+       for (first = 1, i = 0; i < elf->e_shnum; i++, shp++) {
+               if (shp->sh_type == Elf32_sht_symtab
+                   || shp->sh_type == Elf32_sht_strtab) {
+                       if (first)
+                               printf("symbols @ 0x%lx ", (u_long)addr);
+                       printf("%s%d", first ? "" : "+", shp->sh_size);
+                       (void)lseek(fd, shp->sh_offset, SEEK_SET);
+                       if (read(fd, addr, shp->sh_size) != shp->sh_size) {
+                               printf("read symbols: %s\n", strerror(errno));
+                               return (1);
+                       }
+                       addr += shp->sh_size;
+                       shp->sh_offset = off;
+                       off += shp->sh_size;
+                       first = 0;
+               }
+       }
+       *esymp = addr;
+#endif /* 0 */
+
+       *entryp = elf->e_entry;
+       return (0);
+}
+#endif /* POWERPC_BOOT_ELF */
+
+void
+main()
+{
+       int chosen;
+       char bootline[512];             /* Should check size? */
+       char *cp;
+       int fd;
+       
+       printf("\n>> OpenBSD/powerpc Boot\n");
+
+       /*
+        * Get the boot arguments from Openfirmware
+        */
+       if ((chosen = OF_finddevice("/chosen")) == -1
+           || OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0
+           || OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) {
+               printf("Invalid Openfirmware environment\n");
+               exit();
+       }
+       prom2boot(bootdev);
+       parseargs(bootline, &boothowto);
+       for (;;) {
+               if (boothowto & RB_ASKNAME) {
+                       printf("Boot: ");
+                       gets(bootline);
+                       parseargs(bootline, &boothowto);
+               }
+               if ((fd = open(bootline, 0)) >= 0)
+                       break;
+               if (errno)
+                       printf("open %s: %s\n", opened_name, strerror(errno));
+               boothowto |= RB_ASKNAME;
+       }
+#ifdef __notyet__
+       OF_setprop(chosen, "bootpath", opened_name, strlen(opened_name) + 1);
+       cp = bootline;
+#else
+       strcpy(bootline, opened_name);
+       cp = bootline + strlen(bootline);
+       *cp++ = ' ';
+#endif
+       *cp = '-';
+       if (boothowto & RB_ASKNAME)
+               *++cp = 'a';
+       if (boothowto & RB_SINGLE)
+               *++cp = 's';
+       if (boothowto & RB_KDB)
+               *++cp = 'd';
+       if (*cp == '-')
+#ifdef __notyet__
+               *cp = 0;
+#else
+               *--cp = 0;
+#endif
+       else
+               *++cp = 0;
+#ifdef __notyet__
+       OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
+#endif
+       /* XXX void, for now */
+       (void)loadfile(fd, bootline);
+
+       _rtt();
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/cache.c b/sys/arch/powerpc/stand/ofwboot/cache.c
new file mode 100644 (file)
index 0000000..c40dead
--- /dev/null
@@ -0,0 +1,22 @@
+#define CACHELINESIZE   32                      /* For now              XXX */
+
+void
+syncicache(from, len)  
+       void *from;
+       int len;
+{
+       int l = len;
+       void *p = from;
+
+       do {
+               asm volatile ("dcbst 0,%0" :: "r"(p));
+               p += CACHELINESIZE;
+       } while ((l -= CACHELINESIZE) > 0);
+       asm volatile ("sync");
+       do {
+               asm volatile ("icbi 0,%0" :: "r"(from));
+               from += CACHELINESIZE;
+       } while ((len -= CACHELINESIZE) > 0);
+       asm volatile ("isync");
+}
+
diff --git a/sys/arch/powerpc/stand/ofwboot/net.c b/sys/arch/powerpc/stand/ofwboot/net.c
new file mode 100644 (file)
index 0000000..247598e
--- /dev/null
@@ -0,0 +1,152 @@
+/*     $NetBSD: net.c,v 1.1 1997/04/16 20:29:18 thorpej Exp $  */
+
+/*
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code.  This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface      - netif_open()
+ * BOOTP               - bootp()
+ * RPC/mountd          - nfs_mount()
+ *
+ * The root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ *
+ * Note: this is based in part on sys/arch/sparc/stand/net.c
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include <lib/libsa/netif.h>
+
+char   rootpath[FNAME_SIZE];
+
+static int netdev_sock = -1;
+static int open_count;
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ */
+int
+net_open(op)
+       struct of_dev *op;
+{
+       int error = 0;
+       
+       /*
+        * On first open, do netif open, mount, etc.
+        */
+       if (open_count == 0) {
+               /* Find network interface. */
+               if ((netdev_sock = netif_open(op)) < 0) {
+                       error = errno;
+                       goto bad;
+               }
+               if ((error = net_mountroot()) != 0)
+                       goto bad;
+       }
+       open_count++;
+bad:
+       if (netdev_sock >= 0 && open_count == 0) {
+               netif_close(netdev_sock);
+               netdev_sock = -1;
+       }
+       return error;
+}
+
+int
+net_close(op)
+       struct of_dev *op;
+{
+       /*
+        * On last close, do netif close, etc.
+        */
+       if (open_count > 0)
+               if (--open_count == 0) {
+                       netif_close(netdev_sock);
+                       netdev_sock = -1;
+               }
+}
+
+int
+net_mountroot()
+{
+
+#ifdef DEBUG
+       printf("net_mountroot\n");
+#endif
+       
+       /*
+        * Get info for NFS boot: our IP address, out hostname,
+        * server IP address, and our root path on the server.
+        * We use BOOTP (RFC951, RFC1532) exclusively as mandated
+        * by PowerPC Reference Platform Specification I.4.2
+        */
+       
+       bootp(netdev_sock);
+       
+       if (myip.s_addr == 0)
+               return ETIMEDOUT;
+       
+       printf("Using IP address: %s\n", inet_ntoa(myip));
+       
+#ifdef DEBUG
+       printf("myip: %s (%s)", hostname, inet_ntoa(myip));
+       if (gateip.s_addr)
+               printf(", gateip: %s", inet_ntoa(gateip));
+       if (netmask)
+               printf(", netmask: %s", intoa(netmask));
+       printf("\n");
+#endif
+       printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
+       
+       /*
+        * Get the NFS file handle (mount).
+        */
+       if (nfs_mount(netdev_sock, rootip, rootpath) < 0)
+               return errno;
+       return 0;
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/netif_of.c b/sys/arch/powerpc/stand/ofwboot/netif_of.c
new file mode 100644 (file)
index 0000000..27df48e
--- /dev/null
@@ -0,0 +1,244 @@
+/*     $NetBSD: netif_of.c,v 1.1 1997/04/16 20:29:19 thorpej Exp $     */
+
+/*
+ * Copyright (C) 1995 Wolfgang Solfrank.
+ * Copyright (C) 1995 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Open Firmware does most of the job for interfacing to the hardware,
+ * so it is easiest to just replace the netif module with
+ * this adaptation to the PROM network interface.
+ *
+ * Note: this is based in part on sys/arch/sparc/stand/netif_sun.c
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#if 0                  /* XXX thorpej */
+#include <string.h>
+#include <time.h>
+#endif
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include <lib/libsa/netif.h>
+
+#include <powerpc/stand/ofwboot/ofdev.h>
+#include <powerpc/stand/ofwboot/openfirm.h>
+
+static struct netif netif_of;
+
+struct iodesc sockets[SOPEN_MAX];
+
+struct iodesc *
+socktodesc(sock)
+       int sock;
+{
+       if (sock != 0)
+               return NULL;
+       return sockets;
+}
+
+int
+netif_open(machdep_hint)
+       void *machdep_hint;
+{
+       struct of_dev *op = machdep_hint;
+       struct iodesc *io;
+       int fd, error;
+       char addr[32];
+       
+#ifdef NETIF_DEBUG
+       printf("netif_open...");
+#endif
+       /* find a free socket */
+       io = sockets;
+       if (io->io_netif) {
+#ifdef NETIF_DEBUG
+               printf("device busy\n");
+#endif
+               errno = ENFILE;
+               return -1;
+       }
+       bzero(io, sizeof *io);
+
+       netif_of.nif_devdata = op;
+       io->io_netif = &netif_of;
+       
+       /* Put our ethernet address in io->myea */
+       OF_getprop(OF_instance_to_package(op->handle),
+                  "mac-address", io->myea, sizeof io->myea);
+
+#ifdef NETIF_DEBUG
+       printf("OK\n");
+#endif
+       return 0;
+}
+
+int
+netif_close(fd)
+       int fd;
+{
+       struct iodesc *io;
+       struct netif *ni;
+
+#ifdef NETIF_DEBUG
+       printf("netif_close(%x)...", fd);
+#endif
+       if (fd != 0) {
+#ifdef NETIF_DEBUG
+               printf("EBADF\n");
+#endif
+               errno = EBADF;
+               return -1;
+       }
+
+       io = &sockets[fd];
+       ni = io->io_netif;
+       if (ni != NULL) {
+               ni->nif_devdata = NULL;
+               io->io_netif = NULL;
+       }
+#ifdef NETIF_DEBUG
+       printf("OK\n");
+#endif
+       return 0;
+}
+
+/*
+ * Send a packet.  The ether header is already there.
+ * Return the length sent (or -1 on error).
+ */
+ssize_t
+netif_put(desc, pkt, len)
+       struct iodesc *desc;
+       void *pkt;
+       size_t len;
+{
+       struct of_dev *op;
+       ssize_t rv;
+       size_t sendlen;
+
+       op = desc->io_netif->nif_devdata;
+
+#ifdef NETIF_DEBUG
+       {
+               struct ether_header *eh;
+
+               printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
+                      desc, pkt, len);
+               eh = pkt;
+               printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+               printf("src: %s ", ether_sprintf(eh->ether_shost));
+               printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+       }
+#endif
+
+       sendlen = len;
+       if (sendlen < 60) {
+               sendlen = 60;
+#ifdef NETIF_DEBUG
+               printf("netif_put: length padded to %d\n", sendlen);
+#endif
+       }
+
+       rv = OF_write(op->handle, pkt, sendlen);
+
+#ifdef NETIF_DEBUG
+       printf("netif_put: xmit returned %d\n", rv);
+#endif
+
+       return rv;
+}
+
+/*
+ * Receive a packet, including the ether header.
+ * Return the total length received (or -1 on error).
+ */
+ssize_t
+netif_get(desc, pkt, maxlen, timo)
+       struct iodesc *desc;
+       void *pkt;
+       size_t maxlen;
+       time_t timo;
+{
+       struct of_dev *op;
+       int tick0, tmo_ms;
+       int len;
+
+       op = desc->io_netif->nif_devdata;
+
+#ifdef NETIF_DEBUG
+       printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
+              pkt, maxlen, timo);
+#endif
+
+       tmo_ms = timo * 1000;
+       tick0 = OF_milliseconds();
+
+       do {
+               len = OF_read(op->handle, pkt, maxlen);
+       } while ((len == -2) && ((OF_milliseconds() - tick0) < tmo_ms));
+
+#ifdef NETIF_DEBUG
+       printf("netif_get: received len=%d\n", len);
+#endif
+
+       if (len < 12)
+               return -1;
+
+#ifdef NETIF_DEBUG
+       {
+               struct ether_header *eh = pkt;
+
+               printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+               printf("src: %s ", ether_sprintf(eh->ether_shost));
+               printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
+       }
+#endif
+
+       return len;
+}
+
+/*
+ * Shouldn't really be here, but is used solely for networking, so...
+ */
+time_t
+getsecs()
+{
+       return OF_milliseconds() / 1000;
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/ofdev.c b/sys/arch/powerpc/stand/ofwboot/ofdev.c
new file mode 100644 (file)
index 0000000..5f6beba
--- /dev/null
@@ -0,0 +1,339 @@
+/*     $NetBSD: ofdev.c,v 1.1 1997/04/16 20:29:20 thorpej Exp $        */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Device I/O routines using Open Firmware
+ */
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <netinet/in.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/cd9660.h>
+#include <lib/libsa/nfs.h>
+
+#include <powerpc/stand/ofwboot/ofdev.h>
+
+extern char bootdev[];
+
+static char *
+filename(str, ppart)
+       char *str;
+       char *ppart;
+{
+       char *cp, *lp;
+       char savec;
+       int dhandle;
+       char devtype[16];
+       
+       lp = str;
+       devtype[0] = 0;
+       *ppart = 0;
+       for (cp = str; *cp; lp = cp) {
+               /* For each component of the path name... */
+               while (*++cp && *cp != '/');
+               savec = *cp;
+               *cp = 0;
+               /* ...look whether there is a device with this name */
+               dhandle = OF_finddevice(str);
+               *cp = savec;
+               if (dhandle == -1) {
+                       /* if not, lp is the delimiter between device and path */
+                       /* if the last component was a block device... */
+                       if (!strcmp(devtype, "block")) {
+                               /* search for arguments */
+                               for (cp = lp;
+                                    --cp >= str && *cp != '/' && *cp != ':';);
+                               if (cp >= str && *cp == ':') {
+                                       /* found arguments, make firmware ignore them */
+                                       *cp = 0;
+                                       for (cp = lp; *--cp && *cp != ',';);
+                                       if (*++cp >= 'a' && *cp <= 'a' + MAXPARTITIONS)
+                                               *ppart = *cp;
+                               }
+                       }
+                       return lp;
+               } else if (OF_getprop(dhandle, "device_type", devtype, sizeof devtype) < 0)
+                       devtype[0] = 0;
+       }
+       return 0;
+}
+
+static int
+strategy(devdata, rw, blk, size, buf, rsize)
+       void *devdata;
+       int rw;
+       daddr_t blk;
+       size_t size;
+       void *buf;
+       size_t *rsize;
+{
+       struct of_dev *dev = devdata;
+       u_quad_t pos;
+       int n;
+       
+       if (rw != F_READ)
+               return EPERM;
+       if (dev->type != OFDEV_DISK)
+               panic("strategy");
+       
+       pos = (u_quad_t)(blk + dev->partoff) * dev->bsize;
+       
+       for (;;) {
+               if (OF_seek(dev->handle, pos) < 0)
+                       break;
+               n = OF_read(dev->handle, buf, size);
+               if (n == -2)
+                       continue;
+               if (n < 0)
+                       break;
+               *rsize = n;
+               return 0;
+       }
+       return EIO;
+}
+
+static int
+devclose(of)
+       struct open_file *of;
+{
+       struct of_dev *op = of->f_devdata;
+       
+       if (op->type == OFDEV_NET)
+               net_close(op);
+       OF_close(op->handle);
+       op->handle = -1;
+}
+
+static struct devsw devsw[1] = {
+       "OpenFirmware",
+       strategy,
+       (int (*)__P((struct open_file *, ...)))nodev,
+       devclose,
+       noioctl
+};
+int ndevs = sizeof devsw / sizeof devsw[0];
+
+static struct fs_ops file_system_ufs = {
+       ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat
+};
+static struct fs_ops file_system_cd9660 = {
+       cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
+           cd9660_stat
+};
+static struct fs_ops file_system_nfs = {
+       nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat
+};
+
+struct fs_ops file_system[3];
+int nfsys;
+
+static struct of_dev ofdev = {
+       -1,
+};
+
+char opened_name[256];
+int floppyboot;
+
+static u_long
+get_long(p)
+       const void *p;
+{
+       const unsigned char *cp = p;
+       
+       return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
+}
+
+/*
+ * Find a valid disklabel.
+ */
+static int
+search_label(devp, off, buf, lp, off0)
+       struct of_dev *devp;
+       u_long off;
+       char *buf;
+       struct disklabel *lp;
+       u_long off0;
+{
+       size_t read;
+       struct mbr_partition *p;
+       int i;
+       u_long poff;
+       static int recursion;
+       
+       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+           || read != DEV_BSIZE)
+               return ERDLAB;
+       
+       if (buf[510] != 0x55 || buf[511] != 0xaa)
+               return ERDLAB;
+
+       if (recursion++ <= 1)
+               off0 += off;
+       for (p = (struct mbr_partition *)(buf + MBRPARTOFF), i = 4;
+            --i >= 0; p++) {
+               if (p->mbr_type == MBR_NETBSD) {
+                       poff = get_long(&p->mbr_start) + off0;
+                       if (strategy(devp, F_READ, poff + LABELSECTOR,
+                                    DEV_BSIZE, buf, &read) == 0
+                           && read == DEV_BSIZE) {
+                               if (!getdisklabel(buf, lp)) {
+                                       recursion--;
+                                       return 0;
+                               }
+                       }
+                       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+                           || read != DEV_BSIZE) {
+                               recursion--;
+                               return ERDLAB;
+                       }
+               } else if (p->mbr_type == MBR_EXTENDED) {
+                       poff = get_long(&p->mbr_start);
+                       if (!search_label(devp, poff, buf, lp, off0)) {
+                               recursion--;
+                               return 0;
+                       }
+                       if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+                           || read != DEV_BSIZE) {
+                               recursion--;
+                               return ERDLAB;
+                       }
+               }
+       }
+       recursion--;
+       return ERDLAB;
+}
+
+int
+devopen(of, name, file)
+       struct open_file *of;
+       const char *name;
+       char **file;
+{
+       char *cp;
+       char partition;
+       char fname[256];
+       char buf[DEV_BSIZE];
+       struct disklabel label;
+       int handle, part;
+       size_t read;
+       int error = 0;
+
+       if (ofdev.handle != -1)
+               panic("devopen");
+       if (of->f_flags != F_READ)
+               return EPERM;
+       strcpy(fname, name);
+       cp = filename(fname, &partition);
+       if (cp) {
+               strcpy(buf, cp);
+               *cp = 0;
+       }
+       if (!cp || !*buf)
+               strcpy(buf, DEFAULT_KERNEL);
+       if (!*fname)
+               strcpy(fname, bootdev);
+       strcpy(opened_name, fname);
+       if (partition) {
+               cp = opened_name + strlen(opened_name);
+               *cp++ = ':';
+               *cp++ = partition;
+               *cp = 0;
+       }
+       if (*buf != '/')
+               strcat(opened_name, "/");
+       strcat(opened_name, buf);
+       *file = opened_name + strlen(fname) + 1;
+       if ((handle = OF_finddevice(fname)) == -1)
+               return ENOENT;
+       if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
+               return ENXIO;
+       floppyboot = !strcmp(buf, "floppy");
+       if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
+               return ENXIO;
+       if (!strcmp(buf, "block"))
+               /* For block devices, indicate raw partition (:0 in OpenFirmware) */
+               strcat(fname, ":0");
+       if ((handle = OF_open(fname)) == -1)
+               return ENXIO;
+       bzero(&ofdev, sizeof ofdev);
+       ofdev.handle = handle;
+       if (!strcmp(buf, "block")) {
+               ofdev.type = OFDEV_DISK;
+               ofdev.bsize = DEV_BSIZE;
+               /* First try to find a disklabel without MBR partitions */
+               if (strategy(&ofdev, F_READ,
+                            LABELSECTOR, DEV_BSIZE, buf, &read) != 0
+                   || read != DEV_BSIZE
+                   || getdisklabel(buf, &label)) {
+                       /* Else try MBR partitions */
+                       error = search_label(&ofdev, 0, buf, &label, 0);
+                       if (error && error != ERDLAB)
+                               goto bad;
+               }
+
+               if (error == ERDLAB) {
+                       if (partition)
+                               /* User specified a parititon, but there is none */
+                               goto bad;
+                       /* No, label, just use complete disk */
+                       ofdev.partoff = 0;
+               } else {
+                       part = partition ? partition - 'a' : 0;
+                       ofdev.partoff = label.d_partitions[part].p_offset;
+               }
+               
+               of->f_dev = devsw;
+               of->f_devdata = &ofdev;
+               bcopy(&file_system_ufs, file_system, sizeof file_system[0]);
+               bcopy(&file_system_cd9660, file_system + 1,
+                   sizeof file_system[0]);
+               nfsys = 2;
+               return 0;
+       }
+       if (!strcmp(buf, "network")) {
+               ofdev.type = OFDEV_NET;
+               of->f_dev = devsw;
+               of->f_devdata = &ofdev;
+               bcopy(&file_system_nfs, file_system, sizeof file_system[0]);
+               nfsys = 1;
+               if (error = net_open(&ofdev))
+                       goto bad;
+               return 0;
+       }
+       error = EFTYPE;
+bad:
+       OF_close(handle);
+       ofdev.handle = -1;
+       return error;
+}
diff --git a/sys/arch/powerpc/stand/ofwboot/ofdev.h b/sys/arch/powerpc/stand/ofwboot/ofdev.h
new file mode 100644 (file)
index 0000000..63349ea
--- /dev/null
@@ -0,0 +1,52 @@
+/*     $NetBSD: ofdev.h,v 1.1 1997/04/16 20:29:22 thorpej Exp $        */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef        _STAND_DEV_H_
+#define        _STAND_DEV_H_
+
+struct of_dev {
+       int handle;
+       int type;
+       u_long partoff;
+       int bsize;
+};
+
+/* Known types: */
+#define        OFDEV_NET       1
+#define        OFDEV_DISK      2
+
+#define        DEFAULT_KERNEL  "/bsd"
+
+extern char opened_name[];
+extern int floppyboot;
+
+#endif
diff --git a/sys/arch/powerpc/stand/ofwboot/ofwmagic.S b/sys/arch/powerpc/stand/ofwboot/ofwmagic.S
new file mode 100644 (file)
index 0000000..4851e50
--- /dev/null
@@ -0,0 +1,74 @@
+/*     $NetBSD: ofwmagic.S,v 1.1 1997/04/16 21:19:00 thorpej Exp $     */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Magic note section used by OpenFirmware.
+ */
+
+       .section ".note"
+
+       # note header
+
+       # length of name
+       .long   8
+
+       # note descriptor size
+       .long   20
+
+       # note type (IEEE 1275)
+       .long   0x1275
+
+       # name of owner
+       .asciz  "PowerPC"
+       .balign 4
+
+
+       # note descriptor
+
+       # real mode (-1) or virtual mode (0)
+       .long   0
+
+       # real-base
+       .long   -1
+       # real-size
+       .long   -1
+
+       # virt-base
+       .long   -1
+       # virt-size
+       .long   -1
diff --git a/sys/arch/powerpc/stand/ofwboot/openfirm.h b/sys/arch/powerpc/stand/ofwboot/openfirm.h
new file mode 100644 (file)
index 0000000..3bbcd73
--- /dev/null
@@ -0,0 +1,55 @@
+/*     $NetBSD: openfirm.h,v 1.1 1997/04/16 20:29:23 thorpej Exp $     */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Prototypes for Openfirmware Interface Routines
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+int OF_finddevice __P((char *name));
+int OF_instance_to_package __P((int ihandle));
+int OF_getprop __P((int handle, char *prop, void *buf, int buflen));
+#ifdef __notyet__
+int OF_setprop __P((int handle, char *prop, void *buf, int len));
+#endif
+int OF_open __P((char *dname));
+void OF_close __P((int handle));
+int OF_write __P((int handle, void *addr, int len));
+int OF_read __P((int handle, void *addr, int len));
+int OF_seek __P((int handle, u_quad_t pos));
+void *OF_claim __P((void *virt, u_int size, u_int align));
+void OF_release __P((void *virt, u_int size));
+int OF_milliseconds __P((void));
+void OF_chain __P((void *addr, u_int size, void (*entry)(), void *parm, u_int parmlen));
+
diff --git a/sys/arch/powerpc/stand/ofwboot/version b/sys/arch/powerpc/stand/ofwboot/version
new file mode 100644 (file)
index 0000000..9c0dad2
--- /dev/null
@@ -0,0 +1,5 @@
+$NetBSD: version,v 1.3 1997/04/19 01:40:08 thorpej Exp $
+
+1.1:           Boot program for OpenFirmware; initial revision
+1.2:           Boot program rearrangement
+1.3:           Added support for loading ELF kernels