memswitch.c revision 1.2 1 /* $NetBSD: memswitch.c,v 1.2 1999/06/25 14:27:55 minoura Exp $ */
2
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Minoura Makoto.
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 /* memswitch.c */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <err.h>
45 #include <unistd.h>
46 #include <fcntl.h>
47
48 #include <sys/ioctl.h>
49
50 #include <machine/sram.h>
51
52 #include "memswitch.h"
53
54 char *progname;
55 int nflag = 0;
56 u_int8_t *current_values = 0;
57 u_int8_t *modified_values = 0;
58 int main __P((int, char*[]));
59
60 void
61 usage(void)
62 {
63 fprintf (stderr, "Usage: %s -a\n", progname);
64 fprintf (stderr, " %s [-h] variable ...\n", progname);
65 fprintf (stderr, " %s variable=value ...\n", progname);
66 fprintf (stderr, " %s [-rs] filename\n", progname);
67 exit(1);
68 }
69
70 int
71 main(argc, argv)
72 int argc;
73 char *argv[];
74 {
75 int ch;
76 extern char *optarg;
77 extern int optind;
78 enum md {
79 MD_NONE, MD_WRITE, MD_HELP, MD_SHOWALL, MD_SAVE, MD_RESTORE
80 } mode = MD_NONE;
81
82 progname = argv[0];
83
84 while ((ch = getopt(argc, argv, "whanrs")) != -1) {
85 switch (ch) {
86 case 'w': /* write */
87 mode = MD_WRITE;
88 break;
89 case 'h':
90 mode = MD_HELP;
91 break;
92 case 'a':
93 mode = MD_SHOWALL;
94 break;
95 case 'n':
96 nflag = 1;
97 break;
98 case 's':
99 mode = MD_SAVE;
100 break;
101 case 'r':
102 mode = MD_RESTORE;
103 break;
104 }
105 }
106 argc -= optind;
107 argv += optind;
108
109 switch (mode) {
110 case MD_NONE:
111 if (argc == 0)
112 usage();
113 while (argv[0]) {
114 show_single (argv[0]);
115 argv++;
116 }
117 break;
118 case MD_SHOWALL:
119 if (argc)
120 usage();
121 show_all();
122 break;
123 case MD_WRITE:
124 if (argc == 0)
125 usage();
126 while (argv[0]) {
127 modify_single (argv[0]);
128 argv++;
129 }
130 flush ();
131 break;
132 case MD_HELP:
133 if (argc == 0)
134 usage();
135 while (argv[0]) {
136 help_single (argv[0]);
137 argv++;
138 }
139 break;
140 case MD_SAVE:
141 if (argc != 1)
142 usage();
143 save(argv[0]);
144 break;
145 case MD_RESTORE:
146 if (argc != 1)
147 usage();
148 restore(argv[0]);
149 break;
150
151 }
152
153 return 0;
154 }
155
156 void
157 show_single(name)
158 const char *name;
159 {
160 int i;
161 char fullname[50];
162 char valuestr[MAXVALUELEN];
163
164 for (i = 0; i < number_of_props; i++) {
165 sprintf(fullname, "%s.%s",
166 properties[i].class, properties[i].node);
167 if (strcmp(name, fullname) == 0) {
168 properties[i].print (&properties[i], valuestr);
169 if (!nflag)
170 printf ("%s=%s\n", fullname, valuestr);
171 break;
172 }
173 }
174 if (i >= number_of_props) {
175 errx (1, "No such property: %s\n", name);
176 }
177
178 return;
179 }
180
181 void
182 show_all(void)
183 {
184 int i;
185 char valuestr[MAXVALUELEN];
186
187 for (i = 0; i < number_of_props; i++) {
188 properties[i].print (&properties[i], valuestr);
189 if (!nflag)
190 printf ("%s.%s=",
191 properties[i].class, properties[i].node);
192 printf ("%s\n", valuestr);
193 }
194
195 return;
196 }
197
198 void
199 modify_single(expr)
200 const char *expr;
201 {
202 int i, l, n;
203 char *class, *node;
204 const char *value;
205 char valuestr[MAXVALUELEN];
206
207 l = 0;
208 n = strlen(expr);
209 for (i = 0; i < n; i++) {
210 if (expr[i] == '.') {
211 l = i + 1;
212 class = alloca(l);
213 if (class == 0)
214 err (1, "alloca");
215 strncpy (class, expr, i);
216 class[i] = 0;
217 break;
218 }
219 }
220 if (i >= n)
221 errx (1, "Invalid expression: %s\n", expr);
222
223 for ( ; i < n; i++) {
224 if (expr[i] == '=') {
225 node = alloca(i - l + 1);
226 if (node == 0)
227 err (1, "alloca");
228 strncpy (node, &(expr[l]), i - l);
229 node[i - l] = 0;
230 break;
231 }
232 }
233 if (i >= n)
234 errx (1, "Invalid expression: %s\n", expr);
235
236 value = &(expr[++i]);
237
238 for (i = 0; i < number_of_props; i++) {
239 if (strcmp(properties[i].class, class) == 0 &&
240 strcmp(properties[i].node, node) == 0) {
241 if (properties[i].parse(&properties[i], value) < 0) {
242 /* error: do nothing */
243 } else {
244 properties[i].print (&properties[i], valuestr);
245 printf("%s.%s -> %s\n", class, node, valuestr);
246 }
247 break;
248 }
249 }
250 if (i >= number_of_props) {
251 errx (1, "No such property: %s.%s\n", class, node);
252 }
253
254 return;
255 }
256
257 void
258 help_single(name)
259 const char *name;
260 {
261 int i;
262 char fullname[50];
263 char valuestr[MAXVALUELEN];
264
265 for (i = 0; i < number_of_props; i++) {
266 sprintf(fullname, "%s.%s",
267 properties[i].class, properties[i].node);
268 if (strcmp(name, fullname) == 0) {
269 properties[i].print (&properties[i], valuestr);
270 if (!nflag)
271 printf ("%s=", fullname);
272 printf ("%s\n", valuestr);
273 printf ("%s", properties[i].descr);
274 break;
275 }
276 }
277 if (i >= number_of_props) {
278 errx (1, "No such property: %s\n", name);
279 }
280
281 return;
282 }
283
284 void
285 alloc_modified_values(void)
286 {
287 if (current_values == 0)
288 alloc_current_values();
289 modified_values = malloc (256);
290 if (modified_values == 0)
291 err (1, "malloc");
292 memcpy (modified_values, current_values, 256);
293 }
294
295 void
296 alloc_current_values(void)
297 {
298 int i;
299 int sramfd = 0;
300 struct sram_io buffer;
301
302 current_values = malloc (256);
303 if (current_values == 0)
304 err (1, "malloc");
305
306 sramfd = open (_PATH_DEVSRAM, O_RDONLY);
307 if (sramfd < 0)
308 err (1, "Opening %s", _PATH_DEVSRAM);
309
310 /* Assume SRAM_IO_SIZE = n * 16. */
311 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
312 buffer.offset = i;
313 if (ioctl (sramfd, SIOGSRAM, &buffer) < 0)
314 err (1, "ioctl");
315 memcpy (¤t_values[i], buffer.sram, SRAM_IO_SIZE);
316 }
317
318 close (sramfd);
319
320 properties[PROP_MAGIC1].fill (&properties[PROP_MAGIC1]);
321 properties[PROP_MAGIC2].fill (&properties[PROP_MAGIC2]);
322 if ((properties[PROP_MAGIC1].current_value.longword != MAGIC1) ||
323 (properties[PROP_MAGIC2].current_value.longword != MAGIC2))
324 errx (1, "PANIC! INVALID MAGIC");
325 }
326
327 void
328 flush(void)
329 {
330 int i;
331 int sramfd = 0;
332 struct sram_io buffer;
333
334 for (i = 0; i < number_of_props; i++) {
335 if (properties[i].modified)
336 properties[i].flush(&properties[i]);
337 }
338
339 if (modified_values == 0)
340 /* Not modified at all. */
341 return;
342
343 /* Assume SRAM_IO_SIZE = n * 16. */
344 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
345 if (memcmp (¤t_values[i], &modified_values[i],
346 SRAM_IO_SIZE) == 0)
347 continue;
348
349 if (sramfd == 0) {
350 sramfd = open (_PATH_DEVSRAM, O_RDWR);
351 if (sramfd < 0)
352 err (1, "Opening %s", _PATH_DEVSRAM);
353 }
354 buffer.offset = i;
355 memcpy (buffer.sram, &modified_values[i], SRAM_IO_SIZE);
356 #if 0 /* debug */
357 printf ("Issuing ioctl(%d, SIOPSRAM, {%d, ...}\n",
358 sramfd, buffer.offset);
359 #else
360 if (ioctl (sramfd, SIOPSRAM, &buffer) < 0)
361 err (1, "ioctl");
362 #endif
363 }
364
365 if (sramfd != 0)
366 close (sramfd);
367
368 return;
369 }
370
371 int
372 save(name)
373 const char *name;
374 {
375 int fd;
376
377 alloc_current_values ();
378
379 if (strcmp (name, "-") == 0)
380 fd = 1; /* standard output */
381 else {
382 fd = open (name, O_WRONLY|O_CREAT|O_TRUNC, 0666);
383 if (fd < 0)
384 err (1, "Opening output file");
385 }
386
387 if (write (fd, current_values, 256) != 256)
388 err (1, "Writing output file");
389
390 if (fd != 1)
391 close (fd);
392
393 return 0;
394 }
395
396 int
397 restore (name)
398 const char *name;
399 {
400 int sramfd, fd, i;
401 struct sram_io buffer;
402
403 modified_values = malloc (256);
404 if (modified_values == 0)
405 err (1, "Opening %s", _PATH_DEVSRAM);
406
407 if (strcmp (name, "-") == 0)
408 fd = 0; /* standard input */
409 else {
410 fd = open (name, O_RDONLY);
411 if (fd < 0)
412 err (1, "Opening input file");
413 }
414
415 sramfd = open (_PATH_DEVSRAM, O_RDONLY);
416 if (sramfd < 0)
417 err (1, "Opening %s", _PATH_DEVSRAM);
418
419 /* Assume SRAM_IO_SIZE = n * 16. */
420 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
421 buffer.offset = i;
422 memcpy (buffer.sram, &modified_values[i], SRAM_IO_SIZE);
423 #if 0 /* debug */
424 printf ("Issuing ioctl(%d, SIOPSRAM, {%d, ...}\n",
425 sramfd, buffer.offset);
426 #else
427 if (ioctl (sramfd, SIOPSRAM, &buffer) < 0)
428 err (1, "ioctl");
429 #endif
430 }
431
432 close (sramfd);
433
434 return 0;
435 }
436