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