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: stable/11/stand/powerpc/boot1.chrp/boot1.c 332154 2018-04-06 21:37:25Z kevans $"); 20183863Snwhitehorn 21183863Snwhitehorn#include <sys/param.h> 22183863Snwhitehorn#include <sys/dirent.h> 23183863Snwhitehorn#include <machine/elf.h> 24183863Snwhitehorn#include <machine/stdarg.h> 25329175Skevans#include <machine/md_var.h> 26183863Snwhitehorn 27294765Simp#include "paths.h" 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 *); 57332154Skevansstatic int dskread(void *, uint64_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 79183863Snwhitehorn/* 80183863Snwhitehorn * Open Firmware interface functions 81183863Snwhitehorn */ 82332154Skevanstypedef uint32_t ofwcell_t; 83332154Skevanstypedef uint32_t u_ofwh_t; 84183863Snwhitehorntypedef int (*ofwfp_t)(void *); 85183863Snwhitehornofwfp_t ofw; /* the prom Open Firmware entry */ 86183863Snwhitehornofwh_t chosenh; 87183863Snwhitehorn 88183863Snwhitehornvoid ofw_init(void *, int, int (*)(void *), char *, int); 89183863Snwhitehornstatic ofwh_t ofw_finddevice(const char *); 90183863Snwhitehornstatic ofwh_t ofw_open(const char *); 91183863Snwhitehornstatic int ofw_close(ofwh_t); 92183863Snwhitehornstatic int ofw_getprop(ofwh_t, const char *, void *, size_t); 93183863Snwhitehornstatic int ofw_setprop(ofwh_t, const char *, void *, size_t); 94183863Snwhitehornstatic int ofw_read(ofwh_t, void *, size_t); 95183863Snwhitehornstatic int ofw_write(ofwh_t, const void *, size_t); 96183863Snwhitehornstatic int ofw_claim(void *virt, size_t len, u_int align); 97332154Skevansstatic int ofw_seek(ofwh_t, uint64_t); 98183863Snwhitehornstatic void ofw_exit(void) __dead2; 99183863Snwhitehorn 100183863Snwhitehornofwh_t bootdevh; 101183863Snwhitehornofwh_t stdinh, stdouth; 102183863Snwhitehorn 103183863Snwhitehorn__asm(" \n\ 104183863Snwhitehorn .data \n\ 105218822Sdim .align 4 \n\ 106183863Snwhitehornstack: \n\ 107183863Snwhitehorn .space 16384 \n\ 108183863Snwhitehorn \n\ 109183863Snwhitehorn .text \n\ 110183863Snwhitehorn .globl _start \n\ 111183863Snwhitehorn_start: \n\ 112183863Snwhitehorn lis %r1,stack@ha \n\ 113183863Snwhitehorn addi %r1,%r1,stack@l \n\ 114183863Snwhitehorn addi %r1,%r1,8192 \n\ 115183863Snwhitehorn \n\ 116183863Snwhitehorn b ofw_init \n\ 117183863Snwhitehorn"); 118183863Snwhitehorn 119183863Snwhitehornvoid 120183863Snwhitehornofw_init(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl) 121183863Snwhitehorn{ 122183863Snwhitehorn char *av[16]; 123183863Snwhitehorn char *p; 124183863Snwhitehorn int ac; 125183863Snwhitehorn 126183863Snwhitehorn ofw = openfirm; 127183863Snwhitehorn 128183863Snwhitehorn chosenh = ofw_finddevice("/chosen"); 129183863Snwhitehorn ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh)); 130183863Snwhitehorn ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth)); 131183863Snwhitehorn ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs)); 132183863Snwhitehorn ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); 133183863Snwhitehorn 134183863Snwhitehorn bootargs[sizeof(bootargs) - 1] = '\0'; 135183863Snwhitehorn bootpath[sizeof(bootpath) - 1] = '\0'; 136183863Snwhitehorn 137183863Snwhitehorn p = bootpath; 138183863Snwhitehorn while (*p != '\0') { 139305249Snwhitehorn /* Truncate partition ID */ 140183863Snwhitehorn if (*p == ':') { 141305249Snwhitehorn ofw_close(bootdev); 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 325332154Skevansofw_seek(ofwh_t devh, uint64_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 399294765Simp 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 423305249Snwhitehorn if (bootpath_full[len-1] != ':') { 424305249Snwhitehorn /* First try full volume */ 425305249Snwhitehorn if (domount(bootpath_full,1) == 0) 426305249Snwhitehorn goto out; 427183863Snwhitehorn 428305249Snwhitehorn /* Add a : so that we try partitions if that fails */ 429305249Snwhitehorn if (bootdev > 0) 430305249Snwhitehorn ofw_close(bootdev); 431305249Snwhitehorn bootpath_full[len] = ':'; 432305249Snwhitehorn len += 1; 433305249Snwhitehorn } 434305249Snwhitehorn 435305249Snwhitehorn /* Loop through first 16 partitions to find a UFS one */ 436305249Snwhitehorn for (i = 0; i < 16; i++) { 437305249Snwhitehorn if (i < 10) { 438305249Snwhitehorn bootpath_full[len] = i + '0'; 439305249Snwhitehorn bootpath_full[len+1] = '\0'; 440305249Snwhitehorn } else { 441305249Snwhitehorn bootpath_full[len] = '1'; 442305249Snwhitehorn bootpath_full[len+1] = i - 10 + '0'; 443305249Snwhitehorn bootpath_full[len+2] = '\0'; 444183863Snwhitehorn } 445305249Snwhitehorn 446305249Snwhitehorn if (domount(bootpath_full,1) >= 0) 447305249Snwhitehorn break; 448183863Snwhitehorn 449305249Snwhitehorn if (bootdev > 0) 450305249Snwhitehorn ofw_close(bootdev); 451183863Snwhitehorn } 452183863Snwhitehorn 453305249Snwhitehorn if (i >= 16) 454305249Snwhitehorn panic("domount"); 455305249Snwhitehorn 456305249Snwhitehornout: 457183863Snwhitehorn printf(" Boot volume: %s\n",bootpath_full); 458183863Snwhitehorn ofw_setprop(chosenh, "bootargs", bootpath_full, len+2); 459183863Snwhitehorn load(path); 460183863Snwhitehorn return (1); 461183863Snwhitehorn} 462183863Snwhitehorn 463183863Snwhitehornstatic void 464183863Snwhitehornusage(void) 465183863Snwhitehorn{ 466183863Snwhitehorn 467183863Snwhitehorn printf("usage: boot device [/path/to/loader]\n"); 468183863Snwhitehorn exit(1); 469183863Snwhitehorn} 470183863Snwhitehorn 471183863Snwhitehornstatic void 472183863Snwhitehornexit(int code) 473183863Snwhitehorn{ 474183863Snwhitehorn 475183863Snwhitehorn ofw_exit(); 476183863Snwhitehorn} 477183863Snwhitehorn 478183863Snwhitehornstatic struct dmadat __dmadat; 479183863Snwhitehorn 480183863Snwhitehornstatic int 481243254Straszdomount(const char *device, int quiet) 482183863Snwhitehorn{ 483183863Snwhitehorn 484183863Snwhitehorn dmadat = &__dmadat; 485183863Snwhitehorn if ((bootdev = ofw_open(device)) == -1) { 486243254Strasz printf("domount: can't open device\n"); 487183863Snwhitehorn return (-1); 488183863Snwhitehorn } 489183863Snwhitehorn if (fsread(0, NULL, 0)) { 490183863Snwhitehorn if (!quiet) 491243254Strasz printf("domount: can't read superblock\n"); 492183863Snwhitehorn return (-1); 493183863Snwhitehorn } 494183863Snwhitehorn return (0); 495183863Snwhitehorn} 496183863Snwhitehorn 497183863Snwhitehornstatic void 498183863Snwhitehornload(const char *fname) 499183863Snwhitehorn{ 500183863Snwhitehorn Elf32_Ehdr eh; 501183863Snwhitehorn Elf32_Phdr ph; 502183863Snwhitehorn caddr_t p; 503235988Sgleb ufs_ino_t ino; 504183863Snwhitehorn int i; 505183863Snwhitehorn 506183863Snwhitehorn if ((ino = lookup(fname)) == 0) { 507183863Snwhitehorn printf("File %s not found\n", fname); 508183863Snwhitehorn return; 509183863Snwhitehorn } 510183863Snwhitehorn if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) { 511183863Snwhitehorn printf("Can't read elf header\n"); 512183863Snwhitehorn return; 513183863Snwhitehorn } 514183863Snwhitehorn if (!IS_ELF(eh)) { 515183863Snwhitehorn printf("Not an ELF file\n"); 516183863Snwhitehorn return; 517183863Snwhitehorn } 518183863Snwhitehorn for (i = 0; i < eh.e_phnum; i++) { 519183863Snwhitehorn fs_off = eh.e_phoff + i * eh.e_phentsize; 520183863Snwhitehorn if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) { 521183863Snwhitehorn printf("Can't read program header %d\n", i); 522183863Snwhitehorn return; 523183863Snwhitehorn } 524183863Snwhitehorn if (ph.p_type != PT_LOAD) 525183863Snwhitehorn continue; 526183863Snwhitehorn fs_off = ph.p_offset; 527183863Snwhitehorn p = (caddr_t)ph.p_vaddr; 528183863Snwhitehorn ofw_claim(p,(ph.p_filesz > ph.p_memsz) ? 529183863Snwhitehorn ph.p_filesz : ph.p_memsz,0); 530183863Snwhitehorn if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) { 531183863Snwhitehorn printf("Can't read content of section %d\n", i); 532183863Snwhitehorn return; 533183863Snwhitehorn } 534183863Snwhitehorn if (ph.p_filesz != ph.p_memsz) 535183863Snwhitehorn bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz); 536231810Snwhitehorn __syncicache(p, ph.p_memsz); 537183863Snwhitehorn } 538183863Snwhitehorn ofw_close(bootdev); 539183863Snwhitehorn (*(void (*)(void *, int, ofwfp_t, char *, int))eh.e_entry)(NULL, 0, 540183863Snwhitehorn ofw,NULL,0); 541183863Snwhitehorn} 542183863Snwhitehorn 543183863Snwhitehornstatic int 544332154Skevansdskread(void *buf, uint64_t lba, int nblk) 545183863Snwhitehorn{ 546183863Snwhitehorn /* 547183863Snwhitehorn * The Open Firmware should open the correct partition for us. 548183863Snwhitehorn * That means, if we read from offset zero on an open instance handle, 549183863Snwhitehorn * we should read from offset zero of that partition. 550183863Snwhitehorn */ 551183863Snwhitehorn ofw_seek(bootdev, lba * DEV_BSIZE); 552183863Snwhitehorn ofw_read(bootdev, buf, nblk * DEV_BSIZE); 553183863Snwhitehorn return (0); 554183863Snwhitehorn} 555183863Snwhitehorn 556183863Snwhitehornstatic void 557183863Snwhitehornpanic(const char *fmt, ...) 558183863Snwhitehorn{ 559183863Snwhitehorn char buf[128]; 560183863Snwhitehorn va_list ap; 561183863Snwhitehorn 562183863Snwhitehorn va_start(ap, fmt); 563183863Snwhitehorn vsnprintf(buf, sizeof buf, fmt, ap); 564183863Snwhitehorn printf("panic: %s\n", buf); 565183863Snwhitehorn va_end(ap); 566183863Snwhitehorn 567183863Snwhitehorn exit(1); 568183863Snwhitehorn} 569183863Snwhitehorn 570183863Snwhitehornstatic int 571183863Snwhitehornprintf(const char *fmt, ...) 572183863Snwhitehorn{ 573183863Snwhitehorn va_list ap; 574183863Snwhitehorn int ret; 575183863Snwhitehorn 576183863Snwhitehorn va_start(ap, fmt); 577183863Snwhitehorn ret = vprintf(fmt, ap); 578183863Snwhitehorn va_end(ap); 579183863Snwhitehorn return (ret); 580183863Snwhitehorn} 581183863Snwhitehorn 582183863Snwhitehornstatic int 583183863Snwhitehornputchar(char c, void *arg) 584183863Snwhitehorn{ 585183863Snwhitehorn char buf; 586183863Snwhitehorn 587183863Snwhitehorn if (c == '\n') { 588183863Snwhitehorn buf = '\r'; 589183863Snwhitehorn ofw_write(stdouth, &buf, 1); 590183863Snwhitehorn } 591183863Snwhitehorn buf = c; 592183863Snwhitehorn ofw_write(stdouth, &buf, 1); 593183863Snwhitehorn return (1); 594183863Snwhitehorn} 595183863Snwhitehorn 596183863Snwhitehornstatic int 597183863Snwhitehornvprintf(const char *fmt, va_list ap) 598183863Snwhitehorn{ 599183863Snwhitehorn int ret; 600183863Snwhitehorn 601183863Snwhitehorn ret = __printf(fmt, putchar, 0, ap); 602183863Snwhitehorn return (ret); 603183863Snwhitehorn} 604183863Snwhitehorn 605183863Snwhitehornstatic int 606183863Snwhitehornvsnprintf(char *str, size_t sz, const char *fmt, va_list ap) 607183863Snwhitehorn{ 608183863Snwhitehorn struct sp_data sp; 609183863Snwhitehorn int ret; 610183863Snwhitehorn 611183863Snwhitehorn sp.sp_buf = str; 612183863Snwhitehorn sp.sp_len = 0; 613183863Snwhitehorn sp.sp_size = sz; 614183863Snwhitehorn ret = __printf(fmt, __sputc, &sp, ap); 615183863Snwhitehorn return (ret); 616183863Snwhitehorn} 617183863Snwhitehorn 618183863Snwhitehornstatic int 619183863Snwhitehorn__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) 620183863Snwhitehorn{ 621183863Snwhitehorn char buf[(sizeof(long) * 8) + 1]; 622183863Snwhitehorn char *nbuf; 623183863Snwhitehorn u_long ul; 624183863Snwhitehorn u_int ui; 625183863Snwhitehorn int lflag; 626183863Snwhitehorn int sflag; 627183863Snwhitehorn char *s; 628183863Snwhitehorn int pad; 629183863Snwhitehorn int ret; 630183863Snwhitehorn int c; 631183863Snwhitehorn 632183863Snwhitehorn nbuf = &buf[sizeof buf - 1]; 633183863Snwhitehorn ret = 0; 634183863Snwhitehorn while ((c = *fmt++) != 0) { 635183863Snwhitehorn if (c != '%') { 636183863Snwhitehorn ret += putc(c, arg); 637183863Snwhitehorn continue; 638183863Snwhitehorn } 639183863Snwhitehorn lflag = 0; 640183863Snwhitehorn sflag = 0; 641183863Snwhitehorn pad = 0; 642183863Snwhitehornreswitch: c = *fmt++; 643183863Snwhitehorn switch (c) { 644183863Snwhitehorn case '#': 645183863Snwhitehorn sflag = 1; 646183863Snwhitehorn goto reswitch; 647183863Snwhitehorn case '%': 648183863Snwhitehorn ret += putc('%', arg); 649183863Snwhitehorn break; 650183863Snwhitehorn case 'c': 651183863Snwhitehorn c = va_arg(ap, int); 652183863Snwhitehorn ret += putc(c, arg); 653183863Snwhitehorn break; 654183863Snwhitehorn case 'd': 655183863Snwhitehorn if (lflag == 0) { 656183863Snwhitehorn ui = (u_int)va_arg(ap, int); 657183863Snwhitehorn if (ui < (int)ui) { 658183863Snwhitehorn ui = -ui; 659183863Snwhitehorn ret += putc('-', arg); 660183863Snwhitehorn } 661183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 662183863Snwhitehorn } else { 663183863Snwhitehorn ul = (u_long)va_arg(ap, long); 664183863Snwhitehorn if (ul < (long)ul) { 665183863Snwhitehorn ul = -ul; 666183863Snwhitehorn ret += putc('-', arg); 667183863Snwhitehorn } 668183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 669183863Snwhitehorn } 670183863Snwhitehorn ret += __puts(s, putc, arg); 671183863Snwhitehorn break; 672183863Snwhitehorn case 'l': 673183863Snwhitehorn lflag = 1; 674183863Snwhitehorn goto reswitch; 675183863Snwhitehorn case 'o': 676183863Snwhitehorn if (lflag == 0) { 677183863Snwhitehorn ui = (u_int)va_arg(ap, u_int); 678183863Snwhitehorn s = __uitoa(nbuf, ui, 8); 679183863Snwhitehorn } else { 680183863Snwhitehorn ul = (u_long)va_arg(ap, u_long); 681183863Snwhitehorn s = __ultoa(nbuf, ul, 8); 682183863Snwhitehorn } 683183863Snwhitehorn ret += __puts(s, putc, arg); 684183863Snwhitehorn break; 685183863Snwhitehorn case 'p': 686183863Snwhitehorn ul = (u_long)va_arg(ap, void *); 687183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 688183863Snwhitehorn ret += __puts("0x", putc, arg); 689183863Snwhitehorn ret += __puts(s, putc, arg); 690183863Snwhitehorn break; 691183863Snwhitehorn case 's': 692183863Snwhitehorn s = va_arg(ap, char *); 693183863Snwhitehorn ret += __puts(s, putc, arg); 694183863Snwhitehorn break; 695183863Snwhitehorn case 'u': 696183863Snwhitehorn if (lflag == 0) { 697183863Snwhitehorn ui = va_arg(ap, u_int); 698183863Snwhitehorn s = __uitoa(nbuf, ui, 10); 699183863Snwhitehorn } else { 700183863Snwhitehorn ul = va_arg(ap, u_long); 701183863Snwhitehorn s = __ultoa(nbuf, ul, 10); 702183863Snwhitehorn } 703183863Snwhitehorn ret += __puts(s, putc, arg); 704183863Snwhitehorn break; 705183863Snwhitehorn case 'x': 706183863Snwhitehorn if (lflag == 0) { 707183863Snwhitehorn ui = va_arg(ap, u_int); 708183863Snwhitehorn s = __uitoa(nbuf, ui, 16); 709183863Snwhitehorn } else { 710183863Snwhitehorn ul = va_arg(ap, u_long); 711183863Snwhitehorn s = __ultoa(nbuf, ul, 16); 712183863Snwhitehorn } 713183863Snwhitehorn if (sflag) 714183863Snwhitehorn ret += __puts("0x", putc, arg); 715183863Snwhitehorn ret += __puts(s, putc, arg); 716183863Snwhitehorn break; 717183863Snwhitehorn case '0': case '1': case '2': case '3': case '4': 718183863Snwhitehorn case '5': case '6': case '7': case '8': case '9': 719183863Snwhitehorn pad = pad * 10 + c - '0'; 720183863Snwhitehorn goto reswitch; 721183863Snwhitehorn default: 722183863Snwhitehorn break; 723183863Snwhitehorn } 724183863Snwhitehorn } 725183863Snwhitehorn return (ret); 726183863Snwhitehorn} 727183863Snwhitehorn 728183863Snwhitehornstatic int 729183863Snwhitehorn__sputc(char c, void *arg) 730183863Snwhitehorn{ 731183863Snwhitehorn struct sp_data *sp; 732183863Snwhitehorn 733183863Snwhitehorn sp = arg; 734183863Snwhitehorn if (sp->sp_len < sp->sp_size) 735183863Snwhitehorn sp->sp_buf[sp->sp_len++] = c; 736183863Snwhitehorn sp->sp_buf[sp->sp_len] = '\0'; 737183863Snwhitehorn return (1); 738183863Snwhitehorn} 739183863Snwhitehorn 740183863Snwhitehornstatic int 741183863Snwhitehorn__puts(const char *s, putc_func_t *putc, void *arg) 742183863Snwhitehorn{ 743183863Snwhitehorn const char *p; 744183863Snwhitehorn int ret; 745183863Snwhitehorn 746183863Snwhitehorn ret = 0; 747183863Snwhitehorn for (p = s; *p != '\0'; p++) 748183863Snwhitehorn ret += putc(*p, arg); 749183863Snwhitehorn return (ret); 750183863Snwhitehorn} 751183863Snwhitehorn 752183863Snwhitehornstatic char * 753183863Snwhitehorn__uitoa(char *buf, u_int ui, int base) 754183863Snwhitehorn{ 755183863Snwhitehorn char *p; 756183863Snwhitehorn 757183863Snwhitehorn p = buf; 758183863Snwhitehorn *p = '\0'; 759183863Snwhitehorn do 760183863Snwhitehorn *--p = digits[ui % base]; 761183863Snwhitehorn while ((ui /= base) != 0); 762183863Snwhitehorn return (p); 763183863Snwhitehorn} 764183863Snwhitehorn 765183863Snwhitehornstatic char * 766183863Snwhitehorn__ultoa(char *buf, u_long ul, int base) 767183863Snwhitehorn{ 768183863Snwhitehorn char *p; 769183863Snwhitehorn 770183863Snwhitehorn p = buf; 771183863Snwhitehorn *p = '\0'; 772183863Snwhitehorn do 773183863Snwhitehorn *--p = digits[ul % base]; 774183863Snwhitehorn while ((ul /= base) != 0); 775183863Snwhitehorn return (p); 776183863Snwhitehorn} 777