1 /* $NetBSD: bootxx.c,v 1.5 2002/11/22 16:27:09 tsutsui 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 #include <sys/bootblock.h> 35 36 struct shared_bbinfo bbinfo = { 37 { NEWSMIPS_BBINFO_MAGIC }, /* bbi_magic[] */ 38 0, /* bbi_block_size */ 39 SHARED_BBINFO_MAXBLOCKS, /* bbi_block_count */ 40 { 0 } /* bbi_block_tagle[] */ 41 }; 42 43 #ifndef DEFAULT_ENTRY_POINT 44 #define DEFAULT_ENTRY_POINT 0xa0700000 45 #endif 46 47 void bootxx __P((u_int32_t, u_int32_t, uint32_t, u_int32_t, u_int32_t, 48 u_int32_t)); 49 void (*entry_point) __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *)) = 50 (void *)DEFAULT_ENTRY_POINT; 51 52 #ifdef BOOTXX_DEBUG 53 # define DPRINTF(x) printf x 54 #else 55 # define DPRINTF(x) 56 #endif 57 58 char *devs[] = { "sd", "fh", "fd", NULL, NULL, "rd", "st" }; 59 struct apbus_sysinfo *_sip; 60 int apbus = 0; 61 62 void 63 bootxx(a0, a1, a2, a3, a4, a5) 64 u_int32_t a0, a1, a2, a3, a4, a5; 65 { 66 int fd, blk, bs; 67 int ctlr, unit, part, type; 68 int i; 69 int bootdev = a1; 70 char *addr; 71 char devname[32]; 72 73 /* 74 * XXX a3 contains: 75 * maxmem (nws-3xxx) 76 * argv (apbus-based machine) 77 */ 78 if (a3 & 0x80000000) 79 apbus = 1; 80 else 81 apbus = 0; 82 83 printf("NetBSD/newsmips Primary Boot\n"); 84 85 DPRINTF(("\n")); 86 DPRINTF(("a0 %x\n", a0)); 87 DPRINTF(("a1 %x\n", a1)); 88 DPRINTF(("a2 %x (%s)\n", a2, (char *)a2)); 89 DPRINTF(("a3 %x\n", a3)); 90 DPRINTF(("a4 %x\n", a4)); 91 DPRINTF(("a5 %x\n", a5)); 92 93 DPRINTF(("block_size = %d\n", bbinfo.bbi_block_size)); 94 DPRINTF(("block_count = %d\n", bbinfo.bbi_block_count)); 95 DPRINTF(("entry_point = %p\n", entry_point)); 96 97 if (apbus) { 98 strcpy(devname, (char *)a1); 99 fd = apcall_open(devname, 0); 100 } else { 101 /* sd(ctlr, lun, part, bus?, host) */ 102 103 ctlr = BOOTDEV_CTLR(bootdev); 104 unit = BOOTDEV_UNIT(bootdev); 105 part = BOOTDEV_PART(bootdev); 106 type = BOOTDEV_TYPE(bootdev); 107 108 if (devs[type] == NULL) { 109 printf("unknown bootdev (0x%x)\n", bootdev); 110 return; 111 } 112 sprintf(devname, "%s(%d,%d,%d)", devs[type], ctlr, unit, part); 113 114 fd = rom_open(devname, 0); 115 } 116 if (fd == -1) { 117 printf("cannot open %s\n", devname); 118 return; 119 } 120 121 addr = (char *)entry_point; 122 bs = bbinfo.bbi_block_size; 123 DPRINTF(("reading block:")); 124 for (i = 0; i < bbinfo.bbi_block_count; i++) { 125 blk = bbinfo.bbi_block_table[i]; 126 127 DPRINTF((" %d", blk)); 128 129 if (apbus) { 130 apcall_lseek(fd, blk * 512, 0); 131 apcall_read(fd, addr, bs); 132 } else { 133 rom_lseek(fd, blk * 512, 0); 134 rom_read(fd, addr, bs); 135 } 136 addr += bs; 137 } 138 DPRINTF((" done\n")); 139 if (apbus) 140 apcall_close(fd); 141 else 142 rom_close(fd); 143 144 (*entry_point)(a0, a1, a2, a3, _sip); 145 } 146 147 void 148 putchar(x) 149 int x; 150 { 151 char c = x; 152 153 if (apbus) 154 apcall_write(1, &c, 1); 155 else 156 rom_write(1, &c, 1); 157 } 158