xref: /dflybsd-src/stand/boot/common/misc.c (revision 479ab7f0492f2a51b48e8537e4f1dc686fc6014b)
1*479ab7f0SSascha Wildner /*-
2*479ab7f0SSascha Wildner  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3*479ab7f0SSascha Wildner  * All rights reserved.
4*479ab7f0SSascha Wildner  *
5*479ab7f0SSascha Wildner  * Redistribution and use in source and binary forms, with or without
6*479ab7f0SSascha Wildner  * modification, are permitted provided that the following conditions
7*479ab7f0SSascha Wildner  * are met:
8*479ab7f0SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
9*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer.
10*479ab7f0SSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
11*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
12*479ab7f0SSascha Wildner  *    documentation and/or other materials provided with the distribution.
13*479ab7f0SSascha Wildner  *
14*479ab7f0SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*479ab7f0SSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*479ab7f0SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*479ab7f0SSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*479ab7f0SSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*479ab7f0SSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*479ab7f0SSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*479ab7f0SSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*479ab7f0SSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*479ab7f0SSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*479ab7f0SSascha Wildner  * SUCH DAMAGE.
25*479ab7f0SSascha Wildner  *
26*479ab7f0SSascha Wildner  * $FreeBSD: src/sys/boot/common/misc.c,v 1.8 2003/08/25 23:30:41 obrien Exp $
27*479ab7f0SSascha Wildner  * $DragonFly: src/sys/boot/common/misc.c,v 1.3 2003/11/10 06:08:31 dillon Exp $
28*479ab7f0SSascha Wildner  */
29*479ab7f0SSascha Wildner 
30*479ab7f0SSascha Wildner #include <string.h>
31*479ab7f0SSascha Wildner #include <stand.h>
32*479ab7f0SSascha Wildner #include <bootstrap.h>
33*479ab7f0SSascha Wildner 
34*479ab7f0SSascha Wildner /*
35*479ab7f0SSascha Wildner  * Concatenate the (argc) elements of (argv) into a single string, and return
36*479ab7f0SSascha Wildner  * a copy of same.
37*479ab7f0SSascha Wildner  */
38*479ab7f0SSascha Wildner char *
unargv(int argc,char * argv[])39*479ab7f0SSascha Wildner unargv(int argc, char *argv[])
40*479ab7f0SSascha Wildner {
41*479ab7f0SSascha Wildner     size_t	hlong;
42*479ab7f0SSascha Wildner     int		i;
43*479ab7f0SSascha Wildner     char	*cp;
44*479ab7f0SSascha Wildner 
45*479ab7f0SSascha Wildner     for (hlong = 0, i = 0; i < argc; i++)
46*479ab7f0SSascha Wildner 	hlong += strlen(argv[i]) + 2;
47*479ab7f0SSascha Wildner 
48*479ab7f0SSascha Wildner     if(hlong == 0)
49*479ab7f0SSascha Wildner 	return(NULL);
50*479ab7f0SSascha Wildner 
51*479ab7f0SSascha Wildner     cp = malloc(hlong);
52*479ab7f0SSascha Wildner     cp[0] = 0;
53*479ab7f0SSascha Wildner     for (i = 0; i < argc; i++) {
54*479ab7f0SSascha Wildner 	strcat(cp, argv[i]);
55*479ab7f0SSascha Wildner 	if (i < (argc - 1))
56*479ab7f0SSascha Wildner 	  strcat(cp, " ");
57*479ab7f0SSascha Wildner     }
58*479ab7f0SSascha Wildner 
59*479ab7f0SSascha Wildner     return(cp);
60*479ab7f0SSascha Wildner }
61*479ab7f0SSascha Wildner 
62*479ab7f0SSascha Wildner /*
63*479ab7f0SSascha Wildner  * Get the length of a string in kernel space
64*479ab7f0SSascha Wildner  */
65*479ab7f0SSascha Wildner size_t
strlenout(vm_offset_t src)66*479ab7f0SSascha Wildner strlenout(vm_offset_t src)
67*479ab7f0SSascha Wildner {
68*479ab7f0SSascha Wildner     char	c;
69*479ab7f0SSascha Wildner     size_t	len;
70*479ab7f0SSascha Wildner 
71*479ab7f0SSascha Wildner     for (len = 0; ; len++) {
72*479ab7f0SSascha Wildner 	archsw.arch_copyout(src++, &c, 1);
73*479ab7f0SSascha Wildner 	if (c == 0)
74*479ab7f0SSascha Wildner 	    break;
75*479ab7f0SSascha Wildner     }
76*479ab7f0SSascha Wildner     return(len);
77*479ab7f0SSascha Wildner }
78*479ab7f0SSascha Wildner 
79*479ab7f0SSascha Wildner /*
80*479ab7f0SSascha Wildner  * Make a duplicate copy of a string in kernel space
81*479ab7f0SSascha Wildner  */
82*479ab7f0SSascha Wildner char *
strdupout(vm_offset_t str)83*479ab7f0SSascha Wildner strdupout(vm_offset_t str)
84*479ab7f0SSascha Wildner {
85*479ab7f0SSascha Wildner     char	*result, *cp;
86*479ab7f0SSascha Wildner 
87*479ab7f0SSascha Wildner     result = malloc(strlenout(str) + 1);
88*479ab7f0SSascha Wildner     for (cp = result; ;cp++) {
89*479ab7f0SSascha Wildner 	archsw.arch_copyout(str++, cp, 1);
90*479ab7f0SSascha Wildner 	if (*cp == 0)
91*479ab7f0SSascha Wildner 	    break;
92*479ab7f0SSascha Wildner     }
93*479ab7f0SSascha Wildner     return(result);
94*479ab7f0SSascha Wildner }
95*479ab7f0SSascha Wildner 
96*479ab7f0SSascha Wildner /* Zero a region in kernel space. */
97*479ab7f0SSascha Wildner void
kern_bzero(vm_offset_t dest,size_t len)98*479ab7f0SSascha Wildner kern_bzero(vm_offset_t dest, size_t len)
99*479ab7f0SSascha Wildner {
100*479ab7f0SSascha Wildner     char	    buf[256];
101*479ab7f0SSascha Wildner     size_t	    chunk, resid;
102*479ab7f0SSascha Wildner 
103*479ab7f0SSascha Wildner     bzero(buf, sizeof(buf));
104*479ab7f0SSascha Wildner     resid = len;
105*479ab7f0SSascha Wildner     while (resid > 0) {
106*479ab7f0SSascha Wildner 	chunk = min(sizeof(buf), resid);
107*479ab7f0SSascha Wildner 	archsw.arch_copyin(buf, dest, chunk);
108*479ab7f0SSascha Wildner 	resid -= chunk;
109*479ab7f0SSascha Wildner 	dest += chunk;
110*479ab7f0SSascha Wildner     }
111*479ab7f0SSascha Wildner }
112*479ab7f0SSascha Wildner 
113*479ab7f0SSascha Wildner /*
114*479ab7f0SSascha Wildner  * Read the specified part of a file to kernel space.  Unlike regular
115*479ab7f0SSascha Wildner  * pread, the file pointer is advanced to the end of the read data,
116*479ab7f0SSascha Wildner  * and it just returns 0 if successful.
117*479ab7f0SSascha Wildner  */
118*479ab7f0SSascha Wildner int
kern_pread(int fd,vm_offset_t dest,size_t len,off_t off)119*479ab7f0SSascha Wildner kern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
120*479ab7f0SSascha Wildner {
121*479ab7f0SSascha Wildner     ssize_t	    nread;
122*479ab7f0SSascha Wildner 
123*479ab7f0SSascha Wildner     if (lseek(fd, off, SEEK_SET) == -1) {
124*479ab7f0SSascha Wildner 	printf("\nlseek failed\n");
125*479ab7f0SSascha Wildner 	return (-1);
126*479ab7f0SSascha Wildner     }
127*479ab7f0SSascha Wildner     nread = archsw.arch_readin(fd, dest, len);
128*479ab7f0SSascha Wildner     if ((size_t)nread != len) {
129*479ab7f0SSascha Wildner 	printf("\nreadin failed\n");
130*479ab7f0SSascha Wildner 	return (-1);
131*479ab7f0SSascha Wildner     }
132*479ab7f0SSascha Wildner     return (0);
133*479ab7f0SSascha Wildner }
134*479ab7f0SSascha Wildner 
135*479ab7f0SSascha Wildner /*
136*479ab7f0SSascha Wildner  * Read the specified part of a file to a malloced buffer.  The file
137*479ab7f0SSascha Wildner  * pointer is advanced to the end of the read data.
138*479ab7f0SSascha Wildner  */
139*479ab7f0SSascha Wildner void *
alloc_pread(int fd,off_t off,size_t len)140*479ab7f0SSascha Wildner alloc_pread(int fd, off_t off, size_t len)
141*479ab7f0SSascha Wildner {
142*479ab7f0SSascha Wildner     void           *buf;
143*479ab7f0SSascha Wildner     ssize_t	    nread;
144*479ab7f0SSascha Wildner 
145*479ab7f0SSascha Wildner     buf = malloc(len);
146*479ab7f0SSascha Wildner     if (buf == NULL) {
147*479ab7f0SSascha Wildner 	printf("\nmalloc(%d) failed\n", (int)len);
148*479ab7f0SSascha Wildner 	return (NULL);
149*479ab7f0SSascha Wildner     }
150*479ab7f0SSascha Wildner     if (lseek(fd, off, SEEK_SET) == -1) {
151*479ab7f0SSascha Wildner 	printf("\nlseek failed\n");
152*479ab7f0SSascha Wildner 	free(buf);
153*479ab7f0SSascha Wildner 	return (NULL);
154*479ab7f0SSascha Wildner     }
155*479ab7f0SSascha Wildner     nread = read(fd, buf, len);
156*479ab7f0SSascha Wildner     if ((size_t)nread != len) {
157*479ab7f0SSascha Wildner 	printf("\nread failed\n");
158*479ab7f0SSascha Wildner 	free(buf);
159*479ab7f0SSascha Wildner 	return (NULL);
160*479ab7f0SSascha Wildner     }
161*479ab7f0SSascha Wildner     return (buf);
162*479ab7f0SSascha Wildner }
163*479ab7f0SSascha Wildner 
164*479ab7f0SSascha Wildner /*
165*479ab7f0SSascha Wildner  * Display a region in traditional hexdump format.
166*479ab7f0SSascha Wildner  */
167*479ab7f0SSascha Wildner void
hexdump(caddr_t region,size_t len)168*479ab7f0SSascha Wildner hexdump(caddr_t region, size_t len)
169*479ab7f0SSascha Wildner {
170*479ab7f0SSascha Wildner     caddr_t	line;
171*479ab7f0SSascha Wildner     int		x, c;
172*479ab7f0SSascha Wildner     char	lbuf[80];
173*479ab7f0SSascha Wildner #define emit(fmt, args...)	{sprintf(lbuf, fmt , ## args); pager_output(lbuf);}
174*479ab7f0SSascha Wildner 
175*479ab7f0SSascha Wildner     pager_open();
176*479ab7f0SSascha Wildner     for (line = region; line < (region + len); line += 16) {
177*479ab7f0SSascha Wildner 	emit("%08lx  ", (long) line);
178*479ab7f0SSascha Wildner 
179*479ab7f0SSascha Wildner 	for (x = 0; x < 16; x++) {
180*479ab7f0SSascha Wildner 	    if ((line + x) < (region + len)) {
181*479ab7f0SSascha Wildner 		emit("%02x ", *(u_int8_t *)(line + x));
182*479ab7f0SSascha Wildner 	    } else {
183*479ab7f0SSascha Wildner 		emit("-- ");
184*479ab7f0SSascha Wildner 	    }
185*479ab7f0SSascha Wildner 	    if (x == 7)
186*479ab7f0SSascha Wildner 		emit(" ");
187*479ab7f0SSascha Wildner 	}
188*479ab7f0SSascha Wildner 	emit(" |");
189*479ab7f0SSascha Wildner 	for (x = 0; x < 16; x++) {
190*479ab7f0SSascha Wildner 	    if ((line + x) < (region + len)) {
191*479ab7f0SSascha Wildner 		c = *(u_int8_t *)(line + x);
192*479ab7f0SSascha Wildner 		if ((c < ' ') || (c > '~'))	/* !isprint(c) */
193*479ab7f0SSascha Wildner 		    c = '.';
194*479ab7f0SSascha Wildner 		emit("%c", c);
195*479ab7f0SSascha Wildner 	    } else {
196*479ab7f0SSascha Wildner 		emit(" ");
197*479ab7f0SSascha Wildner 	    }
198*479ab7f0SSascha Wildner 	}
199*479ab7f0SSascha Wildner 	emit("|\n");
200*479ab7f0SSascha Wildner     }
201*479ab7f0SSascha Wildner     pager_close();
202*479ab7f0SSascha Wildner }
203*479ab7f0SSascha Wildner 
204*479ab7f0SSascha Wildner void
dev_cleanup(void)205*479ab7f0SSascha Wildner dev_cleanup(void)
206*479ab7f0SSascha Wildner {
207*479ab7f0SSascha Wildner     int		i;
208*479ab7f0SSascha Wildner 
209*479ab7f0SSascha Wildner     /* Call cleanup routines */
210*479ab7f0SSascha Wildner     for (i = 0; devsw[i] != NULL; ++i)
211*479ab7f0SSascha Wildner 	if (devsw[i]->dv_cleanup != NULL)
212*479ab7f0SSascha Wildner 	    (devsw[i]->dv_cleanup)();
213*479ab7f0SSascha Wildner }
214