1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * This file contains the functions for performing Fast Reboot -- a 29 * reboot which bypasses the firmware and bootloader, considerably 30 * reducing downtime. 31 * 32 * load_kernel(): This function is invoked by mdpreboot() in the reboot 33 * path. It loads the new kernel and boot archive into memory, builds 34 * the data structure containing sufficient information about the new 35 * kernel and boot archive to be passed to the fast reboot switcher 36 * (see fb_swtch_src.s for details). When invoked the switcher relocates 37 * the new kernel and boot archive to physically contiguous low memory, 38 * similar to where the boot loader would have loaded them, and jumps to 39 * the new kernel. 40 * 41 * The physical addresses of the memory allocated for the new kernel, boot 42 * archive and their page tables must be above where the boot archive ends 43 * after it has been relocated by the switcher, otherwise the new files 44 * and their page tables could be overridden during relocation. 45 * 46 * fast_reboot(): This function is invoked by mdboot() once it's determined 47 * that the system is capable of fast reboot. It jumps to the fast reboot 48 * switcher with the data structure built by load_kernel() as the argument. 49 */ 50 51 #include <sys/types.h> 52 #include <sys/param.h> 53 #include <sys/segments.h> 54 #include <sys/sysmacros.h> 55 #include <sys/vm.h> 56 57 #include <sys/proc.h> 58 #include <sys/buf.h> 59 #include <sys/kmem.h> 60 61 #include <sys/reboot.h> 62 #include <sys/uadmin.h> 63 64 #include <sys/cred.h> 65 #include <sys/vnode.h> 66 #include <sys/file.h> 67 68 #include <sys/cmn_err.h> 69 #include <sys/dumphdr.h> 70 #include <sys/bootconf.h> 71 #include <sys/ddidmareq.h> 72 #include <sys/varargs.h> 73 #include <sys/promif.h> 74 #include <sys/modctl.h> 75 76 #include <vm/hat.h> 77 #include <vm/as.h> 78 #include <vm/page.h> 79 #include <vm/seg.h> 80 #include <vm/hat_i86.h> 81 #include <sys/vm_machparam.h> 82 #include <sys/archsystm.h> 83 #include <sys/machsystm.h> 84 #include <sys/mman.h> 85 #include <sys/x86_archext.h> 86 87 #include <sys/fastboot.h> 88 #include <sys/machelf.h> 89 #include <sys/kobj.h> 90 #include <sys/multiboot.h> 91 92 /* 93 * Data structure containing necessary information for the fast reboot 94 * switcher to jump to the new kernel. 95 */ 96 fastboot_info_t newkernel = { 0 }; 97 98 static char fastboot_filename[2][OBP_MAXPATHLEN] = { { 0 }, { 0 }}; 99 static x86pte_t ptp_bits = PT_VALID | PT_REF | PT_USER | PT_WRITABLE; 100 static x86pte_t pte_bits = 101 PT_VALID | PT_REF | PT_MOD | PT_NOCONSIST | PT_WRITABLE; 102 static uint_t fastboot_shift_amt_pae[] = {12, 21, 30, 39}; 103 104 int fastboot_debug = 0; 105 int fastboot_contig = 0; 106 107 /* 108 * Fake starting va for new kernel and boot archive. 109 */ 110 static uintptr_t fake_va = FASTBOOT_FAKE_VA; 111 112 /* 113 * Below 1G for page tables as we are using 2G as the fake virtual address for 114 * the new kernel and boot archive. 115 */ 116 static ddi_dma_attr_t fastboot_below_1G_dma_attr = { 117 DMA_ATTR_V0, 118 0x0000000008000000ULL, /* dma_attr_addr_lo: 128MB */ 119 0x000000003FFFFFFFULL, /* dma_attr_addr_hi: 1G */ 120 0x00000000FFFFFFFFULL, /* dma_attr_count_max */ 121 0x0000000000001000ULL, /* dma_attr_align: 4KB */ 122 1, /* dma_attr_burstsize */ 123 1, /* dma_attr_minxfer */ 124 0x00000000FFFFFFFFULL, /* dma_attr_maxxfer */ 125 0x00000000FFFFFFFFULL, /* dma_attr_seg */ 126 1, /* dma_attr_sgllen */ 127 0x1000ULL, /* dma_attr_granular */ 128 0, /* dma_attr_flags */ 129 }; 130 131 static ddi_dma_attr_t fastboot_dma_attr = { 132 DMA_ATTR_V0, 133 0x0000000008000000ULL, /* dma_attr_addr_lo: 128MB */ 134 0x0000000FFFFFFFFFULL, /* dma_attr_addr_hi: 64GB */ 135 0x00000000FFFFFFFFULL, /* dma_attr_count_max */ 136 0x0000000000001000ULL, /* dma_attr_align: 4KB */ 137 1, /* dma_attr_burstsize */ 138 1, /* dma_attr_minxfer */ 139 0x00000000FFFFFFFFULL, /* dma_attr_maxxfer */ 140 0x00000000FFFFFFFFULL, /* dma_attr_seg */ 141 1, /* dma_attr_sgllen */ 142 0x1000ULL, /* dma_attr_granular */ 143 0, /* dma_attr_flags */ 144 }; 145 146 /* 147 * Various information saved from the previous boot to reconstruct 148 * multiboot_info. 149 */ 150 extern multiboot_info_t saved_mbi; 151 extern mb_memory_map_t saved_mmap[FASTBOOT_SAVED_MMAP_COUNT]; 152 extern struct sol_netinfo saved_drives[FASTBOOT_SAVED_DRIVES_COUNT]; 153 extern char saved_cmdline[FASTBOOT_SAVED_CMDLINE_LEN]; 154 extern int saved_cmdline_len; 155 156 extern void* contig_alloc(size_t size, ddi_dma_attr_t *attr, 157 uintptr_t align, int cansleep); 158 extern void contig_free(void *addr, size_t size); 159 160 161 /* PRINTLIKE */ 162 extern void vprintf(const char *, va_list); 163 164 165 /* 166 * Need to be able to get boot_archives from other places 167 */ 168 #define BOOTARCHIVE64 "/platform/i86pc/amd64/boot_archive" 169 #define BOOTARCHIVE32 "/platform/i86pc/boot_archive" 170 #define BOOTARCHIVE_FAILSAFE "/boot/x86.miniroot-safe" 171 #define FAILSAFE_BOOTFILE "/boot/platform/i86pc/kernel/unix" 172 173 static uint_t fastboot_vatoindex(fastboot_info_t *, uintptr_t, int); 174 static void fastboot_map_with_size(fastboot_info_t *, uintptr_t, 175 paddr_t, size_t, int); 176 static void fastboot_build_pagetables(fastboot_info_t *); 177 static int fastboot_build_mbi(char *, fastboot_info_t *); 178 179 static const char fastboot_enomem_msg[] = "Fastboot: Couldn't allocate 0x%" 180 PRIx64" bytes below %s to do fast reboot"; 181 182 static void 183 dprintf(char *fmt, ...) 184 { 185 va_list adx; 186 187 if (!fastboot_debug) 188 return; 189 190 va_start(adx, fmt); 191 vprintf(fmt, adx); 192 va_end(adx); 193 } 194 195 196 /* 197 * Return the index corresponding to a virt address at a given page table level. 198 */ 199 static uint_t 200 fastboot_vatoindex(fastboot_info_t *nk, uintptr_t va, int level) 201 { 202 return ((va >> nk->fi_shift_amt[level]) & (nk->fi_ptes_per_table - 1)); 203 } 204 205 206 /* 207 * Add mapping from vstart to pstart for the specified size. 208 * Only handles 2 level. Must use 2M pages. vstart, pstart 209 * and size should all have been aligned at 2M boundaries. 210 */ 211 static void 212 fastboot_map_with_size(fastboot_info_t *nk, uintptr_t vstart, paddr_t pstart, 213 size_t size, int level) 214 { 215 x86pte_t pteval, *table; 216 uintptr_t vaddr; 217 paddr_t paddr; 218 int index, l; 219 220 table = (x86pte_t *)(nk->fi_pagetable_va); 221 222 for (l = nk->fi_top_level; l >= level; l--) { 223 224 index = fastboot_vatoindex(nk, vstart, l); 225 226 if (l == level) { 227 /* 228 * Last level. Program the page table entries. 229 */ 230 for (vaddr = vstart, paddr = pstart; 231 vaddr < vstart + size; 232 vaddr += (1ULL << nk->fi_shift_amt[l]), 233 paddr += (1ULL << nk->fi_shift_amt[l])) { 234 235 uint_t index = fastboot_vatoindex(nk, vaddr, l); 236 237 if (l > 0) 238 pteval = paddr | pte_bits | PT_PAGESIZE; 239 else 240 pteval = paddr | pte_bits; 241 242 table[index] = pteval; 243 } 244 } else if (table[index] & PT_VALID) { 245 if (l == level) 246 break; 247 248 table = (x86pte_t *) 249 ((uintptr_t)(((paddr_t)table[index] & MMU_PAGEMASK) 250 - nk->fi_pagetable_pa) + nk->fi_pagetable_va); 251 } else { 252 /* 253 * Intermediate levels. Program with either valid 254 * bit or PTP bits. 255 */ 256 if (l == nk->fi_top_level) { 257 table[index] = nk->fi_next_table_pa | PT_VALID; 258 } else { 259 table[index] = nk->fi_next_table_pa | ptp_bits; 260 } 261 table = (x86pte_t *)(nk->fi_next_table_va); 262 nk->fi_next_table_va += MMU_PAGESIZE; 263 nk->fi_next_table_pa += MMU_PAGESIZE; 264 } 265 } 266 } 267 268 /* 269 * Build page tables for the lower 1G of physical memory using 2M 270 * pages, and prepare page tables for mapping new kernel and boot 271 * archive pages using 4K pages. 272 */ 273 static void 274 fastboot_build_pagetables(fastboot_info_t *nk) 275 { 276 /* 277 * Map lower 1G physical memory. Use large pages. 278 */ 279 fastboot_map_with_size(nk, 0, 0, ONE_GIG, 1); 280 281 /* 282 * Map one 4K page to get the middle page tables set up. 283 */ 284 fake_va = P2ALIGN_TYPED(fake_va, nk->fi_lpagesize, uintptr_t); 285 fastboot_map_with_size(nk, fake_va, 286 nk->fi_files[0].fb_pte_list_va[0] & MMU_PAGEMASK, PAGESIZE, 0); 287 } 288 289 290 /* 291 * Sanity check. Look for dboot offset. 292 */ 293 static int 294 fastboot_elf64_find_dboot_load_offset(void *img, off_t imgsz, uint32_t *offp) 295 { 296 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)img; 297 Elf64_Phdr *phdr; 298 uint8_t *phdrbase; 299 int i; 300 301 if ((ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize) >= imgsz) 302 return (-1); 303 304 phdrbase = (uint8_t *)img + ehdr->e_phoff; 305 306 for (i = 0; i < ehdr->e_phnum; i++) { 307 phdr = (Elf64_Phdr *)(phdrbase + ehdr->e_phentsize * i); 308 309 if (phdr->p_type == PT_LOAD) { 310 if (phdr->p_vaddr == phdr->p_paddr && 311 phdr->p_vaddr == DBOOT_ENTRY_ADDRESS) { 312 ASSERT(phdr->p_offset <= UINT32_MAX); 313 *offp = (uint32_t)phdr->p_offset; 314 return (0); 315 } 316 } 317 } 318 319 return (-1); 320 } 321 322 323 /* 324 * Initialize text and data section information for 32-bit kernel. 325 */ 326 static int 327 fastboot_elf32_find_loadables(void *img, off_t imgsz, fastboot_section_t *sectp, 328 int *sectcntp, uint32_t *offp) 329 { 330 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)img; 331 Elf32_Phdr *phdr; 332 uint8_t *phdrbase; 333 int i; 334 int used_sections = 0; 335 336 337 if ((ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize) >= imgsz) 338 return (-1); 339 340 phdrbase = (uint8_t *)img + ehdr->e_phoff; 341 342 for (i = 0; i < ehdr->e_phnum; i++) { 343 phdr = (Elf32_Phdr *)(phdrbase + ehdr->e_phentsize * i); 344 345 if (phdr->p_type == PT_INTERP) 346 return (-1); 347 348 if (phdr->p_type != PT_LOAD) 349 continue; 350 351 if (phdr->p_vaddr == phdr->p_paddr && 352 phdr->p_paddr == DBOOT_ENTRY_ADDRESS) { 353 *offp = (uint32_t)phdr->p_offset; 354 } else { 355 sectp[used_sections].fb_sec_offset = phdr->p_offset; 356 sectp[used_sections].fb_sec_paddr = phdr->p_paddr; 357 sectp[used_sections].fb_sec_size = phdr->p_filesz; 358 sectp[used_sections].fb_sec_bss_size = 359 (phdr->p_filesz < phdr->p_memsz) ? 360 (phdr->p_memsz - phdr->p_filesz) : 0; 361 362 used_sections++; 363 } 364 365 } 366 367 *sectcntp = used_sections; 368 return (0); 369 } 370 371 /* 372 * Create multiboot info structure 373 */ 374 static int 375 fastboot_build_mbi(char *mdep, fastboot_info_t *nk) 376 { 377 mb_module_t *mbp; 378 uintptr_t next_addr; 379 uintptr_t new_mbi_pa; 380 size_t size; 381 void *buf = NULL; 382 size_t arglen; 383 char bootargs[OBP_MAXPATHLEN]; 384 385 bzero(bootargs, OBP_MAXPATHLEN); 386 387 if (mdep != NULL && strlen(mdep) != 0) { 388 arglen = strlen(mdep) + 1; 389 } else { 390 arglen = saved_cmdline_len; 391 } 392 393 size = PAGESIZE + P2ROUNDUP(arglen, PAGESIZE); 394 buf = contig_alloc(size, &fastboot_below_1G_dma_attr, PAGESIZE, 0); 395 if (buf == NULL) { 396 cmn_err(CE_WARN, fastboot_enomem_msg, (uint64_t)size, "1G"); 397 return (-1); 398 } 399 400 bzero(buf, size); 401 402 new_mbi_pa = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, (caddr_t)buf)); 403 404 hat_devload(kas.a_hat, (caddr_t)new_mbi_pa, size, 405 mmu_btop(new_mbi_pa), PROT_READ | PROT_WRITE, HAT_LOAD_NOCONSIST); 406 407 nk->fi_new_mbi_pa = (paddr_t)new_mbi_pa; 408 409 bcopy(&saved_mbi, (void *)new_mbi_pa, sizeof (multiboot_info_t)); 410 411 next_addr = new_mbi_pa + sizeof (multiboot_info_t); 412 ((multiboot_info_t *)new_mbi_pa)->mods_addr = next_addr; 413 mbp = (mb_module_t *)(uintptr_t)next_addr; 414 mbp->mod_start = newkernel.fi_files[FASTBOOT_BOOTARCHIVE].fb_dest_pa; 415 mbp->mod_end = newkernel.fi_files[FASTBOOT_BOOTARCHIVE].fb_next_pa; 416 417 next_addr += sizeof (mb_module_t); 418 bcopy(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE], (void *)next_addr, 419 strlen(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE])); 420 421 mbp->mod_name = next_addr; 422 mbp->reserved = 0; 423 next_addr += strlen(fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE]); 424 *(char *)next_addr = '\0'; 425 next_addr++; 426 next_addr = P2ROUNDUP_TYPED(next_addr, 16, uintptr_t); 427 428 ((multiboot_info_t *)new_mbi_pa)->mmap_addr = next_addr; 429 bcopy((void *)(uintptr_t)saved_mmap, (void *)next_addr, 430 saved_mbi.mmap_length); 431 next_addr += saved_mbi.mmap_length; 432 433 ((multiboot_info_t *)new_mbi_pa)->drives_addr = next_addr; 434 bcopy((void *)(uintptr_t)saved_drives, (void *)next_addr, 435 saved_mbi.drives_length); 436 next_addr += saved_mbi.drives_length; 437 438 ((multiboot_info_t *)new_mbi_pa)->cmdline = next_addr; 439 440 if (mdep != NULL && strlen(mdep) != 0) { 441 bcopy(mdep, (void *)(uintptr_t) 442 (((multiboot_info_t *)new_mbi_pa)->cmdline), (arglen - 1)); 443 } else { 444 bcopy((void *)saved_cmdline, (void *)next_addr, (arglen - 1)); 445 } 446 /* Terminate the string */ 447 ((char *)(intptr_t)next_addr)[arglen - 1] = '\0'; 448 449 return (0); 450 } 451 452 /* 453 * Initialize HAT related fields 454 */ 455 static void 456 fastboot_init_fields(fastboot_info_t *nk) 457 { 458 if (x86_feature & X86_PAE) { 459 nk->fi_has_pae = 1; 460 nk->fi_shift_amt = fastboot_shift_amt_pae; 461 nk->fi_ptes_per_table = 512; 462 nk->fi_lpagesize = (2 << 20); /* 2M */ 463 nk->fi_top_level = 2; 464 } 465 } 466 467 /* 468 * Process boot argument 469 */ 470 static void 471 fastboot_parse_mdep(char *mdep, char *kern_bootpath, int *bootpath_len, 472 char *bootargs) 473 { 474 int i; 475 476 /* 477 * If mdep is not NULL, it comes in the format of 478 * mountpoint unix args 479 */ 480 if (mdep != NULL && strlen(mdep) != 0) { 481 if (mdep[0] != '-') { 482 /* First get the root argument */ 483 i = 0; 484 while (mdep[i] != '\0' && mdep[i] != ' ') { 485 i++; 486 } 487 488 if (i < 4 || strncmp(&mdep[i-4], "unix", 4) != 0) { 489 /* mount point */ 490 bcopy(mdep, kern_bootpath, i); 491 kern_bootpath[i] = '\0'; 492 *bootpath_len = i; 493 494 /* 495 * Get the next argument. It should be unix as 496 * we have validated in in halt.c. 497 */ 498 if (strlen(mdep) > i) { 499 mdep += (i + 1); 500 i = 0; 501 while (mdep[i] != '\0' && 502 mdep[i] != ' ') { 503 i++; 504 } 505 } 506 507 } 508 bcopy(mdep, kern_bootfile, i); 509 kern_bootfile[i] = '\0'; 510 bcopy(mdep, bootargs, strlen(mdep)); 511 } else { 512 int off = strlen(kern_bootfile); 513 bcopy(kern_bootfile, bootargs, off); 514 bcopy(" ", &bootargs[off++], 1); 515 bcopy(mdep, &bootargs[off], strlen(mdep)); 516 off += strlen(mdep); 517 bootargs[off] = '\0'; 518 } 519 } 520 } 521 522 /* 523 * Free up the memory we have allocated for this file 524 */ 525 static void 526 fastboot_free_file(fastboot_file_t *fb) 527 { 528 size_t fsize_roundup, pt_size; 529 int pt_entry_count; 530 531 fsize_roundup = P2ROUNDUP_TYPED(fb->fb_size, PAGESIZE, size_t); 532 contig_free((void *)fb->fb_va, fsize_roundup); 533 534 pt_entry_count = (fsize_roundup >> PAGESHIFT) + 1; 535 pt_size = P2ROUNDUP(pt_entry_count * 8, PAGESIZE); 536 contig_free((void *)fb->fb_pte_list_va, pt_size); 537 } 538 539 /* 540 * This function performs the following tasks: 541 * - Read the sizes of the new kernel and boot archive. 542 * - Allocate memory for the new kernel and boot archive. 543 * - Allocate memory for page tables necessary for mapping the memory 544 * allocated for the files. 545 * - Read the new kernel and boot archive into memory. 546 * - Map in the fast reboot switcher. 547 * - Load the fast reboot switcher to FASTBOOT_SWTCH_PA. 548 * - Build the new multiboot_info structure 549 * - Build page tables for the low 1G of physical memory. 550 * - Mark the data structure as valid if all steps have succeeded. 551 */ 552 void 553 load_kernel(char *mdep) 554 { 555 void *buf = NULL; 556 int i; 557 fastboot_file_t *fb; 558 uint32_t dboot_start_offset; 559 char kern_bootpath[OBP_MAXPATHLEN]; 560 char bootargs[OBP_MAXPATHLEN]; 561 extern uintptr_t postbootkernelbase; 562 extern char fb_swtch_image[]; 563 int bootpath_len = 0; 564 int is_failsafe = 0; 565 int is_retry = 0; 566 uint64_t end_addr; 567 568 ASSERT(fastreboot_capable); 569 570 postbootkernelbase = 0; 571 572 /* 573 * Initialize various HAT related fields in the data structure 574 */ 575 fastboot_init_fields(&newkernel); 576 577 bzero(kern_bootpath, OBP_MAXPATHLEN); 578 579 /* 580 * Process the boot argument 581 */ 582 bzero(bootargs, OBP_MAXPATHLEN); 583 fastboot_parse_mdep(mdep, kern_bootpath, &bootpath_len, bootargs); 584 585 /* 586 * Make sure we get the null character 587 */ 588 bcopy(kern_bootpath, fastboot_filename[FASTBOOT_NAME_UNIX], 589 bootpath_len); 590 bcopy(kern_bootfile, 591 &fastboot_filename[FASTBOOT_NAME_UNIX][bootpath_len], 592 strlen(kern_bootfile) + 1); 593 594 bcopy(kern_bootpath, fastboot_filename[FASTBOOT_NAME_BOOTARCHIVE], 595 bootpath_len); 596 597 if (bcmp(kern_bootfile, FAILSAFE_BOOTFILE, 598 (sizeof (FAILSAFE_BOOTFILE) - 1)) == 0) { 599 is_failsafe = 1; 600 } 601 602 load_kernel_retry: 603 /* 604 * Read in unix and boot_archive 605 */ 606 end_addr = DBOOT_ENTRY_ADDRESS; 607 for (i = 0; i < FASTBOOT_MAX_FILES_MAP; i++) { 608 struct _buf *file; 609 uintptr_t va; 610 uint64_t fsize; 611 size_t fsize_roundup, pt_size; 612 int page_index; 613 uintptr_t offset; 614 int pt_entry_count; 615 ddi_dma_attr_t dma_attr = fastboot_dma_attr; 616 617 618 dprintf("fastboot_filename[%d] = %s\n", 619 i, fastboot_filename[i]); 620 621 if ((file = kobj_open_file(fastboot_filename[i])) == 622 (struct _buf *)-1) { 623 cmn_err(CE_WARN, "Fastboot: Couldn't open %s", 624 fastboot_filename[i]); 625 goto err_out; 626 } 627 628 if (kobj_get_filesize(file, &fsize) != 0) { 629 cmn_err(CE_WARN, 630 "Fastboot: Couldn't get filesize for %s", 631 fastboot_filename[i]); 632 goto err_out; 633 } 634 635 fsize_roundup = P2ROUNDUP_TYPED(fsize, PAGESIZE, size_t); 636 637 /* 638 * Where the files end in physical memory after being 639 * relocated by the fast boot switcher. 640 */ 641 end_addr += fsize_roundup; 642 if (end_addr > fastboot_below_1G_dma_attr.dma_attr_addr_hi) { 643 cmn_err(CE_WARN, "Fastboot: boot archive is too big"); 644 goto err_out; 645 } 646 647 /* 648 * Adjust dma_attr_addr_lo so that the new kernel and boot 649 * archive will not be overridden during relocation. 650 */ 651 if (end_addr > fastboot_dma_attr.dma_attr_addr_lo || 652 end_addr > fastboot_below_1G_dma_attr.dma_attr_addr_lo) { 653 654 if (is_retry) { 655 /* 656 * If we have already tried and didn't succeed, 657 * just give up. 658 */ 659 cmn_err(CE_WARN, 660 "Fastboot: boot archive is too big"); 661 goto err_out; 662 } else { 663 int j; 664 665 /* Set the flag so we don't keep retrying */ 666 is_retry++; 667 668 /* Adjust dma_attr_addr_lo */ 669 fastboot_dma_attr.dma_attr_addr_lo = end_addr; 670 fastboot_below_1G_dma_attr.dma_attr_addr_lo = 671 end_addr; 672 673 /* 674 * Free the memory we have already allocated 675 * whose physical addresses might not fit 676 * the new lo and hi constraints. 677 */ 678 for (j = 0; j < i; j++) 679 fastboot_free_file( 680 &newkernel.fi_files[j]); 681 goto load_kernel_retry; 682 } 683 } 684 685 686 if (!fastboot_contig) 687 dma_attr.dma_attr_sgllen = (fsize / PAGESIZE) + 688 (((fsize % PAGESIZE) == 0) ? 0 : 1); 689 690 if ((buf = contig_alloc(fsize, &dma_attr, PAGESIZE, 0)) 691 == NULL) { 692 cmn_err(CE_WARN, fastboot_enomem_msg, fsize, "64G"); 693 goto err_out; 694 } 695 696 va = P2ROUNDUP_TYPED((uintptr_t)buf, PAGESIZE, uintptr_t); 697 698 if (kobj_read_file(file, (char *)va, fsize, 0) < 0) { 699 cmn_err(CE_WARN, "Fastboot: Couldn't read %s", 700 fastboot_filename[i]); 701 goto err_out; 702 } 703 704 fb = &newkernel.fi_files[i]; 705 fb->fb_va = va; 706 fb->fb_size = fsize; 707 fb->fb_sectcnt = 0; 708 709 /* 710 * Allocate one extra page table entry for terminating 711 * the list. 712 */ 713 pt_entry_count = (fsize_roundup >> PAGESHIFT) + 1; 714 pt_size = P2ROUNDUP(pt_entry_count * 8, PAGESIZE); 715 716 if ((fb->fb_pte_list_va = 717 (x86pte_t *)contig_alloc(pt_size, 718 &fastboot_below_1G_dma_attr, PAGESIZE, 0)) == NULL) { 719 cmn_err(CE_WARN, fastboot_enomem_msg, 720 (uint64_t)pt_size, "1G"); 721 goto err_out; 722 } 723 724 bzero((void *)(fb->fb_pte_list_va), pt_size); 725 726 fb->fb_pte_list_pa = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 727 (caddr_t)fb->fb_pte_list_va)); 728 729 for (page_index = 0, offset = 0; offset < fb->fb_size; 730 offset += PAGESIZE) { 731 uint64_t paddr; 732 733 paddr = mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 734 (caddr_t)fb->fb_va + offset)); 735 736 ASSERT(paddr >= fastboot_dma_attr.dma_attr_addr_lo); 737 738 /* 739 * Include the pte_bits so we don't have to make 740 * it in assembly. 741 */ 742 fb->fb_pte_list_va[page_index++] = (x86pte_t) 743 (paddr | pte_bits); 744 } 745 746 fb->fb_pte_list_va[page_index] = FASTBOOT_TERMINATE; 747 748 if (i == FASTBOOT_UNIX) { 749 Ehdr *ehdr = (Ehdr *)va; 750 int j; 751 752 /* 753 * Sanity checks: 754 */ 755 for (j = 0; j < SELFMAG; j++) { 756 if (ehdr->e_ident[j] != ELFMAG[j]) { 757 cmn_err(CE_WARN, "Fastboot: Bad ELF " 758 "signature"); 759 goto err_out; 760 } 761 } 762 763 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32 && 764 ehdr->e_ident[EI_DATA] == ELFDATA2LSB && 765 ehdr->e_machine == EM_386) { 766 767 if (fastboot_elf32_find_loadables((void *)va, 768 fsize, &fb->fb_sections[0], 769 &fb->fb_sectcnt, &dboot_start_offset) < 0) { 770 cmn_err(CE_WARN, "Fastboot: ELF32 " 771 "program section failure"); 772 goto err_out; 773 } 774 775 if (fb->fb_sectcnt == 0) { 776 cmn_err(CE_WARN, "Fastboot: No ELF32 " 777 "program sections found"); 778 goto err_out; 779 } 780 781 if (is_failsafe) { 782 /* Failsafe boot_archive */ 783 bcopy(BOOTARCHIVE_FAILSAFE, 784 &fastboot_filename 785 [FASTBOOT_NAME_BOOTARCHIVE] 786 [bootpath_len], 787 sizeof (BOOTARCHIVE_FAILSAFE)); 788 } else { 789 bcopy(BOOTARCHIVE32, 790 &fastboot_filename 791 [FASTBOOT_NAME_BOOTARCHIVE] 792 [bootpath_len], 793 sizeof (BOOTARCHIVE32)); 794 } 795 796 } else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64 && 797 ehdr->e_ident[EI_DATA] == ELFDATA2LSB && 798 ehdr->e_machine == EM_AMD64) { 799 800 if (fastboot_elf64_find_dboot_load_offset( 801 (void *)va, fsize, &dboot_start_offset) 802 != 0) { 803 cmn_err(CE_WARN, "Fastboot: Couldn't " 804 "find ELF64 dboot entry offset"); 805 goto err_out; 806 } 807 808 if ((x86_feature & X86_64) == 0 || 809 newkernel.fi_has_pae == 0) { 810 cmn_err(CE_WARN, "Fastboot: Cannot " 811 "reboot to %s: " 812 "not a 64-bit capable system", 813 kern_bootfile); 814 goto err_out; 815 } 816 817 bcopy(BOOTARCHIVE64, 818 &fastboot_filename 819 [FASTBOOT_NAME_BOOTARCHIVE][bootpath_len], 820 sizeof (BOOTARCHIVE64)); 821 } else { 822 cmn_err(CE_WARN, "Fastboot: Unknown ELF type"); 823 goto err_out; 824 } 825 826 fb->fb_dest_pa = DBOOT_ENTRY_ADDRESS - 827 dboot_start_offset; 828 829 fb->fb_next_pa = DBOOT_ENTRY_ADDRESS + fsize_roundup; 830 } else { 831 fb->fb_dest_pa = newkernel.fi_files[i - 1].fb_next_pa; 832 fb->fb_next_pa = fb->fb_dest_pa + fsize_roundup; 833 } 834 835 kobj_close_file(file); 836 837 } 838 839 /* 840 * Set fb_va to fake_va 841 */ 842 for (i = 0; i < FASTBOOT_MAX_FILES_MAP; i++) { 843 newkernel.fi_files[i].fb_va = fake_va; 844 845 } 846 847 /* 848 * Add the function that will switch us to 32-bit protected mode 849 */ 850 fb = &newkernel.fi_files[FASTBOOT_SWTCH]; 851 fb->fb_va = fb->fb_dest_pa = FASTBOOT_SWTCH_PA; 852 fb->fb_size = PAGESIZE; 853 854 /* 855 * Map in FASTBOOT_SWTCH_PA 856 */ 857 hat_devload(kas.a_hat, (caddr_t)fb->fb_va, MMU_PAGESIZE, 858 mmu_btop(fb->fb_dest_pa), 859 PROT_READ | PROT_WRITE | PROT_EXEC, HAT_LOAD_NOCONSIST); 860 861 bcopy((void *)fb_swtch_image, (void *)fb->fb_va, fb->fb_size); 862 863 /* 864 * Build the new multiboot_info structure 865 */ 866 if (fastboot_build_mbi(bootargs, &newkernel) != 0) { 867 goto err_out; 868 } 869 870 /* 871 * Build page table for low 1G physical memory. Use big pages. 872 * Allocate 4 pages for the page tables. 873 * 1 page for Page-Directory-Pointer Table 874 * 2 page for Page Directory 875 * 1 page for Page Table. 876 * The page table entry will be rewritten to map the physical 877 * address as we do the copying. 878 */ 879 if (newkernel.fi_has_pae) { 880 size_t size = MMU_PAGESIZE * 4; 881 882 if ((newkernel.fi_pagetable_va = (uintptr_t) 883 contig_alloc(size, &fastboot_below_1G_dma_attr, 884 PAGESIZE, 0)) == NULL) { 885 cmn_err(CE_WARN, fastboot_enomem_msg, 886 (uint64_t)size, "1G"); 887 goto err_out; 888 } 889 890 bzero((void *)(newkernel.fi_pagetable_va), size); 891 892 newkernel.fi_pagetable_pa = 893 mmu_ptob((uint64_t)hat_getpfnum(kas.a_hat, 894 (caddr_t)newkernel.fi_pagetable_va)); 895 896 newkernel.fi_last_table_pa = newkernel.fi_pagetable_pa + 897 MMU_PAGESIZE * 3; 898 899 newkernel.fi_next_table_va = newkernel.fi_pagetable_va + 900 MMU_PAGESIZE; 901 newkernel.fi_next_table_pa = newkernel.fi_pagetable_pa + 902 MMU_PAGESIZE; 903 904 fastboot_build_pagetables(&newkernel); 905 } 906 907 908 /* Mark it as valid */ 909 newkernel.fi_valid = 1; 910 newkernel.fi_magic = FASTBOOT_MAGIC; 911 912 return; 913 914 err_out: 915 newkernel.fi_valid = 0; 916 } 917 918 /* 919 * Jump to the fast reboot switcher. This function never returns. 920 */ 921 void 922 fast_reboot() 923 { 924 void (*fastboot_func)(fastboot_info_t *); 925 926 fastboot_func = (void (*)())(newkernel.fi_files[FASTBOOT_SWTCH].fb_va); 927 (*fastboot_func)(&newkernel); 928 } 929