1 /* 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57 #ifndef lint 58 static const char rcsid[] = 59 "$FreeBSD$"; 60 #endif /* not lint */ 61 62 #include "opt_ddb.h" 63 #include "opt_compat.h" 64 #include "opt_msgbuf.h" 65 66 #include <sys/param.h> 67 #include <sys/systm.h> 68 #include <sys/eventhandler.h> 69 #include <sys/sysproto.h> 70 #include <sys/lock.h> 71 #include <sys/mutex.h> 72 #include <sys/ktr.h> 73 #include <sys/signalvar.h> 74 #include <sys/kernel.h> 75 #include <sys/proc.h> 76 #include <sys/malloc.h> 77 #include <sys/reboot.h> 78 #include <sys/bio.h> 79 #include <sys/buf.h> 80 #include <sys/bus.h> 81 #include <sys/mbuf.h> 82 #include <sys/vmmeter.h> 83 #include <sys/msgbuf.h> 84 #include <sys/exec.h> 85 #include <sys/sysctl.h> 86 #include <sys/uio.h> 87 #include <sys/linker.h> 88 #include <sys/cons.h> 89 #include <net/netisr.h> 90 #include <vm/vm.h> 91 #include <vm/vm_kern.h> 92 #include <vm/vm_page.h> 93 #include <vm/vm_map.h> 94 #include <vm/vm_extern.h> 95 #include <vm/vm_object.h> 96 #include <vm/vm_pager.h> 97 #include <sys/user.h> 98 #include <sys/ptrace.h> 99 #include <machine/bat.h> 100 #include <machine/clock.h> 101 #include <machine/md_var.h> 102 #include <machine/reg.h> 103 #include <machine/fpu.h> 104 #include <machine/vmparam.h> 105 #include <machine/elf.h> 106 #include <machine/trap.h> 107 #include <machine/powerpc.h> 108 #include <dev/ofw/openfirm.h> 109 #include <ddb/ddb.h> 110 #include <sys/vnode.h> 111 #include <machine/sigframe.h> 112 113 int physmem = 0; 114 int cold = 1; 115 116 struct mtx sched_lock; 117 struct mtx Giant; 118 119 char pcpu0[PAGE_SIZE]; 120 char uarea0[UAREA_PAGES * PAGE_SIZE]; 121 struct trapframe frame0; 122 123 vm_offset_t kstack0; 124 vm_offset_t kstack0_phys; 125 126 char machine[] = "powerpc"; 127 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 128 129 static char model[128]; 130 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, ""); 131 132 char bootpath[256]; 133 134 #ifdef DDB 135 /* start and end of kernel symbol table */ 136 void *ksym_start, *ksym_end; 137 #endif /* DDB */ 138 139 static void cpu_startup(void *); 140 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 141 142 void powerpc_init(u_int, u_int, u_int, char *); 143 144 int save_ofw_mapping(void); 145 int restore_ofw_mapping(void); 146 147 void install_extint(void (*)(void)); 148 149 #ifdef COMPAT_43 150 void osendsig(sig_t, int, sigset_t *, u_long); 151 #endif 152 153 static int 154 sysctl_hw_physmem(SYSCTL_HANDLER_ARGS) 155 { 156 int error = sysctl_handle_int(oidp, 0, ctob(physmem), req); 157 return (error); 158 } 159 160 SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, 161 0, 0, sysctl_hw_physmem, "IU", ""); 162 163 int Maxmem = 0; 164 long dumplo; 165 166 static int chosen; 167 168 struct pmap ofw_pmap; 169 extern int ofmsr; 170 171 struct bat battable[16]; 172 173 static void identifycpu(void); 174 175 struct kva_md_info kmi; 176 177 static void 178 powerpc_ofw_shutdown(void *junk, int howto) 179 { 180 if (howto & RB_HALT) { 181 OF_exit(); 182 } 183 } 184 185 static void 186 cpu_startup(void *dummy) 187 { 188 189 /* 190 * Good {morning,afternoon,evening,night}. 191 */ 192 identifycpu(); 193 194 /* startrtclock(); */ 195 #ifdef PERFMON 196 perfmon_init(); 197 #endif 198 printf("real memory = %ld (%ldK bytes)\n", ptoa(Maxmem), 199 ptoa(Maxmem) / 1024); 200 201 /* 202 * Display any holes after the first chunk of extended memory. 203 */ 204 if (bootverbose) { 205 int indx; 206 207 printf("Physical memory chunk(s):\n"); 208 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 209 int size1 = phys_avail[indx + 1] - phys_avail[indx]; 210 211 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 212 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 213 size1 / PAGE_SIZE); 214 } 215 } 216 217 vm_ksubmap_init(&kmi); 218 219 #if defined(USERCONFIG) 220 #if defined(USERCONFIG_BOOT) 221 if (1) 222 #else 223 if (boothowto & RB_CONFIG) 224 #endif 225 { 226 userconfig(); 227 cninit(); /* the preferred console may have changed */ 228 } 229 #endif 230 231 printf("avail memory = %ld (%ldK bytes)\n", ptoa(cnt.v_free_count), 232 ptoa(cnt.v_free_count) / 1024); 233 234 /* 235 * Set up buffers, so they can be used to read disk labels. 236 */ 237 bufinit(); 238 vm_pager_bufferinit(); 239 EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, 240 SHUTDOWN_PRI_LAST); 241 242 #ifdef SMP 243 /* 244 * OK, enough kmem_alloc/malloc state should be up, lets get on with it! 245 */ 246 mp_start(); /* fire up the secondaries */ 247 mp_announce(); 248 #endif /* SMP */ 249 } 250 251 void 252 identifycpu() 253 { 254 unsigned int pvr, version, revision; 255 256 /* 257 * Find cpu type (Do it by OpenFirmware?) 258 */ 259 __asm ("mfpvr %0" : "=r"(pvr)); 260 version = pvr >> 16; 261 revision = pvr & 0xffff; 262 switch (version) { 263 case 0x0000: 264 sprintf(model, "Simulator (psim)"); 265 break; 266 case 0x0001: 267 sprintf(model, "601"); 268 break; 269 case 0x0003: 270 sprintf(model, "603 (Wart)"); 271 break; 272 case 0x0004: 273 sprintf(model, "604 (Zephyr)"); 274 break; 275 case 0x0005: 276 sprintf(model, "602 (Galahad)"); 277 break; 278 case 0x0006: 279 sprintf(model, "603e (Stretch)"); 280 break; 281 case 0x0007: 282 if ((revision && 0xf000) == 0x0000) 283 sprintf(model, "603ev (Valiant)"); 284 else 285 sprintf(model, "603r (Goldeneye)"); 286 break; 287 case 0x0008: 288 if ((revision && 0xf000) == 0x0000) 289 sprintf(model, "G3 / 750 (Arthur)"); 290 else 291 sprintf(model, "G3 / 755 (Goldfinger)"); 292 break; 293 case 0x0009: 294 if ((revision && 0xf000) == 0x0000) 295 sprintf(model, "604e (Sirocco)"); 296 else 297 sprintf(model, "604r (Mach V)"); 298 break; 299 case 0x000a: 300 sprintf(model, "604r (Mach V)"); 301 break; 302 case 0x000c: 303 sprintf(model, "G4 / 7400 (Max)"); 304 break; 305 case 0x0014: 306 sprintf(model, "620 (Red October)"); 307 break; 308 case 0x0081: 309 sprintf(model, "8240 (Kahlua)"); 310 break; 311 case 0x8000: 312 sprintf(model, "G4 / 7450 (V'ger)"); 313 break; 314 case 0x800c: 315 sprintf(model, "G4 / 7410 (Nitro)"); 316 break; 317 case 0x8081: 318 sprintf(model, "8245 (Kahlua II)"); 319 break; 320 default: 321 sprintf(model, "Version %x", version); 322 break; 323 } 324 sprintf(model + strlen(model), " (Revision %x)", revision); 325 printf("CPU: PowerPC %s\n", model); 326 } 327 328 extern char kernel_text[], _end[]; 329 330 extern void *trapcode, *trapsize; 331 extern void *alitrap, *alisize; 332 extern void *dsitrap, *dsisize; 333 extern void *isitrap, *isisize; 334 extern void *decrint, *decrsize; 335 extern void *tlbimiss, *tlbimsize; 336 extern void *tlbdlmiss, *tlbdlmsize; 337 extern void *tlbdsmiss, *tlbdsmsize; 338 339 #if 0 /* XXX: interrupt handler. We'll get to this later */ 340 extern void ext_intr(void); 341 #endif 342 343 #ifdef DDB 344 extern ddblow, ddbsize; 345 #endif 346 #ifdef IPKDB 347 extern ipkdblow, ipkdbsize; 348 #endif 349 350 void 351 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) 352 { 353 struct pcpu *pc; 354 vm_offset_t off; 355 356 /* 357 * Initialize the console before printing anything. 358 */ 359 cninit(); 360 361 /* 362 * Initialize tunables. 363 */ 364 init_param1(); 365 init_param2(physmem); 366 367 /* 368 * Initialise virtual memory. 369 */ 370 ofmsr |= PSL_IR | PSL_DR; 371 pmap_bootstrap(startkernel, endkernel); 372 373 /* 374 * XXX: Initialize the interrupt tables. 375 */ 376 bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize); 377 378 /* 379 * Initialize proc0. 380 */ 381 proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0); 382 /* proc0.p_md.md_utrap = NULL; */ 383 proc0.p_uarea = (struct user *)uarea0; 384 proc0.p_stats = &proc0.p_uarea->u_stats; 385 thread0.td_kstack = kstack0; 386 thread0.td_pcb = (struct pcb *) 387 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 388 /* frame0.tf_tstate = TSTATE_IE | TSTATE_PEF; */ 389 thread0.td_frame = &frame0; 390 LIST_INIT(&thread0.td_contested); 391 392 /* 393 * Set up per-cpu data. 394 */ 395 pc = (struct pcpu *)(pcpu0 + PAGE_SIZE) - 1; 396 pcpu_init(pc, 0, sizeof(struct pcpu)); 397 pc->pc_curthread = &thread0; 398 pc->pc_curpcb = thread0.td_pcb; 399 /* pc->pc_mid = mid; */ 400 401 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 402 403 /* 404 * Map and initialise the message buffer. 405 */ 406 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 407 pmap_kenter((vm_offset_t)msgbufp + off, msgbuf_phys + off); 408 msgbufinit(msgbufp, MSGBUF_SIZE); 409 410 /* 411 * Initialize mutexes. 412 */ 413 mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); 414 mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE); 415 mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); 416 417 mtx_lock(&Giant); 418 } 419 420 #if 0 /* XXX: Old powerpc_init */ 421 void 422 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) 423 { 424 unsigned int exc, scratch; 425 struct mem_region *allmem, *availmem, *mp; 426 struct pcpu *pcpup; 427 428 /* 429 * Set up BAT0 to only map the lowest 256 MB area 430 */ 431 battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); 432 battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); 433 434 /* 435 * Map PCI memory space. 436 */ 437 battable[0x8].batl = BATL(0x80000000, BAT_I, BAT_PP_RW); 438 battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs); 439 440 battable[0x9].batl = BATL(0x90000000, BAT_I, BAT_PP_RW); 441 battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs); 442 443 battable[0xa].batl = BATL(0xa0000000, BAT_I, BAT_PP_RW); 444 battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs); 445 446 /* 447 * Map obio devices. 448 */ 449 battable[0xf].batl = BATL(0xf0000000, BAT_I, BAT_PP_RW); 450 battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs); 451 452 /* 453 * Now setup fixed bat registers 454 * 455 * Note that we still run in real mode, and the BAT 456 * registers were cleared above. 457 */ 458 /* BAT0 used for initial 256 MB segment */ 459 __asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;" 460 "mtdbatl 0,%0; mtdbatu 0,%1;" 461 :: "r"(battable[0].batl), "r"(battable[0].batu)); 462 /* 463 * Set up battable to map all RAM regions. 464 * This is here because mem_regions() call needs bat0 set up. 465 */ 466 mem_regions(&allmem, &availmem); 467 468 /* Calculate the physical memory in the machine */ 469 for (mp = allmem; mp->size; mp++) 470 physmem += btoc(mp->size); 471 472 for (mp = allmem; mp->size; mp++) { 473 vm_offset_t pa = mp->start & 0xf0000000; 474 vm_offset_t end = mp->start + mp->size; 475 476 do { 477 u_int n = pa >> 28; 478 479 battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW); 480 battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs); 481 pa += 0x10000000; 482 } while (pa < end); 483 } 484 485 chosen = OF_finddevice("/chosen"); 486 save_ofw_mapping(); 487 488 pmap_setavailmem(startkernel, endkernel); 489 490 proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0); 491 492 proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE); 493 proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE); 494 proc0.p_uarea = proc0uarea; 495 thread0.td_kstack = proc0kstack; 496 thread0.td_pcb = (struct pcb *) 497 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 498 499 pcpup = pmap_steal_memory(round_page(sizeof(struct pcpu))); 500 501 /* 502 * XXX: Pass 0 as CPU id. This is bad. We need to work out 503 * XXX: which CPU we are somehow. 504 */ 505 pcpu_init(pcpup, 0, sizeof(struct pcpu)); 506 __asm ("mtsprg 0, %0" :: "r"(pcpup)); 507 508 /* Init basic tunables, hz etc */ 509 init_param1(); 510 init_param2(physmem); 511 512 /* setup curproc so the mutexes work */ 513 514 PCPU_SET(curthread, &thread0); 515 516 LIST_INIT(&thread0.td_contested); 517 518 /* XXX: NetBSDism I _think_. Not sure yet. */ 519 #if 0 520 curpm = PCPU_GET(curpcb)->pcb_pmreal = PCPU_GET(curpcb)->pcb_pm = kernel_pmap; 521 #endif 522 523 /* 524 * Initialise some mutexes. 525 */ 526 mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE); 527 mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); 528 mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); 529 mtx_lock(&Giant); 530 531 /* 532 * Initialise console. 533 */ 534 cninit(); 535 536 #ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */ 537 OF_set_callback(callback); 538 #endif 539 540 /* 541 * Set up trap vectors 542 */ 543 for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) { 544 switch (exc) { 545 default: 546 bcopy(&trapcode, (void *)exc, (size_t)&trapsize); 547 break; 548 case EXC_DECR: 549 bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize); 550 break; 551 #if 0 /* XXX: Not enabling these traps yet. */ 552 case EXC_EXI: 553 /* 554 * This one is (potentially) installed during autoconf 555 */ 556 break; 557 case EXC_ALI: 558 bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize); 559 break; 560 case EXC_DSI: 561 bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize); 562 break; 563 case EXC_ISI: 564 bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize); 565 break; 566 case EXC_IMISS: 567 bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize); 568 break; 569 case EXC_DLMISS: 570 bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize); 571 break; 572 case EXC_DSMISS: 573 bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize); 574 break; 575 #if defined(DDB) || defined(IPKDB) 576 case EXC_TRC: 577 case EXC_PGM: 578 case EXC_BPT: 579 #if defined(DDB) 580 bcopy(&ddblow, (void *)exc, (size_t)&ddbsize); 581 #else 582 bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize); 583 #endif 584 break; 585 #endif /* DDB || IPKDB */ 586 #endif 587 } 588 } 589 590 #if 0 /* XXX: coming soon... */ 591 /* 592 * external interrupt handler install 593 */ 594 install_extint(ext_intr); 595 #endif 596 597 __syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100); 598 599 /* 600 * Now enable translation (and machine checks/recoverable interrupts). 601 */ 602 __asm ("mfmsr %0" : "=r"(scratch)); 603 scratch |= PSL_IR | PSL_DR | PSL_ME | PSL_RI; 604 __asm ("mtmsr %0" :: "r"(scratch)); 605 606 ofmsr &= ~PSL_IP; 607 608 /* 609 * Parse arg string. 610 */ 611 #ifdef DDB 612 bcopy(args + strlen(args) + 1, &startsym, sizeof(startsym)); 613 bcopy(args + strlen(args) + 5, &endsym, sizeof(endsym)); 614 if (startsym == NULL || endsym == NULL) 615 startsym = endsym = NULL; 616 #endif 617 618 strcpy(bootpath, args); 619 args = bootpath; 620 while (*++args && *args != ' '); 621 if (*args) { 622 *args++ = 0; 623 while (*args) { 624 switch (*args++) { 625 case 'a': 626 boothowto |= RB_ASKNAME; 627 break; 628 case 's': 629 boothowto |= RB_SINGLE; 630 break; 631 case 'd': 632 boothowto |= RB_KDB; 633 break; 634 case 'v': 635 boothowto |= RB_VERBOSE; 636 break; 637 } 638 } 639 } 640 641 #ifdef DDB 642 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym); 643 #endif 644 #ifdef IPKDB 645 /* 646 * Now trap to IPKDB 647 */ 648 ipkdb_init(); 649 if (boothowto & RB_KDB) 650 ipkdb_connect(0); 651 #endif 652 653 /* 654 * Set the page size. 655 */ 656 #if 0 657 vm_set_page_size(); 658 #endif 659 660 /* 661 * Initialize pmap module. 662 */ 663 pmap_bootstrap(); 664 665 restore_ofw_mapping(); 666 667 PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ 668 669 /* setup proc 0's pcb */ 670 thread0.td_pcb->pcb_flags = 0; /* XXXKSE */ 671 thread0.td_frame = &proc0_tf; 672 } 673 #endif 674 675 static int N_mapping; 676 static struct { 677 vm_offset_t va; 678 int len; 679 vm_offset_t pa; 680 int mode; 681 } ofw_mapping[256]; 682 683 int 684 save_ofw_mapping() 685 { 686 int mmui, mmu; 687 688 OF_getprop(chosen, "mmu", &mmui, 4); 689 mmu = OF_instance_to_package(mmui); 690 691 bzero(ofw_mapping, sizeof(ofw_mapping)); 692 693 N_mapping = 694 OF_getprop(mmu, "translations", ofw_mapping, sizeof(ofw_mapping)); 695 N_mapping /= sizeof(ofw_mapping[0]); 696 697 return 0; 698 } 699 700 int 701 restore_ofw_mapping() 702 { 703 int i; 704 struct vm_page pg; 705 706 pmap_pinit(&ofw_pmap); 707 708 ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT; 709 710 for (i = 0; i < N_mapping; i++) { 711 vm_offset_t pa = ofw_mapping[i].pa; 712 vm_offset_t va = ofw_mapping[i].va; 713 int size = ofw_mapping[i].len; 714 715 if (va < 0x80000000) /* XXX */ 716 continue; 717 718 while (size > 0) { 719 pg.phys_addr = pa; 720 pmap_enter(&ofw_pmap, va, &pg, VM_PROT_ALL, 721 VM_PROT_ALL); 722 pa += PAGE_SIZE; 723 va += PAGE_SIZE; 724 size -= PAGE_SIZE; 725 } 726 } 727 728 return 0; 729 } 730 731 void 732 bzero(void *buf, size_t len) 733 { 734 caddr_t p; 735 736 p = buf; 737 738 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 739 *p++ = 0; 740 len--; 741 } 742 743 while (len >= sizeof(u_long) * 8) { 744 *(u_long*) p = 0; 745 *((u_long*) p + 1) = 0; 746 *((u_long*) p + 2) = 0; 747 *((u_long*) p + 3) = 0; 748 len -= sizeof(u_long) * 8; 749 *((u_long*) p + 4) = 0; 750 *((u_long*) p + 5) = 0; 751 *((u_long*) p + 6) = 0; 752 *((u_long*) p + 7) = 0; 753 p += sizeof(u_long) * 8; 754 } 755 756 while (len >= sizeof(u_long)) { 757 *(u_long*) p = 0; 758 len -= sizeof(u_long); 759 p += sizeof(u_long); 760 } 761 762 while (len) { 763 *p++ = 0; 764 len--; 765 } 766 } 767 768 #if 0 769 void 770 delay(unsigned n) 771 { 772 u_long tb; 773 774 do { 775 __asm __volatile("mftb %0" : "=r" (tb)); 776 } while (n > (int)(tb & 0xffffffff)); 777 } 778 #endif 779 780 #ifdef COMPAT_43 781 void 782 osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 783 { 784 785 /* XXX: To be done */ 786 return; 787 } 788 #endif 789 790 void 791 sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 792 { 793 794 /* XXX: To be done */ 795 return; 796 } 797 798 /* 799 * Stub to satisfy the reference to osigreturn in the syscall table. This 800 * is needed even for newer arches that don't support old signals because 801 * the syscall table is machine-independent. 802 */ 803 int 804 osigreturn(struct thread *td, struct osigreturn_args *uap) 805 { 806 807 return (nosys(td, (struct nosys_args *)uap)); 808 } 809 810 int 811 sigreturn(struct thread *td, struct sigreturn_args *uap) 812 { 813 814 /* XXX: To be done */ 815 return(ENOSYS); 816 } 817 818 void 819 cpu_boot(int howto) 820 { 821 } 822 823 /* 824 * Shutdown the CPU as much as possible. 825 */ 826 void 827 cpu_halt(void) 828 { 829 830 OF_exit(); 831 } 832 833 /* 834 * Set set up registers on exec. 835 */ 836 void 837 setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 838 { 839 struct trapframe *tf; 840 struct ps_strings arginfo; 841 842 tf = trapframe(td); 843 bzero(tf, sizeof *tf); 844 tf->fixreg[1] = -roundup(-stack + 8, 16); 845 846 /* 847 * XXX Machine-independent code has already copied arguments and 848 * XXX environment to userland. Get them back here. 849 */ 850 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 851 852 /* 853 * Set up arguments for _start(): 854 * _start(argc, argv, envp, obj, cleanup, ps_strings); 855 * 856 * Notes: 857 * - obj and cleanup are the auxilliary and termination 858 * vectors. They are fixed up by ld.elf_so. 859 * - ps_strings is a NetBSD extention, and will be 860 * ignored by executables which are strictly 861 * compliant with the SVR4 ABI. 862 * 863 * XXX We have to set both regs and retval here due to different 864 * XXX calling convention in trap.c and init_main.c. 865 */ 866 tf->fixreg[3] = arginfo.ps_nargvstr; 867 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 868 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 869 tf->fixreg[6] = 0; /* auxillary vector */ 870 tf->fixreg[7] = 0; /* termination vector */ 871 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 872 873 tf->srr0 = entry; 874 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 875 td->td_pcb->pcb_flags = 0; 876 } 877 878 extern void *extint, *extsize; 879 extern u_long extint_call; 880 881 void 882 install_extint(void (*handler)(void)) 883 { 884 u_long offset; 885 int omsr, msr; 886 887 offset = (u_long)handler - (u_long)&extint_call; 888 889 #ifdef DIAGNOSTIC 890 if (offset > 0x1ffffff) 891 panic("install_extint: too far away"); 892 #endif 893 894 msr = mfmsr(); 895 mtmsr(msr & ~PSL_EE); 896 897 extint_call = (extint_call & 0xfc000003) | offset; 898 bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize); 899 __syncicache((void *)&extint_call, sizeof extint_call); 900 __syncicache((void *)EXC_EXI, (int)&extsize); 901 902 mtmsr(msr); 903 } 904 905 #if !defined(DDB) 906 void 907 Debugger(const char *msg) 908 { 909 910 printf("Debugger(\"%s\") called.\n", msg); 911 } 912 #endif /* !defined(DDB) */ 913 914 /* XXX: dummy {fill,set}_[fp]regs */ 915 int 916 fill_regs(struct thread *td, struct reg *regs) 917 { 918 919 return (ENOSYS); 920 } 921 922 int 923 fill_dbregs(struct thread *td, struct dbreg *dbregs) 924 { 925 926 return (ENOSYS); 927 } 928 929 int 930 fill_fpregs(struct thread *td, struct fpreg *fpregs) 931 { 932 933 return (ENOSYS); 934 } 935 936 int 937 set_regs(struct thread *td, struct reg *regs) 938 { 939 940 return (ENOSYS); 941 } 942 943 int 944 set_dbregs(struct thread *td, struct dbreg *dbregs) 945 { 946 947 return (ENOSYS); 948 } 949 950 int 951 set_fpregs(struct thread *td, struct fpreg *fpregs) 952 { 953 954 return (ENOSYS); 955 } 956 957 int 958 ptrace_set_pc(struct thread *td, unsigned long addr) 959 { 960 961 /* XXX: coming soon... */ 962 return (ENOSYS); 963 } 964 965 int 966 ptrace_single_step(struct thread *td) 967 { 968 969 /* XXX: coming soon... */ 970 return (ENOSYS); 971 } 972 973 int 974 ptrace_clear_single_step(struct thread *td) 975 { 976 977 /* XXX: coming soon... */ 978 return (ENOSYS); 979 } 980 981 /* 982 * Initialise a struct pcpu. 983 */ 984 void 985 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 986 { 987 988 pcpu->pc_current_asngen = 1; 989 } 990 991 void 992 enable_fpu(struct pcb *pcb) 993 { 994 int msr, scratch; 995 996 if (!(pcb->pcb_flags & PCB_FPU)) { 997 bzero(&pcb->pcb_fpu, sizeof pcb->pcb_fpu); 998 pcb->pcb_flags |= PCB_FPU; 999 } 1000 __asm volatile ("mfmsr %0; ori %1,%0,%2; mtmsr %1; isync" 1001 : "=r"(msr), "=r"(scratch) : "K"(PSL_FP)); 1002 __asm volatile ("lfd 0,0(%0); mtfsf 0xff,0" :: "b"(&pcb->pcb_fpu.fpscr)); 1003 __asm ("lfd 0,0(%0);" 1004 "lfd 1,8(%0);" 1005 "lfd 2,16(%0);" 1006 "lfd 3,24(%0);" 1007 "lfd 4,32(%0);" 1008 "lfd 5,40(%0);" 1009 "lfd 6,48(%0);" 1010 "lfd 7,56(%0);" 1011 "lfd 8,64(%0);" 1012 "lfd 9,72(%0);" 1013 "lfd 10,80(%0);" 1014 "lfd 11,88(%0);" 1015 "lfd 12,96(%0);" 1016 "lfd 13,104(%0);" 1017 "lfd 14,112(%0);" 1018 "lfd 15,120(%0);" 1019 "lfd 16,128(%0);" 1020 "lfd 17,136(%0);" 1021 "lfd 18,144(%0);" 1022 "lfd 19,152(%0);" 1023 "lfd 20,160(%0);" 1024 "lfd 21,168(%0);" 1025 "lfd 22,176(%0);" 1026 "lfd 23,184(%0);" 1027 "lfd 24,192(%0);" 1028 "lfd 25,200(%0);" 1029 "lfd 26,208(%0);" 1030 "lfd 27,216(%0);" 1031 "lfd 28,224(%0);" 1032 "lfd 29,232(%0);" 1033 "lfd 30,240(%0);" 1034 "lfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); 1035 __asm volatile ("mtmsr %0; isync" :: "r"(msr)); 1036 } 1037 1038 void 1039 save_fpu(struct pcb *pcb) 1040 { 1041 int msr, scratch; 1042 1043 __asm volatile ("mfmsr %0; ori %1,%0,%2; mtmsr %1; isync" 1044 : "=r"(msr), "=r"(scratch) : "K"(PSL_FP)); 1045 __asm ("stfd 0,0(%0);" 1046 "stfd 1,8(%0);" 1047 "stfd 2,16(%0);" 1048 "stfd 3,24(%0);" 1049 "stfd 4,32(%0);" 1050 "stfd 5,40(%0);" 1051 "stfd 6,48(%0);" 1052 "stfd 7,56(%0);" 1053 "stfd 8,64(%0);" 1054 "stfd 9,72(%0);" 1055 "stfd 10,80(%0);" 1056 "stfd 11,88(%0);" 1057 "stfd 12,96(%0);" 1058 "stfd 13,104(%0);" 1059 "stfd 14,112(%0);" 1060 "stfd 15,120(%0);" 1061 "stfd 16,128(%0);" 1062 "stfd 17,136(%0);" 1063 "stfd 18,144(%0);" 1064 "stfd 19,152(%0);" 1065 "stfd 20,160(%0);" 1066 "stfd 21,168(%0);" 1067 "stfd 22,176(%0);" 1068 "stfd 23,184(%0);" 1069 "stfd 24,192(%0);" 1070 "stfd 25,200(%0);" 1071 "stfd 26,208(%0);" 1072 "stfd 27,216(%0);" 1073 "stfd 28,224(%0);" 1074 "stfd 29,232(%0);" 1075 "stfd 30,240(%0);" 1076 "stfd 31,248(%0)" :: "b"(&pcb->pcb_fpu.fpr[0])); 1077 __asm volatile ("mffs 0; stfd 0,0(%0)" :: "b"(&pcb->pcb_fpu.fpscr)); 1078 __asm volatile ("mtmsr %0; isync" :: "r"(msr)); 1079 } 1080