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: releng/10.3/sys/boot/powerpc/boot1.chrp/boot1.c 295453 2016-02-09 22:32:24Z emaste $"); 20183863Snwhitehorn 21183863Snwhitehorn#include <sys/param.h> 22183863Snwhitehorn#include <sys/dirent.h> 23183863Snwhitehorn#include <machine/elf.h> 24183863Snwhitehorn#include <machine/stdarg.h> 25183863Snwhitehorn 26295453Semaste#include "paths.h" 27183863Snwhitehorn 28183863Snwhitehorn#define BSIZEMAX 16384 29183863Snwhitehorn 30183863Snwhitehorntypedef int putc_func_t(char c, void *arg); 31183863Snwhitehorntypedef int32_t ofwh_t; 32183863Snwhitehorn 33183863Snwhitehornstruct sp_data { 34183863Snwhitehorn char *sp_buf; 35183863Snwhitehorn u_int sp_len; 36183863Snwhitehorn u_int sp_size; 37183863Snwhitehorn}; 38183863Snwhitehorn 39183863Snwhitehornstatic const char digits[] = "0123456789abcdef"; 40183863Snwhitehorn 41183863Snwhitehornstatic char bootpath[128]; 42183863Snwhitehornstatic char bootargs[128]; 43183863Snwhitehorn 44183863Snwhitehornstatic ofwh_t bootdev; 45183863Snwhitehorn 46183863Snwhitehornstatic struct fs fs; 47183863Snwhitehornstatic char blkbuf[BSIZEMAX]; 48183863Snwhitehornstatic unsigned int fsblks; 49183863Snwhitehorn 50183863Snwhitehornstatic uint32_t fs_off; 51183863Snwhitehorn 52183863Snwhitehornint main(int ac, char **av); 53183863Snwhitehorn 54183863Snwhitehornstatic void exit(int) __dead2; 55183863Snwhitehornstatic void load(const char *); 56183863Snwhitehornstatic int dskread(void *, u_int64_t, int); 57183863Snwhitehorn 58183863Snwhitehornstatic void usage(void); 59183863Snwhitehorn 60183863Snwhitehornstatic void bcopy(const void *src, void *dst, size_t len); 61183863Snwhitehornstatic void bzero(void *b, size_t len); 62183863Snwhitehorn 63243254Straszstatic int domount(const char *device, int quiet); 64183863Snwhitehorn 65183863Snwhitehornstatic void panic(const char *fmt, ...) __dead2; 66183863Snwhitehornstatic int printf(const char *fmt, ...); 67183863Snwhitehornstatic int putchar(char c, void *arg); 68183863Snwhitehornstatic int vprintf(const char *fmt, va_list ap); 69183863Snwhitehornstatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); 70183863Snwhitehorn 71183863Snwhitehornstatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); 72183863Snwhitehornstatic int __putc(char c, void *arg); 73183863Snwhitehornstatic int __puts(const char *s, putc_func_t *putc, void *arg); 74183863Snwhitehornstatic int __sputc(char c, void *arg); 75183863Snwhitehornstatic char *__uitoa(char *buf, u_int val, int base); 76183863Snwhitehornstatic char *__ultoa(char *buf, u_long val, int base); 77183863Snwhitehorn 78231810Snwhitehornvoid __syncicache(void *, int); 79231810Snwhitehorn 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 398295453Semaste 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 433243254Strasz if (domount(bootpath_full,1) >= 0) 434183863Snwhitehorn break; 435183863Snwhitehorn 436183863Snwhitehorn if (bootdev > 0) 437183863Snwhitehorn ofw_close(bootdev); 438183863Snwhitehorn } 439183863Snwhitehorn 440183863Snwhitehorn if (i >= 16) 441243254Strasz panic("domount"); 442183863Snwhitehorn } else { 443243254Strasz if (domount(bootpath_full,0) == -1) 444243254Strasz panic("domount"); 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 471243254Straszdomount(const char *device, int quiet) 472183863Snwhitehorn{ 473183863Snwhitehorn 474183863Snwhitehorn dmadat = &__dmadat; 475183863Snwhitehorn if ((bootdev = ofw_open(device)) == -1) { 476243254Strasz printf("domount: can't open device\n"); 477183863Snwhitehorn return (-1); 478183863Snwhitehorn } 479183863Snwhitehorn if (fsread(0, NULL, 0)) { 480183863Snwhitehorn if (!quiet) 481243254Strasz printf("domount: 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; 493235988Sgleb ufs_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); 526231810Snwhitehorn __syncicache(p, ph.p_memsz); 527183863Snwhitehorn } 528183863Snwhitehorn ofw_close(bootdev); 529183863Snwhitehorn (*(void (*)(void *, int, ofwfp_t, char *, int))eh.e_entry)(NULL, 0, 530183863Snwhitehorn ofw,NULL,0); 531183863Snwhitehorn} 532183863Snwhitehorn 533183863Snwhitehornstatic int 534183863Snwhitehorndskread(void *buf, u_int64_t lba, int nblk) 535183863Snwhitehorn{ 536183863Snwhitehorn /* 537183863Snwhitehorn * The Open Firmware should open the correct partition for us. 538183863Snwhitehorn * That means, if we read from offset zero on an open instance handle, 539183863Snwhitehorn * we should read from offset zero of that partition. 540183863Snwhitehorn */ 541183863Snwhitehorn ofw_seek(bootdev, lba * DEV_BSIZE); 542183863Snwhitehorn ofw_read(bootdev, buf, nblk * DEV_BSIZE); 543183863Snwhitehorn return (0); 544183863Snwhitehorn} 545183863Snwhitehorn 546183863Snwhitehornstatic void 547183863Snwhitehornpanic(const char *fmt, ...) 548183863Snwhitehorn{ 549183863Snwhitehorn char buf[128]; 550183863Snwhitehorn va_list ap; 551183863Snwhitehorn 552183863Snwhitehorn va_start(ap, fmt); 553183863Snwhitehorn vsnprintf(buf, sizeof buf, fmt, ap); 554183863Snwhitehorn printf("panic: %s\n", buf); 555183863Snwhitehorn va_end(ap); 556183863Snwhitehorn 557183863Snwhitehorn exit(1); 558183863Snwhitehorn} 559183863Snwhitehorn 560183863Snwhitehornstatic int 561183863Snwhitehornprintf(const char *fmt, ...) 562183863Snwhitehorn{ 563183863Snwhitehorn va_list ap; 564183863Snwhitehorn int ret; 565183863Snwhitehorn 566183863Snwhitehorn va_start(ap, fmt); 567183863Snwhitehorn ret = vprintf(fmt, ap); 568183863Snwhitehorn va_end(ap); 569183863Snwhitehorn return (ret); 570183863Snwhitehorn} 571183863Snwhitehorn 572183863Snwhitehornstatic int 573183863Snwhitehornputchar(char c, void *arg) 574183863Snwhitehorn{ 575183863Snwhitehorn char buf; 576183863Snwhitehorn 577183863Snwhitehorn if (c == '\n') { 578183863Snwhitehorn buf = '\r'; 579183863Snwhitehorn ofw_write(stdouth, &buf, 1); 580183863Snwhitehorn } 581183863Snwhitehorn buf = c; 582183863Snwhitehorn ofw_write(stdouth, &buf, 1); 583183863Snwhitehorn return (1); 584183863Snwhitehorn} 585183863Snwhitehorn 586183863Snwhitehornstatic int 587183863Snwhitehornvprintf(const char *fmt, va_list ap) 588183863Snwhitehorn{ 589183863Snwhitehorn int ret; 590183863Snwhitehorn 591183863Snwhitehorn ret = __printf(fmt, putchar, 0, ap); 592183863Snwhitehorn return (ret); 593183863Snwhitehorn} 594183863Snwhitehorn 595183863Snwhitehornstatic int 596183863Snwhitehornvsnprintf(char *str, size_t sz, const char *fmt, va_list ap) 597183863Snwhitehorn{ 598183863Snwhitehorn struct sp_data sp; 599183863Snwhitehorn int ret; 600183863Snwhitehorn 601183863Snwhitehorn sp.sp_buf = str; 602183863Snwhitehorn sp.sp_len = 0; 603183863Snwhitehorn sp.sp_size = sz; 604183863Snwhitehorn ret = __printf(fmt, __sputc, &sp, ap); 605183863Snwhitehorn return (ret); 606183863Snwhitehorn} 607183863Snwhitehorn 608183863Snwhitehornstatic int 609183863Snwhitehorn__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) 610183863Snwhitehorn{ 611183863Snwhitehorn char buf[(sizeof(long) * 8) + 1]; 612183863Snwhitehorn char *nbuf; 613183863Snwhitehorn u_long ul; 614183863Snwhitehorn u_int ui; 615183863Snwhitehorn int lflag; 616183863Snwhitehorn int sflag; 617183863Snwhitehorn char *s; 618183863Snwhitehorn int pad; 619183863Snwhitehorn int ret; 620183863Snwhitehorn int c; 621183863Snwhitehorn 622183863Snwhitehorn nbuf = &buf[sizeof buf - 1]; 623183863Snwhitehorn ret = 0; 624183863Snwhitehorn while ((c = *fmt++) != 0) { 625183863Snwhitehorn if (c != '%') { 626183863Snwhitehorn ret += putc(c, arg); 627183863Snwhitehorn continue; 628183863Snwhitehorn } 629183863Snwhitehorn lflag = 0; 630183863Snwhitehorn sflag = 0; 631183863Snwhitehorn pad = 0; 632183863Snwhitehornreswitch: c = *fmt++; 633183863Snwhitehorn switch (c) { 634183863Snwhitehorn case '#': 635183863Snwhitehorn sflag = 1; 636183863Snwhitehorn goto reswitch; 637183863Snwhitehorn case '%': 638183863Snwhitehorn ret += putc('%', arg); 639183863Snwhitehorn break; 640183863Snwhitehorn case 'c': 641183863Snwhitehorn c = va_arg(ap, int); 642183863Snwhitehorn ret += putc(c, arg); 643183863Snwhitehorn break; 644183863Snwhitehorn case 'd': 645183863Snwhitehorn if (lflag == 0) { 646183863Snwhitehorn ui = (u_int)va_arg(ap, int); 647183863Snwhitehorn if (ui < (int)ui) { 648183863Snwhitehorn ui = -ui; 649183863Snwhitehorn ret += putc('-', arg); 650183863Snwhitehorn } 651183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 652183863Snwhitehorn } else { 653183863Snwhitehorn ul = (u_long)va_arg(ap, long); 654183863Snwhitehorn if (ul < (long)ul) { 655183863Snwhitehorn ul = -ul; 656183863Snwhitehorn ret += putc('-', arg); 657183863Snwhitehorn } 658183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 659183863Snwhitehorn } 660183863Snwhitehorn ret += __puts(s, putc, arg); 661183863Snwhitehorn break; 662183863Snwhitehorn case 'l': 663183863Snwhitehorn lflag = 1; 664183863Snwhitehorn goto reswitch; 665183863Snwhitehorn case 'o': 666183863Snwhitehorn if (lflag == 0) { 667183863Snwhitehorn ui = (u_int)va_arg(ap, u_int); 668183863Snwhitehorn s = __uitoa(nbuf, ui, 8); 669183863Snwhitehorn } else { 670183863Snwhitehorn ul = (u_long)va_arg(ap, u_long); 671183863Snwhitehorn s = __ultoa(nbuf, ul, 8); 672183863Snwhitehorn } 673183863Snwhitehorn ret += __puts(s, putc, arg); 674183863Snwhitehorn break; 675183863Snwhitehorn case 'p': 676183863Snwhitehorn ul = (u_long)va_arg(ap, void *); 677183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 678183863Snwhitehorn ret += __puts("0x", putc, arg); 679183863Snwhitehorn ret += __puts(s, putc, arg); 680183863Snwhitehorn break; 681183863Snwhitehorn case 's': 682183863Snwhitehorn s = va_arg(ap, char *); 683183863Snwhitehorn ret += __puts(s, putc, arg); 684183863Snwhitehorn break; 685183863Snwhitehorn case 'u': 686183863Snwhitehorn if (lflag == 0) { 687183863Snwhitehorn ui = va_arg(ap, u_int); 688183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 689183863Snwhitehorn } else { 690183863Snwhitehorn ul = va_arg(ap, u_long); 691183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 692183863Snwhitehorn } 693183863Snwhitehorn ret += __puts(s, putc, arg); 694183863Snwhitehorn break; 695183863Snwhitehorn case 'x': 696183863Snwhitehorn if (lflag == 0) { 697183863Snwhitehorn ui = va_arg(ap, u_int); 698183863Snwhitehorn s = __uitoa(nbuf, ui, 16); 699183863Snwhitehorn } else { 700183863Snwhitehorn ul = va_arg(ap, u_long); 701183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 702183863Snwhitehorn } 703183863Snwhitehorn if (sflag) 704183863Snwhitehorn ret += __puts("0x", putc, arg); 705183863Snwhitehorn ret += __puts(s, putc, arg); 706183863Snwhitehorn break; 707183863Snwhitehorn case '0': case '1': case '2': case '3': case '4': 708183863Snwhitehorn case '5': case '6': case '7': case '8': case '9': 709183863Snwhitehorn pad = pad * 10 + c - '0'; 710183863Snwhitehorn goto reswitch; 711183863Snwhitehorn default: 712183863Snwhitehorn break; 713183863Snwhitehorn } 714183863Snwhitehorn } 715183863Snwhitehorn return (ret); 716183863Snwhitehorn} 717183863Snwhitehorn 718183863Snwhitehornstatic int 719183863Snwhitehorn__sputc(char c, void *arg) 720183863Snwhitehorn{ 721183863Snwhitehorn struct sp_data *sp; 722183863Snwhitehorn 723183863Snwhitehorn sp = arg; 724183863Snwhitehorn if (sp->sp_len < sp->sp_size) 725183863Snwhitehorn sp->sp_buf[sp->sp_len++] = c; 726183863Snwhitehorn sp->sp_buf[sp->sp_len] = '\0'; 727183863Snwhitehorn return (1); 728183863Snwhitehorn} 729183863Snwhitehorn 730183863Snwhitehornstatic int 731183863Snwhitehorn__puts(const char *s, putc_func_t *putc, void *arg) 732183863Snwhitehorn{ 733183863Snwhitehorn const char *p; 734183863Snwhitehorn int ret; 735183863Snwhitehorn 736183863Snwhitehorn ret = 0; 737183863Snwhitehorn for (p = s; *p != '\0'; p++) 738183863Snwhitehorn ret += putc(*p, arg); 739183863Snwhitehorn return (ret); 740183863Snwhitehorn} 741183863Snwhitehorn 742183863Snwhitehornstatic char * 743183863Snwhitehorn__uitoa(char *buf, u_int ui, int base) 744183863Snwhitehorn{ 745183863Snwhitehorn char *p; 746183863Snwhitehorn 747183863Snwhitehorn p = buf; 748183863Snwhitehorn *p = '\0'; 749183863Snwhitehorn do 750183863Snwhitehorn *--p = digits[ui % base]; 751183863Snwhitehorn while ((ui /= base) != 0); 752183863Snwhitehorn return (p); 753183863Snwhitehorn} 754183863Snwhitehorn 755183863Snwhitehornstatic char * 756183863Snwhitehorn__ultoa(char *buf, u_long ul, int base) 757183863Snwhitehorn{ 758183863Snwhitehorn char *p; 759183863Snwhitehorn 760183863Snwhitehorn p = buf; 761183863Snwhitehorn *p = '\0'; 762183863Snwhitehorn do 763183863Snwhitehorn *--p = digits[ul % base]; 764183863Snwhitehorn while ((ul /= base) != 0); 765183863Snwhitehorn return (p); 766183863Snwhitehorn} 767