1 1.45 rin /* $NetBSD: boot.c,v 1.45 2023/06/14 00:42:21 rin Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.1 jmcneill * Copyright (c) 2016 Kimihiro Nonaka <nonaka (at) netbsd.org> 5 1.1 jmcneill * Copyright (c) 2018 Jared McNeill <jmcneill (at) invisible.ca> 6 1.1 jmcneill * All rights reserved. 7 1.1 jmcneill * 8 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 9 1.1 jmcneill * modification, are permitted provided that the following conditions 10 1.1 jmcneill * are met: 11 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 12 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 13 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the 15 1.1 jmcneill * documentation and/or other materials provided with the distribution. 16 1.1 jmcneill * 17 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 1.1 jmcneill * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 1.1 jmcneill * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 1.1 jmcneill * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 1.1 jmcneill * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.1 jmcneill * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 1.1 jmcneill * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 1.1 jmcneill * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 1.1 jmcneill * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 1.1 jmcneill * SUCH DAMAGE. 28 1.1 jmcneill */ 29 1.1 jmcneill 30 1.1 jmcneill #include "efiboot.h" 31 1.3 jmcneill #include "efiblock.h" 32 1.25 jmcneill #include "efifile.h" 33 1.21 riastrad #include "efirng.h" 34 1.22 jmcneill #include "module.h" 35 1.38 jmcneill #include "bootmenu.h" 36 1.38 jmcneill 37 1.38 jmcneill #ifdef EFIBOOT_FDT 38 1.38 jmcneill #include "efifdt.h" 39 1.24 thorpej #include "overlay.h" 40 1.38 jmcneill #endif 41 1.38 jmcneill 42 1.38 jmcneill #ifdef EFIBOOT_ACPI 43 1.38 jmcneill #include "efiacpi.h" 44 1.38 jmcneill #endif 45 1.1 jmcneill 46 1.1 jmcneill #include <sys/bootblock.h> 47 1.1 jmcneill #include <sys/boot_flag.h> 48 1.1 jmcneill #include <machine/limits.h> 49 1.1 jmcneill 50 1.1 jmcneill #include <loadfile.h> 51 1.23 jmcneill #include <bootcfg.h> 52 1.1 jmcneill 53 1.1 jmcneill extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[]; 54 1.1 jmcneill 55 1.1 jmcneill extern char twiddle_toggle; 56 1.1 jmcneill 57 1.11 mrg static const char * const names[] = { 58 1.11 mrg "netbsd", "netbsd.gz", 59 1.11 mrg "onetbsd", "onetbsd.gz", 60 1.11 mrg "netbsd.old", "netbsd.old.gz", 61 1.1 jmcneill }; 62 1.1 jmcneill 63 1.1 jmcneill #define NUMNAMES __arraycount(names) 64 1.1 jmcneill 65 1.13 jmcneill static const char *efi_memory_type[] = { 66 1.13 jmcneill [EfiReservedMemoryType] = "Reserved Memory Type", 67 1.13 jmcneill [EfiLoaderCode] = "Loader Code", 68 1.13 jmcneill [EfiLoaderData] = "Loader Data", 69 1.13 jmcneill [EfiBootServicesCode] = "Boot Services Code", 70 1.13 jmcneill [EfiBootServicesData] = "Boot Services Data", 71 1.13 jmcneill [EfiRuntimeServicesCode] = "Runtime Services Code", 72 1.13 jmcneill [EfiRuntimeServicesData] = "Runtime Services Data", 73 1.13 jmcneill [EfiConventionalMemory] = "Conventional Memory", 74 1.13 jmcneill [EfiUnusableMemory] = "Unusable Memory", 75 1.13 jmcneill [EfiACPIReclaimMemory] = "ACPI Reclaim Memory", 76 1.13 jmcneill [EfiACPIMemoryNVS] = "ACPI Memory NVS", 77 1.13 jmcneill [EfiMemoryMappedIO] = "MMIO", 78 1.13 jmcneill [EfiMemoryMappedIOPortSpace] = "MMIO (Port Space)", 79 1.13 jmcneill [EfiPalCode] = "Pal Code", 80 1.13 jmcneill [EfiPersistentMemory] = "Persistent Memory", 81 1.13 jmcneill }; 82 1.13 jmcneill 83 1.3 jmcneill static char default_device[32]; 84 1.28 jmcneill static int default_fstype = FS_UNUSED; 85 1.6 jmcneill static char initrd_path[255]; 86 1.7 jmcneill static char dtb_path[255]; 87 1.14 jmcneill static char netbsd_path[255]; 88 1.15 skrll static char netbsd_args[255]; 89 1.19 riastrad static char rndseed_path[255]; 90 1.11 mrg 91 1.11 mrg #define DEFFILENAME names[0] 92 1.11 mrg 93 1.11 mrg int set_bootfile(const char *); 94 1.15 skrll int set_bootargs(const char *); 95 1.3 jmcneill 96 1.42 skrll #ifdef EFIBOOT_ACPI 97 1.41 skrll void command_acpi(char *); 98 1.42 skrll #endif 99 1.1 jmcneill void command_boot(char *); 100 1.3 jmcneill void command_dev(char *); 101 1.6 jmcneill void command_initrd(char *); 102 1.19 riastrad void command_rndseed(char *); 103 1.38 jmcneill #ifdef EFIBOOT_FDT 104 1.38 jmcneill void command_dtb(char *); 105 1.24 thorpej void command_dtoverlay(char *); 106 1.24 thorpej void command_dtoverlays(char *); 107 1.38 jmcneill #endif 108 1.22 jmcneill void command_modules(char *); 109 1.22 jmcneill void command_load(char *); 110 1.22 jmcneill void command_unload(char *); 111 1.3 jmcneill void command_ls(char *); 112 1.37 jmcneill void command_gop(char *); 113 1.13 jmcneill void command_mem(char *); 114 1.23 jmcneill void command_menu(char *); 115 1.1 jmcneill void command_reset(char *); 116 1.39 jmcneill void command_setup(char *); 117 1.43 jmcneill void command_userconf(char *); 118 1.1 jmcneill void command_version(char *); 119 1.1 jmcneill void command_quit(char *); 120 1.1 jmcneill 121 1.1 jmcneill const struct boot_command commands[] = { 122 1.42 skrll #ifdef EFIBOOT_ACPI 123 1.41 skrll { "acpi", command_acpi, "acpi [{on|off}]" }, 124 1.42 skrll #endif 125 1.6 jmcneill { "boot", command_boot, "boot [dev:][filename] [args]\n (ex. \"hd0a:\\netbsd.old -s\"" }, 126 1.3 jmcneill { "dev", command_dev, "dev" }, 127 1.38 jmcneill #ifdef EFIBOOT_FDT 128 1.7 jmcneill { "dtb", command_dtb, "dtb [dev:][filename]" }, 129 1.38 jmcneill { "dtoverlay", command_dtoverlay, "dtoverlay [dev:][filename]" }, 130 1.38 jmcneill { "dtoverlays", command_dtoverlays, "dtoverlays [{on|off|reset}]" }, 131 1.38 jmcneill #endif 132 1.6 jmcneill { "initrd", command_initrd, "initrd [dev:][filename]" }, 133 1.35 jmcneill { "fs", command_initrd, NULL }, 134 1.19 riastrad { "rndseed", command_rndseed, "rndseed [dev:][filename]" }, 135 1.22 jmcneill { "modules", command_modules, "modules [{on|off|reset}]" }, 136 1.22 jmcneill { "load", command_load, "load <module_name>" }, 137 1.22 jmcneill { "unload", command_unload, "unload <module_name>" }, 138 1.4 jmcneill { "ls", command_ls, "ls [hdNn:/path]" }, 139 1.37 jmcneill { "gop", command_gop, "gop [mode]" }, 140 1.13 jmcneill { "mem", command_mem, "mem" }, 141 1.23 jmcneill { "menu", command_menu, "menu" }, 142 1.9 jmcneill { "reboot", command_reset, "reboot|reset" }, 143 1.9 jmcneill { "reset", command_reset, NULL }, 144 1.39 jmcneill { "setup", command_setup, "setup" }, 145 1.43 jmcneill { "userconf", command_userconf, "userconf <command>" }, 146 1.1 jmcneill { "version", command_version, "version" }, 147 1.20 jmcneill { "ver", command_version, NULL }, 148 1.1 jmcneill { "help", command_help, "help|?" }, 149 1.1 jmcneill { "?", command_help, NULL }, 150 1.1 jmcneill { "quit", command_quit, "quit" }, 151 1.45 rin { NULL, NULL, NULL }, 152 1.1 jmcneill }; 153 1.1 jmcneill 154 1.28 jmcneill static int 155 1.28 jmcneill bootcfg_path(char *pathbuf, size_t pathbuflen) 156 1.28 jmcneill { 157 1.28 jmcneill 158 1.28 jmcneill /* 159 1.30 rin * Fallback to default_device 160 1.30 rin * - for ISO9660 (efi_file_path() succeeds but does not work correctly) 161 1.30 rin * - or whenever efi_file_path() fails (due to broken firmware) 162 1.28 jmcneill */ 163 1.30 rin if (default_fstype == FS_ISO9660 || efi_bootdp == NULL || 164 1.30 rin efi_file_path(efi_bootdp, BOOTCFG_FILENAME, pathbuf, pathbuflen)) 165 1.30 rin snprintf(pathbuf, pathbuflen, "%s:%s", default_device, 166 1.30 rin BOOTCFG_FILENAME); 167 1.28 jmcneill 168 1.30 rin return 0; 169 1.28 jmcneill } 170 1.28 jmcneill 171 1.1 jmcneill void 172 1.1 jmcneill command_help(char *arg) 173 1.1 jmcneill { 174 1.1 jmcneill int n; 175 1.1 jmcneill 176 1.1 jmcneill printf("commands are:\n"); 177 1.1 jmcneill for (n = 0; commands[n].c_name; n++) { 178 1.1 jmcneill if (commands[n].c_help) 179 1.1 jmcneill printf("%s\n", commands[n].c_help); 180 1.1 jmcneill } 181 1.1 jmcneill } 182 1.1 jmcneill 183 1.42 skrll #ifdef EFIBOOT_ACPI 184 1.1 jmcneill void 185 1.41 skrll command_acpi(char *arg) 186 1.41 skrll { 187 1.41 skrll if (arg && *arg) { 188 1.41 skrll if (strcmp(arg, "on") == 0) 189 1.41 skrll efi_acpi_enable(1); 190 1.41 skrll else if (strcmp(arg, "off") == 0) 191 1.41 skrll efi_acpi_enable(0); 192 1.41 skrll else { 193 1.41 skrll command_help(""); 194 1.41 skrll return; 195 1.41 skrll } 196 1.41 skrll } else { 197 1.41 skrll printf("ACPI support is %sabled\n", 198 1.41 skrll efi_acpi_enabled() ? "en" : "dis"); 199 1.41 skrll } 200 1.41 skrll } 201 1.42 skrll #endif 202 1.42 skrll 203 1.41 skrll void 204 1.1 jmcneill command_boot(char *arg) 205 1.1 jmcneill { 206 1.1 jmcneill char *fname = arg; 207 1.11 mrg const char *kernel = *fname ? fname : bootfile; 208 1.1 jmcneill char *bootargs = gettrailer(arg); 209 1.1 jmcneill 210 1.11 mrg if (!kernel || !*kernel) 211 1.11 mrg kernel = DEFFILENAME; 212 1.11 mrg 213 1.16 skrll if (!*bootargs) 214 1.16 skrll bootargs = netbsd_args; 215 1.16 skrll 216 1.32 jmcneill efi_block_set_readahead(true); 217 1.11 mrg exec_netbsd(kernel, bootargs); 218 1.32 jmcneill efi_block_set_readahead(false); 219 1.1 jmcneill } 220 1.1 jmcneill 221 1.1 jmcneill void 222 1.3 jmcneill command_dev(char *arg) 223 1.3 jmcneill { 224 1.3 jmcneill if (arg && *arg) { 225 1.3 jmcneill set_default_device(arg); 226 1.3 jmcneill } else { 227 1.3 jmcneill efi_block_show(); 228 1.4 jmcneill efi_net_show(); 229 1.3 jmcneill } 230 1.3 jmcneill 231 1.3 jmcneill if (strlen(default_device) > 0) { 232 1.3 jmcneill printf("\n"); 233 1.3 jmcneill printf("default: %s\n", default_device); 234 1.3 jmcneill } 235 1.3 jmcneill } 236 1.3 jmcneill 237 1.3 jmcneill void 238 1.38 jmcneill command_initrd(char *arg) 239 1.7 jmcneill { 240 1.38 jmcneill set_initrd_path(arg); 241 1.7 jmcneill } 242 1.7 jmcneill 243 1.7 jmcneill void 244 1.38 jmcneill command_rndseed(char *arg) 245 1.18 thorpej { 246 1.38 jmcneill set_rndseed_path(arg); 247 1.18 thorpej } 248 1.18 thorpej 249 1.38 jmcneill #ifdef EFIBOOT_FDT 250 1.18 thorpej void 251 1.38 jmcneill command_dtb(char *arg) 252 1.24 thorpej { 253 1.38 jmcneill set_dtb_path(arg); 254 1.24 thorpej } 255 1.24 thorpej 256 1.24 thorpej void 257 1.24 thorpej command_dtoverlays(char *arg) 258 1.6 jmcneill { 259 1.24 thorpej if (arg && *arg) { 260 1.24 thorpej if (strcmp(arg, "on") == 0) 261 1.24 thorpej dtoverlay_enable(1); 262 1.24 thorpej else if (strcmp(arg, "off") == 0) 263 1.24 thorpej dtoverlay_enable(0); 264 1.24 thorpej else if (strcmp(arg, "reset") == 0) 265 1.24 thorpej dtoverlay_remove_all(); 266 1.24 thorpej else { 267 1.24 thorpej command_help(""); 268 1.24 thorpej return; 269 1.24 thorpej } 270 1.24 thorpej } else { 271 1.24 thorpej printf("Device Tree overlays are %sabled\n", 272 1.24 thorpej dtoverlay_enabled ? "en" : "dis"); 273 1.24 thorpej } 274 1.6 jmcneill } 275 1.6 jmcneill 276 1.6 jmcneill void 277 1.24 thorpej command_dtoverlay(char *arg) 278 1.19 riastrad { 279 1.24 thorpej if (!arg || !*arg) { 280 1.24 thorpej command_help(""); 281 1.24 thorpej return; 282 1.24 thorpej } 283 1.24 thorpej 284 1.24 thorpej dtoverlay_add(arg); 285 1.19 riastrad } 286 1.38 jmcneill #endif 287 1.19 riastrad 288 1.19 riastrad void 289 1.22 jmcneill command_modules(char *arg) 290 1.22 jmcneill { 291 1.22 jmcneill if (arg && *arg) { 292 1.22 jmcneill if (strcmp(arg, "on") == 0) 293 1.22 jmcneill module_enable(1); 294 1.22 jmcneill else if (strcmp(arg, "off") == 0) 295 1.22 jmcneill module_enable(0); 296 1.22 jmcneill else if (strcmp(arg, "reset") == 0) 297 1.22 jmcneill module_remove_all(); 298 1.22 jmcneill else { 299 1.22 jmcneill command_help(""); 300 1.22 jmcneill return; 301 1.22 jmcneill } 302 1.22 jmcneill } else { 303 1.22 jmcneill printf("modules are %sabled\n", module_enabled ? "en" : "dis"); 304 1.22 jmcneill } 305 1.22 jmcneill } 306 1.22 jmcneill 307 1.22 jmcneill void 308 1.22 jmcneill command_load(char *arg) 309 1.22 jmcneill { 310 1.22 jmcneill if (!arg || !*arg) { 311 1.22 jmcneill command_help(""); 312 1.22 jmcneill return; 313 1.22 jmcneill } 314 1.22 jmcneill 315 1.22 jmcneill module_add(arg); 316 1.22 jmcneill } 317 1.22 jmcneill 318 1.22 jmcneill void 319 1.22 jmcneill command_unload(char *arg) 320 1.22 jmcneill { 321 1.22 jmcneill if (!arg || !*arg) { 322 1.22 jmcneill command_help(""); 323 1.22 jmcneill return; 324 1.22 jmcneill } 325 1.22 jmcneill 326 1.22 jmcneill module_remove(arg); 327 1.22 jmcneill } 328 1.22 jmcneill 329 1.22 jmcneill void 330 1.3 jmcneill command_ls(char *arg) 331 1.3 jmcneill { 332 1.3 jmcneill ls(arg); 333 1.3 jmcneill } 334 1.3 jmcneill 335 1.3 jmcneill void 336 1.37 jmcneill command_gop(char *arg) 337 1.37 jmcneill { 338 1.37 jmcneill UINT32 mode; 339 1.37 jmcneill 340 1.37 jmcneill if (!arg || !*arg) { 341 1.37 jmcneill efi_gop_dump(); 342 1.37 jmcneill return; 343 1.37 jmcneill } 344 1.37 jmcneill 345 1.37 jmcneill mode = atoi(arg); 346 1.37 jmcneill efi_gop_setmode(mode); 347 1.37 jmcneill } 348 1.37 jmcneill 349 1.37 jmcneill void 350 1.13 jmcneill command_mem(char *arg) 351 1.13 jmcneill { 352 1.13 jmcneill EFI_MEMORY_DESCRIPTOR *md, *memmap; 353 1.13 jmcneill UINTN nentries, mapkey, descsize; 354 1.13 jmcneill UINT32 descver; 355 1.13 jmcneill int n; 356 1.13 jmcneill 357 1.13 jmcneill printf("Type Start End Attributes\n"); 358 1.13 jmcneill printf("---------------------- ---------------- ---------------- ----------------\n"); 359 1.13 jmcneill memmap = LibMemoryMap(&nentries, &mapkey, &descsize, &descver); 360 1.13 jmcneill for (n = 0, md = memmap; n < nentries; n++, md = NextMemoryDescriptor(md, descsize)) { 361 1.13 jmcneill const char *mem_type = "<unknown>"; 362 1.13 jmcneill if (md->Type < __arraycount(efi_memory_type)) 363 1.13 jmcneill mem_type = efi_memory_type[md->Type]; 364 1.13 jmcneill 365 1.13 jmcneill printf("%-22s %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", 366 1.13 jmcneill mem_type, md->PhysicalStart, md->PhysicalStart + (md->NumberOfPages * EFI_PAGE_SIZE) - 1, 367 1.13 jmcneill md->Attribute); 368 1.13 jmcneill } 369 1.13 jmcneill } 370 1.13 jmcneill 371 1.13 jmcneill void 372 1.23 jmcneill command_menu(char *arg) 373 1.23 jmcneill { 374 1.23 jmcneill if (bootcfg_info.nummenu == 0) { 375 1.23 jmcneill printf("No menu defined in boot.cfg\n"); 376 1.23 jmcneill return; 377 1.23 jmcneill } 378 1.23 jmcneill 379 1.23 jmcneill doboottypemenu(); /* Does not return */ 380 1.23 jmcneill } 381 1.23 jmcneill 382 1.23 jmcneill void 383 1.44 jmcneill command_printtab(const char *key, const char *fmt, ...) 384 1.44 jmcneill { 385 1.44 jmcneill va_list ap; 386 1.44 jmcneill 387 1.44 jmcneill printf("%-16s: ", key); 388 1.44 jmcneill 389 1.44 jmcneill va_start(ap, fmt); 390 1.44 jmcneill vprintf(fmt, ap); 391 1.44 jmcneill va_end(ap); 392 1.44 jmcneill } 393 1.44 jmcneill 394 1.44 jmcneill void 395 1.1 jmcneill command_version(char *arg) 396 1.1 jmcneill { 397 1.26 jmcneill char pathbuf[80]; 398 1.1 jmcneill char *ufirmware; 399 1.39 jmcneill const UINT64 *osindsup; 400 1.1 jmcneill int rv; 401 1.1 jmcneill 402 1.44 jmcneill command_printtab("Version", "%s (%s)\n", 403 1.44 jmcneill bootprog_rev, bootprog_kernrev); 404 1.44 jmcneill command_printtab("EFI", "%d.%02d\n", 405 1.1 jmcneill ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); 406 1.44 jmcneill 407 1.1 jmcneill ufirmware = NULL; 408 1.1 jmcneill rv = ucs2_to_utf8(ST->FirmwareVendor, &ufirmware); 409 1.1 jmcneill if (rv == 0) { 410 1.44 jmcneill command_printtab("Firmware", "%s (rev 0x%x)\n", ufirmware, 411 1.17 jmcneill ST->FirmwareRevision); 412 1.1 jmcneill FreePool(ufirmware); 413 1.1 jmcneill } 414 1.28 jmcneill if (bootcfg_path(pathbuf, sizeof(pathbuf)) == 0) { 415 1.44 jmcneill command_printtab("Config path", "%s\n", pathbuf); 416 1.26 jmcneill } 417 1.5 jmcneill 418 1.39 jmcneill osindsup = LibGetVariable(L"OsIndicationsSupported", &EfiGlobalVariable); 419 1.39 jmcneill if (osindsup != NULL) { 420 1.44 jmcneill command_printtab("OS Indications", "0x%" PRIx64 "\n", 421 1.44 jmcneill *osindsup); 422 1.39 jmcneill } 423 1.39 jmcneill 424 1.38 jmcneill #ifdef EFIBOOT_FDT 425 1.5 jmcneill efi_fdt_show(); 426 1.38 jmcneill #endif 427 1.38 jmcneill #ifdef EFIBOOT_ACPI 428 1.10 jmcneill efi_acpi_show(); 429 1.38 jmcneill #endif 430 1.21 riastrad efi_rng_show(); 431 1.29 jmcneill efi_md_show(); 432 1.37 jmcneill efi_gop_show(); 433 1.1 jmcneill } 434 1.1 jmcneill 435 1.1 jmcneill void 436 1.1 jmcneill command_quit(char *arg) 437 1.1 jmcneill { 438 1.1 jmcneill efi_exit(); 439 1.1 jmcneill } 440 1.1 jmcneill 441 1.9 jmcneill void 442 1.9 jmcneill command_reset(char *arg) 443 1.9 jmcneill { 444 1.9 jmcneill efi_reboot(); 445 1.9 jmcneill } 446 1.9 jmcneill 447 1.39 jmcneill void 448 1.39 jmcneill command_setup(char *arg) 449 1.39 jmcneill { 450 1.39 jmcneill EFI_STATUS status; 451 1.39 jmcneill const UINT64 *osindsup; 452 1.39 jmcneill UINT64 osind; 453 1.39 jmcneill 454 1.39 jmcneill osindsup = LibGetVariable(L"OsIndicationsSupported", &EfiGlobalVariable); 455 1.39 jmcneill if (osindsup == NULL || (*osindsup & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) == 0) { 456 1.39 jmcneill printf("Not supported by firmware\n"); 457 1.39 jmcneill return; 458 1.39 jmcneill } 459 1.39 jmcneill 460 1.39 jmcneill osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; 461 1.39 jmcneill status = LibSetNVVariable(L"OsIndications", &EfiGlobalVariable, sizeof(osind), &osind); 462 1.39 jmcneill if (EFI_ERROR(status)) { 463 1.39 jmcneill printf("Failed to set OsIndications variable: %lu\n", (u_long)status); 464 1.39 jmcneill return; 465 1.39 jmcneill } 466 1.39 jmcneill 467 1.39 jmcneill efi_reboot(); 468 1.39 jmcneill } 469 1.39 jmcneill 470 1.43 jmcneill void 471 1.43 jmcneill command_userconf(char *arg) 472 1.43 jmcneill { 473 1.43 jmcneill userconf_add(arg); 474 1.43 jmcneill } 475 1.43 jmcneill 476 1.3 jmcneill int 477 1.11 mrg set_default_device(const char *arg) 478 1.3 jmcneill { 479 1.3 jmcneill if (strlen(arg) + 1 > sizeof(default_device)) 480 1.3 jmcneill return ERANGE; 481 1.3 jmcneill strcpy(default_device, arg); 482 1.3 jmcneill return 0; 483 1.3 jmcneill } 484 1.3 jmcneill 485 1.3 jmcneill char * 486 1.3 jmcneill get_default_device(void) 487 1.3 jmcneill { 488 1.3 jmcneill return default_device; 489 1.3 jmcneill } 490 1.3 jmcneill 491 1.28 jmcneill void 492 1.28 jmcneill set_default_fstype(int fstype) 493 1.28 jmcneill { 494 1.28 jmcneill default_fstype = fstype; 495 1.28 jmcneill } 496 1.28 jmcneill 497 1.28 jmcneill int 498 1.28 jmcneill get_default_fstype(void) 499 1.28 jmcneill { 500 1.28 jmcneill return default_fstype; 501 1.28 jmcneill } 502 1.28 jmcneill 503 1.6 jmcneill int 504 1.11 mrg set_initrd_path(const char *arg) 505 1.6 jmcneill { 506 1.6 jmcneill if (strlen(arg) + 1 > sizeof(initrd_path)) 507 1.6 jmcneill return ERANGE; 508 1.6 jmcneill strcpy(initrd_path, arg); 509 1.6 jmcneill return 0; 510 1.6 jmcneill } 511 1.6 jmcneill 512 1.6 jmcneill char * 513 1.6 jmcneill get_initrd_path(void) 514 1.6 jmcneill { 515 1.6 jmcneill return initrd_path; 516 1.6 jmcneill } 517 1.6 jmcneill 518 1.7 jmcneill int 519 1.11 mrg set_dtb_path(const char *arg) 520 1.7 jmcneill { 521 1.7 jmcneill if (strlen(arg) + 1 > sizeof(dtb_path)) 522 1.7 jmcneill return ERANGE; 523 1.7 jmcneill strcpy(dtb_path, arg); 524 1.7 jmcneill return 0; 525 1.7 jmcneill } 526 1.7 jmcneill 527 1.7 jmcneill char * 528 1.7 jmcneill get_dtb_path(void) 529 1.7 jmcneill { 530 1.7 jmcneill return dtb_path; 531 1.7 jmcneill } 532 1.7 jmcneill 533 1.11 mrg int 534 1.19 riastrad set_rndseed_path(const char *arg) 535 1.19 riastrad { 536 1.19 riastrad if (strlen(arg) + 1 > sizeof(rndseed_path)) 537 1.19 riastrad return ERANGE; 538 1.19 riastrad strcpy(rndseed_path, arg); 539 1.19 riastrad return 0; 540 1.19 riastrad } 541 1.19 riastrad 542 1.19 riastrad char * 543 1.19 riastrad get_rndseed_path(void) 544 1.19 riastrad { 545 1.19 riastrad return rndseed_path; 546 1.19 riastrad } 547 1.19 riastrad 548 1.19 riastrad int 549 1.11 mrg set_bootfile(const char *arg) 550 1.11 mrg { 551 1.14 jmcneill if (strlen(arg) + 1 > sizeof(netbsd_path)) 552 1.11 mrg return ERANGE; 553 1.14 jmcneill strcpy(netbsd_path, arg); 554 1.11 mrg return 0; 555 1.11 mrg } 556 1.11 mrg 557 1.15 skrll int 558 1.15 skrll set_bootargs(const char *arg) 559 1.15 skrll { 560 1.15 skrll if (strlen(arg) + 1 > sizeof(netbsd_args)) 561 1.15 skrll return ERANGE; 562 1.15 skrll strcpy(netbsd_args, arg); 563 1.15 skrll return 0; 564 1.15 skrll } 565 1.15 skrll 566 1.1 jmcneill void 567 1.1 jmcneill boot(void) 568 1.1 jmcneill { 569 1.25 jmcneill char pathbuf[80]; 570 1.1 jmcneill int currname, c; 571 1.1 jmcneill 572 1.28 jmcneill if (bootcfg_path(pathbuf, sizeof(pathbuf)) == 0) { 573 1.25 jmcneill twiddle_toggle = 1; 574 1.25 jmcneill parsebootconf(pathbuf); 575 1.25 jmcneill } 576 1.23 jmcneill 577 1.23 jmcneill if (bootcfg_info.clear) 578 1.23 jmcneill uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); 579 1.23 jmcneill 580 1.36 nia print_bootcfg_banner(bootprog_name, bootprog_rev); 581 1.23 jmcneill 582 1.23 jmcneill /* Display menu if configured */ 583 1.23 jmcneill if (bootcfg_info.nummenu > 0) { 584 1.23 jmcneill doboottypemenu(); /* No return */ 585 1.23 jmcneill } 586 1.23 jmcneill 587 1.11 mrg printf("Press return to boot now, any other key for boot prompt\n"); 588 1.1 jmcneill 589 1.14 jmcneill if (netbsd_path[0] != '\0') 590 1.11 mrg currname = -1; 591 1.11 mrg else 592 1.11 mrg currname = 0; 593 1.11 mrg 594 1.12 mrg for (; currname < (int)NUMNAMES; currname++) { 595 1.11 mrg if (currname >= 0) 596 1.11 mrg set_bootfile(names[currname]); 597 1.16 skrll printf("booting %s%s%s - starting in ", netbsd_path, 598 1.16 skrll netbsd_args[0] != '\0' ? " " : "", netbsd_args); 599 1.1 jmcneill 600 1.40 jmcneill c = awaitkey(bootcfg_info.timeout, 1); 601 1.11 mrg if (c != '\r' && c != '\n' && c != '\0') 602 1.1 jmcneill bootprompt(); /* does not return */ 603 1.1 jmcneill 604 1.32 jmcneill efi_block_set_readahead(true); 605 1.15 skrll exec_netbsd(netbsd_path, netbsd_args); 606 1.32 jmcneill efi_block_set_readahead(false); 607 1.1 jmcneill } 608 1.1 jmcneill 609 1.1 jmcneill bootprompt(); /* does not return */ 610 1.1 jmcneill } 611