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