1 /* $OpenBSD: cmd_i386.c,v 1.37 2022/03/29 13:57:53 deraadt 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
Xdiskinfo(void)73 Xdiskinfo(void)
74 {
75 dump_diskinfo();
76 return 0;
77 }
78
79 #ifdef DEBUG
80 int
Xregs(void)81 Xregs(void)
82 {
83 DUMP_REGS;
84 return 0;
85 }
86 #endif
87
88 int
Xboot(void)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
Xmemory(void)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
Xcomaddr(void)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