xref: /netbsd-src/sys/arch/ews4800mips/stand/common/mem.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
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