mem.c revision 1.4 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