1 /* $NetBSD: loader.c,v 1.3 2007/02/22 05:31:54 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <lib/libsa/stand.h> 40 #include <lib/libkern/libkern.h> 41 42 #include <lib/libsa/loadfile.h> 43 44 #include <machine/bootinfo.h> 45 46 #include "console.h" 47 #include "cmd.h" 48 #include "local.h" 49 50 void r4k_pdcache_wbinv_all(uint32_t); 51 void r4k_sdcache_wbinv_all(uint32_t, int); 52 void boot_usage(void); 53 54 int 55 cmd_jump(int argc, char *argp[], int interactive) 56 { 57 uint32_t addr; 58 uint32_t sp; 59 60 if (argc < 2) { 61 printf("jump jump_addr [stack_addr]\n"); 62 return 1; 63 } 64 addr = strtoul(argp[1], 0, 0); 65 if (argc == 3) 66 sp = strtoul(argp[2], 0, 0); 67 else 68 __asm volatile("move %0, $29" : "=r"(sp)); /* current stack */ 69 70 printf("jump to 0x%08x. sp=0x%08x Y/N\n", addr, sp); 71 if (prompt_yesno(interactive)) { 72 __asm volatile( 73 ".set noreorder;" 74 "jalr %0;" 75 "move $29, %1;" 76 ".set reorder" :: "r"(addr), "r"(sp)); 77 /* NOTREACHED */ 78 } else { 79 printf("canceled.\n"); 80 return 1; 81 } 82 83 return 0; 84 } 85 86 int 87 cmd_load_binary(int argc, char *argp[], int interactive) 88 { 89 extern uint8_t kernel_binary[]; 90 extern int kernel_binary_size; 91 extern char start[]; 92 uint8_t *p, *q; 93 int i, j; 94 95 if (argc < 2) { 96 printf("load load_addr\n"); 97 return 1; 98 } 99 100 if (kernel_binary_size == 0) { 101 printf("no kernel image\n"); 102 return 1; 103 } 104 105 q = (uint8_t *)strtoul(argp[1], 0, 0); 106 p = kernel_binary; 107 108 /* check load reagion */ 109 printf("load end=%p loader start=%p\n", 110 q + kernel_binary_size, start); 111 if ((uint32_t)(q + kernel_binary_size) >= (uint32_t)start) { 112 printf("kernel load area is overlapped with loader.\n"); 113 return 1; 114 } 115 116 printf("load kernel to %p %dbytes. Y/N\n", q, kernel_binary_size); 117 if (!prompt_yesno(interactive)) { 118 printf("canceled.\n"); 119 return 1; 120 } 121 122 j = kernel_binary_size / 30; 123 for (i = 0; i < kernel_binary_size; i ++) { 124 *q++ = *p++; 125 if ((i % j) == 0) 126 printf("loading kernel. %d/%dbytes\r", i, 127 kernel_binary_size); 128 } 129 r4k_pdcache_wbinv_all(PD_CACHE_SIZE); 130 r4k_sdcache_wbinv_all(SD_CACHE_SIZE, SD_CACHE_LINESIZE); 131 132 printf("loading kernel. %d/%d\r", i , kernel_binary_size); 133 printf("\ndone.\n"); 134 135 return 0; 136 } 137 138 int 139 cmd_boot_ux(int argc, char *argp[], int interactive) 140 { 141 u_long marks[MARK_MAX]; 142 uint32_t entry; 143 144 marks[MARK_START] = 0; 145 console_cursor(false); 146 if (loadfile("sd0d:iopboot", marks, LOAD_KERNEL) != 0) { 147 printf("load iopboot failed.\n"); 148 return 1; 149 } 150 printf("start=%lx entry=%lx nsym=%lx sym=%lx end=%lx\n", 151 marks[MARK_START], marks[MARK_ENTRY], marks[MARK_NSYM], 152 marks[MARK_SYM], marks[MARK_END]); 153 154 entry = marks[MARK_ENTRY]; 155 printf("jump to iopboot entry.(0x%x) Y/N\n", entry); 156 157 r4k_pdcache_wbinv_all(PD_CACHE_SIZE); 158 r4k_sdcache_wbinv_all(SD_CACHE_SIZE, SD_CACHE_LINESIZE); 159 160 if (prompt_yesno(interactive)) { 161 __asm volatile( 162 ".set noreorder;" 163 "lw $4, %1;" 164 "lw $2, %2;" 165 "lw $3, %3;" 166 "jr %0;" 167 "move $29, %0;" 168 ".set reorder" 169 :: "r"(entry), 170 "m"(ipl_args.a0), 171 "m"(ipl_args.v0), 172 "m"(ipl_args.v1)); 173 /* NOTREACHED */ 174 } 175 console_cursor(true); 176 177 return 0; 178 } 179 180 int 181 cmd_boot(int argc, char *argp[], int interactive) 182 { 183 u_long marks[MARK_MAX]; 184 uint32_t entry; 185 struct bootinfo bi; 186 char *filename; 187 188 if (argc < 2) { 189 boot_usage(); 190 return 1; 191 } else { 192 filename = argp[1]; 193 } 194 195 marks[MARK_START] = 0; 196 console_cursor(false); 197 if (loadfile(filename, marks, LOAD_KERNEL) != 0) { 198 printf("load file failed.\n"); 199 return 1; 200 } 201 printf("start=%lx entry=%lx nsym=%lx sym=%lx end=%lx\n", 202 marks[MARK_START], marks[MARK_ENTRY], marks[MARK_NSYM], 203 marks[MARK_SYM], marks[MARK_END]); 204 205 entry = marks[MARK_ENTRY]; 206 printf("jump to kernel entry.(0x%x)%s\n", entry, 207 interactive ? " Y/N" : ""); 208 209 /* Setup argument */ 210 bi.bi_version = 0x1; 211 bi.bi_size = sizeof bi; 212 bi.bi_nsym = marks[MARK_NSYM]; 213 bi.bi_ssym = (uint8_t *)marks[MARK_SYM]; 214 bi.bi_esym = (uint8_t *)marks[MARK_END]; 215 bi.bi_mainfo = ipl_args.v1; 216 217 r4k_pdcache_wbinv_all(PD_CACHE_SIZE); 218 r4k_sdcache_wbinv_all(SD_CACHE_SIZE, SD_CACHE_LINESIZE); 219 220 if (prompt_yesno(interactive)) { 221 __asm volatile( 222 ".set noreorder;" 223 "lw $4, %1;" 224 "lw $5, %2;" 225 "la $6, %3;" 226 "jr %0;" 227 "move $29, %0;" 228 ".set reorder" 229 :: "r"(entry), "m"(argc), "m"(argp), "m"(bi)); 230 /* NOTREACHED */ 231 } 232 console_cursor(true); 233 234 return 0; 235 } 236 237 void 238 r4k_pdcache_wbinv_all(uint32_t pdcache_size) 239 { 240 uint32_t va = 0x80000000; 241 uint32_t eva = va + pdcache_size; 242 243 while (va < eva) { 244 __asm volatile( 245 ".set noreorder;" 246 ".set mips3;" 247 "cache %1, 0x000(%0); cache %1, 0x010(%0);" 248 "cache %1, 0x020(%0); cache %1, 0x030(%0);" 249 "cache %1, 0x040(%0); cache %1, 0x050(%0);" 250 "cache %1, 0x060(%0); cache %1, 0x070(%0);" 251 "cache %1, 0x080(%0); cache %1, 0x090(%0);" 252 "cache %1, 0x0a0(%0); cache %1, 0x0b0(%0);" 253 "cache %1, 0x0c0(%0); cache %1, 0x0d0(%0);" 254 "cache %1, 0x0e0(%0); cache %1, 0x0f0(%0);" 255 "cache %1, 0x100(%0); cache %1, 0x110(%0);" 256 "cache %1, 0x120(%0); cache %1, 0x130(%0);" 257 "cache %1, 0x140(%0); cache %1, 0x150(%0);" 258 "cache %1, 0x160(%0); cache %1, 0x170(%0);" 259 "cache %1, 0x180(%0); cache %1, 0x190(%0);" 260 "cache %1, 0x1a0(%0); cache %1, 0x1b0(%0);" 261 "cache %1, 0x1c0(%0); cache %1, 0x1d0(%0);" 262 "cache %1, 0x1e0(%0); cache %1, 0x1f0(%0);" 263 ".set reorder" 264 : : "r" (va), "i" (1 |(0 << 2)) : "memory"); 265 va += (32 * 16); 266 } 267 } 268 269 void 270 r4k_sdcache_wbinv_all(uint32_t sdcache_size, int line_size) 271 { 272 uint32_t va = 0x80000000; 273 uint32_t eva = va + sdcache_size; 274 275 while (va < eva) { 276 __asm volatile( 277 ".set noreorder;" 278 ".set mips3;" 279 "cache %1, 0(%0);" 280 ".set reorder" 281 : : "r" (va), "i" (3 |(0 << 2)) : "memory"); 282 va += line_size; 283 } 284 } 285 286 void 287 boot_usage(void) 288 { 289 290 printf("boot dev:filename [argument to kernel]\n"); 291 printf("\tex).\n"); 292 printf("\t Disk 0, Partition 10, /netbsd => sd0k:netbsd\n"); 293 printf("\t NFS, /netbsd => nfs:netbsd\n"); 294 printf("\t `kernel embeded in data section' => mem:\n"); 295 } 296