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