diff options
Diffstat (limited to 'sys/boot/ofw')
-rw-r--r-- | sys/boot/ofw/Makefile | 5 | ||||
-rw-r--r-- | sys/boot/ofw/common/Makefile.inc | 3 | ||||
-rw-r--r-- | sys/boot/ofw/common/main.c | 162 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/Makefile | 32 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/devicename.c | 126 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/elf_freebsd.c | 88 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/libofw.h | 73 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_console.c | 124 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_copy.c | 110 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_disk.c | 126 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_memory.c | 100 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_module.c | 48 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_net.c | 260 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_reboot.c | 36 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/ofw_time.c | 60 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/openfirm.c | 943 | ||||
-rw-r--r-- | sys/boot/ofw/libofw/openfirm.h | 129 |
17 files changed, 2425 insertions, 0 deletions
diff --git a/sys/boot/ofw/Makefile b/sys/boot/ofw/Makefile new file mode 100644 index 0000000..3b881b7 --- /dev/null +++ b/sys/boot/ofw/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= libofw + +.include <bsd.subdir.mk> diff --git a/sys/boot/ofw/common/Makefile.inc b/sys/boot/ofw/common/Makefile.inc new file mode 100644 index 0000000..5d20372 --- /dev/null +++ b/sys/boot/ofw/common/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD$ + +SRCS+= main.c diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c new file mode 100644 index 0000000..8e201b3 --- /dev/null +++ b/sys/boot/ofw/common/main.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2000 Benno Rice <benno@jeamland.net> + * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include "openfirm.h" +#include "libofw.h" +#include "bootstrap.h" + +struct arch_switch archsw; /* MI/MD interface boundary */ + +extern char end[]; +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +phandle_t chosen; + +#define HEAP_SIZE 0x40000 + +void +init_heap(void) +{ + void *base; + + if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) { + printf("Heap memory claim failed!\n"); + OF_enter(); + } + + setheap(base, base + (HEAP_SIZE / sizeof(base))); +} + +uint32_t +memsize(void) +{ + ihandle_t meminstance; + phandle_t memory; + struct ofw_reg reg; + + OF_getprop(chosen, "memory", &meminstance, sizeof(meminstance)); + memory = OF_instance_to_package(meminstance); + + OF_getprop(memory, "reg", ®, sizeof(reg)); + + return (reg.size); +} + +int +main(int (*openfirm)(void *)) +{ + int i; + char bootpath[64]; + char *ch; + + /* + * Initalise the OpenFirmware routines by giving them the entry point. + */ + OF_init(openfirm); + + chosen = OF_finddevice("/chosen"); + + /* + * Set up console. + */ + cons_probe(); + + /* + * Initialise the heap as early as possible. Once this is done, + * alloc() is usable. The stack is buried inside us, so this is + * safe. + */ + init_heap(); + + /* + * Initialise the block cache + */ + bcache_init(32, 512); /* 16k XXX tune this */ + + /* + * March through the device switch probing for things. + */ + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + printf("Memory: %dKB\n", memsize() / 1024); + + OF_getprop(chosen, "bootpath", bootpath, 64); + ch = index(bootpath, ':'); + *ch = '\0'; + printf("Booted from: %s\n", bootpath); + + printf("\n"); + + env_setenv("currdev", EV_VOLATILE, bootpath, + ofw_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, + env_nounset); + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_getdev = ofw_getdev; + archsw.arch_copyin = ofw_copyin; + archsw.arch_copyout = ofw_copyout; + archsw.arch_readin = ofw_readin; + archsw.arch_autoload = ofw_autoload; + + interact(); /* doesn't return */ + + OF_exit(); + + return 0; +} + +COMMAND_SET(halt, "halt", "halt the system", command_halt); + +static int +command_halt(int argc, char *argv[]) +{ + + OF_exit(); + return (CMD_OK); +} + +COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); + +int +command_memmap(int argc, char **argv) +{ + + ofw_memmap(); + return (CMD_OK); +} diff --git a/sys/boot/ofw/libofw/Makefile b/sys/boot/ofw/libofw/Makefile new file mode 100644 index 0000000..a153f4f --- /dev/null +++ b/sys/boot/ofw/libofw/Makefile @@ -0,0 +1,32 @@ +# $FreeBSD$ + +LIB= ofw +INTERNALLIB= true + +SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ + ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ + ofw_time.c openfirm.c + +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ + +# Pick up the bootstrap header for some interface items +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. + +CFLAGS+= -ffreestanding +.if ${MACHINE_ARCH} == "powerpc" +CFLAGS+= -msoft-float +.endif + +.ifdef(BOOT_DISK_DEBUG) +# Make the disk code more talkative +CFLAGS+= -DDISK_DEBUG +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +CLEANFILES+= machine + +.include <bsd.lib.mk> + +beforedepend ${OBJS}: machine diff --git a/sys/boot/ofw/libofw/devicename.c b/sys/boot/ofw/libofw/devicename.c new file mode 100644 index 0000000..14a6058 --- /dev/null +++ b/sys/boot/ofw/libofw/devicename.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include "libofw.h" + +static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +ofw_getdev(void **vdev, const char *devspec, const char **path) +{ + struct ofw_devdesc **dev = (struct ofw_devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no + * device, go with the current device. + */ + if ((devspec == NULL) || + (strchr(devspec, '@') == NULL)) { + + if (((rv = ofw_parsedev(dev, getenv("currdev"), NULL)) == 0) && + (path != NULL)) + *path = devspec; + return(rv); + } + + /* + * Try to parse the device name off the beginning of the devspec + */ + return(ofw_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + */ +static int +ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path) +{ + struct ofw_devdesc *idev; + struct devsw *dv; + phandle_t handle; + const char *p; + const char *s; + char name[256]; + char type[64]; + int len; + int i; + + for (p = s = devspec; *s != '\0'; p = s) { + if ((s = strchr(p + 1, '/')) == NULL) + s = strchr(p, '\0'); + len = s - devspec; + bcopy(devspec, name, len); + name[len] = '\0'; + if ((handle = OF_finddevice(name)) == -1) + break; + if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1) + continue; + for (i = 0; (dv = devsw[i]) != NULL; i++) { + if (strncmp(dv->dv_name, type, strlen(dv->dv_name)) == 0) + goto found; + } + } + return(ENOENT); + +found: + if (*s != '\0') + *path = s; + idev = malloc(sizeof(struct ofw_devdesc)); + strcpy(idev->d_path, name); + idev->d_dev = dv; + idev->d_type = dv->dv_type; + if (dev == NULL) { + free(idev); + } else { + *dev = idev; + } + return(0); +} + +int +ofw_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct ofw_devdesc *ncurr; + int rv; + + if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0) + return rv; + + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return 0; +} diff --git a/sys/boot/ofw/libofw/elf_freebsd.c b/sys/boot/ofw/libofw/elf_freebsd.c new file mode 100644 index 0000000..7fa7586 --- /dev/null +++ b/sys/boot/ofw/libofw/elf_freebsd.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/linker.h> + +#include <machine/metadata.h> +#include <machine/elf.h> + +#include <stand.h> + +#include "bootstrap.h" +#include "libofw.h" +#include "openfirm.h" + +extern char end[]; +extern vm_offset_t reloc; /* From <arch>/conf.c */ + +int +__elfN(ofw_loadfile)(char *filename, vm_offset_t dest, + struct preloaded_file **result) +{ + int r; + void *addr; + + r = __elfN(loadfile)(filename, dest, result); + if (r != 0) + return (r); + + return (0); +} + +int +__elfN(ofw_exec)(struct preloaded_file *fp) +{ + struct file_metadata *fmp; + vm_offset_t mdp; + Elf_Ehdr *e; + int error; + + if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { + return(EFTYPE); + } + e = (Elf_Ehdr *)&fmp->md_data; + + if ((error = md_load(fp->f_args, &mdp)) != 0) + return (error); + + printf("Kernel entry at 0x%lx ...\n", e->e_entry); + + dev_cleanup(); + ofw_release_heap(); + OF_chain((void *)reloc, end - (char *)reloc, (void *)e->e_entry, + (void *)mdp, sizeof(mdp)); + + panic("exec returned"); +} + +struct file_format ofw_elf = +{ + __elfN(ofw_loadfile), + __elfN(ofw_exec) +}; diff --git a/sys/boot/ofw/libofw/libofw.h b/sys/boot/ofw/libofw/libofw.h new file mode 100644 index 0000000..a7d73e6 --- /dev/null +++ b/sys/boot/ofw/libofw/libofw.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2000 Benno Rice. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include "openfirm.h" + +/* Note: Must match the 'struct devdesc' in bootstrap.h */ +struct ofw_devdesc { + struct devsw *d_dev; + int d_type; + phandle_t d_handle; + char d_path[256]; +}; + +extern int ofw_getdev(void **vdev, const char *devspec, const char **path); +extern int ofw_setcurrdev(struct env_var *ev, int flags, void *value); + +extern struct devsw ofwdisk; +extern struct netif_driver ofwnet; + +int ofwn_getunit(const char *); + +ssize_t ofw_copyin(const void *src, vm_offset_t dest, const size_t len); +ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len); +ssize_t ofw_readin(const int fd, vm_offset_t dest, const size_t len); + +extern int ofw_boot(void); +extern int ofw_autoload(void); + +void ofw_memmap(void); +void *ofw_alloc_heap(unsigned int); +void ofw_release_heap(void); + +struct preloaded_file; +struct file_format; + +int ofw_elf_loadfile(char *, vm_offset_t, struct preloaded_file **); +int ofw_elf_exec(struct preloaded_file *); + +extern struct file_format ofw_elf; + +extern void reboot(void); + +struct ofw_reg +{ + cell_t base; + cell_t size; +}; + +extern int (*openfirmware)(void *); diff --git a/sys/boot/ofw/libofw/ofw_console.c b/sys/boot/ofw/libofw/ofw_console.c new file mode 100644 index 0000000..77d9ad5 --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_console.c @@ -0,0 +1,124 @@ +/* $FreeBSD$ +/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#include <sys/types.h> + +#include "bootstrap.h" +#include "openfirm.h" + +int console; + +static void ofw_cons_probe(struct console *cp); +static int ofw_cons_init(int); +void ofw_cons_putchar(int); +int ofw_cons_getchar(void); +int ofw_cons_poll(void); + +static ihandle_t stdin; +static ihandle_t stdout; + +struct console ofwconsole = { + "ofw", + "OpenFirmware console", + 0, + ofw_cons_probe, + ofw_cons_init, + ofw_cons_putchar, + ofw_cons_getchar, + ofw_cons_poll, +}; + +static void +ofw_cons_probe(struct console *cp) +{ + phandle_t chosen; + + if ((chosen = OF_finddevice("/chosen")) == -1) + OF_exit(); + OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)); + OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); + cp->c_flags |= C_PRESENTIN|C_PRESENTOUT; +} + +static int +ofw_cons_init(int arg) +{ + return 0; +} + +void +ofw_cons_putchar(int c) +{ + char cbuf; + + if (c == '\n') { + cbuf = '\r'; + OF_write(stdout, &cbuf, 1); + } + + cbuf = c; + OF_write(stdout, &cbuf, 1); +} + +static int saved_char = -1; + +int +ofw_cons_getchar() +{ + unsigned char ch = '\0'; + int l; + + if (saved_char != -1) { + l = saved_char; + saved_char = -1; + return l; + } + + while ((l = OF_read(stdin, &ch, 1)) != 1) + if (l != -2 && l != 0) + return -1; + return ch; +} + +int +ofw_cons_poll() +{ + unsigned char ch; + int l; + + if (saved_char != -1) + return 1; + + if (OF_read(stdin, &ch, 1) > 0) { + saved_char = ch; + return 1; + } + + return 0; +} diff --git a/sys/boot/ofw/libofw/ofw_copy.c b/sys/boot/ofw/libofw/ofw_copy.c new file mode 100644 index 0000000..a9e0fd6 --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_copy.c @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ +/* + * MD primitives supporting placement of module data + * + * XXX should check load address/size against memory top. + */ +#include <stand.h> + +#include "libofw.h" + +#define READIN_BUF (4 * 1024) +#define PAGE_SIZE 0x1000 +#define PAGE_MASK 0x0fff + +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + +ssize_t +ofw_copyin(const void *src, vm_offset_t dest, const size_t len) +{ + void *destp, *addr; + size_t dlen; + + destp = (void *)(dest & ~PAGE_MASK); + dlen = roundup(len, PAGE_SIZE); + + if (OF_call_method("claim", memory, 3, 1, destp, dlen, 0, &addr) + == -1) { + printf("ofw_copyin: physical claim failed\n"); + return (0); + } + + if (OF_call_method("claim", mmu, 3, 1, destp, dlen, 0, &addr) == -1) { + printf("ofw_copyin: virtual claim failed\n"); + return (0); + } + + if (OF_call_method("map", mmu, 4, 0, destp, destp, dlen, 0) == -1) { + printf("ofw_copyin: map failed\n"); + return (0); + } + + bcopy(src, (void *)dest, len); + return(len); +} + +ssize_t +ofw_copyout(const vm_offset_t src, void *dest, const size_t len) +{ + bcopy((void *)src, dest, len); + return(len); +} + +ssize_t +ofw_readin(const int fd, vm_offset_t dest, const size_t len) +{ + void *buf; + size_t resid, chunk, get; + ssize_t got; + vm_offset_t p; + + p = dest; + + chunk = min(READIN_BUF, len); + buf = malloc(chunk); + if (buf == NULL) { + printf("ofw_readin: buf malloc failed\n"); + return(0); + } + + for (resid = len; resid > 0; resid -= got, p += got) { + get = min(chunk, resid); + got = read(fd, buf, get); + + if (got <= 0) { + printf("ofw_readin: read failed\n"); + break; + } + + ofw_copyin(buf, p, got); + } + + free(buf); + return(len - resid); +} diff --git a/sys/boot/ofw/libofw/ofw_disk.c b/sys/boot/ofw/libofw/ofw_disk.c new file mode 100644 index 0000000..b6c3e6c --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_disk.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2000 Benno Rice. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +/* + * Disk I/O routines using Open Firmware + */ + +#include <sys/param.h> + +#include <netinet/in.h> + +#include <machine/stdarg.h> + +#include <stand.h> + +#include "bootstrap.h" +#include "libofw.h" + +static int ofwd_init(void); +static int ofwd_strategy(void *devdata, int flag, daddr_t dblk, + size_t size, char *buf, size_t *rsize); +static int ofwd_open(struct open_file *f, ...); +static int ofwd_close(struct open_file *f); +static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data); +static void ofwd_print(int verbose); + +struct devsw ofwdisk = { + "block", + DEVT_DISK, + ofwd_init, + ofwd_strategy, + ofwd_open, + ofwd_close, + ofwd_ioctl, + ofwd_print +}; + +static int +ofwd_init(void) +{ + return 0; +} + +static int +ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, + size_t *rsize) +{ + struct ofw_devdesc *dp = (struct ofw_devdesc *)devdata; + unsigned long pos; + int n; + int i, j; + + pos = dblk * 512; + do { + if (OF_seek(dp->d_handle, pos) < 0) + return EIO; + n = OF_read(dp->d_handle, buf, size); + if (n < 0 && n != -2) + return EIO; + } while (n == -2); + *rsize = size; + return 0; +} + +static int +ofwd_open(struct open_file *f, ...) +{ + struct ofw_devdesc *dp; + phandle_t handle; + va_list vl; + + va_start(vl, f); + dp = va_arg(vl, struct ofw_devdesc *); + va_end(vl); + if ((handle = OF_open(dp->d_path)) == -1) { + printf("ofwd_open: Could not open %s\n", dp->d_path); + return 1; + } + dp->d_handle = handle; + return 0; +} + +static int +ofwd_close(struct open_file *f) +{ + struct ofw_devdesc *dev = f->f_devdata; + + OF_close(dev->d_handle); + return 0; +} + +static int +ofwd_ioctl(struct open_file *f, u_long cmd, void *data) +{ + + return (EINVAL); +} + +static void +ofwd_print(int verbose) +{ +} diff --git a/sys/boot/ofw/libofw/ofw_memory.c b/sys/boot/ofw/libofw/ofw_memory.c new file mode 100644 index 0000000..59fdce2 --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_memory.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001 Benno Rice + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/types.h> + +#include <stand.h> + +#include "libofw.h" +#include "openfirm.h" + +static void *heap_base = 0; +static unsigned int heap_size = 0; + +struct ofw_mapping { + vm_offset_t va; + int len; + vm_offset_t pa; + int mode; +}; + +void +ofw_memmap(void) +{ + phandle_t mmup; + int nmapping, i; + struct ofw_mapping mappings[256]; + + mmup = OF_instance_to_package(mmu); + + bzero(mappings, sizeof(mappings)); + + nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings)); + if (nmapping == -1) { + printf("Could not get memory map (%d)\n", + nmapping); + return; + } + nmapping /= sizeof(struct ofw_mapping); + + printf("%17s %17s %8s %6s\n", "Virtual Range", "Physical Range", + "#Pages", "Mode"); + + for (i = 0; i < nmapping; i++) { + printf("%08x-%08x %08x-%08x %8d %6x\n", mappings[i].pa, + mappings[i].pa + mappings[i].len, mappings[i].va, + mappings[i].va + mappings[i].len, mappings[i].len / 0x1000, + mappings[i].mode); + } +} + +void * +ofw_alloc_heap(unsigned int size) +{ + phandle_t memoryp; + struct ofw_reg available; + void *base; + + memoryp = OF_instance_to_package(memory); + OF_getprop(memoryp, "available", &available, sizeof(available)); + + heap_base = OF_claim((void *)available.base, size, sizeof(register_t)); + + if (heap_base != (void *)-1) { + heap_size = size; + } + + return (heap_base); +} + +void +ofw_release_heap(void) +{ + OF_release(heap_base, heap_size); +} diff --git a/sys/boot/ofw/libofw/ofw_module.c b/sys/boot/ofw/libofw/ofw_module.c new file mode 100644 index 0000000..3339d44 --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_module.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* + * ofw-specific module functionality. + * + */ + +#include <stand.h> +#include <string.h> + +#include "bootstrap.h" +#include "libofw.h" + +/* + * Use voodoo to load modules required by current hardware. + */ +int +ofw_autoload(void) +{ + /* XXX Call some machdep autoload routine? */ + return(0); +} diff --git a/sys/boot/ofw/libofw/ofw_net.c b/sys/boot/ofw/libofw/ofw_net.c new file mode 100644 index 0000000..0add05b --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_net.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2000-2001 Benno Rice + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> + +#include <stand.h> +#include <net.h> +#include <netif.h> + +#include "openfirm.h" + +static int ofwn_probe(struct netif *, void *); +static int ofwn_match(struct netif *, void *); +static void ofwn_init(struct iodesc *, void *); +static int ofwn_get(struct iodesc *, void *, size_t, time_t); +static int ofwn_put(struct iodesc *, void *, size_t); +static void ofwn_end(struct netif *); + +extern struct netif_stats ofwn_stats[]; + +struct netif_dif ofwn_ifs[] = { + /* dif_unit dif_nsel dif_stats dif_private */ + { 0, 1, &ofwn_stats[0], 0, }, +}; + +struct netif_stats ofwn_stats[NENTS(ofwn_ifs)]; + +struct netif_driver ofwnet = { + "net", /* netif_bname */ + ofwn_match, /* netif_match */ + ofwn_probe, /* netif_probe */ + ofwn_init, /* netif_init */ + ofwn_get, /* netif_get */ + ofwn_put, /* netif_put */ + ofwn_end, /* netif_end */ + ofwn_ifs, /* netif_ifs */ + NENTS(ofwn_ifs) /* netif_nifs */ +}; + +static phandle_t netdevice; +static ihandle_t netinstance; +static ihandle_t memory; + +static void *dmabuf; + +static int +ofwn_match(struct netif *nif, void *machdep_hint) +{ + return 1; +} + +static int +ofwn_probe(struct netif *nif, void *machdep_hint) +{ + return 0; +} + +static int +ofwn_put(struct iodesc *desc, void *pkt, size_t len) +{ + struct ether_header *eh; + size_t sendlen; + ssize_t rv; + +#if defined(NETIF_DEBUG) + 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; +#if defined(NETIF_DEBUG) + printf("netif_put: length padded to %d\n", sendlen); +#endif + } + + if (dmabuf) { + bcopy(pkt, dmabuf, sendlen); + pkt = dmabuf; + } + + rv = OF_write(netinstance, pkt, len); + +#if defined(NETIF_DEBUG) + printf("netif_put: OF_write returned %d\n", rv); +#endif + + return rv; +} + +static int +ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) +{ + time_t t; + int length; + +#if defined(NETIF_DEBUG) + printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len, + timeout); +#endif + + t = getsecs(); + do { + length = OF_read(netinstance, pkt, len); + } while ((length == -2 || length == 0) && + (getsecs() - t < timeout)); + +#if defined(NETIF_DEBUG) + printf("netif_get: received length=%d (%x)\n", length, length); +#endif + + if (length < 12) + return -1; + +#if defined(NETIF_VERBOSE_DEBUG) + { + char *ch = pkt; + int i; + + for(i = 0; i < 96; i += 4) { + printf("%02x%02x%02x%02x ", ch[i], ch[i+1], + ch[i+2], ch[i+3]); + } + printf("\n"); + } +#endif + +#if defined(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 length; +} + +extern char *strchr(); + +static void +ofwn_init(struct iodesc *desc, void *machdep_hint) +{ + phandle_t chosen, netdev; + char path[64]; + char *ch; + int pathlen; + + chosen = OF_finddevice("/chosen"); + OF_getprop(chosen, "memory", &memory, sizeof(memory)); + pathlen = OF_getprop(chosen, "bootpath", path, 64); + if ((ch = index(path, ':')) != NULL) + *ch = '\0'; + netdev = OF_finddevice(path); +#ifdef __sparc64__ + if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1) +#else + if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1) +#endif + goto punt; + + printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea)); + + if ((netinstance = OF_open(path)) == -1) { + printf("Could not open network device.\n"); + goto punt; + } + +#if defined(NETIF_DEBUG) + printf("ofwn_init: OpenFirmware instance handle: %08x\n", netinstance); +#endif + +#ifndef __sparc64__ + dmabuf = NULL; + if (OF_call_method("dma-alloc", netinstance, 1, 1, (64 * 1024), &dmabuf) + < 0) { + printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf); + goto punt; + } + +#if defined(NETIF_DEBUG) + printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf); +#endif +#endif + + return; + +punt: + printf("\n"); + printf("Could not boot from %s.\n", path); + OF_enter(); +} + +static void +ofwn_end(struct netif *nif) +{ + OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS); + OF_close(netinstance); +} + +#if 0 +int +ofwn_getunit(const char *path) +{ + int i; + char newpath[255]; + + OF_canon(path, newpath, 254); + + for (i = 0; i < nofwninfo; i++) { + printf(">>> test =\t%s\n", ofwninfo[i].ofwn_path); + if (strcmp(path, ofwninfo[i].ofwn_path) == 0) + return i; + + if (strcmp(newpath, ofwninfo[i].ofwn_path) == 0) + return i; + } + + return -1; +} +#endif diff --git a/sys/boot/ofw/libofw/ofw_reboot.c b/sys/boot/ofw/libofw/ofw_reboot.c new file mode 100644 index 0000000..14a1eac --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_reboot.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 Benno Rice + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include "openfirm.h" + +void +exit(int code) +{ + OF_exit(); +} diff --git a/sys/boot/ofw/libofw/ofw_time.c b/sys/boot/ofw/libofw/ofw_time.c new file mode 100644 index 0000000..1043ad0 --- /dev/null +++ b/sys/boot/ofw/libofw/ofw_time.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2000 Benno Rice + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include <stand.h> +#include "openfirm.h" + +time_t +time(time_t *tloc) +{ + int secs; + + secs = OF_milliseconds() / 1000; + if (tloc) + *tloc = secs; + return secs; +} + +int +getsecs() +{ + time_t n = 0; + time(&n); + return n; +} + +void +delay(int usecs) +{ + int msecs, start; + + msecs = usecs / 1000; + start = OF_milliseconds(); + + while (OF_milliseconds() - start < msecs); +} diff --git a/sys/boot/ofw/libofw/openfirm.c b/sys/boot/ofw/libofw/openfirm.c new file mode 100644 index 0000000..4181067 --- /dev/null +++ b/sys/boot/ofw/libofw/openfirm.c @@ -0,0 +1,943 @@ +/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai 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. + */ +/* + * Copyright (C) 2000 Benno Rice. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ + +#include <machine/stdarg.h> + +#include <stand.h> + +#include "openfirm.h" + +int (*openfirmware)(void *); + +static ihandle_t stdin; +static ihandle_t stdout; + +ihandle_t mmu; +ihandle_t memory; + +/* Initialiaser */ + +void +OF_init(int (*openfirm)(void *)) +{ + phandle_t chosen; + + openfirmware = openfirm; + + chosen = OF_finddevice("/chosen"); + OF_getprop(chosen, "memory", &memory, sizeof(memory)); + if (memory == 0) + panic("failed to get memory ihandle"); + OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)); + if (mmu == 0) + panic("failed to get mmu ihandle"); +} + +/* + * Generic functions + */ + +/* Test to see if a service exists. */ +int +OF_test(char *name) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t service; + cell_t missing; + } args = { + (cell_t)"test", + 1, + 1, + 0, + 0 + }; + + args.service = (cell_t)name; + if (openfirmware(&args) == -1) + return -1; + return (int)args.missing; +} + +/* Return firmware millisecond count. */ +int +OF_milliseconds() +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t ms; + } args = { + (cell_t)"milliseconds", + 0, + 1, + 0 + }; + + openfirmware(&args); + return (int)args.ms; +} + +/* + * Device tree functions + */ + +/* Return the next sibling of this node or 0. */ +phandle_t +OF_peer(phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t next; + } args = { + (cell_t)"peer", + 1, + 1, + 0, + 0 + }; + + args.node = (u_int)node; + if (openfirmware(&args) == -1) + return -1; + return (phandle_t)args.next; +} + +/* Return the first child of this node or 0. */ +phandle_t +OF_child(phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t child; + } args = { + (cell_t)"child", + 1, + 1, + 0, + 0 + }; + + args.node = (u_int)node; + if (openfirmware(&args) == -1) + return -1; + return (phandle_t)args.child; +} + +/* Return the parent of this node or 0. */ +phandle_t +OF_parent(phandle_t node) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t node; + cell_t parent; + } args = { + (cell_t)"parent", + 1, + 1, + 0, + 0 + }; + + args.node = (u_int)node; + if (openfirmware(&args) == -1) + return -1; + return (phandle_t)args.parent; +} + +/* Return the package handle that corresponds to an instance handle. */ +phandle_t +OF_instance_to_package(ihandle_t instance) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t package; + } args = { + (cell_t)"instance-to-package", + 1, + 1, + 0, + 0 + }; + + args.instance = (u_int)instance; + if (openfirmware(&args) == -1) + return -1; + return (phandle_t)args.package; +} + +/* Get the length of a property of a package. */ +int +OF_getproplen(phandle_t package, char *propname) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t proplen; + } args = { + (cell_t)"getproplen", + 2, + 1, + 0, + 0, + 0 + }; + + args.package = (u_int)package; + args.propname = (cell_t)propname; + if (openfirmware(&args) == -1) + return -1; + return (int)args.proplen; +} + +/* Get the value of a property of a package. */ +int +OF_getprop(phandle_t package, char *propname, void *buf, int buflen) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t buf; + cell_t buflen; + cell_t size; + } args = { + (cell_t)"getprop", + 4, + 1, + 0, + 0, + 0, + 0, + 0 + }; + + args.package = (u_int)package; + args.propname = (cell_t)propname; + args.buf = (cell_t)buf; + args.buflen = (u_int)buflen; + if (openfirmware(&args) == -1) + return -1; + return (int)args.size; +} + +/* Get the next property of a package. */ +int +OF_nextprop(phandle_t package, char *previous, char *buf) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t previous; + cell_t buf; + cell_t flag; + } args = { + (cell_t)"nextprop", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.package = (u_int)package; + args.previous = (cell_t)previous; + args.buf = (cell_t)buf; + if (openfirmware(&args) == -1) + return -1; + return (int)args.flag; +} + +/* Set the value of a property of a package. */ +/* XXX Has a bug on FirePower */ +int +OF_setprop(phandle_t package, char *propname, void *buf, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t propname; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"setprop", + 4, + 1, + 0, + 0, + 0, + 0, + 0 + }; + + args.package = (u_int)package; + args.propname = (cell_t)propname; + args.buf = (cell_t)buf; + args.len = (u_int)len; + if (openfirmware(&args) == -1) + return -1; + return (int)args.size; +} + +/* Convert a device specifier to a fully qualified pathname. */ +int +OF_canon(const char *device, char *buf, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"canon", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.device = (cell_t)device; + args.buf = (cell_t)buf; + args.len = (cell_t)len; + if (openfirmware(&args) == -1) + return -1; + return (int)args.size; +} + +/* Return a package handle for the specified device. */ +phandle_t +OF_finddevice(const char *device) +{ + int i; + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t package; + } args = { + (cell_t)"finddevice", + 1, + 1, + 0, + 0 + }; + + args.device = (cell_t)device; + if (openfirmware(&args) == -1) + return -1; + + return (phandle_t)args.package; +} + +/* Return the fully qualified pathname corresponding to an instance. */ +int +OF_instance_to_path(ihandle_t instance, char *buf, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"instance-to-path", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.instance = (u_int)instance; + args.buf = (cell_t)buf; + args.len = (u_int)len; + if (openfirmware(&args) == -1) + return -1; + return (int)args.size; +} + +/* Return the fully qualified pathname corresponding to a package. */ +int +OF_package_to_path(phandle_t package, char *buf, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t package; + cell_t buf; + cell_t len; + cell_t size; + } args = { + (cell_t)"package-to-path", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.package = (u_int)package; + args.buf = (cell_t)buf; + args.len = (u_int)len; + if (openfirmware(&args) == -1) + return -1; + return (int)args.size; +} + +/* Call the method in the scope of a given instance. */ +int +OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) +{ + va_list ap; + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t method; + cell_t instance; + cell_t args_n_results[12]; + } args = { + (cell_t)"call-method", + 2, + 1, + 0, + 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + int *ip, n; + + if (nargs > 6) + return -1; + args.nargs = nargs + 2; + args.nreturns = nreturns + 1; + args.method = (cell_t)method; + args.instance = (u_int)instance; + va_start(ap, nreturns); + for (ip = (int *)(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 (int)args.args_n_results[nargs]; + for (ip = (int *)(args.args_n_results + nargs + (n = args.nreturns)); + --n > 0;) + *va_arg(ap, int *) = *--ip; + va_end(ap); + return 0; +} + +/* + * Device I/O functions. + */ + +/* Open an instance for a device. */ +ihandle_t +OF_open(char *device) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t device; + cell_t instance; + } args = { + (cell_t)"open", + 1, + 1, + 0, + 0 + }; + + args.device = (cell_t)device; + if (openfirmware(&args) == -1 || args.instance == 0) { + return -1; + } + return (ihandle_t)args.instance; +} + +/* Close an instance. */ +void +OF_close(ihandle_t instance) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + } args = { + (cell_t)"close", + 1, + 0, + 0 + }; + + args.instance = (u_int)instance; + openfirmware(&args); +} + +/* Read from an instance. */ +int +OF_read(ihandle_t instance, void *addr, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t addr; + cell_t len; + cell_t actual; + } args = { + (cell_t)"read", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.instance = (u_int)instance; + args.addr = (cell_t)addr; + args.len = (u_int)len; + +#if defined(OPENFIRM_DEBUG) + printf("OF_read: called with instance=%08x, addr=%p, len=%d\n", + args.instance, args.addr, args.len); +#endif + + if (openfirmware(&args) == -1) + return -1; + +#if defined(OPENFIRM_DEBUG) + printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n", + args.instance, args.addr, args.len, args.actual); +#endif + + return (int)args.actual; +} + +/* Write to an instance. */ +int +OF_write(ihandle_t instance, void *addr, int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t addr; + cell_t len; + cell_t actual; + } args = { + (cell_t)"write", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.instance = (u_int)instance; + args.addr = (cell_t)addr; + args.len = (u_int)len; + if (openfirmware(&args) == -1) + return -1; + return (int)args.actual; +} + +/* Seek to a position. */ +int +OF_seek(ihandle_t instance, u_int64_t pos) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t instance; + cell_t poshi; + cell_t poslo; + cell_t status; + } args = { + (cell_t)"seek", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.instance = (u_int)instance; + args.poshi = pos >> 32; + args.poslo = pos; + if (openfirmware(&args) == -1) + return -1; + return (int)args.status; +} + +/* + * Memory functions. + */ + +/* Claim an area of memory. */ +void * +OF_claim(void *virt, u_int size, u_int align) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t virt; + cell_t size; + cell_t align; + cell_t baseaddr; + } args = { + (cell_t)"claim", + 3, + 1, + 0, + 0, + 0, + 0 + }; + + args.virt = (cell_t)virt; + args.size = size; + args.align = align; + if (openfirmware(&args) == -1) + return (void *)-1; + return (void *)args.baseaddr; +} + +/* Allocate an area of physical memory */ +vm_offset_t +OF_claim_virt(vm_offset_t virt, size_t size, int align) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nret; + cell_t method; + cell_t ihandle; + cell_t align; + cell_t size; + cell_t virt; + cell_t status; + cell_t ret; + } args = { + (cell_t)"call-method", + 5, + 2, + (cell_t)"claim", + 0, + 0, + 0, + 0, + 0, /* ret */ + 0, + }; + + args.ihandle = mmu; + args.align = align; + args.size = size; + args.virt = virt; + + if (openfirmware(&args) == -1) + return (vm_offset_t)-1; + + return (vm_offset_t)args.ret; +} + +/* Allocate an area of physical memory */ +void * +OF_alloc_phys(size_t size, int align) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nret; + cell_t method; + cell_t ihandle; + cell_t align; + cell_t size; + cell_t status; + cell_t phys_hi; + cell_t phys_low; + } args = { + (cell_t)"call-method", + 4, + 3, + (cell_t)"claim", + 0, + 0, + 0, + 0, /* ret */ + 0, + 0, + }; + + args.ihandle = memory; + args.size = size; + args.align = align; + + if (openfirmware(&args) == -1) + return (void *)-1; + + return (void *)(args.phys_hi << 32 | args.phys_low); +} + +/* Release an area of memory. */ +void +OF_release(void *virt, u_int size) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t virt; + cell_t size; + } args = { + (cell_t)"release", + 2, + 0, + 0, + 0 + }; + + args.virt = (cell_t)virt; + args.size = size; + openfirmware(&args); +} + +/* Release an area of physical memory. */ +void +OF_release_phys(vm_offset_t phys, u_int size) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nret; + cell_t method; + cell_t ihandle; + cell_t size; + cell_t phys_hi; + cell_t phys_lo; + } args = { + (cell_t)"call-method", + 5, + 0, + (cell_t)"release", + 0, + 0, + 0, + 0 + }; + + args.ihandle = memory; + args.phys_hi = (u_int32_t)(phys >> 32); + args.phys_lo = (u_int32_t)phys; + args.size = size; + openfirmware(&args); +} + +/* + * Control transfer functions. + */ + +/* Reset the system and call "boot <bootspec>". */ +void +OF_boot(char *bootspec) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t bootspec; + } args = { + (cell_t)"boot", + 1, + 0, + 0 + }; + + args.bootspec = (cell_t)bootspec; + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Suspend and drop back to the OpenFirmware interface. */ +void +OF_enter() +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + } args = { + (cell_t)"enter", + 0, + 0 + }; + + openfirmware(&args); +} + +/* Shut down and drop back to the OpenFirmware interface. */ +void +OF_exit() +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + } args = { + (cell_t)"exit", + 0, + 0 + }; + + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ +#ifdef __notyet__ +void +OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) +{ + static struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t virt; + cell_t size; + cell_t entry; + cell_t arg; + cell_t len; + } args = { + (cell_t)"chain", + 5, + 0, + 0, + 0, + 0, + 0, + 0 + }; + + args.virt = (cell_t)virt; + args.size = size; + args.entry = (cell_t)entry; + args.arg = (cell_t)arg; + args.len = len; + openfirmware(&args); +} +#else +void +OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) +{ + /* + * This is a REALLY dirty hack till the firmware gets this going + */ + if (size > 0) + OF_release(virt, size); + + entry(0, 0, openfirmware, arg, len); +} +#endif diff --git a/sys/boot/ofw/libofw/openfirm.h b/sys/boot/ofw/libofw/openfirm.h new file mode 100644 index 0000000..e060117 --- /dev/null +++ b/sys/boot/ofw/libofw/openfirm.h @@ -0,0 +1,129 @@ +/* $NetBSD: openfirm.h,v 1.1 1998/05/15 10:16:00 tsubai 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. + */ +/* + * Copyright (C) 2000 Benno Rice. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD$ + */ +#ifndef _OPENFIRM_H_ +#define _OPENFIRM_H_ +/* + * Prototypes for Openfirmware Interface Routines + */ + +#include <sys/cdefs.h> +#include <sys/types.h> + +typedef unsigned int ihandle_t; +typedef unsigned int phandle_t; +typedef unsigned long int cell_t; + +extern int (*openfirmware)(void *); +extern phandle_t chosen; +extern ihandle_t memory, mmu; + +/* + * This isn't actually an OpenFirmware function, but it seemed like the right + * place for it to go. + */ +void OF_init(int (*openfirm)(void *)); + +/* Generic functions */ +int OF_test(char *); + +/* Device tree functions */ +phandle_t OF_peer(phandle_t); +phandle_t OF_child(phandle_t); +phandle_t OF_parent(phandle_t); +phandle_t OF_instance_to_package(ihandle_t); +int OF_getproplen(phandle_t, char *); +int OF_getprop(phandle_t, char *, void *, int); +int OF_nextprop(phandle_t, char *, char *); +int OF_setprop(phandle_t, char *, void *, int); +int OF_canon(const char *, char *, int); +phandle_t OF_finddevice(const char *); +int OF_instance_to_path(ihandle_t, char *, int); +int OF_package_to_path(phandle_t, char *, int); +int OF_call_method(char *, ihandle_t, int, int, ...); + +/* Device I/O functions */ +ihandle_t OF_open(char *); +void OF_close(ihandle_t); +int OF_read(ihandle_t, void *, int); +int OF_write(ihandle_t, void *, int); +int OF_seek(ihandle_t, u_quad_t); + +/* Memory functions */ +void *OF_claim(void *, u_int, u_int); +vm_offset_t OF_claim_virt(vm_offset_t, size_t, int); +void *OF_alloc_phys(size_t, int); +void OF_release(void *, u_int); +void OF_release_phys(vm_offset_t, u_int); + +/* Control transfer functions */ +void OF_boot(char *); +void OF_enter(void); +void OF_exit(void) __attribute__((noreturn)); +void OF_chain(void *, u_int, void (*)(), void *, u_int); + +#if 0 +/* User interface functions */ +/* OF_interpret */ +void *OF_set_callback(void *); +void OF_set_symbol_lookup(void *, void *); +#endif + +/* Time function */ +int OF_milliseconds(void); +#endif /* _OPENFIRM_H_ */ |