1 /* $OpenBSD: cmd_i386.c,v 1.10 2016/06/10 18:36:06 jcs 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 #ifdef EFIBOOT 41 #include "efiboot.h" 42 #include "efidev.h" 43 #endif 44 45 extern const char version[]; 46 47 int Xboot(void); 48 int Xcomaddr(void); 49 int Xdiskinfo(void); 50 int Xmemory(void); 51 int Xregs(void); 52 53 /* From gidt.S */ 54 int bootbuf(void *, int); 55 56 const struct cmd_table cmd_machine[] = { 57 { "boot", CMDT_CMD, Xboot }, 58 { "comaddr", CMDT_CMD, Xcomaddr }, 59 { "diskinfo", CMDT_CMD, Xdiskinfo }, 60 { "memory", CMDT_CMD, Xmemory }, 61 #ifdef EFIBOOT 62 { "video", CMDT_CMD, Xvideo_efi }, 63 { "exit", CMDT_CMD, Xexit_efi }, 64 { "poweroff", CMDT_CMD, Xpoweroff_efi }, 65 #endif 66 #ifdef DEBUG 67 { "regs", CMDT_CMD, Xregs }, 68 #endif 69 { NULL, 0 } 70 }; 71 72 int 73 Xdiskinfo(void) 74 { 75 #ifndef EFIBOOT 76 dump_diskinfo(); 77 #else 78 efi_dump_diskinfo(); 79 #endif 80 return 0; 81 } 82 83 #ifdef DEBUG 84 int 85 Xregs(void) 86 { 87 DUMP_REGS; 88 return 0; 89 } 90 #endif 91 92 int 93 Xboot(void) 94 { 95 #ifdef EFIBOOT 96 printf("Not supported yet\n"); 97 #else 98 int dev, part, st; 99 struct diskinfo *dip; 100 char buf[DEV_BSIZE], *dest = (void *)BOOTBIOS_ADDR; 101 102 if (cmd.argc != 2) { 103 printf("machine boot {fd,hd}<0123>[abcd]\n"); 104 printf("Where [0123] is the disk number," 105 " and [abcd] is the partition.\n"); 106 return 0; 107 } 108 109 /* Check arg */ 110 if (cmd.argv[1][0] != 'f' && cmd.argv[1][0] != 'h') 111 goto bad; 112 if (cmd.argv[1][1] != 'd') 113 goto bad; 114 if (cmd.argv[1][2] < '0' || cmd.argv[1][2] > '3') 115 goto bad; 116 if ((cmd.argv[1][3] < 'a' || cmd.argv[1][3] > 'd') && 117 cmd.argv[1][3] != '\0') 118 goto bad; 119 120 printf("Booting from %s ", cmd.argv[1]); 121 122 dev = (cmd.argv[1][0] == 'h')?0x80:0; 123 dev += (cmd.argv[1][2] - '0'); 124 part = (cmd.argv[1][3] - 'a'); 125 126 if (part > 0) 127 printf("[%x,%d]\n", dev, part); 128 else 129 printf("[%x]\n", dev); 130 131 /* Read boot sector from device */ 132 dip = dklookup(dev); 133 st = dip->diskio(F_READ, dip, 0, 1, buf); 134 if (st) 135 goto bad; 136 137 /* Frob boot flag in buffer from HD */ 138 if ((dev & 0x80) && (part > 0)){ 139 int i, j; 140 141 for (i = 0, j = DOSPARTOFF; i < 4; i++, j += 16) 142 if (part == i) 143 buf[j] |= 0x80; 144 else 145 buf[j] &= ~0x80; 146 } 147 148 /* Load %dl, ljmp */ 149 bcopy(buf, dest, DEV_BSIZE); 150 bootbuf(dest, dev); 151 152 bad: 153 printf("Invalid device!\n"); 154 #endif 155 return 0; 156 } 157 158 int 159 Xmemory(void) 160 { 161 if (cmd.argc >= 2) { 162 int i; 163 /* parse the memory specs */ 164 165 for (i = 1; i < cmd.argc; i++) { 166 char *p; 167 long long addr, size; 168 169 p = cmd.argv[i]; 170 171 size = strtoll(p + 1, &p, 0); 172 /* Size the size */ 173 switch (*p) { 174 case 'G': 175 case 'g': 176 size *= 1024; 177 case 'M': 178 case 'm': 179 size *= 1024; 180 case 'K': 181 case 'k': 182 size *= 1024; 183 p++; 184 } 185 186 /* Handle (possibly non-existent) address part */ 187 switch (*p) { 188 case '@': 189 addr = strtoll(p + 1, NULL, 0); 190 break; 191 192 /* Adjust address if we don't need it */ 193 default: 194 if (cmd.argv[i][0] == '=') 195 addr = -1; 196 else 197 addr = 0; 198 } 199 200 if (addr == 0 || size == 0) { 201 printf("bad language\n"); 202 return 0; 203 } else { 204 switch (cmd.argv[i][0]) { 205 case '-': 206 mem_delete(addr, addr + size); 207 break; 208 case '+': 209 mem_add(addr, addr + size); 210 break; 211 case '=': 212 mem_limit(size); 213 break; 214 default : 215 printf("bad OP\n"); 216 return 0; 217 } 218 } 219 } 220 } 221 222 dump_biosmem(NULL); 223 224 return 0; 225 } 226 227 int 228 Xcomaddr(void) 229 { 230 extern int com_addr; 231 232 if (cmd.argc >= 2) 233 com_addr = (int)strtol(cmd.argv[1], NULL, 0); 234 235 return 0; 236 } 237