xref: /openbsd-src/sys/arch/amd64/stand/libsa/cmd_i386.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: cmd_i386.c,v 1.10 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 "biosdev.h"
37 #include "libsa.h"
38 #include <cmd.h>
39 
40 #ifdef EFIBOOT
41 #include "efiboot.h"
42 #include "efidev.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 #ifndef EFIBOOT
76 	dump_diskinfo();
77 #else
78 	efi_dump_diskinfo();
79 #endif
80 	return 0;
81 }
82 
83 #ifdef DEBUG
84 int
85 Xregs(void)
86 {
87 	DUMP_REGS;
88 	return 0;
89 }
90 #endif
91 
92 int
93 Xboot(void)
94 {
95 #ifdef EFIBOOT
96 	printf("Not supported yet\n");
97 #else
98 	int dev, part, st;
99 	struct diskinfo *dip;
100 	char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
101 
102 	if (cmd.argc != 2) {
103 		printf("machine boot {fd,hd}<0123>[abcd]\n");
104 		printf("Where [0123] is the disk number,"
105 		    " and [abcd] is the partition.\n");
106 		return 0;
107 	}
108 
109 	/* Check arg */
110 	if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
111 		goto bad;
112 	if (cmd.argv[1][1] != 'd')
113 		goto bad;
114 	if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
115 		goto bad;
116 	if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') &&
117 	    cmd.argv[1][3] != '\0')
118 		goto bad;
119 
120 	printf("Booting from %s ", cmd.argv[1]);
121 
122 	dev = (cmd.argv[1][0] == 'h')?0x80:0;
123 	dev += (cmd.argv[1][2] - '0');
124 	part = (cmd.argv[1][3] - 'a');
125 
126 	if (part > 0)
127 		printf("[%x,%d]\n", dev, part);
128 	else
129 		printf("[%x]\n", dev);
130 
131 	/* Read boot sector from device */
132 	dip = dklookup(dev);
133 	st = dip->diskio(F_READ, dip, 0, 1, buf);
134 	if (st)
135 		goto bad;
136 
137 	/* Frob boot flag in buffer from HD */
138 	if ((dev & 0x80) && (part > 0)){
139 		int i, j;
140 
141 		for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
142 			if (part == i)
143 				buf[j] |= 0x80;
144 			else
145 				buf[j] &= ~0x80;
146 	}
147 
148 	/* Load %dl, ljmp */
149 	bcopy(buf, dest, DEV_BSIZE);
150 	bootbuf(dest, dev);
151 
152 bad:
153 	printf("Invalid device!\n");
154 #endif
155 	return 0;
156 }
157 
158 int
159 Xmemory(void)
160 {
161 	if (cmd.argc >= 2) {
162 		int i;
163 		/* parse the memory specs */
164 
165 		for (i = 1; i < cmd.argc; i++) {
166 			char *p;
167 			long long addr, size;
168 
169 			p = cmd.argv[i];
170 
171 			size = strtoll(p + 1, &p, 0);
172 			/* Size the size */
173 			switch (*p) {
174 				case 'G':
175 				case 'g':
176 					size *= 1024;
177 				case 'M':
178 				case 'm':
179 					size *= 1024;
180 				case 'K':
181 				case 'k':
182 					size *= 1024;
183 					p++;
184 			}
185 
186 			/* Handle (possibly non-existent) address part */
187 			switch (*p) {
188 				case '@':
189 					addr = strtoll(p + 1, NULL, 0);
190 					break;
191 
192 				/* Adjust address if we don't need it */
193 				default:
194 					if (cmd.argv[i][0] == '=')
195 						addr = -1;
196 					else
197 						addr = 0;
198 			}
199 
200 			if (addr == 0 || size == 0) {
201 				printf("bad language\n");
202 				return 0;
203 			} else {
204 				switch (cmd.argv[i][0]) {
205 				case '-':
206 					mem_delete(addr, addr + size);
207 					break;
208 				case '+':
209 					mem_add(addr, addr + size);
210 					break;
211 				case '=':
212 					mem_limit(size);
213 					break;
214 				default :
215 					printf("bad OP\n");
216 					return 0;
217 				}
218 			}
219 		}
220 	}
221 
222 	dump_biosmem(NULL);
223 
224 	return 0;
225 }
226 
227 int
228 Xcomaddr(void)
229 {
230 	extern int com_addr;
231 
232 	if (cmd.argc >= 2)
233 		com_addr = (int)strtol(cmd.argv[1], NULL, 0);
234 
235 	return 0;
236 }
237