xref: /openbsd/sys/arch/amd64/stand/libsa/cmd_i386.c (revision 73471bf0)
1 /*	$OpenBSD: cmd_i386.c,v 1.14 2019/05/10 21:20:43 mlarkin 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
63 Xdiskinfo(void)
64 {
65 	dump_diskinfo();
66 	return 0;
67 }
68 
69 #ifdef DEBUG
70 int
71 Xregs(void)
72 {
73 	DUMP_REGS;
74 	return 0;
75 }
76 #endif
77 
78 int
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
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
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