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