main.c revision 182877
1/*- 2 * Initial implementation: 3 * Copyright (c) 2001 Robert Drehmel 4 * All rights reserved. 5 * 6 * As long as the above copyright statement and this notice remain 7 * unchanged, you can do what ever you want with this file. 8 */ 9 10#include <sys/cdefs.h> 11__FBSDID("$FreeBSD: head/sys/boot/sparc64/loader/main.c 182877 2008-09-08 20:38:48Z marius $"); 12 13/* 14 * FreeBSD/sparc64 kernel loader - machine dependent part 15 * 16 * - implements copyin and readin functions that map kernel 17 * pages on demand. The machine independent code does not 18 * know the size of the kernel early enough to pre-enter 19 * TTEs and install just one 4MB mapping seemed to limiting 20 * to me. 21 */ 22 23#include <stand.h> 24#include <sys/exec.h> 25#include <sys/param.h> 26#include <sys/queue.h> 27#include <sys/linker.h> 28#include <sys/types.h> 29 30#include <vm/vm.h> 31#include <machine/asi.h> 32#include <machine/cpufunc.h> 33#include <machine/elf.h> 34#include <machine/lsu.h> 35#include <machine/metadata.h> 36#include <machine/tte.h> 37#include <machine/tlb.h> 38#include <machine/upa.h> 39#include <machine/ver.h> 40#include <machine/vmparam.h> 41 42#include "bootstrap.h" 43#include "libofw.h" 44#include "dev_net.h" 45 46extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; 47 48enum { 49 HEAPVA = 0x800000, 50 HEAPSZ = 0x1000000, 51 LOADSZ = 0x1000000 /* for kernel and modules */ 52}; 53 54static struct mmu_ops { 55 void (*tlb_init)(void); 56 int (*mmu_mapin)(vm_offset_t va, vm_size_t len); 57} *mmu_ops; 58 59typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, 60 void *openfirmware); 61 62static inline u_long dtlb_get_data_sun4u(int slot); 63static void dtlb_enter_sun4u(u_long vpn, u_long data); 64static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); 65static inline u_long itlb_get_data_sun4u(int slot); 66static void itlb_enter_sun4u(u_long vpn, u_long data); 67static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); 68extern vm_offset_t md_load(char *, vm_offset_t *); 69static int sparc64_autoload(void); 70static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); 71static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t); 72static void sparc64_maphint(vm_offset_t, size_t); 73static vm_offset_t claim_virt(vm_offset_t, size_t, int); 74static vm_offset_t alloc_phys(size_t, int); 75static int map_phys(int, size_t, vm_offset_t, vm_offset_t); 76static void release_phys(vm_offset_t, u_int); 77static int __elfN(exec)(struct preloaded_file *); 78static int mmu_mapin_sun4u(vm_offset_t, vm_size_t); 79static int mmu_mapin_sun4v(vm_offset_t, vm_size_t); 80static vm_offset_t init_heap(void); 81static void tlb_init_sun4u(void); 82static void tlb_init_sun4v(void); 83 84#ifdef LOADER_DEBUG 85typedef u_int64_t tte_t; 86 87static void pmap_print_tlb_sun4u(void); 88static void pmap_print_tte_sun4u(tte_t, tte_t); 89#endif 90 91static struct mmu_ops mmu_ops_sun4u = { tlb_init_sun4u, mmu_mapin_sun4u }; 92static struct mmu_ops mmu_ops_sun4v = { tlb_init_sun4v, mmu_mapin_sun4v }; 93 94/* sun4u */ 95struct tlb_entry *dtlb_store; 96struct tlb_entry *itlb_store; 97int dtlb_slot; 98int itlb_slot; 99int cpu_impl; 100static int dtlb_slot_max; 101static int itlb_slot_max; 102 103/* sun4v */ 104static struct tlb_entry *tlb_store; 105static int is_sun4v = 0; 106/* 107 * no direct TLB access on sun4v 108 * we somewhat arbitrarily declare enough 109 * slots to cover a 4GB AS with 4MB pages 110 */ 111#define SUN4V_TLB_SLOT_MAX (1 << 10) 112 113static vm_offset_t curkva = 0; 114static vm_offset_t heapva; 115 116static phandle_t root; 117 118/* 119 * Machine dependent structures that the machine independent 120 * loader part uses. 121 */ 122struct devsw *devsw[] = { 123#ifdef LOADER_DISK_SUPPORT 124 &ofwdisk, 125#endif 126#ifdef LOADER_NET_SUPPORT 127 &netdev, 128#endif 129 0 130}; 131struct arch_switch archsw; 132 133static struct file_format sparc64_elf = { 134 __elfN(loadfile), 135 __elfN(exec) 136}; 137struct file_format *file_formats[] = { 138 &sparc64_elf, 139 0 140}; 141struct fs_ops *file_system[] = { 142#ifdef LOADER_UFS_SUPPORT 143 &ufs_fsops, 144#endif 145#ifdef LOADER_CD9660_SUPPORT 146 &cd9660_fsops, 147#endif 148#ifdef LOADER_ZIP_SUPPORT 149 &zipfs_fsops, 150#endif 151#ifdef LOADER_GZIP_SUPPORT 152 &gzipfs_fsops, 153#endif 154#ifdef LOADER_BZIP2_SUPPORT 155 &bzipfs_fsops, 156#endif 157#ifdef LOADER_NFS_SUPPORT 158 &nfs_fsops, 159#endif 160#ifdef LOADER_TFTP_SUPPORT 161 &tftp_fsops, 162#endif 163 0 164}; 165struct netif_driver *netif_drivers[] = { 166#ifdef LOADER_NET_SUPPORT 167 &ofwnet, 168#endif 169 0 170}; 171 172extern struct console ofwconsole; 173struct console *consoles[] = { 174 &ofwconsole, 175 0 176}; 177 178#ifdef LOADER_DEBUG 179static int 180watch_phys_set_mask(vm_offset_t pa, u_long mask) 181{ 182 u_long lsucr; 183 184 stxa(AA_DMMU_PWPR, ASI_DMMU, pa & (((2UL << 38) - 1) << 3)); 185 lsucr = ldxa(0, ASI_LSU_CTL_REG); 186 lsucr = ((lsucr | LSU_PW) & ~LSU_PM_MASK) | 187 (mask << LSU_PM_SHIFT); 188 stxa(0, ASI_LSU_CTL_REG, lsucr); 189 return (0); 190} 191 192static int 193watch_phys_set(vm_offset_t pa, int sz) 194{ 195 u_long off; 196 197 off = (u_long)pa & 7; 198 /* Test for misaligned watch points. */ 199 if (off + sz > 8) 200 return (-1); 201 return (watch_phys_set_mask(pa, ((1 << sz) - 1) << off)); 202} 203 204 205static int 206watch_virt_set_mask(vm_offset_t va, u_long mask) 207{ 208 u_long lsucr; 209 210 stxa(AA_DMMU_VWPR, ASI_DMMU, va & (((2UL << 41) - 1) << 3)); 211 lsucr = ldxa(0, ASI_LSU_CTL_REG); 212 lsucr = ((lsucr | LSU_VW) & ~LSU_VM_MASK) | 213 (mask << LSU_VM_SHIFT); 214 stxa(0, ASI_LSU_CTL_REG, lsucr); 215 return (0); 216} 217 218static int 219watch_virt_set(vm_offset_t va, int sz) 220{ 221 u_long off; 222 223 off = (u_long)va & 7; 224 /* Test for misaligned watch points. */ 225 if (off + sz > 8) 226 return (-1); 227 return (watch_virt_set_mask(va, ((1 << sz) - 1) << off)); 228} 229#endif 230 231/* 232 * archsw functions 233 */ 234static int 235sparc64_autoload(void) 236{ 237 238 printf("nothing to autoload yet.\n"); 239 return (0); 240} 241 242static ssize_t 243sparc64_readin(const int fd, vm_offset_t va, const size_t len) 244{ 245 246 mmu_ops->mmu_mapin(va, len); 247 return (read(fd, (void *)va, len)); 248} 249 250static ssize_t 251sparc64_copyin(const void *src, vm_offset_t dest, size_t len) 252{ 253 254 mmu_ops->mmu_mapin(dest, len); 255 memcpy((void *)dest, src, len); 256 return (len); 257} 258 259static void 260sparc64_maphint(vm_offset_t va, size_t len) 261{ 262 vm_paddr_t pa; 263 vm_offset_t mva; 264 size_t size; 265 int i, free_excess = 0; 266 267 if (!is_sun4v) 268 return; 269 270 if (tlb_store[va >> 22].te_pa != -1) 271 return; 272 273 /* round up to nearest 4MB page */ 274 size = (len + PAGE_MASK_4M) & ~PAGE_MASK_4M; 275#if 0 276 pa = alloc_phys(PAGE_SIZE_256M, PAGE_SIZE_256M); 277 278 if (pa != -1) 279 free_excess = 1; 280 else 281#endif 282 pa = alloc_phys(size, PAGE_SIZE_256M); 283 if (pa == -1) 284 pa = alloc_phys(size, PAGE_SIZE_4M); 285 if (pa == -1) 286 panic("%s: out of memory", __func__); 287 288 for (i = 0; i < size; i += PAGE_SIZE_4M) { 289 mva = claim_virt(va + i, PAGE_SIZE_4M, 0); 290 if (mva != (va + i)) 291 panic("%s: can't claim virtual page " 292 "(wanted %#lx, got %#lx)", 293 __func__, va, mva); 294 295 tlb_store[mva >> 22].te_pa = pa + i; 296 if (map_phys(-1, PAGE_SIZE_4M, mva, pa + i) != 0) 297 printf("%s: can't map physical page\n", __func__); 298 } 299 if (free_excess) 300 release_phys(pa, PAGE_SIZE_256M); 301} 302 303/* 304 * other MD functions 305 */ 306static vm_offset_t 307claim_virt(vm_offset_t virt, size_t size, int align) 308{ 309 vm_offset_t mva; 310 311 if (OF_call_method("claim", mmu, 3, 1, virt, size, align, &mva) == -1) 312 return ((vm_offset_t)-1); 313 return (mva); 314} 315 316static vm_offset_t 317alloc_phys(size_t size, int align) 318{ 319 cell_t phys_hi, phys_low; 320 321 if (OF_call_method("claim", memory, 2, 2, size, align, &phys_low, 322 &phys_hi) == -1) 323 return ((vm_offset_t)-1); 324 return ((vm_offset_t)phys_hi << 32 | phys_low); 325} 326 327static int 328map_phys(int mode, size_t size, vm_offset_t virt, vm_offset_t phys) 329{ 330 331 return (OF_call_method("map", mmu, 5, 0, (uint32_t)phys, 332 (uint32_t)(phys >> 32), virt, size, mode)); 333} 334 335static void 336release_phys(vm_offset_t phys, u_int size) 337{ 338 339 (void)OF_call_method("release", memory, 3, 0, (uint32_t)phys, 340 (uint32_t)(phys >> 32), size); 341} 342 343static int 344__elfN(exec)(struct preloaded_file *fp) 345{ 346 struct file_metadata *fmp; 347 vm_offset_t mdp; 348 Elf_Addr entry; 349 Elf_Ehdr *e; 350 int error; 351 352 if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == 0) 353 return (EFTYPE); 354 e = (Elf_Ehdr *)&fmp->md_data; 355 356 if ((error = md_load(fp->f_args, &mdp)) != 0) 357 return (error); 358 359 printf("jumping to kernel entry at %#lx.\n", e->e_entry); 360#if LOADER_DEBUG 361 pmap_print_tlb_sun4u(); 362#endif 363 364 entry = e->e_entry; 365 366 OF_release((void *)heapva, HEAPSZ); 367 368 ((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware); 369 370 panic("%s: exec returned", __func__); 371} 372 373static inline u_long 374dtlb_get_data_sun4u(int slot) 375{ 376 377 /* 378 * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work 379 * around errata of USIII and beyond. 380 */ 381 (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); 382 return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); 383} 384 385static inline u_long 386itlb_get_data_sun4u(int slot) 387{ 388 389 /* 390 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work 391 * around errata of USIII and beyond. 392 */ 393 (void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG); 394 return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG)); 395} 396 397static vm_offset_t 398dtlb_va_to_pa_sun4u(vm_offset_t va) 399{ 400 u_long pstate, reg; 401 int i; 402 403 pstate = rdpr(pstate); 404 wrpr(pstate, pstate & ~PSTATE_IE, 0); 405 for (i = 0; i < dtlb_slot_max; i++) { 406 reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); 407 if (TLB_TAR_VA(reg) != va) 408 continue; 409 reg = dtlb_get_data_sun4u(i); 410 wrpr(pstate, pstate, 0); 411 if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) 412 return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); 413 return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); 414 } 415 wrpr(pstate, pstate, 0); 416 return (-1); 417} 418 419static vm_offset_t 420itlb_va_to_pa_sun4u(vm_offset_t va) 421{ 422 u_long pstate, reg; 423 int i; 424 425 pstate = rdpr(pstate); 426 wrpr(pstate, pstate & ~PSTATE_IE, 0); 427 for (i = 0; i < itlb_slot_max; i++) { 428 reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); 429 if (TLB_TAR_VA(reg) != va) 430 continue; 431 reg = itlb_get_data_sun4u(i); 432 wrpr(pstate, pstate, 0); 433 if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) 434 return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); 435 return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); 436 } 437 wrpr(pstate, pstate, 0); 438 return (-1); 439} 440 441static void 442dtlb_enter_sun4u(u_long vpn, u_long data) 443{ 444 u_long reg; 445 446 reg = rdpr(pstate); 447 wrpr(pstate, reg & ~PSTATE_IE, 0); 448 stxa(AA_DMMU_TAR, ASI_DMMU, 449 TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); 450 stxa(0, ASI_DTLB_DATA_IN_REG, data); 451 membar(Sync); 452 wrpr(pstate, reg, 0); 453} 454 455static void 456itlb_enter_sun4u(u_long vpn, u_long data) 457{ 458 u_long reg; 459 460 reg = rdpr(pstate); 461 wrpr(pstate, reg & ~PSTATE_IE, 0); 462 stxa(AA_IMMU_TAR, ASI_IMMU, 463 TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); 464 stxa(0, ASI_ITLB_DATA_IN_REG, data); 465 flush(KERNBASE); 466 wrpr(pstate, reg, 0); 467} 468 469static int 470mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) 471{ 472 vm_offset_t pa, mva; 473 u_long data; 474 475 if (va + len > curkva) 476 curkva = va + len; 477 478 pa = (vm_offset_t)-1; 479 len += va & PAGE_MASK_4M; 480 va &= ~PAGE_MASK_4M; 481 while (len) { 482 if (dtlb_va_to_pa_sun4u(va) == (vm_offset_t)-1 || 483 itlb_va_to_pa_sun4u(va) == (vm_offset_t)-1) { 484 /* Allocate a physical page, claim the virtual area. */ 485 if (pa == (vm_offset_t)-1) { 486 pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M); 487 if (pa == (vm_offset_t)-1) 488 panic("%s: out of memory", __func__); 489 mva = claim_virt(va, PAGE_SIZE_4M, 0); 490 if (mva != va) 491 panic("%s: can't claim virtual page " 492 "(wanted %#lx, got %#lx)", 493 __func__, va, mva); 494 /* 495 * The mappings may have changed, be paranoid. 496 */ 497 continue; 498 } 499 /* 500 * Actually, we can only allocate two pages less at 501 * most (depending on the kernel TSB size). 502 */ 503 if (dtlb_slot >= dtlb_slot_max) 504 panic("%s: out of dtlb_slots", __func__); 505 if (itlb_slot >= itlb_slot_max) 506 panic("%s: out of itlb_slots", __func__); 507 data = TD_V | TD_4M | TD_PA(pa) | TD_L | TD_CP | 508 TD_CV | TD_P | TD_W; 509 dtlb_store[dtlb_slot].te_pa = pa; 510 dtlb_store[dtlb_slot].te_va = va; 511 itlb_store[itlb_slot].te_pa = pa; 512 itlb_store[itlb_slot].te_va = va; 513 dtlb_slot++; 514 itlb_slot++; 515 dtlb_enter_sun4u(va, data); 516 itlb_enter_sun4u(va, data); 517 pa = (vm_offset_t)-1; 518 } 519 len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; 520 va += PAGE_SIZE_4M; 521 } 522 if (pa != (vm_offset_t)-1) 523 release_phys(pa, PAGE_SIZE_4M); 524 return (0); 525} 526 527static int 528mmu_mapin_sun4v(vm_offset_t va, vm_size_t len) 529{ 530 vm_offset_t pa, mva; 531 532 if (va + len > curkva) 533 curkva = va + len; 534 535 pa = (vm_offset_t)-1; 536 len += va & PAGE_MASK_4M; 537 va &= ~PAGE_MASK_4M; 538 while (len) { 539 if ((va >> 22) > SUN4V_TLB_SLOT_MAX) 540 panic("%s: trying to map more than 4GB", __func__); 541 if (tlb_store[va >> 22].te_pa == -1) { 542 /* Allocate a physical page, claim the virtual area */ 543 if (pa == (vm_offset_t)-1) { 544 pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M); 545 if (pa == (vm_offset_t)-1) 546 panic("%s: out of memory", __func__); 547 mva = claim_virt(va, PAGE_SIZE_4M, 0); 548 if (mva != va) 549 panic("%s: can't claim virtual page " 550 "(wanted %#lx, got %#lx)", 551 __func__, va, mva); 552 } 553 554 tlb_store[va >> 22].te_pa = pa; 555 if (map_phys(-1, PAGE_SIZE_4M, va, pa) == -1) 556 printf("%s: can't map physical page\n", 557 __func__); 558 pa = (vm_offset_t)-1; 559 } 560 len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len; 561 va += PAGE_SIZE_4M; 562 } 563 if (pa != (vm_offset_t)-1) 564 release_phys(pa, PAGE_SIZE_4M); 565 return (0); 566} 567 568static vm_offset_t 569init_heap(void) 570{ 571 572 /* There is no need for continuous physical heap memory. */ 573 heapva = (vm_offset_t)OF_claim((void *)HEAPVA, HEAPSZ, 32); 574 return (heapva); 575} 576 577static void 578tlb_init_sun4u(void) 579{ 580 phandle_t child; 581 char buf[128]; 582 u_int bootcpu; 583 u_int cpu; 584 585 cpu_impl = VER_IMPL(rdpr(ver)); 586 bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); 587 for (child = OF_child(root); child != 0; child = OF_peer(child)) { 588 if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0) 589 continue; 590 if (strcmp(buf, "cpu") != 0) 591 continue; 592 if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? 593 "upa-portid" : "portid", &cpu, sizeof(cpu)) <= 0) 594 continue; 595 if (cpu == bootcpu) 596 break; 597 } 598 if (cpu != bootcpu) 599 panic("%s: no node for bootcpu?!?!", __func__); 600 601 if (OF_getprop(child, "#dtlb-entries", &dtlb_slot_max, 602 sizeof(dtlb_slot_max)) == -1 || 603 OF_getprop(child, "#itlb-entries", &itlb_slot_max, 604 sizeof(itlb_slot_max)) == -1) 605 panic("%s: can't get TLB slot max.", __func__); 606 dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store)); 607 itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store)); 608 if (dtlb_store == NULL || itlb_store == NULL) 609 panic("%s: can't allocate TLB store", __func__); 610} 611 612static void 613tlb_init_sun4v(void) 614{ 615 616 tlb_store = malloc(SUN4V_TLB_SLOT_MAX * sizeof(*tlb_store)); 617 memset(tlb_store, 0xFF, SUN4V_TLB_SLOT_MAX * sizeof(*tlb_store)); 618} 619 620int 621main(int (*openfirm)(void *)) 622{ 623 char bootpath[64]; 624 char compatible[32]; 625 struct devsw **dp; 626 627 /* 628 * Tell the Open Firmware functions where they find the OFW gate. 629 */ 630 OF_init(openfirm); 631 632 archsw.arch_getdev = ofw_getdev; 633 archsw.arch_copyin = sparc64_copyin; 634 archsw.arch_copyout = ofw_copyout; 635 archsw.arch_readin = sparc64_readin; 636 archsw.arch_autoload = sparc64_autoload; 637 archsw.arch_maphint = sparc64_maphint; 638 639 init_heap(); 640 setheap((void *)heapva, (void *)(heapva + HEAPSZ)); 641 642 /* 643 * Probe for a console. 644 */ 645 cons_probe(); 646 647 if ((root = OF_peer(0)) == -1) 648 panic("%s: can't get root phandle", __func__); 649 OF_getprop(root, "compatible", compatible, sizeof(compatible)); 650 if (!strcmp(compatible, "sun4v")) { 651 printf("\nBooting with sun4v support.\n"); 652 mmu_ops = &mmu_ops_sun4v; 653 is_sun4v = 1; 654 } else { 655 printf("\nBooting with sun4u support.\n"); 656 mmu_ops = &mmu_ops_sun4u; 657 } 658 659 mmu_ops->tlb_init(); 660 661 /* 662 * Initialize devices. 663 */ 664 for (dp = devsw; *dp != 0; dp++) { 665 if ((*dp)->dv_init != 0) 666 (*dp)->dv_init(); 667 } 668 669 /* 670 * Set up the current device. 671 */ 672 OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath)); 673 674 /* 675 * Sun compatible bootable CD-ROMs have a disk label placed 676 * before the cd9660 data, with the actual filesystem being 677 * in the first partition, while the other partitions contain 678 * pseudo disk labels with embedded boot blocks for different 679 * architectures, which may be followed by UFS filesystems. 680 * The firmware will set the boot path to the partition it 681 * boots from ('f' in the sun4u case), but we want the kernel 682 * to be loaded from the cd9660 fs ('a'), so the boot path 683 * needs to be altered. 684 */ 685 if (bootpath[strlen(bootpath) - 2] == ':' && 686 bootpath[strlen(bootpath) - 1] == 'f') { 687 bootpath[strlen(bootpath) - 1] = 'a'; 688 printf("Boot path set to %s\n", bootpath); 689 } 690 691 env_setenv("currdev", EV_VOLATILE, bootpath, 692 ofw_setcurrdev, env_nounset); 693 env_setenv("loaddev", EV_VOLATILE, bootpath, 694 env_noset, env_nounset); 695 696 printf("\n"); 697 printf("%s, Revision %s\n", bootprog_name, bootprog_rev); 698 printf("(%s, %s)\n", bootprog_maker, bootprog_date); 699 printf("bootpath=\"%s\"\n", bootpath); 700 701 /* Give control to the machine independent loader code. */ 702 interact(); 703 return (1); 704} 705 706COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); 707 708static int 709command_reboot(int argc, char *argv[]) 710{ 711 int i; 712 713 for (i = 0; devsw[i] != NULL; ++i) 714 if (devsw[i]->dv_cleanup != NULL) 715 (devsw[i]->dv_cleanup)(); 716 717 printf("Rebooting...\n"); 718 OF_exit(); 719} 720 721/* provide this for panic, as it's not in the startup code */ 722void 723exit(int code) 724{ 725 726 OF_exit(); 727} 728 729#ifdef LOADER_DEBUG 730static const char *page_sizes[] = { 731 " 8k", " 64k", "512k", " 4m" 732}; 733 734static void 735pmap_print_tte_sun4u(tte_t tag, tte_t tte) 736{ 737 738 printf("%s %s ", 739 page_sizes[(tte & TD_SIZE_MASK) >> TD_SIZE_SHIFT], 740 tag & TD_G ? "G" : " "); 741 printf(tte & TD_W ? "W " : " "); 742 printf(tte & TD_P ? "\e[33mP\e[0m " : " "); 743 printf(tte & TD_E ? "E " : " "); 744 printf(tte & TD_CV ? "CV " : " "); 745 printf(tte & TD_CP ? "CP " : " "); 746 printf(tte & TD_L ? "\e[32mL\e[0m " : " "); 747 printf(tte & TD_IE ? "IE " : " "); 748 printf(tte & TD_NFO ? "NFO " : " "); 749 printf("pa=0x%lx va=0x%lx ctx=%ld\n", 750 TD_PA(tte), TLB_TAR_VA(tag), TLB_TAR_CTX(tag)); 751} 752 753static void 754pmap_print_tlb_sun4u(void) 755{ 756 tte_t tag, tte; 757 u_long pstate; 758 int i; 759 760 pstate = rdpr(pstate); 761 for (i = 0; i < itlb_slot_max; i++) { 762 wrpr(pstate, pstate & ~PSTATE_IE, 0); 763 tte = itlb_get_data_sun4u(i); 764 wrpr(pstate, pstate, 0); 765 if (!(tte & TD_V)) 766 continue; 767 tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); 768 printf("iTLB-%2u: ", i); 769 pmap_print_tte_sun4u(tag, tte); 770 } 771 for (i = 0; i < dtlb_slot_max; i++) { 772 wrpr(pstate, pstate & ~PSTATE_IE, 0); 773 tte = dtlb_get_data_sun4u(i); 774 wrpr(pstate, pstate, 0); 775 if (!(tte & TD_V)) 776 continue; 777 tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); 778 printf("dTLB-%2u: ", i); 779 pmap_print_tte_sun4u(tag, tte); 780 } 781} 782#endif 783