1183863Snwhitehorn/*- 2183863Snwhitehorn * Copyright (c) 1998 Robert Nordier 3183863Snwhitehorn * All rights reserved. 4183863Snwhitehorn * Copyright (c) 2001 Robert Drehmel 5183863Snwhitehorn * All rights reserved. 6183863Snwhitehorn * 7183863Snwhitehorn * Redistribution and use in source and binary forms are freely 8183863Snwhitehorn * permitted provided that the above copyright notice and this 9183863Snwhitehorn * paragraph and the following disclaimer are duplicated in all 10183863Snwhitehorn * such forms. 11183863Snwhitehorn * 12183863Snwhitehorn * This software is provided "AS IS" and without any express or 13183863Snwhitehorn * implied warranties, including, without limitation, the implied 14183863Snwhitehorn * warranties of merchantability and fitness for a particular 15183863Snwhitehorn * purpose. 16183863Snwhitehorn */ 17183863Snwhitehorn 18183863Snwhitehorn#include <sys/cdefs.h> 19183863Snwhitehorn__FBSDID("$FreeBSD$"); 20183863Snwhitehorn 21183863Snwhitehorn#include <sys/param.h> 22183863Snwhitehorn#include <sys/dirent.h> 23183863Snwhitehorn#include <machine/elf.h> 24183863Snwhitehorn#include <machine/stdarg.h> 25183863Snwhitehorn 26183863Snwhitehorn#define _PATH_LOADER "/boot/loader" 27183863Snwhitehorn#define _PATH_KERNEL "/boot/kernel/kernel" 28183863Snwhitehorn 29183863Snwhitehorn#define BSIZEMAX 16384 30183863Snwhitehorn 31183863Snwhitehorntypedef int putc_func_t(char c, void *arg); 32183863Snwhitehorntypedef int32_t ofwh_t; 33183863Snwhitehorn 34183863Snwhitehornstruct sp_data { 35183863Snwhitehorn char *sp_buf; 36183863Snwhitehorn u_int sp_len; 37183863Snwhitehorn u_int sp_size; 38183863Snwhitehorn}; 39183863Snwhitehorn 40183863Snwhitehornstatic const char digits[] = "0123456789abcdef"; 41183863Snwhitehorn 42183863Snwhitehornstatic char bootpath[128]; 43183863Snwhitehornstatic char bootargs[128]; 44183863Snwhitehorn 45183863Snwhitehornstatic ofwh_t bootdev; 46183863Snwhitehorn 47183863Snwhitehornstatic struct fs fs; 48183863Snwhitehornstatic char blkbuf[BSIZEMAX]; 49183863Snwhitehornstatic unsigned int fsblks; 50183863Snwhitehorn 51183863Snwhitehornstatic uint32_t fs_off; 52183863Snwhitehorn 53183863Snwhitehornint main(int ac, char **av); 54183863Snwhitehorn 55183863Snwhitehornstatic void exit(int) __dead2; 56183863Snwhitehornstatic void load(const char *); 57183863Snwhitehornstatic int dskread(void *, u_int64_t, int); 58183863Snwhitehorn 59183863Snwhitehornstatic void usage(void); 60183863Snwhitehorn 61183863Snwhitehornstatic void bcopy(const void *src, void *dst, size_t len); 62183863Snwhitehornstatic void bzero(void *b, size_t len); 63183863Snwhitehorn 64243254Straszstatic int domount(const char *device, int quiet); 65183863Snwhitehorn 66183863Snwhitehornstatic void panic(const char *fmt, ...) __dead2; 67183863Snwhitehornstatic int printf(const char *fmt, ...); 68183863Snwhitehornstatic int putchar(char c, void *arg); 69183863Snwhitehornstatic int vprintf(const char *fmt, va_list ap); 70183863Snwhitehornstatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); 71183863Snwhitehorn 72183863Snwhitehornstatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); 73183863Snwhitehornstatic int __putc(char c, void *arg); 74183863Snwhitehornstatic int __puts(const char *s, putc_func_t *putc, void *arg); 75183863Snwhitehornstatic int __sputc(char c, void *arg); 76183863Snwhitehornstatic char *__uitoa(char *buf, u_int val, int base); 77183863Snwhitehornstatic char *__ultoa(char *buf, u_long val, int base); 78183863Snwhitehorn 79231810Snwhitehornvoid __syncicache(void *, int); 80231810Snwhitehorn 81183863Snwhitehorn/* 82183863Snwhitehorn * Open Firmware interface functions 83183863Snwhitehorn */ 84183863Snwhitehorntypedef u_int32_t ofwcell_t; 85183863Snwhitehorntypedef u_int32_t u_ofwh_t; 86183863Snwhitehorntypedef int (*ofwfp_t)(void *); 87183863Snwhitehornofwfp_t ofw; /* the prom Open Firmware entry */ 88183863Snwhitehornofwh_t chosenh; 89183863Snwhitehorn 90183863Snwhitehornvoid ofw_init(void *, int, int (*)(void *), char *, int); 91183863Snwhitehornstatic ofwh_t ofw_finddevice(const char *); 92183863Snwhitehornstatic ofwh_t ofw_open(const char *); 93183863Snwhitehornstatic int ofw_close(ofwh_t); 94183863Snwhitehornstatic int ofw_getprop(ofwh_t, const char *, void *, size_t); 95183863Snwhitehornstatic int ofw_setprop(ofwh_t, const char *, void *, size_t); 96183863Snwhitehornstatic int ofw_read(ofwh_t, void *, size_t); 97183863Snwhitehornstatic int ofw_write(ofwh_t, const void *, size_t); 98183863Snwhitehornstatic int ofw_claim(void *virt, size_t len, u_int align); 99183863Snwhitehornstatic int ofw_seek(ofwh_t, u_int64_t); 100183863Snwhitehornstatic void ofw_exit(void) __dead2; 101183863Snwhitehorn 102183863Snwhitehornofwh_t bootdevh; 103183863Snwhitehornofwh_t stdinh, stdouth; 104183863Snwhitehorn 105183863Snwhitehorn__asm(" \n\ 106183863Snwhitehorn .data \n\ 107218822Sdim .align 4 \n\ 108183863Snwhitehornstack: \n\ 109183863Snwhitehorn .space 16384 \n\ 110183863Snwhitehorn \n\ 111183863Snwhitehorn .text \n\ 112183863Snwhitehorn .globl _start \n\ 113183863Snwhitehorn_start: \n\ 114183863Snwhitehorn lis %r1,stack@ha \n\ 115183863Snwhitehorn addi %r1,%r1,stack@l \n\ 116183863Snwhitehorn addi %r1,%r1,8192 \n\ 117183863Snwhitehorn \n\ 118183863Snwhitehorn b ofw_init \n\ 119183863Snwhitehorn"); 120183863Snwhitehorn 121183863Snwhitehornvoid 122183863Snwhitehornofw_init(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl) 123183863Snwhitehorn{ 124183863Snwhitehorn char *av[16]; 125183863Snwhitehorn char *p; 126183863Snwhitehorn int ac; 127183863Snwhitehorn 128183863Snwhitehorn ofw = openfirm; 129183863Snwhitehorn 130183863Snwhitehorn chosenh = ofw_finddevice("/chosen"); 131183863Snwhitehorn ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh)); 132183863Snwhitehorn ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth)); 133183863Snwhitehorn ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs)); 134183863Snwhitehorn ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); 135183863Snwhitehorn 136183863Snwhitehorn bootargs[sizeof(bootargs) - 1] = '\0'; 137183863Snwhitehorn bootpath[sizeof(bootpath) - 1] = '\0'; 138183863Snwhitehorn 139183863Snwhitehorn p = bootpath; 140183863Snwhitehorn while (*p != '\0') { 141183863Snwhitehorn if (*p == ':') { 142183863Snwhitehorn *(++p) = '\0'; 143183863Snwhitehorn break; 144183863Snwhitehorn } 145183863Snwhitehorn p++; 146183863Snwhitehorn } 147183863Snwhitehorn 148183863Snwhitehorn ac = 0; 149183863Snwhitehorn p = bootargs; 150183863Snwhitehorn for (;;) { 151183863Snwhitehorn while (*p == ' ' && *p != '\0') 152183863Snwhitehorn p++; 153183863Snwhitehorn if (*p == '\0' || ac >= 16) 154183863Snwhitehorn break; 155183863Snwhitehorn av[ac++] = p; 156183863Snwhitehorn while (*p != ' ' && *p != '\0') 157183863Snwhitehorn p++; 158183863Snwhitehorn if (*p != '\0') 159183863Snwhitehorn *p++ = '\0'; 160183863Snwhitehorn } 161183863Snwhitehorn 162183863Snwhitehorn exit(main(ac, av)); 163183863Snwhitehorn} 164183863Snwhitehorn 165183863Snwhitehornstatic ofwh_t 166183863Snwhitehornofw_finddevice(const char *name) 167183863Snwhitehorn{ 168183863Snwhitehorn ofwcell_t args[] = { 169183863Snwhitehorn (ofwcell_t)"finddevice", 170183863Snwhitehorn 1, 171183863Snwhitehorn 1, 172183863Snwhitehorn (ofwcell_t)name, 173183863Snwhitehorn 0 174183863Snwhitehorn }; 175183863Snwhitehorn 176183863Snwhitehorn if ((*ofw)(args)) { 177183863Snwhitehorn printf("ofw_finddevice: name=\"%s\"\n", name); 178183863Snwhitehorn return (1); 179183863Snwhitehorn } 180183863Snwhitehorn return (args[4]); 181183863Snwhitehorn} 182183863Snwhitehorn 183183863Snwhitehornstatic int 184183863Snwhitehornofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len) 185183863Snwhitehorn{ 186183863Snwhitehorn ofwcell_t args[] = { 187183863Snwhitehorn (ofwcell_t)"getprop", 188183863Snwhitehorn 4, 189183863Snwhitehorn 1, 190183863Snwhitehorn (u_ofwh_t)ofwh, 191183863Snwhitehorn (ofwcell_t)name, 192183863Snwhitehorn (ofwcell_t)buf, 193183863Snwhitehorn len, 194183863Snwhitehorn 0 195183863Snwhitehorn }; 196183863Snwhitehorn 197183863Snwhitehorn if ((*ofw)(args)) { 198183863Snwhitehorn printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n", 199183863Snwhitehorn ofwh, buf, len); 200183863Snwhitehorn return (1); 201183863Snwhitehorn } 202183863Snwhitehorn return (0); 203183863Snwhitehorn} 204183863Snwhitehorn 205183863Snwhitehornstatic int 206183863Snwhitehornofw_setprop(ofwh_t ofwh, const char *name, void *buf, size_t len) 207183863Snwhitehorn{ 208183863Snwhitehorn ofwcell_t args[] = { 209183863Snwhitehorn (ofwcell_t)"setprop", 210183863Snwhitehorn 4, 211183863Snwhitehorn 1, 212183863Snwhitehorn (u_ofwh_t)ofwh, 213183863Snwhitehorn (ofwcell_t)name, 214183863Snwhitehorn (ofwcell_t)buf, 215183863Snwhitehorn len, 216183863Snwhitehorn 0 217183863Snwhitehorn }; 218183863Snwhitehorn 219183863Snwhitehorn if ((*ofw)(args)) { 220183863Snwhitehorn printf("ofw_setprop: ofwh=0x%x buf=%p len=%u\n", 221183863Snwhitehorn ofwh, buf, len); 222183863Snwhitehorn return (1); 223183863Snwhitehorn } 224183863Snwhitehorn return (0); 225183863Snwhitehorn} 226183863Snwhitehorn 227183863Snwhitehornstatic ofwh_t 228183863Snwhitehornofw_open(const char *path) 229183863Snwhitehorn{ 230183863Snwhitehorn ofwcell_t args[] = { 231183863Snwhitehorn (ofwcell_t)"open", 232183863Snwhitehorn 1, 233183863Snwhitehorn 1, 234183863Snwhitehorn (ofwcell_t)path, 235183863Snwhitehorn 0 236183863Snwhitehorn }; 237183863Snwhitehorn 238183863Snwhitehorn if ((*ofw)(args)) { 239183863Snwhitehorn printf("ofw_open: path=\"%s\"\n", path); 240183863Snwhitehorn return (-1); 241183863Snwhitehorn } 242183863Snwhitehorn return (args[4]); 243183863Snwhitehorn} 244183863Snwhitehorn 245183863Snwhitehornstatic int 246183863Snwhitehornofw_close(ofwh_t devh) 247183863Snwhitehorn{ 248183863Snwhitehorn ofwcell_t args[] = { 249183863Snwhitehorn (ofwcell_t)"close", 250183863Snwhitehorn 1, 251183863Snwhitehorn 0, 252183863Snwhitehorn (u_ofwh_t)devh 253183863Snwhitehorn }; 254183863Snwhitehorn 255183863Snwhitehorn if ((*ofw)(args)) { 256183863Snwhitehorn printf("ofw_close: devh=0x%x\n", devh); 257183863Snwhitehorn return (1); 258183863Snwhitehorn } 259183863Snwhitehorn return (0); 260183863Snwhitehorn} 261183863Snwhitehorn 262183863Snwhitehornstatic int 263183863Snwhitehornofw_claim(void *virt, size_t len, u_int align) 264183863Snwhitehorn{ 265183863Snwhitehorn ofwcell_t args[] = { 266183863Snwhitehorn (ofwcell_t)"claim", 267183863Snwhitehorn 3, 268183863Snwhitehorn 1, 269183863Snwhitehorn (ofwcell_t)virt, 270183863Snwhitehorn len, 271183863Snwhitehorn align, 272183863Snwhitehorn 0, 273183863Snwhitehorn 0 274183863Snwhitehorn }; 275183863Snwhitehorn 276183863Snwhitehorn if ((*ofw)(args)) { 277183863Snwhitehorn printf("ofw_claim: virt=%p len=%u\n", virt, len); 278183863Snwhitehorn return (1); 279183863Snwhitehorn } 280183863Snwhitehorn 281183863Snwhitehorn return (0); 282183863Snwhitehorn} 283183863Snwhitehorn 284183863Snwhitehornstatic int 285183863Snwhitehornofw_read(ofwh_t devh, void *buf, size_t len) 286183863Snwhitehorn{ 287183863Snwhitehorn ofwcell_t args[] = { 288183863Snwhitehorn (ofwcell_t)"read", 289183863Snwhitehorn 3, 290183863Snwhitehorn 1, 291183863Snwhitehorn (u_ofwh_t)devh, 292183863Snwhitehorn (ofwcell_t)buf, 293183863Snwhitehorn len, 294183863Snwhitehorn 0 295183863Snwhitehorn }; 296183863Snwhitehorn 297183863Snwhitehorn if ((*ofw)(args)) { 298183863Snwhitehorn printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len); 299183863Snwhitehorn return (1); 300183863Snwhitehorn } 301183863Snwhitehorn return (0); 302183863Snwhitehorn} 303183863Snwhitehorn 304183863Snwhitehornstatic int 305183863Snwhitehornofw_write(ofwh_t devh, const void *buf, size_t len) 306183863Snwhitehorn{ 307183863Snwhitehorn ofwcell_t args[] = { 308183863Snwhitehorn (ofwcell_t)"write", 309183863Snwhitehorn 3, 310183863Snwhitehorn 1, 311183863Snwhitehorn (u_ofwh_t)devh, 312183863Snwhitehorn (ofwcell_t)buf, 313183863Snwhitehorn len, 314183863Snwhitehorn 0 315183863Snwhitehorn }; 316183863Snwhitehorn 317183863Snwhitehorn if ((*ofw)(args)) { 318183863Snwhitehorn printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len); 319183863Snwhitehorn return (1); 320183863Snwhitehorn } 321183863Snwhitehorn return (0); 322183863Snwhitehorn} 323183863Snwhitehorn 324183863Snwhitehornstatic int 325183863Snwhitehornofw_seek(ofwh_t devh, u_int64_t off) 326183863Snwhitehorn{ 327183863Snwhitehorn ofwcell_t args[] = { 328183863Snwhitehorn (ofwcell_t)"seek", 329183863Snwhitehorn 3, 330183863Snwhitehorn 1, 331183863Snwhitehorn (u_ofwh_t)devh, 332183863Snwhitehorn off >> 32, 333183863Snwhitehorn off, 334183863Snwhitehorn 0 335183863Snwhitehorn }; 336183863Snwhitehorn 337183863Snwhitehorn if ((*ofw)(args)) { 338183863Snwhitehorn printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off); 339183863Snwhitehorn return (1); 340183863Snwhitehorn } 341183863Snwhitehorn return (0); 342183863Snwhitehorn} 343183863Snwhitehorn 344183863Snwhitehornstatic void 345183863Snwhitehornofw_exit(void) 346183863Snwhitehorn{ 347183863Snwhitehorn ofwcell_t args[3]; 348183863Snwhitehorn 349183863Snwhitehorn args[0] = (ofwcell_t)"exit"; 350183863Snwhitehorn args[1] = 0; 351183863Snwhitehorn args[2] = 0; 352183863Snwhitehorn 353183863Snwhitehorn for (;;) 354183863Snwhitehorn (*ofw)(args); 355183863Snwhitehorn} 356183863Snwhitehorn 357183863Snwhitehornstatic void 358183863Snwhitehornbcopy(const void *src, void *dst, size_t len) 359183863Snwhitehorn{ 360183863Snwhitehorn const char *s = src; 361183863Snwhitehorn char *d = dst; 362183863Snwhitehorn 363183863Snwhitehorn while (len-- != 0) 364183863Snwhitehorn *d++ = *s++; 365183863Snwhitehorn} 366183863Snwhitehorn 367183863Snwhitehornstatic void 368183863Snwhitehornmemcpy(void *dst, const void *src, size_t len) 369183863Snwhitehorn{ 370183863Snwhitehorn bcopy(src, dst, len); 371183863Snwhitehorn} 372183863Snwhitehorn 373183863Snwhitehornstatic void 374183863Snwhitehornbzero(void *b, size_t len) 375183863Snwhitehorn{ 376183863Snwhitehorn char *p = b; 377183863Snwhitehorn 378183863Snwhitehorn while (len-- != 0) 379183863Snwhitehorn *p++ = 0; 380183863Snwhitehorn} 381183863Snwhitehorn 382183863Snwhitehornstatic int 383183863Snwhitehornstrcmp(const char *s1, const char *s2) 384183863Snwhitehorn{ 385183863Snwhitehorn for (; *s1 == *s2 && *s1; s1++, s2++) 386183863Snwhitehorn ; 387183863Snwhitehorn return ((u_char)*s1 - (u_char)*s2); 388183863Snwhitehorn} 389183863Snwhitehorn 390183863Snwhitehorn#include "ufsread.c" 391183863Snwhitehorn 392183863Snwhitehornint 393183863Snwhitehornmain(int ac, char **av) 394183863Snwhitehorn{ 395183863Snwhitehorn const char *path; 396183863Snwhitehorn char bootpath_full[255]; 397183863Snwhitehorn int i, len; 398183863Snwhitehorn 399183863Snwhitehorn path = _PATH_LOADER; 400183863Snwhitehorn for (i = 0; i < ac; i++) { 401183863Snwhitehorn switch (av[i][0]) { 402183863Snwhitehorn case '-': 403183863Snwhitehorn switch (av[i][1]) { 404183863Snwhitehorn default: 405183863Snwhitehorn usage(); 406183863Snwhitehorn } 407183863Snwhitehorn break; 408183863Snwhitehorn default: 409183863Snwhitehorn path = av[i]; 410183863Snwhitehorn break; 411183863Snwhitehorn } 412183863Snwhitehorn } 413183863Snwhitehorn 414183863Snwhitehorn printf(" \n>> FreeBSD/powerpc Open Firmware boot block\n" 415183863Snwhitehorn " Boot path: %s\n" 416183863Snwhitehorn " Boot loader: %s\n", bootpath, path); 417183863Snwhitehorn 418183863Snwhitehorn len = 0; 419183863Snwhitehorn while (bootpath[len] != '\0') len++; 420183863Snwhitehorn 421183863Snwhitehorn memcpy(bootpath_full,bootpath,len+1); 422183863Snwhitehorn 423183863Snwhitehorn if (bootpath_full[len-1] == ':') { 424183863Snwhitehorn for (i = 0; i < 16; i++) { 425183863Snwhitehorn if (i < 10) { 426183863Snwhitehorn bootpath_full[len] = i + '0'; 427183863Snwhitehorn bootpath_full[len+1] = '\0'; 428183863Snwhitehorn } else { 429183863Snwhitehorn bootpath_full[len] = '1'; 430183863Snwhitehorn bootpath_full[len+1] = i - 10 + '0'; 431183863Snwhitehorn bootpath_full[len+2] = '\0'; 432183863Snwhitehorn } 433183863Snwhitehorn 434243254Strasz if (domount(bootpath_full,1) >= 0) 435183863Snwhitehorn break; 436183863Snwhitehorn 437183863Snwhitehorn if (bootdev > 0) 438183863Snwhitehorn ofw_close(bootdev); 439183863Snwhitehorn } 440183863Snwhitehorn 441183863Snwhitehorn if (i >= 16) 442243254Strasz panic("domount"); 443183863Snwhitehorn } else { 444243254Strasz if (domount(bootpath_full,0) == -1) 445243254Strasz panic("domount"); 446183863Snwhitehorn } 447183863Snwhitehorn 448183863Snwhitehorn printf(" Boot volume: %s\n",bootpath_full); 449183863Snwhitehorn ofw_setprop(chosenh, "bootargs", bootpath_full, len+2); 450183863Snwhitehorn load(path); 451183863Snwhitehorn return (1); 452183863Snwhitehorn} 453183863Snwhitehorn 454183863Snwhitehornstatic void 455183863Snwhitehornusage(void) 456183863Snwhitehorn{ 457183863Snwhitehorn 458183863Snwhitehorn printf("usage: boot device [/path/to/loader]\n"); 459183863Snwhitehorn exit(1); 460183863Snwhitehorn} 461183863Snwhitehorn 462183863Snwhitehornstatic void 463183863Snwhitehornexit(int code) 464183863Snwhitehorn{ 465183863Snwhitehorn 466183863Snwhitehorn ofw_exit(); 467183863Snwhitehorn} 468183863Snwhitehorn 469183863Snwhitehornstatic struct dmadat __dmadat; 470183863Snwhitehorn 471183863Snwhitehornstatic int 472243254Straszdomount(const char *device, int quiet) 473183863Snwhitehorn{ 474183863Snwhitehorn 475183863Snwhitehorn dmadat = &__dmadat; 476183863Snwhitehorn if ((bootdev = ofw_open(device)) == -1) { 477243254Strasz printf("domount: can't open device\n"); 478183863Snwhitehorn return (-1); 479183863Snwhitehorn } 480183863Snwhitehorn if (fsread(0, NULL, 0)) { 481183863Snwhitehorn if (!quiet) 482243254Strasz printf("domount: can't read superblock\n"); 483183863Snwhitehorn return (-1); 484183863Snwhitehorn } 485183863Snwhitehorn return (0); 486183863Snwhitehorn} 487183863Snwhitehorn 488183863Snwhitehornstatic void 489183863Snwhitehornload(const char *fname) 490183863Snwhitehorn{ 491183863Snwhitehorn Elf32_Ehdr eh; 492183863Snwhitehorn Elf32_Phdr ph; 493183863Snwhitehorn caddr_t p; 494235988Sgleb ufs_ino_t ino; 495183863Snwhitehorn int i; 496183863Snwhitehorn 497183863Snwhitehorn if ((ino = lookup(fname)) == 0) { 498183863Snwhitehorn printf("File %s not found\n", fname); 499183863Snwhitehorn return; 500183863Snwhitehorn } 501183863Snwhitehorn if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) { 502183863Snwhitehorn printf("Can't read elf header\n"); 503183863Snwhitehorn return; 504183863Snwhitehorn } 505183863Snwhitehorn if (!IS_ELF(eh)) { 506183863Snwhitehorn printf("Not an ELF file\n"); 507183863Snwhitehorn return; 508183863Snwhitehorn } 509183863Snwhitehorn for (i = 0; i < eh.e_phnum; i++) { 510183863Snwhitehorn fs_off = eh.e_phoff + i * eh.e_phentsize; 511183863Snwhitehorn if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) { 512183863Snwhitehorn printf("Can't read program header %d\n", i); 513183863Snwhitehorn return; 514183863Snwhitehorn } 515183863Snwhitehorn if (ph.p_type != PT_LOAD) 516183863Snwhitehorn continue; 517183863Snwhitehorn fs_off = ph.p_offset; 518183863Snwhitehorn p = (caddr_t)ph.p_vaddr; 519183863Snwhitehorn ofw_claim(p,(ph.p_filesz > ph.p_memsz) ? 520183863Snwhitehorn ph.p_filesz : ph.p_memsz,0); 521183863Snwhitehorn if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) { 522183863Snwhitehorn printf("Can't read content of section %d\n", i); 523183863Snwhitehorn return; 524183863Snwhitehorn } 525183863Snwhitehorn if (ph.p_filesz != ph.p_memsz) 526183863Snwhitehorn bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz); 527231810Snwhitehorn __syncicache(p, ph.p_memsz); 528183863Snwhitehorn } 529183863Snwhitehorn ofw_close(bootdev); 530183863Snwhitehorn (*(void (*)(void *, int, ofwfp_t, char *, int))eh.e_entry)(NULL, 0, 531183863Snwhitehorn ofw,NULL,0); 532183863Snwhitehorn} 533183863Snwhitehorn 534183863Snwhitehornstatic int 535183863Snwhitehorndskread(void *buf, u_int64_t lba, int nblk) 536183863Snwhitehorn{ 537183863Snwhitehorn /* 538183863Snwhitehorn * The Open Firmware should open the correct partition for us. 539183863Snwhitehorn * That means, if we read from offset zero on an open instance handle, 540183863Snwhitehorn * we should read from offset zero of that partition. 541183863Snwhitehorn */ 542183863Snwhitehorn ofw_seek(bootdev, lba * DEV_BSIZE); 543183863Snwhitehorn ofw_read(bootdev, buf, nblk * DEV_BSIZE); 544183863Snwhitehorn return (0); 545183863Snwhitehorn} 546183863Snwhitehorn 547183863Snwhitehornstatic void 548183863Snwhitehornpanic(const char *fmt, ...) 549183863Snwhitehorn{ 550183863Snwhitehorn char buf[128]; 551183863Snwhitehorn va_list ap; 552183863Snwhitehorn 553183863Snwhitehorn va_start(ap, fmt); 554183863Snwhitehorn vsnprintf(buf, sizeof buf, fmt, ap); 555183863Snwhitehorn printf("panic: %s\n", buf); 556183863Snwhitehorn va_end(ap); 557183863Snwhitehorn 558183863Snwhitehorn exit(1); 559183863Snwhitehorn} 560183863Snwhitehorn 561183863Snwhitehornstatic int 562183863Snwhitehornprintf(const char *fmt, ...) 563183863Snwhitehorn{ 564183863Snwhitehorn va_list ap; 565183863Snwhitehorn int ret; 566183863Snwhitehorn 567184490Snwhitehorn /* Don't annoy the user as we probe for partitions */ 568184490Snwhitehorn if (strcmp(fmt,"Not ufs\n") == 0) 569184490Snwhitehorn return 0; 570184490Snwhitehorn 571183863Snwhitehorn va_start(ap, fmt); 572183863Snwhitehorn ret = vprintf(fmt, ap); 573183863Snwhitehorn va_end(ap); 574183863Snwhitehorn return (ret); 575183863Snwhitehorn} 576183863Snwhitehorn 577183863Snwhitehornstatic int 578183863Snwhitehornputchar(char c, void *arg) 579183863Snwhitehorn{ 580183863Snwhitehorn char buf; 581183863Snwhitehorn 582183863Snwhitehorn if (c == '\n') { 583183863Snwhitehorn buf = '\r'; 584183863Snwhitehorn ofw_write(stdouth, &buf, 1); 585183863Snwhitehorn } 586183863Snwhitehorn buf = c; 587183863Snwhitehorn ofw_write(stdouth, &buf, 1); 588183863Snwhitehorn return (1); 589183863Snwhitehorn} 590183863Snwhitehorn 591183863Snwhitehornstatic int 592183863Snwhitehornvprintf(const char *fmt, va_list ap) 593183863Snwhitehorn{ 594183863Snwhitehorn int ret; 595183863Snwhitehorn 596183863Snwhitehorn ret = __printf(fmt, putchar, 0, ap); 597183863Snwhitehorn return (ret); 598183863Snwhitehorn} 599183863Snwhitehorn 600183863Snwhitehornstatic int 601183863Snwhitehornvsnprintf(char *str, size_t sz, const char *fmt, va_list ap) 602183863Snwhitehorn{ 603183863Snwhitehorn struct sp_data sp; 604183863Snwhitehorn int ret; 605183863Snwhitehorn 606183863Snwhitehorn sp.sp_buf = str; 607183863Snwhitehorn sp.sp_len = 0; 608183863Snwhitehorn sp.sp_size = sz; 609183863Snwhitehorn ret = __printf(fmt, __sputc, &sp, ap); 610183863Snwhitehorn return (ret); 611183863Snwhitehorn} 612183863Snwhitehorn 613183863Snwhitehornstatic int 614183863Snwhitehorn__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) 615183863Snwhitehorn{ 616183863Snwhitehorn char buf[(sizeof(long) * 8) + 1]; 617183863Snwhitehorn char *nbuf; 618183863Snwhitehorn u_long ul; 619183863Snwhitehorn u_int ui; 620183863Snwhitehorn int lflag; 621183863Snwhitehorn int sflag; 622183863Snwhitehorn char *s; 623183863Snwhitehorn int pad; 624183863Snwhitehorn int ret; 625183863Snwhitehorn int c; 626183863Snwhitehorn 627183863Snwhitehorn nbuf = &buf[sizeof buf - 1]; 628183863Snwhitehorn ret = 0; 629183863Snwhitehorn while ((c = *fmt++) != 0) { 630183863Snwhitehorn if (c != '%') { 631183863Snwhitehorn ret += putc(c, arg); 632183863Snwhitehorn continue; 633183863Snwhitehorn } 634183863Snwhitehorn lflag = 0; 635183863Snwhitehorn sflag = 0; 636183863Snwhitehorn pad = 0; 637183863Snwhitehornreswitch: c = *fmt++; 638183863Snwhitehorn switch (c) { 639183863Snwhitehorn case '#': 640183863Snwhitehorn sflag = 1; 641183863Snwhitehorn goto reswitch; 642183863Snwhitehorn case '%': 643183863Snwhitehorn ret += putc('%', arg); 644183863Snwhitehorn break; 645183863Snwhitehorn case 'c': 646183863Snwhitehorn c = va_arg(ap, int); 647183863Snwhitehorn ret += putc(c, arg); 648183863Snwhitehorn break; 649183863Snwhitehorn case 'd': 650183863Snwhitehorn if (lflag == 0) { 651183863Snwhitehorn ui = (u_int)va_arg(ap, int); 652183863Snwhitehorn if (ui < (int)ui) { 653183863Snwhitehorn ui = -ui; 654183863Snwhitehorn ret += putc('-', arg); 655183863Snwhitehorn } 656183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 657183863Snwhitehorn } else { 658183863Snwhitehorn ul = (u_long)va_arg(ap, long); 659183863Snwhitehorn if (ul < (long)ul) { 660183863Snwhitehorn ul = -ul; 661183863Snwhitehorn ret += putc('-', arg); 662183863Snwhitehorn } 663183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 664183863Snwhitehorn } 665183863Snwhitehorn ret += __puts(s, putc, arg); 666183863Snwhitehorn break; 667183863Snwhitehorn case 'l': 668183863Snwhitehorn lflag = 1; 669183863Snwhitehorn goto reswitch; 670183863Snwhitehorn case 'o': 671183863Snwhitehorn if (lflag == 0) { 672183863Snwhitehorn ui = (u_int)va_arg(ap, u_int); 673183863Snwhitehorn s = __uitoa(nbuf, ui, 8); 674183863Snwhitehorn } else { 675183863Snwhitehorn ul = (u_long)va_arg(ap, u_long); 676183863Snwhitehorn s = __ultoa(nbuf, ul, 8); 677183863Snwhitehorn } 678183863Snwhitehorn ret += __puts(s, putc, arg); 679183863Snwhitehorn break; 680183863Snwhitehorn case 'p': 681183863Snwhitehorn ul = (u_long)va_arg(ap, void *); 682183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 683183863Snwhitehorn ret += __puts("0x", putc, arg); 684183863Snwhitehorn ret += __puts(s, putc, arg); 685183863Snwhitehorn break; 686183863Snwhitehorn case 's': 687183863Snwhitehorn s = va_arg(ap, char *); 688183863Snwhitehorn ret += __puts(s, putc, arg); 689183863Snwhitehorn break; 690183863Snwhitehorn case 'u': 691183863Snwhitehorn if (lflag == 0) { 692183863Snwhitehorn ui = va_arg(ap, u_int); 693183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 694183863Snwhitehorn } else { 695183863Snwhitehorn ul = va_arg(ap, u_long); 696183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 697183863Snwhitehorn } 698183863Snwhitehorn ret += __puts(s, putc, arg); 699183863Snwhitehorn break; 700183863Snwhitehorn case 'x': 701183863Snwhitehorn if (lflag == 0) { 702183863Snwhitehorn ui = va_arg(ap, u_int); 703183863Snwhitehorn s = __uitoa(nbuf, ui, 16); 704183863Snwhitehorn } else { 705183863Snwhitehorn ul = va_arg(ap, u_long); 706183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 707183863Snwhitehorn } 708183863Snwhitehorn if (sflag) 709183863Snwhitehorn ret += __puts("0x", putc, arg); 710183863Snwhitehorn ret += __puts(s, putc, arg); 711183863Snwhitehorn break; 712183863Snwhitehorn case '0': case '1': case '2': case '3': case '4': 713183863Snwhitehorn case '5': case '6': case '7': case '8': case '9': 714183863Snwhitehorn pad = pad * 10 + c - '0'; 715183863Snwhitehorn goto reswitch; 716183863Snwhitehorn default: 717183863Snwhitehorn break; 718183863Snwhitehorn } 719183863Snwhitehorn } 720183863Snwhitehorn return (ret); 721183863Snwhitehorn} 722183863Snwhitehorn 723183863Snwhitehornstatic int 724183863Snwhitehorn__sputc(char c, void *arg) 725183863Snwhitehorn{ 726183863Snwhitehorn struct sp_data *sp; 727183863Snwhitehorn 728183863Snwhitehorn sp = arg; 729183863Snwhitehorn if (sp->sp_len < sp->sp_size) 730183863Snwhitehorn sp->sp_buf[sp->sp_len++] = c; 731183863Snwhitehorn sp->sp_buf[sp->sp_len] = '\0'; 732183863Snwhitehorn return (1); 733183863Snwhitehorn} 734183863Snwhitehorn 735183863Snwhitehornstatic int 736183863Snwhitehorn__puts(const char *s, putc_func_t *putc, void *arg) 737183863Snwhitehorn{ 738183863Snwhitehorn const char *p; 739183863Snwhitehorn int ret; 740183863Snwhitehorn 741183863Snwhitehorn ret = 0; 742183863Snwhitehorn for (p = s; *p != '\0'; p++) 743183863Snwhitehorn ret += putc(*p, arg); 744183863Snwhitehorn return (ret); 745183863Snwhitehorn} 746183863Snwhitehorn 747183863Snwhitehornstatic char * 748183863Snwhitehorn__uitoa(char *buf, u_int ui, int base) 749183863Snwhitehorn{ 750183863Snwhitehorn char *p; 751183863Snwhitehorn 752183863Snwhitehorn p = buf; 753183863Snwhitehorn *p = '\0'; 754183863Snwhitehorn do 755183863Snwhitehorn *--p = digits[ui % base]; 756183863Snwhitehorn while ((ui /= base) != 0); 757183863Snwhitehorn return (p); 758183863Snwhitehorn} 759183863Snwhitehorn 760183863Snwhitehornstatic char * 761183863Snwhitehorn__ultoa(char *buf, u_long ul, int base) 762183863Snwhitehorn{ 763183863Snwhitehorn char *p; 764183863Snwhitehorn 765183863Snwhitehorn p = buf; 766183863Snwhitehorn *p = '\0'; 767183863Snwhitehorn do 768183863Snwhitehorn *--p = digits[ul % base]; 769183863Snwhitehorn while ((ul /= base) != 0); 770183863Snwhitehorn return (p); 771183863Snwhitehorn} 772