xref: /openbsd/sys/arch/amd64/stand/libsa/cmd_i386.c (revision 8932bfb7)
1 /*	$OpenBSD: cmd_i386.c,v 1.3 2010/07/02 00:36:52 weingart 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 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 	{ "diskinfo", CMDT_CMD, Xdiskinfo },
54 	{ "memory",   CMDT_CMD, Xmemory },
55 #ifdef DEBUG
56 	{ "regs",     CMDT_CMD, Xregs },
57 #endif
58 	{ NULL, 0 }
59 };
60 
61 int
62 Xdiskinfo(void)
63 {
64 #ifndef _TEST
65 	dump_diskinfo();
66 #endif
67 	return 0;
68 }
69 
70 #ifdef DEBUG
71 int
72 Xregs(void)
73 {
74 	DUMP_REGS;
75 	return 0;
76 }
77 #endif
78 
79 int
80 Xboot(void)
81 {
82 #ifndef _TEST
83 	int dev, part, st;
84 	bios_diskinfo_t *bd = NULL;
85 	char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
86 
87 	if(cmd.argc != 2) {
88 		printf("machine boot {fd,hd}<0123>[abcd]\n");
89 		printf("Where [0123] is the disk number,"
90 			" and [abcd] is the partition.\n");
91 		return 0;
92 	}
93 
94 	/* Check arg */
95 	if(cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
96 		goto bad;
97 	if(cmd.argv[1][1] != 'd')
98 		goto bad;
99 	if(cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
100 		goto bad;
101 	if((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') && 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 	bd = bios_dklookup(dev);
117 	st = biosd_io(F_READ, bd, 0, 1, buf);
118 	if(st) goto bad;
119 
120 	/* Frob boot flag in buffer from HD */
121 	if((dev & 0x80) && (part > 0)){
122 		int i, j;
123 
124 		for(i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
125 			if(part == i)
126 				buf[j] |= 0x80;
127 			else
128 				buf[j] &= ~0x80;
129 	}
130 
131 	/* Load %dl, ljmp */
132 	bcopy(buf, dest, DEV_BSIZE);
133 	bootbuf(dest, dev);
134 
135 bad:
136 	printf("Invalid device!\n");
137 #endif
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 					size *= 1024;
159 				case 'M':
160 					size *= 1024;
161 				case 'K':
162 					size *= 1024;
163 					p++;
164 			}
165 
166 			/* Handle (possibly non-existant) address part */
167 			switch(*p) {
168 				case '@':
169 					addr = strtoll(p + 1, NULL, 0);
170 					break;
171 
172 				/* Adjust address if we don't need it */
173 				default:
174 					if (cmd.argv[i][0] == '=')
175 						addr = -1;
176 					else
177 						addr = 0;
178 			}
179 
180 			if (addr == 0 || size == 0) {
181 				printf ("bad language\n");
182 				return 0;
183 			} else {
184 				switch (cmd.argv[i][0]) {
185 				case '-':
186 					mem_delete(addr, addr + size);
187 					break;
188 				case '+':
189 					mem_add(addr, addr + size);
190 					break;
191 				case '=':
192 					mem_limit(size);
193 					break;
194 				default :
195 					printf ("bad OP\n");
196 					return 0;
197 				}
198 			}
199 		}
200 	}
201 
202 	dump_biosmem(NULL);
203 
204 	return 0;
205 }
206