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