xref: /openbsd/sys/arch/i386/stand/libsa/cmd_i386.c (revision 51dff02e)
1*51dff02eSderaadt /*	$OpenBSD: cmd_i386.c,v 1.37 2022/03/29 13:57:53 deraadt Exp $	*/
2f74c92d6Smickey 
3f74c92d6Smickey /*
4857b0937Smickey  * Copyright (c) 1997-1999 Michael Shalayeff
5857b0937Smickey  * Copyright (c) 1997 Tobias Weingartner
6f74c92d6Smickey  * All rights reserved.
7f74c92d6Smickey  *
8f74c92d6Smickey  * Redistribution and use in source and binary forms, with or without
9f74c92d6Smickey  * modification, are permitted provided that the following conditions
10f74c92d6Smickey  * are met:
11f74c92d6Smickey  * 1. Redistributions of source code must retain the above copyright
12f74c92d6Smickey  *    notice, this list of conditions and the following disclaimer.
13f74c92d6Smickey  * 2. Redistributions in binary form must reproduce the above copyright
14f74c92d6Smickey  *    notice, this list of conditions and the following disclaimer in the
15f74c92d6Smickey  *    documentation and/or other materials provided with the distribution.
16f74c92d6Smickey  *
17f74c92d6Smickey  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18f74c92d6Smickey  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19f74c92d6Smickey  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20f74c92d6Smickey  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21f74c92d6Smickey  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22f74c92d6Smickey  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23f74c92d6Smickey  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24f74c92d6Smickey  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25f74c92d6Smickey  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26f74c92d6Smickey  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27f74c92d6Smickey  * SUCH DAMAGE.
28f74c92d6Smickey  *
29f74c92d6Smickey  */
30f74c92d6Smickey 
31f74c92d6Smickey #include <sys/param.h>
3236fe99eeSmickey #include <sys/reboot.h>
3339023d55Sweingart #include <machine/biosvar.h>
3436fe99eeSmickey #include <sys/disklabel.h>
3536fe99eeSmickey #include "disk.h"
36484dd08aSmickey #include "debug.h"
3739023d55Sweingart #include "biosdev.h"
38f74c92d6Smickey #include "libsa.h"
39f74c92d6Smickey #include <cmd.h>
40f74c92d6Smickey 
41fce71ba5Syasuoka #ifdef EFIBOOT
42fce71ba5Syasuoka #include "efiboot.h"
43fce71ba5Syasuoka #endif
447040ffa9Sweingart 
457040ffa9Sweingart extern const char version[];
467040ffa9Sweingart 
47c4071fd1Smillert int Xboot(void);
48a1e303c3Skettenis int Xcomaddr(void);
49c4071fd1Smillert int Xdiskinfo(void);
50c4071fd1Smillert int Xmemory(void);
51c4071fd1Smillert int Xregs(void);
5256427238Sweingart 
5356427238Sweingart /* From gidt.S */
54c4071fd1Smillert int bootbuf(void *, int);
5556427238Sweingart 
56f74c92d6Smickey const struct cmd_table cmd_machine[] = {
5756427238Sweingart 	{ "boot",	CMDT_CMD, Xboot },
58a1e303c3Skettenis 	{ "comaddr",	CMDT_CMD, Xcomaddr },
597040ffa9Sweingart 	{ "diskinfo",	CMDT_CMD, Xdiskinfo },
6056427238Sweingart 	{ "memory",	CMDT_CMD, Xmemory },
61fce71ba5Syasuoka #ifdef EFIBOOT
62fce71ba5Syasuoka 	{ "video",	CMDT_CMD, Xvideo_efi },
63fce71ba5Syasuoka 	{ "exit",	CMDT_CMD, Xexit_efi },
64fce71ba5Syasuoka 	{ "poweroff",	CMDT_CMD, Xpoweroff_efi },
65fce71ba5Syasuoka #endif
66857b0937Smickey #ifdef DEBUG
677040ffa9Sweingart 	{ "regs",	CMDT_CMD, Xregs },
68857b0937Smickey #endif
69f74c92d6Smickey 	{ NULL, 0 }
70f74c92d6Smickey };
71f74c92d6Smickey 
72857b0937Smickey int
Xdiskinfo(void)73599546b3Sderaadt Xdiskinfo(void)
74f74c92d6Smickey {
7536fe99eeSmickey 	dump_diskinfo();
76f74c92d6Smickey 	return 0;
77f74c92d6Smickey }
78f74c92d6Smickey 
79857b0937Smickey #ifdef DEBUG
80857b0937Smickey int
Xregs(void)81599546b3Sderaadt Xregs(void)
82484dd08aSmickey {
83484dd08aSmickey 	DUMP_REGS;
84484dd08aSmickey 	return 0;
85484dd08aSmickey }
86857b0937Smickey #endif
8756427238Sweingart 
88857b0937Smickey int
Xboot(void)89599546b3Sderaadt Xboot(void)
9056427238Sweingart {
91fce71ba5Syasuoka #ifdef EFIBOOT
92fce71ba5Syasuoka 	printf("Not supported yet\n");
93fce71ba5Syasuoka #else
9456427238Sweingart 	int dev, part, st;
95fce71ba5Syasuoka 	struct diskinfo *dip;
96857b0937Smickey 	char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
9756427238Sweingart 
9856427238Sweingart 	if (cmd.argc != 2) {
997040ffa9Sweingart 		printf("machine boot {fd,hd}<0123>[abcd]\n");
1007040ffa9Sweingart 		printf("Where [0123] is the disk number,"
1017040ffa9Sweingart 		    " and [abcd] is the partition.\n");
10256427238Sweingart 		return 0;
10356427238Sweingart 	}
10456427238Sweingart 
10556427238Sweingart 	/* Check arg */
10656427238Sweingart 	if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
10756427238Sweingart 		goto bad;
10856427238Sweingart 	if (cmd.argv[1][1] != 'd')
10956427238Sweingart 		goto bad;
11056427238Sweingart 	if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
11156427238Sweingart 		goto bad;
11261acb34aStom 	if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') &&
11361acb34aStom 	    cmd.argv[1][3] != '\0')
11456427238Sweingart 		goto bad;
11556427238Sweingart 
11656427238Sweingart 	printf("Booting from %s ", cmd.argv[1]);
11756427238Sweingart 
11856427238Sweingart 	dev = (cmd.argv[1][0] == 'h')?0x80:0;
11956427238Sweingart 	dev += (cmd.argv[1][2] - '0');
12056427238Sweingart 	part = (cmd.argv[1][3] - 'a');
12156427238Sweingart 
122*51dff02eSderaadt 	if (part >= 0)
12356427238Sweingart 		printf("[%x,%d]\n", dev, part);
1247040ffa9Sweingart 	else
1257040ffa9Sweingart 		printf("[%x]\n", dev);
12656427238Sweingart 
12756427238Sweingart 	/* Read boot sector from device */
128fce71ba5Syasuoka 	dip = dklookup(dev);
129fce71ba5Syasuoka 	st = dip->diskio(F_READ, dip, 0, 1, buf);
13061acb34aStom 	if (st)
13161acb34aStom 		goto bad;
13256427238Sweingart 
13356427238Sweingart 	/* Frob boot flag in buffer from HD */
134*51dff02eSderaadt 	if ((dev & 0x80) && (part >= 0)) {
13556427238Sweingart 		int i, j;
13656427238Sweingart 
13756427238Sweingart 		for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
13856427238Sweingart 			if (part == i)
1397040ffa9Sweingart 				buf[j] |= 0x80;
14056427238Sweingart 			else
1417040ffa9Sweingart 				buf[j] &= ~0x80;
14256427238Sweingart 	}
14356427238Sweingart 
14456427238Sweingart 	/* Load %dl, ljmp */
1457040ffa9Sweingart 	bcopy(buf, dest, DEV_BSIZE);
1467040ffa9Sweingart 	bootbuf(dest, dev);
14756427238Sweingart 
14856427238Sweingart bad:
14956427238Sweingart 	printf("Invalid device!\n");
150857b0937Smickey #endif
15156427238Sweingart 	return 0;
15256427238Sweingart }
15356427238Sweingart 
154857b0937Smickey int
Xmemory(void)155599546b3Sderaadt Xmemory(void)
15656427238Sweingart {
157857b0937Smickey 	if (cmd.argc >= 2) {
158857b0937Smickey 		int i;
159857b0937Smickey 		/* parse the memory specs */
16056427238Sweingart 
161857b0937Smickey 		for (i = 1; i < cmd.argc; i++) {
162857b0937Smickey 			char *p;
1634a9e4d17Smpf 			long long addr, size;
164bb6df16fSweingart 
165857b0937Smickey 			p = cmd.argv[i];
166857b0937Smickey 
1674a9e4d17Smpf 			size = strtoll(p + 1, &p, 0);
1682ea094c9Sweingart 			/* Size the size */
1692ea094c9Sweingart 			switch (*p) {
1702ea094c9Sweingart 				case 'G':
171da36460dSmlarkin 				case 'g':
1722ea094c9Sweingart 					size *= 1024;
1732ea094c9Sweingart 				case 'M':
174da36460dSmlarkin 				case 'm':
1752ea094c9Sweingart 					size *= 1024;
1762ea094c9Sweingart 				case 'K':
177da36460dSmlarkin 				case 'k':
1782ea094c9Sweingart 					size *= 1024;
1792ea094c9Sweingart 					p++;
1802ea094c9Sweingart 			}
1812ea094c9Sweingart 
18225cde77aSjcs 			/* Handle (possibly non-existent) address part */
1832ea094c9Sweingart 			switch (*p) {
1842ea094c9Sweingart 				case '@':
1854a9e4d17Smpf 					addr = strtoll(p + 1, NULL, 0);
1862ea094c9Sweingart 					break;
1872ea094c9Sweingart 
1882ea094c9Sweingart 				/* Adjust address if we don't need it */
1892ea094c9Sweingart 				default:
1902ea094c9Sweingart 					if (cmd.argv[i][0] == '=')
1912ea094c9Sweingart 						addr = -1;
192857b0937Smickey 					else
193857b0937Smickey 						addr = 0;
1942ea094c9Sweingart 			}
1952ea094c9Sweingart 
1962ea094c9Sweingart 			if (addr == 0 || size == 0) {
197857b0937Smickey 				printf("bad language\n");
198857b0937Smickey 				return 0;
199857b0937Smickey 			} else {
200857b0937Smickey 				switch (cmd.argv[i][0]) {
201857b0937Smickey 				case '-':
202857b0937Smickey 					mem_delete(addr, addr + size);
203857b0937Smickey 					break;
204857b0937Smickey 				case '+':
205857b0937Smickey 					mem_add(addr, addr + size);
206857b0937Smickey 					break;
2072ea094c9Sweingart 				case '=':
2082ea094c9Sweingart 					mem_limit(size);
2092ea094c9Sweingart 					break;
210857b0937Smickey 				default :
211857b0937Smickey 					printf("bad OP\n");
212857b0937Smickey 					return 0;
213857b0937Smickey 				}
214857b0937Smickey 			}
215857b0937Smickey 		}
21656427238Sweingart 	}
21756427238Sweingart 
218857b0937Smickey 	dump_biosmem(NULL);
21956427238Sweingart 
22056427238Sweingart 	return 0;
22156427238Sweingart }
222a1e303c3Skettenis 
223a1e303c3Skettenis int
Xcomaddr(void)224a1e303c3Skettenis Xcomaddr(void)
225a1e303c3Skettenis {
226a1e303c3Skettenis 	extern int com_addr;
227a1e303c3Skettenis 
228a1e303c3Skettenis 	if (cmd.argc >= 2)
229a1e303c3Skettenis 		com_addr = (int)strtol(cmd.argv[1], NULL, 0);
230a1e303c3Skettenis 
231a1e303c3Skettenis 	return 0;
232a1e303c3Skettenis }
233