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