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