xref: /netbsd-src/usr.sbin/memswitch/methods.c (revision 421949a31fb0942d3d87278998c2d7d432d8b3cb)
1*421949a3Ssevan /*	$NetBSD: methods.c,v 1.8 2018/01/23 21:06:25 sevan Exp $	*/
212769637Sminoura 
312769637Sminoura /*-
412769637Sminoura  * Copyright (c) 1999 The NetBSD Foundation, Inc.
512769637Sminoura  * All rights reserved.
612769637Sminoura  *
712769637Sminoura  * This code is derived from software contributed to The NetBSD Foundation
812769637Sminoura  * by Minoura Makoto.
912769637Sminoura  *
1012769637Sminoura  * Redistribution and use in source and binary forms, with or without
1112769637Sminoura  * modification, are permitted provided that the following conditions
1212769637Sminoura  * are met:
1312769637Sminoura  * 1. Redistributions of source code must retain the above copyright
1412769637Sminoura  *    notice, this list of conditions and the following disclaimer.
1512769637Sminoura  * 2. Redistributions in binary form must reproduce the above copyright
1612769637Sminoura  *    notice, this list of conditions and the following disclaimer in the
1712769637Sminoura  *    documentation and/or other materials provided with the distribution.
1812769637Sminoura  *
1912769637Sminoura  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2012769637Sminoura  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2112769637Sminoura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2212769637Sminoura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2312769637Sminoura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2412769637Sminoura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2512769637Sminoura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2612769637Sminoura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2712769637Sminoura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2812769637Sminoura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2912769637Sminoura  * POSSIBILITY OF SUCH DAMAGE.
3012769637Sminoura  */
3112769637Sminoura 
3212769637Sminoura #include <stdio.h>
3312769637Sminoura #include <string.h>
3412769637Sminoura #include <err.h>
3512769637Sminoura #include <sys/types.h>
3612769637Sminoura 
3712769637Sminoura #include "memswitch.h"
38909e46e9Sminoura #include "methods.h"
3912769637Sminoura 
4012769637Sminoura int
atoi_(const char ** p)41*421949a3Ssevan atoi_(const char **p)
4212769637Sminoura {
43909e46e9Sminoura 	const char *p1 = *p;
4412769637Sminoura 	int v = 0;
4512769637Sminoura 	int first = 1;
4612769637Sminoura 
4712769637Sminoura 	while (*p1 == ' ' || *p1 == '\t')
4812769637Sminoura 		p1++;
4912769637Sminoura 
5012769637Sminoura 	if (*p1 == 0) {
5112769637Sminoura 		*p = 0;
5212769637Sminoura 		return 0;
5312769637Sminoura 	}
5412769637Sminoura 	if (strlen(p1) >= 2 && strncasecmp("0x", p1, 2) == 0) {
5512769637Sminoura 		p1 += 2;
5612769637Sminoura 		while (1) {
5712769637Sminoura 			if (*p1 >= '0' && *p1 <= '9') {
5812769637Sminoura 				v *= 16;
5912769637Sminoura 				v += *p1 - '0';
6012769637Sminoura 				first = 0;
6112769637Sminoura 			} else if (*p1 >= 'A' && *p1 <= 'F') {
6212769637Sminoura 				v *= 16;
6312769637Sminoura 				v += *p1 - 'A' + 10;
6412769637Sminoura 				first = 0;
6512769637Sminoura 			} else if (*p1 >= 'a' && *p1 <= 'f') {
6612769637Sminoura 				v *= 16;
6712769637Sminoura 				v += *p1 - 'a' + 10;
6812769637Sminoura 				first = 0;
6912769637Sminoura 			} else {
7012769637Sminoura 				break;
7112769637Sminoura 			}
7212769637Sminoura 			p1++;
7312769637Sminoura 		}
7412769637Sminoura 	} else {
7512769637Sminoura 		while (1) {
7612769637Sminoura 			if (*p1 >= '0' && *p1 <= '9') {
7712769637Sminoura 				v *= 10;
7812769637Sminoura 				v += *p1 - '0';
7912769637Sminoura 				first = 0;
8012769637Sminoura 			} else {
8112769637Sminoura 				break;
8212769637Sminoura 			}
8312769637Sminoura 			p1++;
8412769637Sminoura 		}
8512769637Sminoura 	}
8612769637Sminoura 
8712769637Sminoura 	if (first) {
8812769637Sminoura 		*p = 0;
8912769637Sminoura 		return 0;
9012769637Sminoura 	}
9112769637Sminoura 
922844bec4Sminoura 	while (*p1 == ' ' || *p1 == '\t') p1++;
9312769637Sminoura 	*p = p1;
9412769637Sminoura 	return v;
9512769637Sminoura }
9612769637Sminoura 
9712769637Sminoura int
fill_uchar(struct property * prop)98*421949a3Ssevan fill_uchar(struct property *prop)
9912769637Sminoura {
10012769637Sminoura 	if (current_values == 0)
10112769637Sminoura 		alloc_current_values();
10212769637Sminoura 
10312769637Sminoura 	prop->current_value.byte[0] = current_values[prop->offset];
10412769637Sminoura 	prop->current_value.byte[1] = 0;
10512769637Sminoura 	prop->current_value.byte[2] = 0;
10612769637Sminoura 	prop->current_value.byte[3] = 0;
10712769637Sminoura 	prop->value_valid = 1;
10812769637Sminoura 
10912769637Sminoura 	return 0;
11012769637Sminoura }
11112769637Sminoura 
11212769637Sminoura int
fill_ushort(struct property * prop)113*421949a3Ssevan fill_ushort(struct property *prop)
11412769637Sminoura {
11512769637Sminoura 	if (current_values == 0)
11612769637Sminoura 		alloc_current_values();
11712769637Sminoura 
11812769637Sminoura 	prop->current_value.byte[0] = current_values[prop->offset];
11912769637Sminoura 	prop->current_value.byte[1] = current_values[prop->offset+1];
12012769637Sminoura 	prop->current_value.byte[2] = 0;
12112769637Sminoura 	prop->current_value.byte[3] = 0;
12212769637Sminoura 	prop->value_valid = 1;
12312769637Sminoura 
12412769637Sminoura 	return 0;
12512769637Sminoura }
12612769637Sminoura 
12712769637Sminoura int
fill_ulong(struct property * prop)128*421949a3Ssevan fill_ulong(struct property *prop)
12912769637Sminoura {
13012769637Sminoura 	if (current_values == 0)
13112769637Sminoura 		alloc_current_values();
13212769637Sminoura 
13312769637Sminoura 	prop->current_value.byte[0] = current_values[prop->offset];
13412769637Sminoura 	prop->current_value.byte[1] = current_values[prop->offset+1];
13512769637Sminoura 	prop->current_value.byte[2] = current_values[prop->offset+2];
13612769637Sminoura 	prop->current_value.byte[3] = current_values[prop->offset+3];
13712769637Sminoura 	prop->value_valid = 1;
13812769637Sminoura 
13912769637Sminoura 	return 0;
14012769637Sminoura }
14112769637Sminoura 
14212769637Sminoura int
flush_uchar(struct property * prop)143*421949a3Ssevan flush_uchar(struct property *prop)
14412769637Sminoura {
14512769637Sminoura 	if (!prop->modified)
14612769637Sminoura 		return 0;
14712769637Sminoura 
14812769637Sminoura 	if (modified_values == 0)
14912769637Sminoura 		alloc_modified_values();
15012769637Sminoura 
15112769637Sminoura 	modified_values[prop->offset] = prop->modified_value.byte[0];
15212769637Sminoura 
15312769637Sminoura 	return 0;
15412769637Sminoura }
15512769637Sminoura 
15612769637Sminoura int
flush_ushort(struct property * prop)157*421949a3Ssevan flush_ushort(struct property *prop)
15812769637Sminoura {
15912769637Sminoura 	if (!prop->modified)
16012769637Sminoura 		return 0;
16112769637Sminoura 
16212769637Sminoura 	if (modified_values == 0)
16312769637Sminoura 		alloc_modified_values();
16412769637Sminoura 
16512769637Sminoura 	modified_values[prop->offset] = prop->modified_value.byte[0];
16612769637Sminoura 	modified_values[prop->offset+1] = prop->modified_value.byte[1];
16712769637Sminoura 
16812769637Sminoura 	return 0;
16912769637Sminoura }
17012769637Sminoura 
17112769637Sminoura int
flush_ulong(struct property * prop)172*421949a3Ssevan flush_ulong(struct property *prop)
17312769637Sminoura {
17412769637Sminoura 	if (!prop->modified)
17512769637Sminoura 		return 0;
17612769637Sminoura 
17712769637Sminoura 	if (modified_values == 0)
17812769637Sminoura 		alloc_modified_values();
17912769637Sminoura 
18012769637Sminoura 	modified_values[prop->offset] = prop->modified_value.byte[0];
18112769637Sminoura 	modified_values[prop->offset+1] = prop->modified_value.byte[1];
18212769637Sminoura 	modified_values[prop->offset+2] = prop->modified_value.byte[2];
18312769637Sminoura 	modified_values[prop->offset+3] = prop->modified_value.byte[3];
18412769637Sminoura 
18512769637Sminoura 	return 0;
18612769637Sminoura }
18712769637Sminoura 
18812769637Sminoura int
flush_dummy(struct property * prop)189*421949a3Ssevan flush_dummy(struct property *prop)
19012769637Sminoura {
19112769637Sminoura 	return 0;
19212769637Sminoura }
19312769637Sminoura 
19412769637Sminoura int
parse_dummy(struct property * prop,const char * value)195*421949a3Ssevan parse_dummy(struct property *prop, const char *value)
19612769637Sminoura {
19712769637Sminoura 	warnx("Cannot modify %s.%s", prop->class, prop->node);
19812769637Sminoura 
19912769637Sminoura 	return -1;
20012769637Sminoura }
20112769637Sminoura 
20212769637Sminoura int
parse_byte(struct property * prop,const char * value)203*421949a3Ssevan parse_byte(struct property *prop, const char *value)
20412769637Sminoura {
20512769637Sminoura 	const char *p = value;
20612769637Sminoura 	int v;
20712769637Sminoura 
20812769637Sminoura 	v = atoi_(&p);
20912769637Sminoura 	if (p == 0) {
21012769637Sminoura 		warnx("%s: Invalid value", value);
21112769637Sminoura 		return -1;
21212769637Sminoura 	}
21312769637Sminoura 
21412769637Sminoura 	if (strcasecmp("MB", p) == 0)
21512769637Sminoura 		v *= 1024 * 1024;
21612769637Sminoura 	else if (strcasecmp("KB", p) == 0)
21712769637Sminoura 		v *= 1024;
21812769637Sminoura 	else if (*p != 0 &&
21912769637Sminoura 		 strcasecmp("B", p) != 0) {
22012769637Sminoura 		warnx("%s: Invalid value", value);
22112769637Sminoura 		return -1;
22212769637Sminoura 	}
22312769637Sminoura 
22412769637Sminoura 	if (v < prop->min) {
22512769637Sminoura 		warnx("%s: Too small", value);
22612769637Sminoura 		return -1;
22712769637Sminoura 	} else if (v > prop->max) {
22812769637Sminoura 		warnx("%s: Too large", value);
22912769637Sminoura 		return -1;
23012769637Sminoura 	}
23112769637Sminoura 
23212769637Sminoura 	prop->modified = 1;
23312769637Sminoura 	prop->modified_value.longword = v;
23412769637Sminoura 
23512769637Sminoura 	return 0;
23612769637Sminoura }
23712769637Sminoura 
23812769637Sminoura int
parse_uchar(struct property * prop,const char * value)239*421949a3Ssevan parse_uchar(struct property *prop, const char *value)
24012769637Sminoura {
24112769637Sminoura 	const char *p = value;
24212769637Sminoura 	int v;
24312769637Sminoura 
24412769637Sminoura 	v = atoi_(&p);
24512769637Sminoura 	if (p == 0) {
24612769637Sminoura 		warnx("%s: Invalid value", value);
24712769637Sminoura 		return -1;
24812769637Sminoura 	}
24912769637Sminoura 
25012769637Sminoura 	if (v < prop->min) {
25112769637Sminoura 		warnx("%s: Too small", value);
25212769637Sminoura 		return -1;
25312769637Sminoura 	} else if (v > prop->max) {
25412769637Sminoura 		warnx("%s: Too large", value);
25512769637Sminoura 		return -1;
25612769637Sminoura 	}
25712769637Sminoura 
25812769637Sminoura 	prop->modified = 1;
25912769637Sminoura 	prop->modified_value.byte[0] = v;
26012769637Sminoura 
26112769637Sminoura 	return 0;
26212769637Sminoura }
26312769637Sminoura 
26412769637Sminoura int
parse_ulong(struct property * prop,const char * value)265*421949a3Ssevan parse_ulong(struct property *prop, const char *value)
26612769637Sminoura {
26712769637Sminoura 	const char *p = value;
26812769637Sminoura 	int v;
26912769637Sminoura 
27012769637Sminoura 	v = atoi_(&p);
27112769637Sminoura 	if (p == 0) {
27212769637Sminoura 		warnx("%s: Invalid value", value);
27312769637Sminoura 		return -1;
27412769637Sminoura 	}
27512769637Sminoura 
27612769637Sminoura 	if (v < prop->min) {
27712769637Sminoura 		warnx("%s: Too small", value);
27812769637Sminoura 		return -1;
27912769637Sminoura 	} else if (v > prop->max) {
28012769637Sminoura 		warnx("%s: Too large", value);
28112769637Sminoura 		return -1;
28212769637Sminoura 	}
28312769637Sminoura 
28412769637Sminoura 	prop->modified = 1;
28512769637Sminoura 	prop->modified_value.longword = v;
28612769637Sminoura 
28712769637Sminoura 	return 0;
28812769637Sminoura }
28912769637Sminoura 
29012769637Sminoura int
parse_ushort(struct property * prop,const char * value)291*421949a3Ssevan parse_ushort(struct property *prop, const char *value)
29212769637Sminoura {
29312769637Sminoura 	const char *p = value;
29412769637Sminoura 	int v;
29512769637Sminoura 
29612769637Sminoura 	v = atoi_(&p);
29712769637Sminoura 	if (p == 0) {
29812769637Sminoura 		warnx("%s: Invalid value", value);
29912769637Sminoura 		return -1;
30012769637Sminoura 	}
30112769637Sminoura 
30212769637Sminoura 	if (v < prop->min) {
30312769637Sminoura 		warnx("%s: Too small", value);
30412769637Sminoura 		return -1;
30512769637Sminoura 	} else if (v > prop->max) {
30612769637Sminoura 		warnx("%s: Too large", value);
30712769637Sminoura 		return -1;
30812769637Sminoura 	}
30912769637Sminoura 
31012769637Sminoura 	prop->modified = 1;
31112769637Sminoura 	prop->modified_value.word[0] = v;
31212769637Sminoura 
31312769637Sminoura 	return 0;
31412769637Sminoura }
31512769637Sminoura 
31612769637Sminoura int
parse_time(struct property * prop,const char * value)317*421949a3Ssevan parse_time(struct property *prop, const char *value)
31812769637Sminoura {
31912769637Sminoura 	const char *p = value;
32012769637Sminoura 	int v;
32112769637Sminoura 
3222844bec4Sminoura 	while (*p == ' ' || *p == '\t') p++;
32312769637Sminoura 	if (*p == '-') {
32412769637Sminoura 		p++;
32512769637Sminoura 		v = -atoi_(&p);
32612769637Sminoura 	} else
32712769637Sminoura 		v = atoi_(&p);
32812769637Sminoura 	if (p == 0) {
32912769637Sminoura 		warnx("%s: Invalid value", value);
33012769637Sminoura 		return -1;
33112769637Sminoura 	}
33212769637Sminoura 
33312769637Sminoura 	if (strcasecmp("hours", p) == 0 || strcasecmp("hour", p) == 0)
33412769637Sminoura 		v *= 60 * 60;
33512769637Sminoura 	else if (strcasecmp("minutes", p) == 0 ||
33612769637Sminoura 		 strcasecmp("minute", p) == 0)
33712769637Sminoura 		v *= 60;
33812769637Sminoura 	else if (*p != 0 &&
33912769637Sminoura 		 strcasecmp("second", p) != 0 &&
34012769637Sminoura 		 strcasecmp("seconds", p) != 0) {
34112769637Sminoura 		warnx("%s: Invalid value", value);
34212769637Sminoura 		return -1;
34312769637Sminoura 	}
34412769637Sminoura 
34512769637Sminoura 	if (v < prop->min) {
34612769637Sminoura 		warnx("%s: Too small", value);
34712769637Sminoura 		return -1;
34812769637Sminoura 	} else if (v > prop->max) {
34912769637Sminoura 		warnx("%s: Too large", value);
35012769637Sminoura 		return -1;
35112769637Sminoura 	}
35212769637Sminoura 
35312769637Sminoura 	prop->modified = 1;
35412769637Sminoura 	prop->modified_value.longword = v;
35512769637Sminoura 
35612769637Sminoura 	return 0;
35712769637Sminoura }
35812769637Sminoura 
35912769637Sminoura int
parse_bootdev(struct property * prop,const char * value)360*421949a3Ssevan parse_bootdev(struct property *prop, const char *value)
36112769637Sminoura {
36212769637Sminoura 	const char *p = value;
36312769637Sminoura 	int v;
364271f6f55Sminoura 	char expr_scsi[32];
36512769637Sminoura 
3662844bec4Sminoura 	while (*p == ' ' || *p == '\t') p++;
36712769637Sminoura 
36812769637Sminoura 	if (strcasecmp("STD", p) == 0)
36912769637Sminoura 		v = 0;
37012769637Sminoura 	else if (strcasecmp("ROM", p) == 0)
37112769637Sminoura 		v = 0xa000;
37212769637Sminoura 	else if (strcasecmp("RAM", p) == 0)
37312769637Sminoura 		v = 0xb000;
37412769637Sminoura 	else if (strncasecmp("HD", p, 2) == 0) {
37512769637Sminoura 		p += 2;
37612769637Sminoura 		v = atoi_(&p);
37712769637Sminoura 		if (p == 0 || v < 0 || v > 15) {
37812769637Sminoura 			warnx("%s: Invalid value", value);
37912769637Sminoura 			return -1;
38012769637Sminoura 		}
38112769637Sminoura 		v *= 0x0100;
38212769637Sminoura 		v += 0x8000;
38312769637Sminoura 	} else if (strncasecmp("FD", p, 2) == 0) {
38412769637Sminoura 		p += 2;
38512769637Sminoura 		v = atoi_(&p);
38612769637Sminoura 		if (p == 0 || v < 0 || v > 3) {
38712769637Sminoura 			warnx("%s: Invalid value", value);
38812769637Sminoura 			return -1;
38912769637Sminoura 		}
39012769637Sminoura 		v *= 0x0100;
39112769637Sminoura 		v += 0x9070;
392271f6f55Sminoura 	} else if (strncasecmp("INSCSI", p, 6) == 0 ||
393271f6f55Sminoura 		   strncasecmp("EXSCSI", p, 6) == 0) {
394271f6f55Sminoura 		int isin = strncasecmp("EXSCSI", p, 6);
395271f6f55Sminoura 
396271f6f55Sminoura 		p += 6;
397271f6f55Sminoura 		v = atoi_(&p);
398271f6f55Sminoura 		if (p == 0 || v < 0 || v > 7) {
399271f6f55Sminoura 			warnx("%s: Invalid value", value);
400271f6f55Sminoura 			return -1;
401271f6f55Sminoura 		}
402271f6f55Sminoura 
403271f6f55Sminoura 		/* change boot.romaddr */
404271f6f55Sminoura 		sprintf(expr_scsi, "boot.romaddr=0x%06x",
405271f6f55Sminoura 			(isin ? 0xfc0000 : 0xea0020) + v * 4);
406271f6f55Sminoura 		modify_single(expr_scsi);
407271f6f55Sminoura 
408271f6f55Sminoura 		/* boot.device again */
409271f6f55Sminoura 		v = 0xa000;
41012769637Sminoura 	} else {
41112769637Sminoura 		warnx("%s: Invalid value", value);
41212769637Sminoura 		return -1;
41312769637Sminoura 	}
41412769637Sminoura 
41512769637Sminoura 	prop->modified = 1;
41612769637Sminoura 	prop->modified_value.word[0] = v;
41712769637Sminoura 
41812769637Sminoura 	return 0;
41912769637Sminoura }
42012769637Sminoura 
42112769637Sminoura int
parse_serial(struct property * prop,const char * value)422*421949a3Ssevan parse_serial(struct property *prop, const char *value)
4232844bec4Sminoura #define NEXTSPEC	while (*p == ' ' || *p == '\t') p++;		\
4242844bec4Sminoura 			if (*p++ != ',') {				\
4252844bec4Sminoura 				warnx("%s: Invalid value", value);	\
4262844bec4Sminoura 				return -1;				\
4272844bec4Sminoura 			}						\
4282844bec4Sminoura 			while (*p == ' ' || *p == '\t') p++;
4292844bec4Sminoura {
4302844bec4Sminoura 	const char *p = value;
4312844bec4Sminoura 	const char *q;
4322844bec4Sminoura 	int baud, bit, parity, stop, flow;
43310bf6fccSyamt 	static const int bauds[] = {75, 150, 300, 600, 1200, 2400, 4800, 9600,
43410bf6fccSyamt 	    17361, 0};
43510bf6fccSyamt 	static const char parities[] = "noe";
4362844bec4Sminoura 	int i;
4372844bec4Sminoura 
4382844bec4Sminoura 	while (*p == ' ' || *p == '\t') p++;
4392844bec4Sminoura 
4402844bec4Sminoura 	/* speed */
4412844bec4Sminoura 	baud = atoi_(&p);
4422844bec4Sminoura 	if (p == 0) {
4432844bec4Sminoura 		warnx("%s: Invalid value", value);
4442844bec4Sminoura 		return -1;
4452844bec4Sminoura 	}
4462844bec4Sminoura 	for (i = 0; bauds[i]; i++)
4472844bec4Sminoura 		if (baud == bauds[i])
4482844bec4Sminoura 			break;
4492844bec4Sminoura 	if (bauds[i] == 0) {
4502844bec4Sminoura 		warnx("%d: Invalid speed", baud);
4512844bec4Sminoura 		return -1;
4522844bec4Sminoura 	}
4532844bec4Sminoura 	baud = i;
4542844bec4Sminoura 
4552844bec4Sminoura 	NEXTSPEC;
4562844bec4Sminoura 
4572844bec4Sminoura 	/* bit size */
4582844bec4Sminoura 	if (*p < '5' || *p > '8') {
4592844bec4Sminoura 		warnx("%c: Invalid bit size", *p);
4602844bec4Sminoura 		return -1;
4612844bec4Sminoura 	}
4622844bec4Sminoura 	bit = *p++ - '5';
4632844bec4Sminoura 
4642844bec4Sminoura 	NEXTSPEC;
4652844bec4Sminoura 
4662844bec4Sminoura 	/* parity */
4672844bec4Sminoura 	q = strchr(parities, *p++);
4682844bec4Sminoura 	if (q == 0) {
4692844bec4Sminoura 		warnx("%c: Invalid parity spec", *p);
4702844bec4Sminoura 		return -1;
4712844bec4Sminoura 	}
4722844bec4Sminoura 	parity = q - parities;
4732844bec4Sminoura 
4742844bec4Sminoura 	NEXTSPEC;
4752844bec4Sminoura 
4762844bec4Sminoura 	/* stop bit */
4772844bec4Sminoura 	if (strncmp(p, "1.5", 3) == 0) {
4782844bec4Sminoura 		stop = 2;
4792844bec4Sminoura 		p += 3;
4802844bec4Sminoura 	} else if (strncmp(p, "2", 1) == 0) {
4812844bec4Sminoura 		stop = 0;
4822844bec4Sminoura 		p++;
4832844bec4Sminoura 	} else if (strncmp(p, "1", 1) == 0) {
4842844bec4Sminoura 		stop = 1;
4852844bec4Sminoura 		p++;
4862844bec4Sminoura 	} else {
4872844bec4Sminoura 		warnx("%s: Invalid value", value);
4882844bec4Sminoura 		return -1;
4892844bec4Sminoura 	}
4902844bec4Sminoura 
4912844bec4Sminoura 	NEXTSPEC;
4922844bec4Sminoura 
4932844bec4Sminoura 	/* flow */
4942844bec4Sminoura 	if (*p == '-')
4952844bec4Sminoura 		flow = 0;
4962844bec4Sminoura 	else if (*p == 's')
4972844bec4Sminoura 		flow = 1;
4982844bec4Sminoura 	else {
4992844bec4Sminoura 		warnx("%s: Invalid value", value);
5002844bec4Sminoura 		return -1;
5012844bec4Sminoura 	}
5022844bec4Sminoura 
5032844bec4Sminoura 	p++;
5042844bec4Sminoura 	while (*p == ' ' || *p == '\t') p++;
5052844bec4Sminoura 	if (*p != 0) {
5062844bec4Sminoura 		warnx("%s: Invalid value", value);
5072844bec4Sminoura 		return -1;
5082844bec4Sminoura 	}
5092844bec4Sminoura 
5102844bec4Sminoura 	prop->modified = 1;
5112844bec4Sminoura 	prop->modified_value.word[0] = ((stop << 14) +
5122844bec4Sminoura 					(parity << 12) +
5132844bec4Sminoura 					(bit << 10) +
5142844bec4Sminoura 					(flow << 9) +
5152844bec4Sminoura 					baud);
5162844bec4Sminoura 
5172844bec4Sminoura 	return 0;
5182844bec4Sminoura }
5192844bec4Sminoura #undef NEXTSPEC
5202844bec4Sminoura 
5212844bec4Sminoura int
parse_srammode(struct property * prop,const char * value)522*421949a3Ssevan parse_srammode(struct property *prop, const char *value)
5232844bec4Sminoura {
52410bf6fccSyamt 	static const char *const sramstrs[] = {"unused", "SRAMDISK", "program"};
5252844bec4Sminoura 	int i;
5262844bec4Sminoura 
5272844bec4Sminoura 	for (i = 0; i <= 2; i++) {
5282844bec4Sminoura 		if (strcasecmp(value, sramstrs[i]) == 0)
5292844bec4Sminoura 			break;
5302844bec4Sminoura 	}
5312844bec4Sminoura 	if (i > 2) {
5322844bec4Sminoura 		warnx("%s: Invalid value", value);
5332844bec4Sminoura 		return -1;
5342844bec4Sminoura 	}
5352844bec4Sminoura 
5362844bec4Sminoura 	prop->modified = 1;
5372844bec4Sminoura 	prop->modified_value.byte[0] = i;
5382844bec4Sminoura 
5392844bec4Sminoura 	return 0;
5402844bec4Sminoura }
5412844bec4Sminoura 
5422844bec4Sminoura int
print_uchar(struct property * prop,char * str)543*421949a3Ssevan print_uchar(struct property *prop, char *str)
54412769637Sminoura {
54512769637Sminoura 	if (prop->modified)
54612769637Sminoura 		snprintf(str, MAXVALUELEN,
54712769637Sminoura 			 "%d", prop->modified_value.byte[0]);
54812769637Sminoura 	else {
54912769637Sminoura 		if (!prop->value_valid)
55012769637Sminoura 			prop->fill(prop);
55112769637Sminoura 		snprintf(str, MAXVALUELEN, "%d",
55212769637Sminoura 			 prop->current_value.byte[0]);
55312769637Sminoura 	}
55412769637Sminoura 
55512769637Sminoura 	return 0;
55612769637Sminoura }
55712769637Sminoura 
55812769637Sminoura int
print_ucharh(struct property * prop,char * str)559*421949a3Ssevan print_ucharh(struct property *prop, char *str)
56012769637Sminoura {
56112769637Sminoura 	if (prop->modified)
56212769637Sminoura 		snprintf(str, MAXVALUELEN,
56312769637Sminoura 			 "0x%4.4x", prop->modified_value.byte[0]);
56412769637Sminoura 	else {
56512769637Sminoura 		if (!prop->value_valid)
56612769637Sminoura 			prop->fill(prop);
56712769637Sminoura 		snprintf(str, MAXVALUELEN,
56812769637Sminoura 			 "0x%4.4x", prop->current_value.byte[0]);
56912769637Sminoura 	}
57012769637Sminoura 
57112769637Sminoura 	return 0;
57212769637Sminoura }
57312769637Sminoura 
57412769637Sminoura int
print_ushorth(struct property * prop,char * str)575*421949a3Ssevan print_ushorth(struct property *prop, char *str)
57612769637Sminoura {
57712769637Sminoura 	if (prop->modified)
57812769637Sminoura 		snprintf(str, MAXVALUELEN,
57912769637Sminoura 			  "0x%4.4x", prop->modified_value.word[0]);
58012769637Sminoura 	else {
58112769637Sminoura 		if (!prop->value_valid)
58212769637Sminoura 			prop->fill(prop);
58312769637Sminoura 		snprintf(str, MAXVALUELEN,
58412769637Sminoura 			 "0x%4.4x", prop->current_value.word[0]);
58512769637Sminoura 	}
58612769637Sminoura 
58712769637Sminoura 	return 0;
58812769637Sminoura }
58912769637Sminoura 
59012769637Sminoura int
print_ulong(struct property * prop,char * str)591*421949a3Ssevan print_ulong(struct property *prop, char *str)
59212769637Sminoura {
59312769637Sminoura 	if (prop->modified)
59412769637Sminoura 		snprintf(str, MAXVALUELEN,
59512769637Sminoura 			 "%ld", prop->modified_value.longword);
59612769637Sminoura 	else {
59712769637Sminoura 		if (!prop->value_valid)
59812769637Sminoura 			prop->fill(prop);
59912769637Sminoura 		snprintf(str, MAXVALUELEN,
60012769637Sminoura 			 "%ld", prop->current_value.longword);
60112769637Sminoura 	}
60212769637Sminoura 
60312769637Sminoura 	return 0;
60412769637Sminoura }
60512769637Sminoura 
60612769637Sminoura int
print_ulongh(struct property * prop,char * str)607*421949a3Ssevan print_ulongh(struct property *prop, char *str)
60812769637Sminoura {
60912769637Sminoura 	if (prop->modified)
61012769637Sminoura 		snprintf(str, MAXVALUELEN,
61112769637Sminoura 			 "0x%8.8lx", prop->modified_value.longword);
61212769637Sminoura 	else {
61312769637Sminoura 		if (!prop->value_valid)
61412769637Sminoura 			prop->fill(prop);
61512769637Sminoura 		snprintf(str, MAXVALUELEN,
61612769637Sminoura 			 "0x%8.8lx", prop->current_value.longword);
61712769637Sminoura 	}
61812769637Sminoura 
61912769637Sminoura 	return 0;
62012769637Sminoura }
62112769637Sminoura 
62212769637Sminoura int
print_magic(struct property * prop,char * str)623*421949a3Ssevan print_magic(struct property *prop, char *str)
62412769637Sminoura {
62512769637Sminoura 	if (!prop->value_valid)
62612769637Sminoura 		prop->fill(prop);
62712769637Sminoura 	snprintf(str, MAXVALUELEN, "%c%c%c%c",
62812769637Sminoura 		 prop->current_value.byte[0],
62912769637Sminoura 		 prop->current_value.byte[1],
63012769637Sminoura 		 prop->current_value.byte[2],
63112769637Sminoura 		 prop->current_value.byte[3]);
63212769637Sminoura 
63312769637Sminoura 	return 0;
63412769637Sminoura }
63512769637Sminoura 
63612769637Sminoura int
print_timesec(struct property * prop,char * str)637*421949a3Ssevan print_timesec(struct property *prop, char *str)
63812769637Sminoura {
63912769637Sminoura 	if (prop->modified)
64012769637Sminoura 		snprintf(str, MAXVALUELEN,
64112769637Sminoura 			 "%ld second", prop->modified_value.longword);
64212769637Sminoura 	else {
64312769637Sminoura 		if (!prop->value_valid)
64412769637Sminoura 			prop->fill(prop);
64512769637Sminoura 		snprintf(str, MAXVALUELEN,
64612769637Sminoura 			 "%ld second", prop->current_value.longword);
64712769637Sminoura 	}
64812769637Sminoura 
64912769637Sminoura 	return 0;
65012769637Sminoura }
65112769637Sminoura 
65212769637Sminoura int
print_bootdev(struct property * prop,char * str)653*421949a3Ssevan print_bootdev(struct property *prop, char *str)
65412769637Sminoura {
65512769637Sminoura 	unsigned int v;
65612769637Sminoura 
65712769637Sminoura 	if (prop->modified)
65812769637Sminoura 		v = prop->modified_value.word[0];
65912769637Sminoura 	else {
66012769637Sminoura 		if (!prop->value_valid)
66112769637Sminoura 			prop->fill(prop);
66212769637Sminoura 		v = prop->current_value.word[0];
66312769637Sminoura 	}
66412769637Sminoura 
66512769637Sminoura 	if (v == 0)
66612769637Sminoura 		strcpy(str, "STD");
66712769637Sminoura 	else if (v == 0xa000)
66812769637Sminoura 		strcpy(str, "ROM");
66912769637Sminoura 	else if (v == 0xb000)
67012769637Sminoura 		strcpy(str, "RAM");
67112769637Sminoura 	else if (v >= 0x8000 && v < 0x9000)
67212769637Sminoura 		snprintf(str, MAXVALUELEN, "HD%d", (v & 0x0f00) >> 8);
67312769637Sminoura 	else if (v >= 0x9000 && v < 0xa000)
67412769637Sminoura 		snprintf(str, MAXVALUELEN, "FD%d", (v & 0x0f00) >> 8);
67512769637Sminoura 	else
67612769637Sminoura 		snprintf(str, MAXVALUELEN, "%8.8x", v);
67712769637Sminoura 
67812769637Sminoura 	return 0;
67912769637Sminoura }
6802844bec4Sminoura 
6812844bec4Sminoura int
print_serial(struct property * prop,char * str)682*421949a3Ssevan print_serial(struct property *prop, char *str)
6832844bec4Sminoura {
6842844bec4Sminoura 	unsigned int v;
685271f6f55Sminoura 	const char *baud, *stop;
686271f6f55Sminoura 	char bit, parity, flow;
68710bf6fccSyamt 	static const char *const bauds[] = {"75", "150", "300", "600", "1200",
6882844bec4Sminoura 			       "2400", "4800", "9600", "17361"};
68910bf6fccSyamt 	static const char bits[] = "5678";
69010bf6fccSyamt 	static const char parities[] = "noen";
69110bf6fccSyamt 	static const char *const stops[] = {"2", "1", "1.5", "2"};
69210bf6fccSyamt 	static const char flows[] = "-s";
6932844bec4Sminoura 
6942844bec4Sminoura 	if (prop->modified)
6952844bec4Sminoura 		v = prop->modified_value.word[0];
6962844bec4Sminoura 	else {
6972844bec4Sminoura 		if (!prop->value_valid)
6982844bec4Sminoura 			prop->fill(prop);
6992844bec4Sminoura 		v = prop->current_value.word[0];
7002844bec4Sminoura 	}
7012844bec4Sminoura 
7022844bec4Sminoura 	baud = bauds[v & 0x000f];
7032844bec4Sminoura 	bit = bits[(v & 0x0c00) >> 10];
7042844bec4Sminoura 	parity = parities[(v & 0x3000) >> 12];
7052844bec4Sminoura 	stop = stops[(v & 0xe000) >> 14];
7062844bec4Sminoura 	flow = flows[(v & 0x0200) >> 9];
7072844bec4Sminoura 	sprintf(str, "%s,%c,%c,%s,%c", baud, bit, parity, stop, flow);
7082844bec4Sminoura 
7092844bec4Sminoura 	return 0;
7102844bec4Sminoura }
7112844bec4Sminoura 
7122844bec4Sminoura int
print_srammode(struct property * prop,char * str)713*421949a3Ssevan print_srammode(struct property *prop, char *str)
7142844bec4Sminoura {
7152844bec4Sminoura 	int v;
71610bf6fccSyamt 	static const char *const sramstrs[] = {"unused", "SRAMDISK", "program"};
7172844bec4Sminoura 
7182844bec4Sminoura 	if (prop->modified)
7192844bec4Sminoura 		v = prop->modified_value.byte[0];
7202844bec4Sminoura 	else {
7212844bec4Sminoura 		if (!prop->value_valid)
7222844bec4Sminoura 			prop->fill(prop);
7232844bec4Sminoura 		v = prop->current_value.byte[0];
7242844bec4Sminoura 	}
7252844bec4Sminoura 
7262844bec4Sminoura 	if (v < 0 || v > 2)
7272844bec4Sminoura 		strcpy(str, "INVALID");
7282844bec4Sminoura 	else
7292844bec4Sminoura 		strcpy(str, sramstrs[v]);
7302844bec4Sminoura 
7312844bec4Sminoura 	return 0;
7322844bec4Sminoura }
733