xref: /openbsd-src/sys/arch/loongson/loongson/autoconf.c (revision 3ad05d8a962fc191553f154302aa10448542cee1)
1 /*	$OpenBSD: autoconf.c,v 1.11 2022/09/02 20:06:56 miod Exp $	*/
2 /*
3  * Copyright (c) 2009 Miodrag Vallat.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/conf.h>
21 #include <sys/device.h>
22 #include <sys/reboot.h>
23 #include <sys/hibernate.h>
24 
25 #include <machine/autoconf.h>
26 
27 #define DUID_SIZE	8
28 
29 extern void dumpconf(void);
30 int	parseduid(const char *, u_char *);
31 void	parsepmonbp(void);
32 
33 int	cold = 1;
34 struct device *bootdv = NULL;
35 char    bootdev[16];
36 enum devclass bootdev_class = DV_DULL;
37 
38 extern char pmon_bootp[];
39 
40 void
cpu_configure(void)41 cpu_configure(void)
42 {
43 	(void)splhigh();
44 
45 	softintr_init();
46 	(void)config_rootfound("mainbus", NULL);
47 
48 	unmap_startup();
49 
50 	splinit();
51 	cold = 0;
52 }
53 
54 void
parsepmonbp(void)55 parsepmonbp(void)
56 {
57 	char *p = NULL;
58 	char *q;
59 	size_t len = 0;
60 
61 	if (strncmp(pmon_bootp, "tftp://", 7) == 0) {
62 		bootdev_class = DV_IFNET;
63 		strlcpy(bootdev, "netboot", sizeof bootdev);
64 		return;
65 	}
66 	strlcpy(bootdev, "unknown", sizeof bootdev);
67 
68 	if (strncmp(pmon_bootp, "/dev/disk/", 10) == 0) {
69 		/* kernel loaded by our boot blocks */
70 		p = pmon_bootp + 10;
71 		len = strlen(p);
72 	} else if (strncmp(pmon_bootp, "bootduid=", 9) == 0) {
73 		/* kernel loaded by our boot blocks */
74 		if (parseduid(pmon_bootp + 9, bootduid) != 0)
75 			return;
76 	} else {
77 		/* kernel loaded by PMON */
78 		p = strchr(pmon_bootp, '@');
79 		if (p == NULL)
80 			return;
81 		p++;
82 
83 		q = strchr(p, '/');
84 		if (q == NULL)
85 			return;
86 		len = q - p;
87 	}
88 
89 	if (len <= 2 || len >= sizeof bootdev - 1)
90 		return;
91 	memcpy(bootdev, p, len);
92 	bootdev[len] = '\0';
93 	bootdev_class = DV_DISK;
94 }
95 
96 static unsigned int
parsehex(int c)97 parsehex(int c)
98 {
99 	if (c >= 'a')
100 		return c - 'a' + 10;
101 	else
102 		return c - '0';
103 }
104 
105 int
parseduid(const char * str,u_char * duid)106 parseduid(const char *str, u_char *duid)
107 {
108 	int i;
109 
110 	for (i = 0; i < DUID_SIZE * 2; i++) {
111 		if (!(str[i] >= '0' && str[i] <= '9') &&
112 		    !(str[i] >= 'a' && str[i] <= 'f'))
113 			return -1;
114 	}
115 	if (str[DUID_SIZE * 2] != '\0')
116 		return -1;
117 
118 	for (i = 0; i < DUID_SIZE; i++) {
119 		duid[i] = parsehex(str[i * 2]) * 0x10 +
120 		    parsehex(str[i * 2 + 1]);
121 	}
122 
123 	return 0;
124 }
125 
126 void
diskconf(void)127 diskconf(void)
128 {
129 	if (*pmon_bootp != '\0')
130 		printf("pmon bootpath: %s\n", pmon_bootp);
131 
132 	if (bootdv != NULL)
133 		printf("boot device: %s\n", bootdv->dv_xname);
134 
135 	setroot(bootdv, 0, RB_USERREQ);
136 	dumpconf();
137 
138 #ifdef HIBERNATE
139 	hibernate_resume();
140 #endif /* HIBERNATE */
141 }
142 
143 void
device_register(struct device * dev,void * aux)144 device_register(struct device *dev, void *aux)
145 {
146 	if (bootdv != NULL)
147 		return;
148 
149 	(*sys_platform->device_register)(dev, aux);
150 }
151 
152 const struct nam2blk nam2blk[] = {
153 	{ "sd",		0 },
154 	{ "vnd",	2 },
155 	{ "cd",		3 },
156 	{ "wd",		4 },
157 	{ "rd",		8 },
158 	{ NULL,		-1 }
159 };
160