xref: /openbsd/sys/arch/i386/stand/libsa/cmd_i386.c (revision 9b7c3dbb)
1 /*	$OpenBSD: cmd_i386.c,v 1.36 2016/06/10 18:36:06 jcs Exp $	*/
2 
3 /*
4  * Copyright (c) 1997-1999 Michael Shalayeff
5  * Copyright (c) 1997 Tobias Weingartner
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  */
30 
31 #include <sys/param.h>
32 #include <sys/reboot.h>
33 #include <machine/biosvar.h>
34 #include <sys/disklabel.h>
35 #include "disk.h"
36 #include "debug.h"
37 #include "biosdev.h"
38 #include "libsa.h"
39 #include <cmd.h>
40 
41 #ifdef EFIBOOT
42 #include "efiboot.h"
43 #endif
44 
45 extern const char version[];
46 
47 int Xboot(void);
48 int Xcomaddr(void);
49 int Xdiskinfo(void);
50 int Xmemory(void);
51 int Xregs(void);
52 
53 /* From gidt.S */
54 int bootbuf(void *, int);
55 
56 const struct cmd_table cmd_machine[] = {
57 	{ "boot",	CMDT_CMD, Xboot },
58 	{ "comaddr",	CMDT_CMD, Xcomaddr },
59 	{ "diskinfo",	CMDT_CMD, Xdiskinfo },
60 	{ "memory",	CMDT_CMD, Xmemory },
61 #ifdef EFIBOOT
62 	{ "video",	CMDT_CMD, Xvideo_efi },
63 	{ "exit",	CMDT_CMD, Xexit_efi },
64 	{ "poweroff",	CMDT_CMD, Xpoweroff_efi },
65 #endif
66 #ifdef DEBUG
67 	{ "regs",	CMDT_CMD, Xregs },
68 #endif
69 	{ NULL, 0 }
70 };
71 
72 int
73 Xdiskinfo(void)
74 {
75 	dump_diskinfo();
76 	return 0;
77 }
78 
79 #ifdef DEBUG
80 int
81 Xregs(void)
82 {
83 	DUMP_REGS;
84 	return 0;
85 }
86 #endif
87 
88 int
89 Xboot(void)
90 {
91 #ifdef EFIBOOT
92 	printf("Not supported yet\n");
93 #else
94 	int dev, part, st;
95 	struct diskinfo *dip;
96 	char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
97 
98 	if (cmd.argc != 2) {
99 		printf("machine boot {fd,hd}<0123>[abcd]\n");
100 		printf("Where [0123] is the disk number,"
101 		    " and [abcd] is the partition.\n");
102 		return 0;
103 	}
104 
105 	/* Check arg */
106 	if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
107 		goto bad;
108 	if (cmd.argv[1][1] != 'd')
109 		goto bad;
110 	if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
111 		goto bad;
112 	if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') &&
113 	    cmd.argv[1][3] != '\0')
114 		goto bad;
115 
116 	printf("Booting from %s ", cmd.argv[1]);
117 
118 	dev = (cmd.argv[1][0] == 'h')?0x80:0;
119 	dev += (cmd.argv[1][2] - '0');
120 	part = (cmd.argv[1][3] - 'a');
121 
122 	if (part > 0)
123 		printf("[%x,%d]\n", dev, part);
124 	else
125 		printf("[%x]\n", dev);
126 
127 	/* Read boot sector from device */
128 	dip = dklookup(dev);
129 	st = dip->diskio(F_READ, dip, 0, 1, buf);
130 	if (st)
131 		goto bad;
132 
133 	/* Frob boot flag in buffer from HD */
134 	if ((dev & 0x80) && (part > 0)){
135 		int i, j;
136 
137 		for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
138 			if (part == i)
139 				buf[j] |= 0x80;
140 			else
141 				buf[j] &= ~0x80;
142 	}
143 
144 	/* Load %dl, ljmp */
145 	bcopy(buf, dest, DEV_BSIZE);
146 	bootbuf(dest, dev);
147 
148 bad:
149 	printf("Invalid device!\n");
150 #endif
151 	return 0;
152 }
153 
154 int
155 Xmemory(void)
156 {
157 	if (cmd.argc >= 2) {
158 		int i;
159 		/* parse the memory specs */
160 
161 		for (i = 1; i < cmd.argc; i++) {
162 			char *p;
163 			long long addr, size;
164 
165 			p = cmd.argv[i];
166 
167 			size = strtoll(p + 1, &p, 0);
168 			/* Size the size */
169 			switch (*p) {
170 				case 'G':
171 				case 'g':
172 					size *= 1024;
173 				case 'M':
174 				case 'm':
175 					size *= 1024;
176 				case 'K':
177 				case 'k':
178 					size *= 1024;
179 					p++;
180 			}
181 
182 			/* Handle (possibly non-existent) address part */
183 			switch (*p) {
184 				case '@':
185 					addr = strtoll(p + 1, NULL, 0);
186 					break;
187 
188 				/* Adjust address if we don't need it */
189 				default:
190 					if (cmd.argv[i][0] == '=')
191 						addr = -1;
192 					else
193 						addr = 0;
194 			}
195 
196 			if (addr == 0 || size == 0) {
197 				printf("bad language\n");
198 				return 0;
199 			} else {
200 				switch (cmd.argv[i][0]) {
201 				case '-':
202 					mem_delete(addr, addr + size);
203 					break;
204 				case '+':
205 					mem_add(addr, addr + size);
206 					break;
207 				case '=':
208 					mem_limit(size);
209 					break;
210 				default :
211 					printf("bad OP\n");
212 					return 0;
213 				}
214 			}
215 		}
216 	}
217 
218 	dump_biosmem(NULL);
219 
220 	return 0;
221 }
222 
223 int
224 Xcomaddr(void)
225 {
226 	extern int com_addr;
227 
228 	if (cmd.argc >= 2)
229 		com_addr = (int)strtol(cmd.argv[1], NULL, 0);
230 
231 	return 0;
232 }
233