xref: /netbsd-src/usr.sbin/eeprom/main.c (revision 9573504567626934c7ee01c7dce0c4bb1dfe7403)
1 /*	$NetBSD: main.c,v 1.1 1995/07/13 18:15:44 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1995 Jason R. Thorpe.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed for the NetBSD Project
18  *	by Jason R. Thorpe.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/param.h>
36 #include <err.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <unistd.h>
40 
41 #ifdef __sparc__
42 #include <fcntl.h>
43 #include <kvm.h>
44 #include <limits.h>
45 #include <nlist.h>
46 
47 #include <machine/openpromio.h>
48 
49 struct	nlist nl[] = {
50 	{ "_cputyp" },
51 #define SYM_CPUTYP	0
52 	{ NULL },
53 };
54 
55 static	char *system = NULL;
56 #endif /* __sparc__ */
57 
58 #include <machine/eeprom.h>
59 
60 #include "defs.h"
61 
62 struct	keytabent eekeytab[] = {
63 	{ "hwupdate",		0x10,	ee_hwupdate },
64 	{ "memsize",		0x14,	ee_num8 },
65 	{ "memtest",		0x15,	ee_num8 },
66 	{ "scrsize",		0x16,	ee_screensize },
67 	{ "watchdog_reboot",	0x17,	ee_truefalse },
68 	{ "default_boot",	0x18,	ee_truefalse },
69 	{ "bootdev",		0x19,	ee_bootdev },
70 	{ "kbdtype",		0x1e,	ee_kbdtype },
71 	{ "console",		0x1f,	ee_constype },
72 	{ "keyclick",		0x21,	ee_truefalse },
73 	{ "diagdev",		0x22,	ee_bootdev },
74 	{ "diagpath",		0x28,	ee_diagpath },
75 	{ "columns",		0x50,	ee_num8 },
76 	{ "rows",		0x51,	ee_num8 },
77 	{ "ttya_use_baud",	0x58,	ee_truefalse },
78 	{ "ttya_baud",		0x59,	ee_num16 },
79 	{ "ttya_no_rtsdtr",	0x5b,	ee_truefalse },
80 	{ "ttyb_use_baud",	0x60,	ee_truefalse },
81 	{ "ttyb_baud",		0x61,	ee_num16 },
82 	{ "ttyb_no_rtsdtr",	0x63,	ee_truefalse },
83 	{ "banner",		0x68,	ee_banner },
84 	{ "secure",		0,	ee_notsupp },
85 	{ "bad_login",		0,	ee_notsupp },
86 	{ "password",		0,	ee_notsupp },
87 	{ NULL,			0,	ee_notsupp },
88 };
89 
90 static	void action __P((char *));
91 static	void dump_prom __P((void));
92 static	void usage __P((void));
93 #ifdef __sparc__
94 static	int getcputype __P((void));
95 #endif /* __sparc__ */
96 
97 char	*path_eeprom = "/dev/eeprom";
98 char	*path_openprom = "/dev/openprom";
99 int	fix_checksum = 0;
100 int	ignore_checksum = 0;
101 int	update_checksums = 0;
102 int	cksumfail = 0;
103 u_short	writecount;
104 int	eval = 0;
105 int	use_openprom = 0;
106 int	verbose = 0;
107 
108 extern	char *__progname;
109 
110 int
111 main(argc, argv)
112 	int argc;
113 	char **argv;
114 {
115 	int ch, do_stdin = 0;
116 	char *cp, line[BUFSIZE];
117 #ifdef __sparc__
118 	char *optstring = "-cf:ivN:";
119 #else
120 	char *optstring = "-cf:i";
121 #endif /* __sparc__ */
122 
123 	while ((ch = getopt(argc, argv, optstring)) != -1)
124 		switch (ch) {
125 		case '-':
126 			do_stdin = 1;
127 			break;
128 
129 		case 'c':
130 			fix_checksum = 1;
131 			break;
132 
133 		case 'f':
134 			path_eeprom = path_openprom = optarg;
135 			break;
136 
137 		case 'i':
138 			ignore_checksum = 1;
139 			break;
140 #ifdef __sparc__
141 		case 'v':
142 			verbose = 1;
143 			break;
144 
145 		case 'N':
146 			system = optarg;
147 			break;
148 
149 #endif /* __sparc__ */
150 
151 		case '?':
152 		default:
153 			usage();
154 		}
155 	argc -= optind;
156 	argv += optind;
157 
158 #ifdef __sparc__
159 	if (getcputype() != CPU_SUN4)
160 		use_openprom = 1;
161 #endif /* __sparc__ */
162 
163 	if (use_openprom == 0) {
164 		ee_verifychecksums();
165 		if (fix_checksum || cksumfail)
166 			exit(cksumfail);
167 	}
168 
169 	if (do_stdin) {
170 		while (fgets(line, BUFSIZE, stdin) != NULL) {
171 			if (line[0] == '\n')
172 				continue;
173 			if ((cp = strrchr(line, '\n')) != NULL)
174 				*cp = '\0';
175 			action(line);
176 		}
177 		if (ferror(stdin))
178 			err(++eval, "stdin");
179 	} else {
180 		if (argc == 0) {
181 			dump_prom();
182 			exit(eval + cksumfail);
183 		}
184 
185 		while (argc) {
186 			action(argv[argc - 1]);
187 			++argv;
188 			--argc;
189 		}
190 	}
191 
192 	if (use_openprom == 0)
193 		if (update_checksums) {
194 			++writecount;
195 			ee_updatechecksums();
196 		}
197 
198 	exit(eval + cksumfail);
199 }
200 
201 #ifdef __sparc__
202 #define KVM_ABORT(kd, str) {						\
203 	(void)kvm_close((kd));						\
204 	errx(1, "%s: %s", (str), kvm_geterr((kd)));			\
205 }
206 
207 static int
208 getcputype()
209 {
210 	char errbuf[_POSIX2_LINE_MAX];
211 	int cputype;
212 	kvm_t *kd;
213 
214 	bzero(errbuf, sizeof(errbuf));
215 
216 	if ((kd = kvm_openfiles(system, NULL, NULL, O_RDONLY, errbuf)) == NULL)
217 		errx(1, "can't open kvm: %s", errbuf);
218 
219 	if (kvm_nlist(kd, nl))
220 		KVM_ABORT(kd, "can't read symbol table");
221 
222 	if (kvm_read(kd, nl[SYM_CPUTYP].n_value, (char *)&cputype,
223 	    sizeof(cputype)) != sizeof(cputype))
224 		KVM_ABORT(kd, "can't determine cpu type");
225 
226 	(void)kvm_close(kd);
227 	return (cputype);
228 }
229 #endif /* __sparc__ */
230 
231 /*
232  * Separate the keyword from the argument (if any), find the keyword in
233  * the table, and call the corresponding handler function.
234  */
235 static void
236 action(line)
237 	char *line;
238 {
239 	char *keyword, *arg, *cp;
240 	struct keytabent *ktent;
241 
242 	keyword = strdup(line);
243 	if ((arg = strrchr(keyword, '=')) != NULL)
244 		*arg++ = '\0';
245 
246 #ifdef __sparc__
247 	if (use_openprom) {
248 		/*
249 		 * The whole point of the Openprom is that one
250 		 * isn't required to know the keywords.  With this
251 		 * in mind, we just dump the whole thing off to
252 		 * the generic op_handler.
253 		 */
254 		if ((cp = op_handler(keyword, arg)) != NULL)
255 			warnx(cp);
256 		return;
257 	} else
258 #endif /* __sparc__ */
259 		for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) {
260 			if (strcmp(ktent->kt_keyword, keyword) == 0) {
261 				(*ktent->kt_handler)(ktent, arg);
262 				return;
263 			}
264 		}
265 
266 	warnx("unknown keyword %s", keyword);
267 	++eval;
268 }
269 
270 /*
271  * Dump the contents of the prom corresponding to all known keywords.
272  */
273 static void
274 dump_prom()
275 {
276 	struct keytabent *ktent;
277 
278 #ifdef __sparc__
279 	if (use_openprom) {
280 		/*
281 		 * We have a special dump routine for this.
282 		 */
283 		op_dump();
284 	} else
285 #endif /* __sparc__ */
286 		for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent)
287 			(*ktent->kt_handler)(ktent, NULL);
288 }
289 
290 static void
291 usage()
292 {
293 
294 #ifdef __sparc__
295 	fprintf(stderr, "usage: %s %s %s\n", __progname,
296 	    "[-] [-c] [-f device] [-i] [-v]",
297 	    "[-N system] [field[=value] ...]");
298 #else
299 	fprintf(stderr, "usage: %s %s\n", __progname,
300 	    "[-] [-c] [-f device] [-i] [field[=value] ...]");
301 #endif /* __sparc__ */
302 	exit(1);
303 }
304