1 /* $OpenBSD: cmd_i386.c,v 1.29 2006/09/18 21:14:15 mpf 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 "debug.h"
37 #include "biosdev.h"
38 #include "libsa.h"
39 #include <cmd.h>
40
41
42 extern const char version[];
43
44 int Xboot(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 { "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 #ifndef _TEST
66 dump_diskinfo();
67 #endif
68 return 0;
69 }
70
71 #ifdef DEBUG
72 int
73 Xregs(void)
74 {
75 DUMP_REGS;
76 return 0;
77 }
78 #endif
79
80 int
81 Xboot(void)
82 {
83 #ifndef _TEST
84 int dev, part, st;
85 bios_diskinfo_t *bd = NULL;
86 char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR;
87
88 if (cmd.argc != 2) {
89 printf("machine boot {fd,hd}<0123>[abcd]\n");
90 printf("Where [0123] is the disk number,"
91 " and [abcd] is the partition.\n");
92 return 0;
93 }
94
95 /* Check arg */
96 if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h')
97 goto bad;
98 if (cmd.argv[1][1] != 'd')
99 goto bad;
100 if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3')
101 goto bad;
102 if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') &&
103 cmd.argv[1][3] != '\0')
104 goto bad;
105
106 printf("Booting from %s ", cmd.argv[1]);
107
108 dev = (cmd.argv[1][0] == 'h')?0x80:0;
109 dev += (cmd.argv[1][2] - '0');
110 part = (cmd.argv[1][3] - 'a');
111
112 if (part > 0)
113 printf("[%x,%d]\n", dev, part);
114 else
115 printf("[%x]\n", dev);
116
117 /* Read boot sector from device */
118 bd = bios_dklookup(dev);
119 st = biosd_io(F_READ, bd, 0, 1, buf);
120 if (st)
121 goto bad;
122
123 /* Frob boot flag in buffer from HD */
124 if ((dev & 0x80) && (part > 0)){
125 int i, j;
126
127 for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
128 if (part == i)
129 buf[j] |= 0x80;
130 else
131 buf[j] &= ~0x80;
132 }
133
134 /* Load %dl, ljmp */
135 bcopy(buf, dest, DEV_BSIZE);
136 bootbuf(dest, dev);
137
138 bad:
139 printf("Invalid device!\n");
140 #endif
141 return 0;
142 }
143
144 int
145 Xmemory(void)
146 {
147 if (cmd.argc >= 2) {
148 int i;
149 /* parse the memory specs */
150
151 for (i = 1; i < cmd.argc; i++) {
152 char *p;
153 long long addr, size;
154
155 p = cmd.argv[i];
156
157 size = strtoll(p + 1, &p, 0);
158 if (*p && *p == '@')
159 addr = strtoll(p + 1, NULL, 0);
160 else
161 addr = 0;
162 if (addr == 0 && (*p != '@' || size == 0)) {
163 printf("bad language\n");
164 return 0;
165 } else {
166 switch (cmd.argv[i][0]) {
167 case '-':
168 mem_delete(addr, addr + size);
169 break;
170 case '+':
171 mem_add(addr, addr + size);
172 break;
173 default :
174 printf("bad OP\n");
175 return 0;
176 }
177 }
178 }
179 }
180
181 dump_biosmem(NULL);
182
183 return 0;
184 }