1 /* $NetBSD: mem.c,v 1.4 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 40 #include <lib/libsa/stand.h> 41 #include <lib/libkern/libkern.h> 42 43 #include <machine/param.h> 44 #include <machine/bfs.h> 45 46 #include "local.h" 47 #include "cmd.h" 48 49 /* 50 * Dump 350 GA-ROM 51 * >> mem g 0xf7e00000 4 4 0x8000 garom.bin 52 */ 53 54 void mem_write(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); 55 void mem_read(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); 56 bool __ga_rom; 57 58 int 59 cmd_mem(int argc, char *argp[], int interactive) 60 { 61 const char *filename = 0; 62 struct bfs *bfs; 63 uint32_t a[4], v; 64 int i, c; 65 size_t size; 66 void *p; 67 68 if (argc < 6) 69 goto error; 70 71 for (i = 0; i < 4; i++) 72 a[i] = strtoul(argp[2 + i], 0, 0); 73 c = *argp[1]; 74 75 if (c == 'g') { 76 size = a[3]; /* GA-ROM special */ 77 __ga_rom = true; 78 } else { 79 size = a[1] * a[3]; 80 __ga_rom = false; 81 } 82 83 p = 0; 84 if ((c == 'd') || (c == 'b') || (c == 'g')) { 85 if (argc < 7) 86 goto error; 87 filename = argp[6]; 88 if (strlen(filename) > BFS_FILENAME_MAXLEN) { 89 printf("too long filename. (max %d)\n", 90 BFS_FILENAME_MAXLEN); 91 return 1; 92 } 93 if ((p = alloc(size)) == 0) { 94 printf("can't allocate buffer.\n"); 95 return 1; 96 } 97 98 if (bfs_init(&bfs) != 0) { 99 printf("no BFS partition.\n"); 100 dealloc(p, size); 101 return 1; 102 } 103 } 104 105 switch (c) { 106 default: 107 goto error; 108 case 'r': 109 mem_read(a[0], a[1], a[2], a[3], 0); 110 break; 111 112 case 'w': 113 if (argc < 7) 114 goto error; 115 v = strtoul(argp[6], 0, 0); 116 mem_write(a[0], a[1], a[2], a[3], (uint32_t)&v); 117 break; 118 119 case 'd': 120 mem_read(a[0], a[1], a[2], a[3], (uint32_t)p); 121 if (bfs_file_write(bfs, filename, p, size) != 0) 122 printf("BFS write failed.\n"); 123 bfs_fini(bfs); 124 break; 125 126 case 'b': 127 if (bfs_file_read(bfs, filename, p, size, 0) != 0) 128 printf("BFS read failed.\n"); 129 else 130 mem_write(a[0], a[1], a[2], a[3], (uint32_t)p); 131 bfs_fini(bfs); 132 break; 133 134 case 'g': /* GA-ROM special */ 135 mem_read(a[0], a[1], a[2], a[3], (uint32_t)p); 136 if (bfs_file_write(bfs, filename, p, size) != 0) 137 printf("BFS write failed.\n"); 138 bfs_fini(bfs); 139 break; 140 141 } 142 143 return 0; 144 error: 145 printf("mem r addr access_byte stride count\n"); 146 printf("mem w addr access_byte stride count value\n"); 147 printf("mem d addr access_byte stride count filename\n"); 148 printf("mem b addr access_byte stride count filename\n"); 149 printf("mem g addr access_byte stride count filename (GA-ROM only)\n"); 150 return 1; 151 } 152 153 void 154 mem_write(uint32_t dst_addr, uint32_t access, uint32_t stride, 155 uint32_t count, uint32_t src_addr) 156 { 157 int i; 158 159 printf("write: addr=%p access=%dbyte stride=%dbyte count=%d Y/N?", 160 (void *)dst_addr, access, stride, count); 161 162 if (!prompt_yesno(1)) 163 return; 164 165 switch (access) { 166 default: 167 printf("invalid %dbyte access.\n", access); 168 break; 169 case 1: 170 if (count == 1) 171 printf("%p = 0x%x\n", 172 (uint8_t *)dst_addr, *(uint8_t *)src_addr); 173 for (i = 0; i < count; i++, 174 dst_addr += stride, src_addr += stride) { 175 *(uint8_t *)dst_addr = *(uint8_t *)src_addr; 176 } 177 case 2: 178 if (count == 1) 179 printf("%p = 0x%x\n", 180 (uint16_t *)dst_addr, *(uint16_t *)src_addr); 181 for (i = 0; i < count; i++, 182 dst_addr += stride, src_addr += stride) { 183 *(uint16_t *)dst_addr = *(uint16_t *)src_addr; 184 } 185 case 4: 186 if (count == 1) 187 printf("%p = 0x%x\n", 188 (uint32_t *)dst_addr, *(uint32_t *)src_addr); 189 for (i = 0; i < count; i++, 190 dst_addr += stride, src_addr += stride) { 191 *(uint32_t *)dst_addr = *(uint32_t *)src_addr; 192 } 193 } 194 } 195 196 void 197 mem_read(uint32_t src_addr, uint32_t access, uint32_t stride, 198 uint32_t count, uint32_t dst_addr) 199 { 200 uint32_t v = 0; 201 int i; 202 203 printf("read: addr=%p access=%dbyte stride=%dbyte count=%d. Y/N?\n", 204 (void *)src_addr, access, stride, count); 205 206 if (!prompt_yesno(1)) 207 return; 208 209 if (dst_addr == 0) { 210 for (i = 0; i < count; i++) { 211 switch (access) { 212 default: 213 printf("invalid %dbyte access.\n", access); 214 break; 215 case 1: 216 v = *(uint8_t *)src_addr; 217 break; 218 case 2: 219 v = *(uint16_t *)src_addr; 220 break; 221 case 4: 222 v = *(uint32_t *)src_addr; 223 break; 224 } 225 printf("%p: > 0x%x\n", (void *)src_addr, v); 226 src_addr += stride; 227 } 228 } else { 229 switch (access) { 230 default: 231 printf("invalid %dbyte access.\n", access); 232 break; 233 case 1: 234 for (i = 0; i < count; i++, 235 src_addr += stride, dst_addr += stride) 236 *(uint8_t *)dst_addr = *(uint8_t *)src_addr; 237 break; 238 case 2: 239 for (i = 0; i < count; i++, 240 src_addr += stride, dst_addr += stride) 241 *(uint16_t *)dst_addr = *(uint16_t *)src_addr; 242 break; 243 case 4: 244 if (__ga_rom) { 245 for (i = 0; i < count; i++, 246 src_addr += 4, dst_addr += 1) 247 *(uint8_t *)dst_addr = 248 *(uint32_t *)src_addr; 249 } else { 250 for (i = 0; i < count; i++, 251 src_addr += stride, dst_addr += stride) 252 *(uint32_t *)dst_addr = 253 *(uint32_t *)src_addr; 254 } 255 break; 256 } 257 } 258 printf("done.\n"); 259 } 260