Sync usage with man page.
[netbsd-mini2440.git] / usr.sbin / memswitch / memswitch.c
blob30ab56eb0626abe573e6c4a7cf51ba4efd92e63d
1 /* $NetBSD: memswitch.c,v 1.9 2005/06/11 18:42:56 he Exp $ */
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Minoura Makoto.
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.
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.
32 /* memswitch.c */
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <err.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <errno.h>
42 #include <sys/ioctl.h>
44 #ifndef DEBUG
45 #include <machine/sram.h>
46 #else
48 * DEBUG -- works on other (faster) platforms;
49 * store in a regular file instead of actual non-volatile static RAM.
51 #define PATH_RAMFILE "/tmp/sramfile"
52 #endif
54 #include "memswitch.h"
56 char *progname;
57 int nflag = 0;
58 u_int8_t *current_values = 0;
59 u_int8_t *modified_values = 0;
61 int main __P((int, char*[]));
63 void
64 usage(void)
66 fprintf (stderr, "usage: %s -a\n", progname);
67 fprintf (stderr, " %s [-h] variable ...\n", progname);
68 fprintf (stderr, " %s -w variable=value ...\n", progname);
69 fprintf (stderr, " %s [-rs] filename\n", progname);
70 exit(1);
73 int
74 main(argc, argv)
75 int argc;
76 char *argv[];
78 int ch;
79 enum md {
80 MD_NONE, MD_WRITE, MD_HELP, MD_SHOWALL, MD_SAVE, MD_RESTORE
81 } mode = MD_NONE;
83 progname = argv[0];
85 while ((ch = getopt(argc, argv, "whanrs")) != -1) {
86 switch (ch) {
87 case 'w': /* write */
88 mode = MD_WRITE;
89 break;
90 case 'h':
91 mode = MD_HELP;
92 break;
93 case 'a':
94 mode = MD_SHOWALL;
95 break;
96 case 'n':
97 nflag = 1;
98 break;
99 case 's':
100 mode = MD_SAVE;
101 break;
102 case 'r':
103 mode = MD_RESTORE;
104 break;
107 argc -= optind;
108 argv += optind;
110 switch (mode) {
111 case MD_NONE:
112 if (argc == 0)
113 usage();
114 while (argv[0]) {
115 show_single (argv[0]);
116 argv++;
118 break;
119 case MD_SHOWALL:
120 if (argc)
121 usage();
122 show_all();
123 break;
124 case MD_WRITE:
125 if (argc == 0)
126 usage();
127 while (argv[0]) {
128 modify_single (argv[0]);
129 argv++;
131 flush ();
132 break;
133 case MD_HELP:
134 if (argc == 0)
135 usage();
136 while (argv[0]) {
137 help_single (argv[0]);
138 argv++;
140 break;
141 case MD_SAVE:
142 if (argc != 1)
143 usage();
144 save(argv[0]);
145 break;
146 case MD_RESTORE:
147 if (argc != 1)
148 usage();
149 restore(argv[0]);
150 break;
154 return 0;
157 void
158 show_single(name)
159 const char *name;
161 int i;
162 int n = 0;
163 char fullname[50];
164 char valuestr[MAXVALUELEN];
166 for (i = 0; i < number_of_props; i++) {
167 snprintf(fullname, sizeof(fullname), "%s.%s",
168 properties[i].class, properties[i].node);
169 if (strcmp(name, fullname) == 0 || strcmp(name, properties[i].class) == 0) {
170 properties[i].print (&properties[i], valuestr);
171 if (!nflag)
172 printf ("%s=%s\n", fullname, valuestr);
173 n++;
176 if (n == 0) {
177 errx (1, "No such %s: %s", strstr(name, ".")?"property":"class", name);
180 return;
183 void
184 show_all(void)
186 int i;
187 char valuestr[MAXVALUELEN];
189 for (i = 0; i < number_of_props; i++) {
190 properties[i].print (&properties[i], valuestr);
191 if (!nflag)
192 printf ("%s.%s=",
193 properties[i].class, properties[i].node);
194 printf ("%s\n", valuestr);
197 return;
200 void
201 modify_single(expr)
202 const char *expr;
204 int i, l, n;
205 char *class = NULL, *node = NULL;
206 const char *value;
207 char valuestr[MAXVALUELEN];
209 l = 0;
210 n = strlen(expr);
211 for (i = 0; i < n; i++) {
212 if (expr[i] == '.') {
213 l = i + 1;
214 class = alloca(l);
215 if (class == 0)
216 err (1, "alloca");
217 strncpy (class, expr, i);
218 class[i] = 0;
219 break;
222 if (i >= n)
223 errx (1, "Invalid expression: %s", expr);
225 for ( ; i < n; i++) {
226 if (expr[i] == '=') {
227 node = alloca(i - l + 1);
228 if (node == 0)
229 err (1, "alloca");
230 strncpy (node, &(expr[l]), i - l);
231 node[i - l] = 0;
232 break;
235 if (i >= n)
236 errx (1, "Invalid expression: %s", expr);
238 value = &(expr[++i]);
240 for (i = 0; i < number_of_props; i++) {
241 if (strcmp(properties[i].class, class) == 0 &&
242 strcmp(properties[i].node, node) == 0) {
243 if (properties[i].parse(&properties[i], value) < 0) {
244 /* error: do nothing */
245 } else {
246 properties[i].print (&properties[i], valuestr);
247 printf("%s.%s -> %s\n", class, node, valuestr);
249 break;
252 if (i >= number_of_props) {
253 errx (1, "No such property: %s.%s", class, node);
256 return;
259 void
260 help_single(name)
261 const char *name;
263 int i;
264 char fullname[50];
265 char valuestr[MAXVALUELEN];
267 for (i = 0; i < number_of_props; i++) {
268 snprintf(fullname, sizeof(fullname), "%s.%s",
269 properties[i].class, properties[i].node);
270 if (strcmp(name, fullname) == 0) {
271 properties[i].print (&properties[i], valuestr);
272 if (!nflag)
273 printf ("%s=", fullname);
274 printf ("%s\n", valuestr);
275 printf ("%s", properties[i].descr);
276 break;
279 if (i >= number_of_props) {
280 errx (1, "No such property: %s", name);
283 return;
286 void
287 alloc_modified_values(void)
289 if (current_values == 0)
290 alloc_current_values();
291 modified_values = malloc (256);
292 if (modified_values == 0)
293 err (1, "malloc");
294 memcpy (modified_values, current_values, 256);
297 void
298 alloc_current_values(void)
300 #ifndef DEBUG
301 int i;
302 int sramfd = 0;
303 struct sram_io buffer;
305 current_values = malloc (256);
306 if (current_values == 0)
307 err (1, "malloc");
309 sramfd = open (_PATH_DEVSRAM, O_RDONLY);
310 if (sramfd < 0)
311 err (1, "Opening %s", _PATH_DEVSRAM);
313 /* Assume SRAM_IO_SIZE = n * 16. */
314 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
315 buffer.offset = i;
316 if (ioctl (sramfd, SIOGSRAM, &buffer) < 0)
317 err (1, "ioctl");
318 memcpy (&current_values[i], buffer.sram, SRAM_IO_SIZE);
321 close (sramfd);
322 #else
323 int i;
324 int fd;
325 struct stat st;
327 current_values = malloc (256);
328 if (current_values == 0)
329 err (1, "malloc");
331 fd = open (PATH_RAMFILE, O_RDONLY);
332 if (fd < 0 && errno == ENOENT) {
333 modified_values = malloc (256);
334 if (modified_values == 0)
335 err (1, NULL);
336 for (i = 0; i < number_of_props; i++) {
337 properties[i].modified_value
338 = properties[i].default_value;
339 properties[i].modified = 1;
340 properties[i].flush (&properties[i]);
343 fd = creat (PATH_RAMFILE, 0666);
344 if (fd < 0)
345 err (1, "Creating %s", PATH_RAMFILE);
346 if (write (fd, modified_values, 256) != 256)
347 err (1, "Writing %s", PATH_RAMFILE);
348 close (fd);
349 free (modified_values);
350 modified_values = 0;
352 fd = open (PATH_RAMFILE, O_RDONLY);
354 if (fd < 0)
355 err (1, "Opening %s", PATH_RAMFILE);
356 if (fstat (fd, &st) < 0)
357 err (1, "fstat");
358 if (st.st_size != 256)
359 errx (1, "PANIC! INVALID RAMFILE");
360 if (read (fd, current_values, 256) != 256)
361 err (1, "reading %s", PATH_RAMFILE);
362 close (fd);
363 #endif
365 properties[PROP_MAGIC1].fill (&properties[PROP_MAGIC1]);
366 properties[PROP_MAGIC2].fill (&properties[PROP_MAGIC2]);
367 if ((properties[PROP_MAGIC1].current_value.longword != MAGIC1) ||
368 (properties[PROP_MAGIC2].current_value.longword != MAGIC2))
369 errx (1, "PANIC! INVALID MAGIC");
372 void
373 flush(void)
375 int i;
376 int sramfd = 0;
377 #ifndef DEBUG
378 struct sram_io buffer;
379 #endif
381 for (i = 0; i < number_of_props; i++) {
382 if (properties[i].modified)
383 properties[i].flush(&properties[i]);
386 if (modified_values == 0)
387 /* Not modified at all. */
388 return;
390 #ifndef DEBUG
391 /* Assume SRAM_IO_SIZE = n * 16. */
392 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
393 if (memcmp (&current_values[i], &modified_values[i],
394 SRAM_IO_SIZE) == 0)
395 continue;
397 if (sramfd == 0) {
398 sramfd = open (_PATH_DEVSRAM, O_RDWR);
399 if (sramfd < 0)
400 err (1, "Opening %s", _PATH_DEVSRAM);
402 buffer.offset = i;
403 memcpy (buffer.sram, &modified_values[i], SRAM_IO_SIZE);
404 if (ioctl (sramfd, SIOPSRAM, &buffer) < 0)
405 err (1, "ioctl");
407 #else
408 sramfd = open (PATH_RAMFILE, O_WRONLY);
409 if (sramfd < 0)
410 err (1, "Opening %s", PATH_RAMFILE);
411 if (write (sramfd, modified_values, 256) != 256)
412 err (1, "Writing %s", PATH_RAMFILE);
413 #endif
415 if (sramfd != 0)
416 close (sramfd);
418 return;
422 save(name)
423 const char *name;
425 #ifndef DEBUG
426 int fd;
428 alloc_current_values ();
430 if (strcmp (name, "-") == 0)
431 fd = 1; /* standard output */
432 else {
433 fd = open (name, O_WRONLY|O_CREAT|O_TRUNC, 0666);
434 if (fd < 0)
435 err (1, "Opening output file");
438 if (write (fd, current_values, 256) != 256)
439 err (1, "Writing output file");
441 if (fd != 1)
442 close (fd);
443 #else
444 fprintf (stderr, "Skipping save...\n");
445 #endif
447 return 0;
451 restore (name)
452 const char *name;
454 #ifndef DEBUG
455 int sramfd, fd, i;
456 struct sram_io buffer;
458 modified_values = malloc (256);
459 if (modified_values == 0)
460 err (1, "Opening %s", _PATH_DEVSRAM);
462 if (strcmp (name, "-") == 0)
463 fd = 0; /* standard input */
464 else {
465 fd = open (name, O_RDONLY);
466 if (fd < 0)
467 err (1, "Opening input file");
470 sramfd = open (_PATH_DEVSRAM, O_RDONLY);
471 if (sramfd < 0)
472 err (1, "Opening %s", _PATH_DEVSRAM);
474 /* Assume SRAM_IO_SIZE = n * 16. */
475 for (i = 0; i < 256; i += SRAM_IO_SIZE) {
476 buffer.offset = i;
477 memcpy (buffer.sram, &modified_values[i], SRAM_IO_SIZE);
478 if (ioctl (sramfd, SIOPSRAM, &buffer) < 0)
479 err (1, "ioctl");
482 close (sramfd);
483 #else
484 fprintf (stderr, "Skipping restore...\n");
485 #endif
487 return 0;