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