Index: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S (revision 276409) +++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S (revision 276410) @@ -1,42 +1,46 @@ #include ENTRY(host_read) li %r0, 3 # SYS_read sc blr ENTRY(host_write) li %r0, 4 # SYS_write sc blr ENTRY(host_seek) - li %r0, 478 # SYS_lseek + li %r0, 19 # SYS_lseek sc blr ENTRY(host_open) li %r0, 5 # SYS_open sc + bso 1f blr +1: + li %r3, 0 + blr ENTRY(host_close) li %r0, 6 # SYS_close sc blr ENTRY(host_mmap) - li %r0, 477 # SYS_mmap + li %r0, 90 # SYS_mmap sc blr ENTRY(host_gettimeofday) - li %r0, 116 # SYS_gettimeofday + li %r0, 78 # SYS_gettimeofday sc blr ENTRY(host_select) - li %r0, 93 # SYS_select + li %r0, 82 # SYS_select sc blr Index: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h (revision 276409) +++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h (revision 276410) @@ -1,48 +1,48 @@ /*- - * Copyright (C) 2010 Nathan Whitehorn + * Copyright (C) 2014 Nathan Whitehorn * 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 ``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 _HOST_SYSCALL_H #define _HOST_SYSCALL_H #include ssize_t host_read(int fd, void *buf, size_t nbyte); ssize_t host_write(int fd, const void *buf, size_t nbyte); -ssize_t host_seek(int fd, uint64_t offset, int whence); +ssize_t host_seek(int fd, int offset, int whence); int host_open(char *path, int flags, int mode); int host_close(int fd); -void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t); -#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x1000 /* ANON */, -1, 0); +void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, int); +#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x22 /* ANON */, -1, 0); struct host_timeval { int tv_sec; int tv_usec; }; int host_gettimeofday(struct host_timeval *a, void *b); int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, struct host_timeval *timeout); #endif Index: user/nwhitehorn/kboot/powerpc/kboot/hostcons.c =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/hostcons.c (revision 276409) +++ user/nwhitehorn/kboot/powerpc/kboot/hostcons.c (revision 276410) @@ -1,96 +1,97 @@ /*- * Copyright (C) 2014 Nathan Whitehorn * 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 ``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 __FBSDID("$FreeBSD$"); #include #include "bootstrap.h" #include "host_syscall.h" static void hostcons_probe(struct console *cp); static int hostcons_init(int arg); static void hostcons_putchar(int c); static int hostcons_getchar(); static int hostcons_poll(); struct console hostconsole = { "host", "Host Console", 0, hostcons_probe, hostcons_init, hostcons_putchar, hostcons_getchar, hostcons_poll, }; static void hostcons_probe(struct console *cp) { cp->c_flags |= C_PRESENTIN|C_PRESENTOUT; } static int hostcons_init(int arg) { /* XXX: set nonblocking */ + /* tcsetattr(~(ICANON | ECHO)) */ return (0); } static void hostcons_putchar(int c) { uint8_t ch = c; host_write(1, &ch, 1); } static int hostcons_getchar() { uint8_t ch; int rv; rv = host_read(0, &ch, 1); if (rv == 1) return (ch); return (-1); } static int hostcons_poll() { struct host_timeval tv = {0,0}; long fds = 1 << 0; int ret; ret = host_select(32, &fds, NULL, NULL, &tv); return (ret > 0); } Index: user/nwhitehorn/kboot/powerpc/kboot/hostdisk.c =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/hostdisk.c (revision 276409) +++ user/nwhitehorn/kboot/powerpc/kboot/hostdisk.c (revision 276410) @@ -1,126 +1,126 @@ /*- * Copyright (C) 2014 Nathan Whitehorn * 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 ``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 __FBSDID("$FreeBSD$"); #include #include #include "bootstrap.h" #include "host_syscall.h" static int hostdisk_init(void); static int hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize); static int hostdisk_open(struct open_file *f, ...); static int hostdisk_close(struct open_file *f); static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); static void hostdisk_print(int verbose); struct devsw hostdisk = { - "a", + "s", DEVT_DISK, hostdisk_init, hostdisk_strategy, hostdisk_open, hostdisk_close, hostdisk_ioctl, hostdisk_print, }; static int hostdisk_init(void) { return (0); } static int hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize) { struct devdesc *desc = devdata; daddr_t pos; int n; pos = dblk * 512; if (host_seek(desc->d_unit, pos, 0) < 0) return (EIO); n = host_read(desc->d_unit, buf, size); if (n < 0) return (EIO); *rsize = n; return (0); } static int hostdisk_open(struct open_file *f, ...) { struct devdesc *desc; char *path; va_list vl; va_start(vl, f); desc = va_arg(vl, struct devdesc *); va_end(vl); path = malloc(strlen((char *)(desc->d_opendata)) + 6); strcpy(path, "/dev/"); strcat(path, (char *)(desc->d_opendata)); desc->d_unit = host_open(path, O_RDONLY, 0); free(path); - if (desc->d_unit < 0) + if (desc->d_unit <= 0) return (ENOENT); return (0); } static int hostdisk_close(struct open_file *f) { struct devdesc *desc = f->f_devdata; host_close(desc->d_unit); return (0); } static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data) { return (EINVAL); } static void hostdisk_print(int verbose) { } Index: user/nwhitehorn/kboot/powerpc/kboot/main.c =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/main.c (revision 276409) +++ user/nwhitehorn/kboot/powerpc/kboot/main.c (revision 276410) @@ -1,286 +1,288 @@ /*- * Copyright (C) 2010-2014 Nathan Whitehorn * 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 ``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 __FBSDID("$FreeBSD$"); #include #include #define _KERNEL #include #include "bootstrap.h" #include "host_syscall.h" struct arch_switch archsw; extern void *_end; extern char bootprog_name[]; extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; int kboot_getdev(void **vdev, const char *devspec, const char **path); ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len); ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len); int kboot_autoload(void); int kboot_setcurrdev(struct env_var *ev, int flags, const void *value); int kboot_getdev(void **vdev, const char *devspec, const char **path) { int i; const char *devpath, *filepath; struct devsw *dv; struct devdesc *desc; if (strchr(devspec, ':') != NULL) { devpath = devspec; filepath = strchr(devspec, ':') + 1; } else { devpath = getenv("currdev"); filepath = devspec; } for (i = 0; (dv = devsw[i]) != NULL; i++) { if (strncmp(dv->dv_name, devpath, strlen(dv->dv_name)) == 0) goto found; } return (ENOENT); found: if (path != NULL && filepath != NULL) *path = filepath; else if (path != NULL) *path = strchr(devspec, ':') + 1; if (vdev != NULL) { desc = malloc(sizeof(*desc)); desc->d_dev = dv; desc->d_unit = 0; desc->d_opendata = strdup(devpath); *vdev = desc; } return (0); } int main(int argc, const char **argv) { void *heapbase; const size_t heapsize = 15*1024*1024; + const char *bootdev = argv[1]; /* * Set the heap to one page after the end of the loader. */ heapbase = host_getmem(heapsize); setheap(heapbase, heapbase + heapsize); /* * Set up console. */ cons_probe(); - printf("Boot device: %s\n", argv[1]); + printf("Boot device: %s\n", bootdev); archsw.arch_getdev = kboot_getdev; archsw.arch_copyin = kboot_copyin; archsw.arch_copyout = kboot_copyout; archsw.arch_readin = kboot_readin; archsw.arch_autoload = kboot_autoload; printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); - setenv("currdev", argv[1], 1); - setenv("loaddev", argv[1], 1); + setenv("currdev", bootdev, 1); + setenv("loaddev", bootdev, 1); setenv("LINES", "24", 1); interact(NULL); /* doesn't return */ return (0); } void exit(int code) { /* XXX: host_exit */ } void delay(int usecs) { struct host_timeval tvi, tv; uint64_t ti, t; host_gettimeofday(&tvi, NULL); ti = tvi.tv_sec*1000000 + tvi.tv_usec; do { host_gettimeofday(&tv, NULL); t = tv.tv_sec*1000000 + tv.tv_usec; } while (t < ti + usecs); } int getsecs() { struct host_timeval tv; host_gettimeofday(&tv, NULL); return (tv.tv_sec); } time_t time(time_t *tloc) { time_t rv; rv = getsecs(); if (tloc != NULL) *tloc = rv; return (rv); } struct kexec_segment { void *buf; size_t bufsz; void *mem; size_t memsz; }; struct kexec_segment loaded_segments[128]; int nkexec_segments = 0; static ssize_t get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) { int i = 0; const size_t segsize = 2*1024*1024; for (i = 0; i < nkexec_segments; i++) { if (dest >= (vm_offset_t)loaded_segments[i].mem && dest < (vm_offset_t)loaded_segments[i].mem + loaded_segments[i].memsz) goto out; } loaded_segments[nkexec_segments].buf = host_getmem(segsize); loaded_segments[nkexec_segments].bufsz = segsize; loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize); loaded_segments[nkexec_segments].memsz = segsize; i = nkexec_segments; nkexec_segments++; out: *buf = loaded_segments[i].buf + (dest - (vm_offset_t)loaded_segments[i].mem); return (min(len,loaded_segments[i].bufsz - (dest - (vm_offset_t)loaded_segments[i].mem))); } ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len) { ssize_t segsize, remainder; void *destbuf; remainder = len; do { segsize = get_phys_buffer(dest, remainder, &destbuf); bcopy(src, destbuf, segsize); remainder -= segsize; src += segsize; dest += segsize; } while (remainder > 0); return (len); } ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len) { ssize_t segsize, remainder; void *srcbuf; remainder = len; do { segsize = get_phys_buffer(src, remainder, &srcbuf); bcopy(srcbuf, dest, segsize); remainder -= segsize; src += segsize; dest += segsize; } while (remainder > 0); return (len); } ssize_t kboot_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(PAGE_SIZE, len); buf = malloc(chunk); if (buf == NULL) { printf("kboot_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) { if (got < 0) printf("kboot_readin: read failed\n"); break; } kboot_copyin(buf, p, got); } free (buf); return (len - resid); } int kboot_autoload(void) { return (0); } void _start(int argc, const char **argv, char **env) { - main(argc, argv); + register volatile void **sp asm("r1"); + main((int)sp[0], (const char **)&sp[1]); }