1 /* $OpenBSD: cmd_i386.c,v 1.15 2022/03/29 13:57:52 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 "biosdev.h"
37 #include "libsa.h"
38 #include <cmd.h>
39
40 extern const char version[];
41
42 int Xboot(void);
43 int Xcomaddr(void);
44 int Xdiskinfo(void);
45 int Xmemory(void);
46 int Xregs(void);
47
48 /* From gidt.S */
49 int bootbuf(void *, int);
50
51 const struct cmd_table cmd_machine[] = {
52 { "boot", CMDT_CMD, Xboot },
53 { "comaddr", CMDT_CMD, Xcomaddr },
54 { "diskinfo", CMDT_CMD, Xdiskinfo },
55 { "memory", CMDT_CMD, Xmemory },
56 #ifdef DEBUG
57 { "regs", CMDT_CMD, Xregs },
58 #endif
59 { NULL, 0 }
60 };
61
62 int
Xdiskinfo(void)63 Xdiskinfo(void)
64 {
65 dump_diskinfo();
66 return 0;
67 }
68
69 #ifdef DEBUG
70 int
Xregs(void)71 Xregs(void)
72 {
73 DUMP_REGS;
74 return 0;
75 }
76 #endif
77
78 int
Xboot(void)79 Xboot(void)
80 {
81 printf("Not supported yet\n");
82 int dev, part, st;
83 struct diskinfo *dip;
84 char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
85
86 if (cmd.argc != 2) {
87 printf("machine boot {fd,hd}<0123>[abcd]\n");
88 printf("Where [0123] is the disk number,"
89 " and [abcd] is the partition.\n");
90 return 0;
91 }
92
93 /* Check arg */
94 if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
95 goto bad;
96 if (cmd.argv[1][1] != 'd')
97 goto bad;
98 if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
99 goto bad;
100 if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') &&
101 cmd.argv[1][3] != '\0')
102 goto bad;
103
104 printf("Booting from %s ", cmd.argv[1]);
105
106 dev = (cmd.argv[1][0] == 'h')?0x80:0;
107 dev += (cmd.argv[1][2] - '0');
108 part = (cmd.argv[1][3] - 'a');
109
110 if (part >= 0)
111 printf("[%x,%d]\n", dev, part);
112 else
113 printf("[%x]\n", dev);
114
115 /* Read boot sector from device */
116 dip = dklookup(dev);
117 st = dip->diskio(F_READ, dip, 0, 1, buf);
118 if (st)
119 goto bad;
120
121 /* Frob boot flag in buffer from HD */
122 if ((dev & 0x80) && (part >= 0)) {
123 int i, j;
124
125 for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
126 if (part == i)
127 buf[j] |= 0x80;
128 else
129 buf[j] &= ~0x80;
130 }
131
132 /* Load %dl, ljmp */
133 bcopy(buf, dest, DEV_BSIZE);
134 bootbuf(dest, dev);
135
136 bad:
137 printf("Invalid device!\n");
138 return 0;
139 }
140
141 int
Xmemory(void)142 Xmemory(void)
143 {
144 if (cmd.argc >= 2) {
145 int i;
146 /* parse the memory specs */
147
148 for (i = 1; i < cmd.argc; i++) {
149 char *p;
150 long long addr, size;
151
152 p = cmd.argv[i];
153
154 size = strtoll(p + 1, &p, 0);
155 /* Size the size */
156 switch (*p) {
157 case 'G':
158 case 'g':
159 size *= 1024;
160 case 'M':
161 case 'm':
162 size *= 1024;
163 case 'K':
164 case 'k':
165 size *= 1024;
166 p++;
167 }
168
169 /* Handle (possibly non-existent) address part */
170 switch (*p) {
171 case '@':
172 addr = strtoll(p + 1, NULL, 0);
173 break;
174
175 /* Adjust address if we don't need it */
176 default:
177 if (cmd.argv[i][0] == '=')
178 addr = -1;
179 else
180 addr = 0;
181 }
182
183 if (addr == 0 || size == 0) {
184 printf("bad language\n");
185 return 0;
186 } else {
187 switch (cmd.argv[i][0]) {
188 case '-':
189 mem_delete(addr, addr + size);
190 break;
191 case '+':
192 mem_add(addr, addr + size);
193 break;
194 case '=':
195 mem_limit(size);
196 break;
197 default :
198 printf("bad OP\n");
199 return 0;
200 }
201 }
202 }
203 }
204
205 dump_biosmem(NULL);
206
207 return 0;
208 }
209
210 int
Xcomaddr(void)211 Xcomaddr(void)
212 {
213 extern int com_addr;
214
215 if (cmd.argc >= 2)
216 com_addr = (int)strtol(cmd.argv[1], NULL, 0);
217
218 return 0;
219 }
220