diff options
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)); + |