1 /* $NetBSD: bootxx.c,v 1.2 2000/10/12 05:34:29 onoe Exp $ */ 2 3 /*- 4 * Copyright (C) 1999 Tsubai Masanari. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <lib/libkern/libkern.h> 30 #include <lib/libsa/stand.h> 31 #include <machine/apcall.h> 32 #include <machine/romcall.h> 33 34 #define MAXBLOCKNUM 64 35 36 void (*entry_point)() = (void *)0; 37 int block_size = 8192; 38 int block_count = MAXBLOCKNUM; 39 int block_table[MAXBLOCKNUM] = { 0 }; 40 41 #ifdef BOOTXX_DEBUG 42 # define DPRINTF printf 43 #else 44 # define DPRINTF while (0) printf 45 #endif 46 47 char *devs[] = { "sd", "fh", "fd", NULL, NULL, "rd", "st" }; 48 struct apbus_sysinfo *_sip; 49 int apbus = 0; 50 51 void 52 bootxx(a0, a1, a2, a3, a4, a5) 53 u_int a0, a1, a2, a3, a4, a5; 54 { 55 int fd, blk, bs; 56 int ctlr, unit, part, type; 57 int i; 58 int bootdev = a1; 59 char *addr; 60 char devname[32]; 61 62 /* 63 * XXX a3 contains: 64 * maxmem (nws-3xxx) 65 * argv (apbus-based machine) 66 */ 67 if (a3 & 0x80000000) 68 apbus = 1; 69 else 70 apbus = 0; 71 72 printf("NetBSD/newsmips Primary Boot\n"); 73 74 DPRINTF("\n"); 75 DPRINTF("a0 %x\n", a0); 76 DPRINTF("a1 %x\n", a1); 77 DPRINTF("a2 %x (%s)\n", a2, (char *)a2); 78 DPRINTF("a3 %x\n", a3); 79 DPRINTF("a4 %x\n", a4); 80 DPRINTF("a5 %x\n", a5); 81 82 DPRINTF("block_size = %d\n", block_size); 83 DPRINTF("block_count = %d\n", block_count); 84 DPRINTF("entry_point = %x\n", (int)entry_point); 85 86 if (apbus) { 87 strcpy(devname, (char *)a1); 88 fd = apcall_open(devname, 0); 89 } else { 90 /* sd(ctlr, lun, part, bus?, host) */ 91 92 ctlr = BOOTDEV_CTLR(bootdev); 93 unit = BOOTDEV_UNIT(bootdev); 94 part = BOOTDEV_PART(bootdev); 95 type = BOOTDEV_TYPE(bootdev); 96 97 if (devs[type] == NULL) { 98 printf("unknown bootdev (0x%x)\n", bootdev); 99 return; 100 } 101 sprintf(devname, "%s(%d,%d,%d)", devs[type], ctlr, unit, part); 102 103 fd = rom_open(devname, 0); 104 } 105 if (fd == -1) { 106 printf("cannot open %s\n", devname); 107 return; 108 } 109 110 addr = (char *)entry_point; 111 bs = block_size; 112 DPRINTF("reading block:"); 113 for (i = 0; i < block_count; i++) { 114 blk = block_table[i]; 115 116 DPRINTF(" %d", blk); 117 118 if (apbus) { 119 apcall_lseek(fd, blk * 512, 0); 120 apcall_read(fd, addr, bs); 121 } else { 122 rom_lseek(fd, blk * 512, 0); 123 rom_read(fd, addr, bs); 124 } 125 addr += bs; 126 } 127 DPRINTF(" done\n"); 128 if (apbus) 129 apcall_close(fd); 130 else 131 rom_close(fd); 132 133 (*entry_point)(a0, a1, a2, a3, _sip); 134 } 135 136 void 137 putchar(x) 138 int x; 139 { 140 char c = x; 141 142 if (apbus) 143 apcall_write(1, &c, 1); 144 else 145 rom_write(1, &c, 1); 146 } 147