1/* $NetBSD: mem.c,v 1.6 2019/01/09 03:28:31 christos 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 33#include <lib/libsa/stand.h> 34#include <lib/libkern/libkern.h> 35 36#include <sys/param.h> 37#include <machine/bfs.h> 38 39#include "local.h" 40#include "cmd.h" 41 42/* 43 * Dump 350 GA-ROM 44 * >> mem g 0xf7e00000 4 4 0x8000 garom.bin 45 */ 46 47void mem_write(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); 48void mem_read(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); 49bool __ga_rom; 50 51int 52cmd_mem(int argc, char *argp[], int interactive) 53{ 54 const char *filename = 0; 55 struct bfs *bfs; 56 uint32_t a[4], v; 57 int i, c; 58 size_t size; 59 void *p; 60 61 if (argc < 6) 62 goto error; 63 64 for (i = 0; i < 4; i++) 65 a[i] = strtoul(argp[2 + i], 0, 0); 66 c = *argp[1]; 67 68 if (c == 'g') { 69 size = a[3]; /* GA-ROM special */ 70 __ga_rom = true; 71 } else { 72 size = a[1] * a[3]; 73 __ga_rom = false; 74 } 75 76 p = 0; 77 if ((c == 'd') || (c == 'b') || (c == 'g')) { 78 if (argc < 7) 79 goto error; 80 filename = argp[6]; 81 if (strlen(filename) > BFS_FILENAME_MAXLEN) { 82 printf("too long filename. (max %d)\n", 83 BFS_FILENAME_MAXLEN); 84 return 1; 85 } 86 if ((p = alloc(size)) == 0) { 87 printf("can't allocate buffer.\n"); 88 return 1; 89 } 90 91 if (bfs_init(&bfs) != 0) { 92 printf("no BFS partition.\n"); 93 dealloc(p, size); 94 return 1; 95 } 96 } 97 98 switch (c) { 99 default: 100 goto error; 101 case 'r': 102 mem_read(a[0], a[1], a[2], a[3], 0); 103 break; 104 105 case 'w': 106 if (argc < 7) 107 goto error; 108 v = strtoul(argp[6], 0, 0); 109 mem_write(a[0], a[1], a[2], a[3], (uint32_t)&v); 110 break; 111 112 case 'd': 113 mem_read(a[0], a[1], a[2], a[3], (uint32_t)p); 114 if (bfs_file_write(bfs, filename, p, size) != 0) 115 printf("BFS write failed.\n"); 116 bfs_fini(bfs); 117 break; 118 119 case 'b': 120 if (bfs_file_read(bfs, filename, p, size, 0) != 0) 121 printf("BFS read failed.\n"); 122 else 123 mem_write(a[0], a[1], a[2], a[3], (uint32_t)p); 124 bfs_fini(bfs); 125 break; 126 127 case 'g': /* GA-ROM special */ 128 mem_read(a[0], a[1], a[2], a[3], (uint32_t)p); 129 if (bfs_file_write(bfs, filename, p, size) != 0) 130 printf("BFS write failed.\n"); 131 bfs_fini(bfs); 132 break; 133 134 } 135 136 return 0; 137 error: 138 printf("mem r addr access_byte stride count\n"); 139 printf("mem w addr access_byte stride count value\n"); 140 printf("mem d addr access_byte stride count filename\n"); 141 printf("mem b addr access_byte stride count filename\n"); 142 printf("mem g addr access_byte stride count filename (GA-ROM only)\n"); 143 return 1; 144} 145 146void 147mem_write(uint32_t dst_addr, uint32_t access, uint32_t stride, 148 uint32_t count, uint32_t src_addr) 149{ 150 int i; 151 152 printf("write: addr=%p access=%dbyte stride=%dbyte count=%d Y/N?", 153 (void *)dst_addr, access, stride, count); 154 155 if (!prompt_yesno(1)) 156 return; 157 158 switch (access) { 159 default: 160 printf("invalid %dbyte access.\n", access); 161 break; 162 case 1: 163 if (count == 1) 164 printf("%p = 0x%x\n", 165 (uint8_t *)dst_addr, *(uint8_t *)src_addr); 166 for (i = 0; i < count; i++, 167 dst_addr += stride, src_addr += stride) { 168 *(uint8_t *)dst_addr = *(uint8_t *)src_addr; 169 } 170 case 2: 171 if (count == 1) 172 printf("%p = 0x%x\n", 173 (uint16_t *)dst_addr, *(uint16_t *)src_addr); 174 for (i = 0; i < count; i++, 175 dst_addr += stride, src_addr += stride) { 176 *(uint16_t *)dst_addr = *(uint16_t *)src_addr; 177 } 178 case 4: 179 if (count == 1) 180 printf("%p = 0x%x\n", 181 (uint32_t *)dst_addr, *(uint32_t *)src_addr); 182 for (i = 0; i < count; i++, 183 dst_addr += stride, src_addr += stride) { 184 *(uint32_t *)dst_addr = *(uint32_t *)src_addr; 185 } 186 } 187} 188 189void 190mem_read(uint32_t src_addr, uint32_t access, uint32_t stride, 191 uint32_t count, uint32_t dst_addr) 192{ 193 uint32_t v = 0; 194 int i; 195 196 printf("read: addr=%p access=%dbyte stride=%dbyte count=%d. Y/N?\n", 197 (void *)src_addr, access, stride, count); 198 199 if (!prompt_yesno(1)) 200 return; 201 202 if (dst_addr == 0) { 203 for (i = 0; i < count; i++) { 204 switch (access) { 205 default: 206 printf("invalid %dbyte access.\n", access); 207 break; 208 case 1: 209 v = *(uint8_t *)src_addr; 210 break; 211 case 2: 212 v = *(uint16_t *)src_addr; 213 break; 214 case 4: 215 v = *(uint32_t *)src_addr; 216 break; 217 } 218 printf("%p: > 0x%x\n", (void *)src_addr, v); 219 src_addr += stride; 220 } 221 } else { 222 switch (access) { 223 default: 224 printf("invalid %dbyte access.\n", access); 225 break; 226 case 1: 227 for (i = 0; i < count; i++, 228 src_addr += stride, dst_addr += stride) 229 *(uint8_t *)dst_addr = *(uint8_t *)src_addr; 230 break; 231 case 2: 232 for (i = 0; i < count; i++, 233 src_addr += stride, dst_addr += stride) 234 *(uint16_t *)dst_addr = *(uint16_t *)src_addr; 235 break; 236 case 4: 237 if (__ga_rom) { 238 for (i = 0; i < count; i++, 239 src_addr += 4, dst_addr += 1) 240 *(uint8_t *)dst_addr = 241 *(uint32_t *)src_addr; 242 } else { 243 for (i = 0; i < count; i++, 244 src_addr += stride, dst_addr += stride) 245 *(uint32_t *)dst_addr = 246 *(uint32_t *)src_addr; 247 } 248 break; 249 } 250 } 251 printf("done.\n"); 252} 253