diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-09-01 15:39:03 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-09-01 15:39:03 +0000 |
commit | 96fd81fad1ecb9c6db1d82029898c5d745862416 (patch) | |
tree | f9b5736bf8ae24f5cc229716015ba28ee3b9d0da /sys/arch/macppc/stand | |
parent | 901d54c0a752adcdf9f140fb1dc64263e237ccea (diff) |
The "powerpc" port which has supported the newer Apple Macintosh powerpc based
is being renamed to macppc. This is to allow sharing of common code
between different powerpc base platforms.
Most of the work involved in the renaming process was performed by miod@
Files moved from powerpc/stand to macppc/stand
Diffstat (limited to 'sys/arch/macppc/stand')
-rw-r--r-- | sys/arch/macppc/stand/Locore.c | 593 | ||||
-rw-r--r-- | sys/arch/macppc/stand/Makefile | 33 | ||||
-rw-r--r-- | sys/arch/macppc/stand/Makefile.inc | 30 | ||||
-rw-r--r-- | sys/arch/macppc/stand/alloc.c | 218 | ||||
-rw-r--r-- | sys/arch/macppc/stand/boot.c | 247 | ||||
-rw-r--r-- | sys/arch/macppc/stand/cache.c | 23 | ||||
-rw-r--r-- | sys/arch/macppc/stand/hfs.c | 131 | ||||
-rw-r--r-- | sys/arch/macppc/stand/hfs.h | 9 | ||||
-rw-r--r-- | sys/arch/macppc/stand/net.c | 153 | ||||
-rw-r--r-- | sys/arch/macppc/stand/netif_of.c | 252 | ||||
-rw-r--r-- | sys/arch/macppc/stand/ofdev.c | 427 | ||||
-rw-r--r-- | sys/arch/macppc/stand/ofdev.h | 53 | ||||
-rw-r--r-- | sys/arch/macppc/stand/ofwmagic.S | 75 | ||||
-rw-r--r-- | sys/arch/macppc/stand/openfirm.h | 56 |
14 files changed, 2300 insertions, 0 deletions
diff --git a/sys/arch/macppc/stand/Locore.c b/sys/arch/macppc/stand/Locore.c new file mode 100644 index 00000000000..e43d875d36c --- /dev/null +++ b/sys/arch/macppc/stand/Locore.c @@ -0,0 +1,593 @@ +/* $OpenBSD: Locore.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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 <macppc/stand/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 +asm(" + .text + .globl bat_init +bat_init: + + mfmsr 8 + li 0,0 + mtmsr 0 + isync + + mtibatu 0,0 + mtibatu 1,0 + mtibatu 2,0 + mtibatu 3,0 + mtdbatu 0,0 + mtdbatu 1,0 + mtdbatu 2,0 + mtdbatu 3,0 + + li 9,0x12 /* BATL(0, BAT_M, BAT_PP_RW) */ + mtibatl 0,9 + mtdbatl 0,9 + li 9,0x1ffe /* BATU(0, BAT_BL_256M, BAT_Vs) */ + mtibatu 0,9 + mtdbatu 0,9 + isync + + mtmsr 8 + isync + blr +"); + +__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 + bat_init(); + openfirmware = openfirm; /* Save entry to Open Firmware */ +#if 0 + patch_dec_intr(); +#endif + setup(); + main(arg, argl); + exit(); +} + +#if 0 +void handle_decr_intr(); +__asm ( " .globl handle_decr_intr\n" + " .type handle_decr_intr@function\n" + "handle_decr_intr:\n" + " rfi\n"); + + +patch_dec_intr() +{ + int time; + unsigned int *decr_intr = (unsigned int *)0x900; + unsigned int br_instr; + + /* this hack is to prevent unexected Decrementer Exceptions + * when Apple openfirmware enables interrupts + */ + time = 0x40000000; + asm("mtdec %0" :: "r"(time)); + /* we assume that handle_decr_intr is in the first 128 Meg */ + br_instr = (18 << 23) | (unsigned int)handle_decr_intr; + *decr_intr = br_instr; + + + +} +#endif +__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 +*/ +#if 0 + /* + * 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; + if (virt != 0) { + return virt; + } + 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 + +int +#ifdef __STDC__ +OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...) +#else +OF_call_method(method, ihandle, nargs, nreturns, va_alist) + char *method; + int ihandle; + int nargs; + int nreturns; + va_dcl +#endif +{ + va_list ap; + static struct { + char *name; + int nargs; + int nreturns; + char *method; + int ihandle; + int args_n_results[12]; + } args = { + "call-method", + 2, + 1, + }; + int *ip, n; + + if (nargs > 6) + return -1; + args.nargs = nargs + 2; + args.nreturns = nreturns + 1; + args.method = method; + args.ihandle = ihandle; + va_start(ap, nreturns); + for (ip = args.args_n_results + (n = nargs); --n >= 0;) + *--ip = va_arg(ap, int); + + if (openfirmware(&args) == -1) + return -1; + if (args.args_n_results[nargs]) + return args.args_n_results[nargs]; + for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) + *va_arg(ap, int *) = *--ip; + va_end(ap); + return 0; +} + +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 = '\0'; + int l; + + while ((l = OF_read(stdin, &ch, 1)) != 1) + if (l != -2 && l != 0) + return -1; + return ch; +} diff --git a/sys/arch/macppc/stand/Makefile b/sys/arch/macppc/stand/Makefile new file mode 100644 index 00000000000..7f06b65d761 --- /dev/null +++ b/sys/arch/macppc/stand/Makefile @@ -0,0 +1,33 @@ +# $OpenBSD: Makefile,v 1.1 2001/09/01 15:39:02 drahn Exp $ +# $NetBSD: Makefile,v 1.1 1996/09/30 16:34:59 ws Exp $ + +SUBDIR= ofwboot boot.mac mbr + +SAREL= +KERNREL= +KERN_AS=library +Z_AS=library +SA_ZLIB=smth +USE_LOADFILE=yes + +.include "Makefile.inc" +.include "$S/lib/libz/Makefile.inc" +.include "$S/lib/libsa/Makefile.inc" +.include "$S/lib/libkern/Makefile.inc" + +all: ${ZLIB} ${SALIB} ${KERNLIB} _SUBDIRUSE + +libdep: + @echo ${.OBJDIR}/${SALIB} $(KERNLIB) ${ZLIB} + + +${PROG}: + +clean:: _SUBDIRUSE + +cleandir: _SUBDIRUSE + +depend:: _SUBDIRUSE + +.include <bsd.obj.mk> +.include <bsd.subdir.mk> diff --git a/sys/arch/macppc/stand/Makefile.inc b/sys/arch/macppc/stand/Makefile.inc new file mode 100644 index 00000000000..24ea0c6d5be --- /dev/null +++ b/sys/arch/macppc/stand/Makefile.inc @@ -0,0 +1,30 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/09/01 15:39:02 drahn Exp $ +# $NetBSD: Makefile.inc,v 1.1 1996/09/30 16:34:59 ws Exp $ + +.if !defined(__stand_makefile_inc) +__stand_makefile_inc=1 + +KERN_AS= library + +S=$(.CURDIR)/../../../$(R) + +.if !make(libdep) && !make(sadep) && !make(salibdir) && !make(kernlibdir) && !make(obj) +.BEGIN: + @([ -h machine ] || ln -s $(S)/arch/$(MACHINE)/include machine) +.endif + +# +EXTRACFLAGS= -msoft-float +REAL_VIRT?= -v +ENTRY?= _start + +INCLUDES+= -I. -I$(.OBJDIR) -I$(.CURDIR)/.. -I$(S)/arch -I$(S) +INCLUDES+= -I$(S)/lib/libsa +DEFS+= -DSTANDALONE -DFIREPOWERBUGS +CFLAGS+= $(INCLUDES) $(DEFS) $(EXTRACFLAGS) +LDFLAGS?= -X -N -Ttext $(RELOC) -e $(ENTRY) + +cleandir: + rm -rf lib machine + +.endif diff --git a/sys/arch/macppc/stand/alloc.c b/sys/arch/macppc/stand/alloc.c new file mode 100644 index 00000000000..f6b6f65cc16 --- /dev/null +++ b/sys/arch/macppc/stand/alloc.c @@ -0,0 +1,218 @@ +/* $OpenBSD: alloc.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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 <macppc/stand/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/macppc/stand/boot.c b/sys/arch/macppc/stand/boot.c new file mode 100644 index 00000000000..06b30565882 --- /dev/null +++ b/sys/arch/macppc/stand/boot.c @@ -0,0 +1,247 @@ +/* $OpenBSD: boot.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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 <sys/param.h> +#include <sys/exec.h> +#include <sys/exec_elf.h> +#include <sys/reboot.h> +#include <sys/disklabel.h> + +#include <lib/libkern/libkern.h> +#include <lib/libsa/stand.h> +#include <lib/libsa/loadfile.h> + + +#include <machine/cpu.h> + +#include <macppc/stand/ofdev.h> +#include <macppc/stand/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; + + 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; + if (str[0] == '\0') { + return; + } + cp = str; + while (*cp != 0) { + /* check for - */ + if (*cp == '-') { + /* start of options found */ + break; + } + while (*cp != 0 && *cp != ' ') { + /* character in the middle of the name, skip */ + cp++; + } + while (*cp == ' ') { + *cp++ = 0; + } + } + 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, ssym, esym) + void (*entry)(); + char *args; + void *ssym; + 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(&ssym, args + l, sizeof(ssym)); + l += sizeof(ssym); + 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 +main() +{ + int chosen; + char bootline[512]; /* Should check size? */ + char *cp; + u_long marks[MARK_MAX]; + u_int32_t entry; + void *ssym, *esym; + int fd; + + printf("\n>> OpenBSD/macppc 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); + } + marks[MARK_START] = 0; + if (loadfile(bootline, marks, LOAD_ALL) >= 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 + entry = marks[MARK_ENTRY]; + ssym = (void *)marks[MARK_SYM]; + esym = (void *)marks[MARK_END]; + + chain ((void*)entry, bootline, ssym, esym); + + _rtt(); + return 0; +} diff --git a/sys/arch/macppc/stand/cache.c b/sys/arch/macppc/stand/cache.c new file mode 100644 index 00000000000..65fa15728b3 --- /dev/null +++ b/sys/arch/macppc/stand/cache.c @@ -0,0 +1,23 @@ +/* $OpenBSD: cache.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +#define CACHELINESIZE 32 /* For now XXX */ + +void +syncicache(from, len) + void *from; + int len; +{ + int l = len; + void *p = from; + + do { + asm volatile ("dcbf %1,%0" :: "r"(p), "r"(0)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + asm volatile ("sync"); + do { + asm volatile ("icbi %1,%0" :: "r"(from), "r"(0)); + from += CACHELINESIZE; + } while ((len -= CACHELINESIZE) > 0); + asm volatile ("isync"); +} + diff --git a/sys/arch/macppc/stand/hfs.c b/sys/arch/macppc/stand/hfs.c new file mode 100644 index 00000000000..de677b7fe74 --- /dev/null +++ b/sys/arch/macppc/stand/hfs.c @@ -0,0 +1,131 @@ +/* $OpenBSD: hfs.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $NetBSD: hfs.c,v 1.1 2000/11/14 11:25:35 tsubai Exp $ */ + +/*- + * Copyright (c) 2000 Tsubai Masanari. 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/param.h> +#include <lib/libkern/libkern.h> +#include <lib/libsa/stand.h> + +#include <openfirm.h> +#include <hfs.h> + +static int OF_fd; /* XXX */ + +int +hfs_open(path, f) + char *path; + struct open_file *f; +{ + int chosen; + char bootpath[128], *cp; + + + if ((chosen = OF_finddevice("/chosen")) == -1) + return ENXIO; + bzero(bootpath, sizeof bootpath); + OF_getprop(chosen, "bootpath", bootpath, sizeof bootpath); + +#ifdef HAVE_STAND_STRRCHR + cp = strrchr(bootpath, ','); +#else + cp = bootpath; + cp += strlen (bootpath); + for (; *cp != ','; cp--) { + if (cp == bootpath) { + cp = NULL; + break; + } + } +#endif + if (cp == NULL) + return ENXIO; + + strcpy(cp + 1, path); + OF_fd = OF_open(bootpath); + if (OF_fd == -1) + return ENOENT; + + return 0; +} + +int +hfs_close(f) + struct open_file *f; +{ + OF_close(OF_fd); + return 0; +} + +int +hfs_read(f, start, size, resid) + struct open_file *f; + void *start; + size_t size, *resid; +{ + int len; + + len = OF_read(OF_fd, start, size); + size -= len; + if (resid) + *resid = size; + return 0; +} + +int +hfs_write(f, start, size, resid) + struct open_file *f; + void *start; + size_t size, *resid; +{ + printf("hfs_write\n"); + return ENXIO; +} + +off_t +hfs_seek(f, offset, where) + struct open_file *f; + off_t offset; + int where; +{ + switch (where) { + case SEEK_SET: + return OF_seek(OF_fd, offset); + case SEEK_CUR: + case SEEK_END: + default: + return -1; + } +} + +int +hfs_stat(f, sb) + struct open_file *f; + struct stat *sb; +{ + return 0; +} diff --git a/sys/arch/macppc/stand/hfs.h b/sys/arch/macppc/stand/hfs.h new file mode 100644 index 00000000000..4f8e3fcc707 --- /dev/null +++ b/sys/arch/macppc/stand/hfs.h @@ -0,0 +1,9 @@ +/* $OpenBSD: hfs.h,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $NetBSD: hfs.h,v 1.1 2000/11/14 11:25:35 tsubai Exp $ */ + +int hfs_open(char *, struct open_file *); +int hfs_close(struct open_file *); +int hfs_read(struct open_file *, void *, size_t, size_t *); +int hfs_write(struct open_file *, void *, size_t, size_t *); +off_t hfs_seek(struct open_file *, off_t, int); +int hfs_stat(struct open_file *, struct stat *); diff --git a/sys/arch/macppc/stand/net.c b/sys/arch/macppc/stand/net.c new file mode 100644 index 00000000000..22b1618d6bc --- /dev/null +++ b/sys/arch/macppc/stand/net.c @@ -0,0 +1,153 @@ +/* $OpenBSD: net.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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/macppc/stand/netif_of.c b/sys/arch/macppc/stand/netif_of.c new file mode 100644 index 00000000000..2ad3d3676a1 --- /dev/null +++ b/sys/arch/macppc/stand/netif_of.c @@ -0,0 +1,252 @@ +/* $OpenBSD: netif_of.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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 <macppc/stand/ofdev.h> +#include <macppc/stand/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), + "local-mac-address", io->myea, sizeof io->myea) == -1 && + 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 + } + + if (op->dmabuf) { + bcopy(pkt, op->dmabuf, sendlen); + pkt = op->dmabuf; + } + 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 || len == 0) && + ((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/macppc/stand/ofdev.c b/sys/arch/macppc/stand/ofdev.c new file mode 100644 index 00000000000..85e3c000dc9 --- /dev/null +++ b/sys/arch/macppc/stand/ofdev.c @@ -0,0 +1,427 @@ +/* $OpenBSD: ofdev.c,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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 <hfs.h> + +#include <macppc/stand/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); + if (op->dmabuf) { + OF_call_method("dma-free", op->handle, 2, 0, + op->dmabuf, MAXPHYS); + } + 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_hfs = { + hfs_open, hfs_close, hfs_read, hfs_write, hfs_seek, hfs_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]; + +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); +} + +int +read_mac_label(devp, buf, lp) + struct of_dev *devp; + char *buf; + struct disklabel *lp; +{ + struct part_map_entry *part; + struct buf *bp; + int err; + size_t read; + int part_cnt; + int i; + char *s; + + if ((strategy(devp, F_READ, 1, DEV_BSIZE, buf, &read) != 0) + || (read != DEV_BSIZE)) + { + return ERDLAB; + } + part = (struct part_map_entry *)buf; + + /* if first partition is not valid, assume not HFS/DPME partitioned */ + if (part->pmSig != PART_ENTRY_MAGIC) { + return ERDLAB; + } + part_cnt = part->pmMapBlkCnt; + + /* first search for "OpenBSD" partition type + * standard bsd disklabel lives inside at offset 0 + * otherwise, we should fake a bsd partition + * with first HFS partition starting at 'i' + * ? will this cause problems with booting bsd.rd from hfs + */ + for (i = 0; i < part_cnt; i++) { + /* read the appropriate block */ + if ((strategy(devp, F_READ, 1+i, DEV_BSIZE, buf, &read) != 0) + || (read != DEV_BSIZE)) + { + return ERDLAB; + } + part = (struct part_map_entry *)buf; + /* toupper the string, in case caps are different... */ + for (s = part->pmPartType; *s; s++) + if ((*s >= 'a') && (*s <= 'z')) + *s = (*s - 'a' + 'A'); + if (0 == strcmp(part->pmPartType, PART_TYPE_OPENBSD)) { + /* FOUND OUR PARTITION!!! */ + printf("found OpenBSD DPME partition\n"); + if(strategy(devp, F_READ, part->pmPyPartStart, + DEV_BSIZE, buf, &read) == 0 + && read == DEV_BSIZE) + { + if (!getdisklabel(buf, lp)) { + return 0; + } + /* If we have an OpenBSD region + * but no valid parition table, + * we cannot load a kernel from + * it, punt. + * should not have more than one + * OpenBSD of DPME type. + */ + return ERDLAB; + + } + + } + } + return ERDLAB; + +} +/* + * 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 dos_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 dos_partition *)(buf + DOSPARTOFF), i = 4; + --i >= 0; p++) { + if (p->dp_typ == DOSPTYP_OPENBSD || + p->dp_typ == DOSPTYP_NETBSD) { + poff = get_long(&p->dp_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->dp_typ == DOSPTYP_EXTEND) { + poff = get_long(&p->dp_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 0 + if (*buf != '/') + strcat(opened_name, "/"); +#endif + 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; + 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; + ofdev.dmabuf = NULL; + OF_call_method("dma-alloc", handle, 1, 1, MAXPHYS, &ofdev.dmabuf); + 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 = read_mac_label(&ofdev, buf, &label); + if (error == ERDLAB) { + error = search_label(&ofdev, 0, buf, &label, 0); + } + if (error && error != ERDLAB) + goto bad; + } + + if (error == ERDLAB) { + if (partition) + /* User specified a partition, 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]); + bcopy(&file_system_hfs, file_system + 2, + sizeof file_system[0]); + nfsys = 3; + 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/macppc/stand/ofdev.h b/sys/arch/macppc/stand/ofdev.h new file mode 100644 index 00000000000..56f0509f6a6 --- /dev/null +++ b/sys/arch/macppc/stand/ofdev.h @@ -0,0 +1,53 @@ +/* $OpenBSD: ofdev.h,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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; + void *dmabuf; +}; + +/* Known types: */ +#define OFDEV_NET 1 +#define OFDEV_DISK 2 + +#define DEFAULT_KERNEL "/bsd" + +extern char opened_name[]; + +#endif diff --git a/sys/arch/macppc/stand/ofwmagic.S b/sys/arch/macppc/stand/ofwmagic.S new file mode 100644 index 00000000000..f917261a2c9 --- /dev/null +++ b/sys/arch/macppc/stand/ofwmagic.S @@ -0,0 +1,75 @@ +/* $OpenBSD: ofwmagic.S,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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/macppc/stand/openfirm.h b/sys/arch/macppc/stand/openfirm.h new file mode 100644 index 00000000000..0ce8e563a33 --- /dev/null +++ b/sys/arch/macppc/stand/openfirm.h @@ -0,0 +1,56 @@ +/* $OpenBSD: openfirm.h,v 1.1 2001/09/01 15:39:02 drahn Exp $ */ +/* $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)); + |