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/imgact.h> 70 #include <sys/sysproto.h> 71 #include <sys/lock.h> 72 #include <sys/mutex.h> 73 #include <sys/ktr.h> 74 #include <sys/signalvar.h> 75 #include <sys/kernel.h> 76 #include <sys/proc.h> 77 #include <sys/malloc.h> 78 #include <sys/reboot.h> 79 #include <sys/bio.h> 80 #include <sys/buf.h> 81 #include <sys/bus.h> 82 #include <sys/mbuf.h> 83 #include <sys/vmmeter.h> 84 #include <sys/msgbuf.h> 85 #include <sys/exec.h> 86 #include <sys/sysctl.h> 87 #include <sys/uio.h> 88 #include <sys/linker.h> 89 #include <sys/cons.h> 90 #include <sys/ucontext.h> 91 #include <sys/sysent.h> 92 #include <net/netisr.h> 93 #include <vm/vm.h> 94 #include <vm/vm_kern.h> 95 #include <vm/vm_page.h> 96 #include <vm/vm_map.h> 97 #include <vm/vm_extern.h> 98 #include <vm/vm_object.h> 99 #include <vm/vm_pager.h> 100 #include <sys/user.h> 101 #include <sys/ptrace.h> 102 #include <machine/bat.h> 103 #include <machine/clock.h> 104 #include <machine/md_var.h> 105 #include <machine/metadata.h> 106 #include <machine/reg.h> 107 #include <machine/fpu.h> 108 #include <machine/vmparam.h> 109 #include <machine/elf.h> 110 #include <machine/trap.h> 111 #include <machine/powerpc.h> 112 #include <dev/ofw/openfirm.h> 113 #include <ddb/ddb.h> 114 #include <sys/vnode.h> 115 #include <machine/sigframe.h> 116 117 int cold = 1; 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 static int cacheline_size = CACHELINESIZE; 133 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 134 CTLFLAG_RD, &cacheline_size, 0, ""); 135 136 char bootpath[256]; 137 138 #ifdef DDB 139 /* start and end of kernel symbol table */ 140 void *ksym_start, *ksym_end; 141 #endif /* DDB */ 142 143 static void cpu_startup(void *); 144 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 145 146 void powerpc_init(u_int, u_int, u_int, void *); 147 148 int save_ofw_mapping(void); 149 int restore_ofw_mapping(void); 150 151 void install_extint(void (*)(void)); 152 153 int setfault(faultbuf); /* defined in locore.S */ 154 155 long Maxmem = 0; 156 157 static int chosen; 158 159 struct pmap ofw_pmap; 160 extern int ofmsr; 161 162 struct bat battable[16]; 163 164 static void identifycpu(void); 165 166 struct kva_md_info kmi; 167 168 static void 169 powerpc_ofw_shutdown(void *junk, int howto) 170 { 171 if (howto & RB_HALT) { 172 OF_exit(); 173 } 174 } 175 176 static void 177 cpu_startup(void *dummy) 178 { 179 180 /* 181 * Good {morning,afternoon,evening,night}. 182 */ 183 identifycpu(); 184 185 /* startrtclock(); */ 186 #ifdef PERFMON 187 perfmon_init(); 188 #endif 189 printf("real memory = %ld (%ld MB)\n", ptoa(Maxmem), 190 ptoa(Maxmem) / 1048576); 191 192 /* 193 * Display any holes after the first chunk of extended memory. 194 */ 195 if (bootverbose) { 196 int indx; 197 198 printf("Physical memory chunk(s):\n"); 199 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 200 int size1 = phys_avail[indx + 1] - phys_avail[indx]; 201 202 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 203 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 204 size1 / PAGE_SIZE); 205 } 206 } 207 208 vm_ksubmap_init(&kmi); 209 210 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 211 ptoa(cnt.v_free_count) / 1048576); 212 213 /* 214 * Set up buffers, so they can be used to read disk labels. 215 */ 216 bufinit(); 217 vm_pager_bufferinit(); 218 219 EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, 220 SHUTDOWN_PRI_LAST); 221 222 #ifdef SMP 223 /* 224 * OK, enough kmem_alloc/malloc state should be up, lets get on with it! 225 */ 226 mp_start(); /* fire up the secondaries */ 227 mp_announce(); 228 #endif /* SMP */ 229 } 230 231 void 232 identifycpu() 233 { 234 unsigned int pvr, version, revision; 235 236 /* 237 * Find cpu type (Do it by OpenFirmware?) 238 */ 239 __asm ("mfpvr %0" : "=r"(pvr)); 240 version = pvr >> 16; 241 revision = pvr & 0xffff; 242 switch (version) { 243 case 0x0000: 244 sprintf(model, "Simulator (psim)"); 245 break; 246 case 0x0001: 247 sprintf(model, "601"); 248 break; 249 case 0x0003: 250 sprintf(model, "603 (Wart)"); 251 break; 252 case 0x0004: 253 sprintf(model, "604 (Zephyr)"); 254 break; 255 case 0x0005: 256 sprintf(model, "602 (Galahad)"); 257 break; 258 case 0x0006: 259 sprintf(model, "603e (Stretch)"); 260 break; 261 case 0x0007: 262 if ((revision && 0xf000) == 0x0000) 263 sprintf(model, "603ev (Valiant)"); 264 else 265 sprintf(model, "603r (Goldeneye)"); 266 break; 267 case 0x0008: 268 if ((revision && 0xf000) == 0x0000) 269 sprintf(model, "G3 / 750 (Arthur)"); 270 else 271 sprintf(model, "G3 / 755 (Goldfinger)"); 272 break; 273 case 0x0009: 274 if ((revision && 0xf000) == 0x0000) 275 sprintf(model, "604e (Sirocco)"); 276 else 277 sprintf(model, "604r (Mach V)"); 278 break; 279 case 0x000a: 280 sprintf(model, "604r (Mach V)"); 281 break; 282 case 0x000c: 283 sprintf(model, "G4 / 7400 (Max)"); 284 break; 285 case 0x0014: 286 sprintf(model, "620 (Red October)"); 287 break; 288 case 0x0081: 289 sprintf(model, "8240 (Kahlua)"); 290 break; 291 case 0x8000: 292 sprintf(model, "G4 / 7450 (V'ger)"); 293 break; 294 case 0x800c: 295 sprintf(model, "G4 / 7410 (Nitro)"); 296 break; 297 case 0x8081: 298 sprintf(model, "8245 (Kahlua II)"); 299 break; 300 default: 301 sprintf(model, "Version %x", version); 302 break; 303 } 304 sprintf(model + strlen(model), " (Revision %x)", revision); 305 printf("CPU: PowerPC %s\n", model); 306 } 307 308 extern char kernel_text[], _end[]; 309 310 extern void *trapcode, *trapsize; 311 extern void *alitrap, *alisize; 312 extern void *dsitrap, *dsisize; 313 extern void *isitrap, *isisize; 314 extern void *decrint, *decrsize; 315 extern void *tlbimiss, *tlbimsize; 316 extern void *tlbdlmiss, *tlbdlmsize; 317 extern void *tlbdsmiss, *tlbdsmsize; 318 extern void *extint, *extsize; 319 320 #if 0 /* XXX: interrupt handler. We'll get to this later */ 321 extern void ext_intr(void); 322 #endif 323 324 #ifdef DDB 325 extern ddblow, ddbsize; 326 #endif 327 #ifdef IPKDB 328 extern ipkdblow, ipkdbsize; 329 #endif 330 331 void 332 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) 333 { 334 struct pcpu *pc; 335 vm_offset_t end, off; 336 void *kmdp; 337 338 end = 0; 339 kmdp = NULL; 340 341 /* 342 * Parse metadata if present and fetch parameters. Must be done 343 * before console is inited so cninit gets the right value of 344 * boothowto. 345 */ 346 if (mdp != NULL) { 347 preload_metadata = mdp; 348 kmdp = preload_search_by_type("elf kernel"); 349 if (kmdp != NULL) { 350 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 351 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 352 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 353 } 354 } 355 356 /* 357 * Initialize the console before printing anything. 358 */ 359 cninit(); 360 361 /* 362 * Complain if there is no metadata. 363 */ 364 if (mdp == NULL || kmdp == NULL) { 365 printf("powerpc_init: no loader metadata.\n"); 366 } 367 368 #ifdef DDB 369 kdb_init(); 370 #endif 371 372 /* 373 * XXX: Initialize the interrupt tables. 374 */ 375 bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize); 376 bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize); 377 bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize); 378 bcopy(&trapcode, (void *)EXC_ALI, (size_t)&trapsize); 379 bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize); 380 bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize); 381 bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize); 382 bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize); 383 bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize); 384 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 385 386 /* 387 * Start initializing proc0 and thread0. 388 */ 389 proc_linkup(&proc0, &ksegrp0, &kse0, &thread0); 390 proc0.p_uarea = (struct user *)uarea0; 391 proc0.p_stats = &proc0.p_uarea->u_stats; 392 thread0.td_frame = &frame0; 393 394 /* 395 * Set up per-cpu data. 396 */ 397 pc = (struct pcpu *)(pcpu0 + PAGE_SIZE) - 1; 398 pcpu_init(pc, 0, sizeof(struct pcpu)); 399 pc->pc_curthread = &thread0; 400 pc->pc_curpcb = thread0.td_pcb; 401 pc->pc_cpuid = 0; 402 /* pc->pc_mid = mid; */ 403 404 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 405 406 mutex_init(); 407 408 /* 409 * Make sure translation has been enabled 410 */ 411 mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI); 412 413 /* 414 * Initialise virtual memory. 415 */ 416 pmap_bootstrap(startkernel, endkernel); 417 418 /* 419 * Initialize tunables. 420 */ 421 init_param1(); 422 init_param2(physmem); 423 424 /* 425 * Finish setting up thread0. 426 */ 427 thread0.td_kstack = kstack0; 428 thread0.td_pcb = (struct pcb *) 429 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 430 431 /* 432 * Map and initialise the message buffer. 433 */ 434 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 435 pmap_kenter((vm_offset_t)msgbufp + off, msgbuf_phys + off); 436 msgbufinit(msgbufp, MSGBUF_SIZE); 437 } 438 439 void 440 bzero(void *buf, size_t len) 441 { 442 caddr_t p; 443 444 p = buf; 445 446 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 447 *p++ = 0; 448 len--; 449 } 450 451 while (len >= sizeof(u_long) * 8) { 452 *(u_long*) p = 0; 453 *((u_long*) p + 1) = 0; 454 *((u_long*) p + 2) = 0; 455 *((u_long*) p + 3) = 0; 456 len -= sizeof(u_long) * 8; 457 *((u_long*) p + 4) = 0; 458 *((u_long*) p + 5) = 0; 459 *((u_long*) p + 6) = 0; 460 *((u_long*) p + 7) = 0; 461 p += sizeof(u_long) * 8; 462 } 463 464 while (len >= sizeof(u_long)) { 465 *(u_long*) p = 0; 466 len -= sizeof(u_long); 467 p += sizeof(u_long); 468 } 469 470 while (len) { 471 *p++ = 0; 472 len--; 473 } 474 } 475 476 void 477 sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 478 { 479 struct trapframe *tf; 480 struct sigframe *sfp; 481 struct sigacts *psp; 482 struct sigframe sf; 483 struct thread *td; 484 struct proc *p; 485 int oonstack, rndfsize; 486 487 td = curthread; 488 p = td->td_proc; 489 psp = p->p_sigacts; 490 tf = td->td_frame; 491 oonstack = sigonstack(tf->fixreg[1]); 492 493 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 494 495 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 496 catcher, sig); 497 498 /* 499 * Save user context 500 */ 501 memset(&sf, 0, sizeof(sf)); 502 sf.sf_uc.uc_sigmask = *mask; 503 sf.sf_uc.uc_stack = p->p_sigstk; 504 sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 505 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 506 507 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 508 memcpy(&sf.sf_uc.uc_mcontext.mc_frame, tf, sizeof(struct trapframe)); 509 510 /* 511 * Allocate and validate space for the signal handler context. 512 */ 513 if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && 514 SIGISMEMBER(psp->ps_sigonstack, sig)) { 515 sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp + 516 p->p_sigstk.ss_size - rndfsize); 517 } else { 518 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); 519 } 520 PROC_UNLOCK(p); 521 522 /* 523 * Translate the signal if appropriate (Linux emu ?) 524 */ 525 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 526 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 527 528 /* 529 * Save the floating-point state, if necessary, then copy it. 530 */ 531 /* XXX */ 532 533 /* 534 * Set up the registers to return to sigcode. 535 * 536 * r1/sp - sigframe ptr 537 * lr - sig function, dispatched to by blrl in trampoline 538 * r3 - sig number 539 * r4 - SIGINFO ? &siginfo : exception code 540 * r5 - user context 541 * srr0 - trampoline function addr 542 */ 543 tf->lr = (register_t)catcher; 544 tf->fixreg[1] = (register_t)sfp; 545 tf->fixreg[FIRSTARG] = sig; 546 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; 547 548 PROC_LOCK(p); 549 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 550 /* 551 * Signal handler installed with SA_SIGINFO. 552 */ 553 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si; 554 555 /* 556 * Fill siginfo structure. 557 */ 558 sf.sf_si.si_signo = sig; 559 sf.sf_si.si_code = code; 560 sf.sf_si.si_addr = (void *)tf->srr0; 561 } else { 562 /* Old FreeBSD-style arguments. */ 563 tf->fixreg[FIRSTARG+1] = code; 564 } 565 PROC_UNLOCK(p); 566 567 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); 568 569 /* 570 * copy the frame out to userland. 571 */ 572 if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) { 573 /* 574 * Process has trashed its stack. Kill it. 575 */ 576 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 577 PROC_LOCK(p); 578 sigexit(td, SIGILL); 579 } 580 581 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 582 tf->srr0, tf->fixreg[1]); 583 584 PROC_LOCK(p); 585 } 586 587 int 588 sigreturn(struct thread *td, struct sigreturn_args *uap) 589 { 590 struct trapframe *tf; 591 struct proc *p; 592 ucontext_t uc; 593 594 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 595 596 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 597 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 598 return (EFAULT); 599 } 600 601 /* 602 * Don't let the user set privileged MSR bits 603 */ 604 tf = td->td_frame; 605 if ((uc.uc_mcontext.mc_frame.srr1 & PSL_USERSTATIC) != 606 (tf->srr1 & PSL_USERSTATIC)) { 607 return (EINVAL); 608 } 609 610 /* 611 * Restore the user-supplied context 612 */ 613 memcpy(tf, &uc.uc_mcontext.mc_frame, sizeof(struct trapframe)); 614 615 p = td->td_proc; 616 PROC_LOCK(p); 617 p->p_sigmask = uc.uc_sigmask; 618 SIG_CANTMASK(p->p_sigmask); 619 signotify(p); 620 PROC_UNLOCK(p); 621 622 /* 623 * Restore FP state 624 */ 625 /* XXX */ 626 627 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 628 td, tf->srr0, tf->fixreg[1]); 629 630 return (EJUSTRETURN); 631 } 632 633 #ifdef COMPAT_FREEBSD4 634 int 635 freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 636 { 637 638 return sigreturn(td, (struct sigreturn_args *)uap); 639 } 640 #endif 641 642 int 643 get_mcontext(struct thread *td, mcontext_t *mcp) 644 { 645 646 return (ENOSYS); 647 } 648 649 int 650 set_mcontext(struct thread *td, const mcontext_t *mcp) 651 { 652 653 return (ENOSYS); 654 } 655 656 void 657 cpu_boot(int howto) 658 { 659 } 660 661 /* 662 * Shutdown the CPU as much as possible. 663 */ 664 void 665 cpu_halt(void) 666 { 667 668 OF_exit(); 669 } 670 671 /* 672 * Set set up registers on exec. 673 */ 674 void 675 exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 676 { 677 struct trapframe *tf; 678 struct ps_strings arginfo; 679 680 tf = trapframe(td); 681 bzero(tf, sizeof *tf); 682 tf->fixreg[1] = -roundup(-stack + 8, 16); 683 684 /* 685 * XXX Machine-independent code has already copied arguments and 686 * XXX environment to userland. Get them back here. 687 */ 688 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 689 690 /* 691 * Set up arguments for _start(): 692 * _start(argc, argv, envp, obj, cleanup, ps_strings); 693 * 694 * Notes: 695 * - obj and cleanup are the auxilliary and termination 696 * vectors. They are fixed up by ld.elf_so. 697 * - ps_strings is a NetBSD extention, and will be 698 * ignored by executables which are strictly 699 * compliant with the SVR4 ABI. 700 * 701 * XXX We have to set both regs and retval here due to different 702 * XXX calling convention in trap.c and init_main.c. 703 */ 704 /* 705 * XXX PG: these get overwritten in the syscall return code. 706 * execve() should return EJUSTRETURN, like it does on NetBSD. 707 * Emulate by setting the syscall return value cells. The 708 * registers still have to be set for init's fork trampoline. 709 */ 710 td->td_retval[0] = arginfo.ps_nargvstr; 711 td->td_retval[1] = (register_t)arginfo.ps_argvstr; 712 tf->fixreg[3] = arginfo.ps_nargvstr; 713 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 714 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 715 tf->fixreg[6] = 0; /* auxillary vector */ 716 tf->fixreg[7] = 0; /* termination vector */ 717 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 718 719 tf->srr0 = entry; 720 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 721 td->td_pcb->pcb_flags = 0; 722 } 723 724 #if !defined(DDB) 725 void 726 Debugger(const char *msg) 727 { 728 729 printf("Debugger(\"%s\") called.\n", msg); 730 } 731 #endif /* !defined(DDB) */ 732 733 /* XXX: dummy {fill,set}_[fp]regs */ 734 int 735 fill_regs(struct thread *td, struct reg *regs) 736 { 737 738 return (ENOSYS); 739 } 740 741 int 742 fill_dbregs(struct thread *td, struct dbreg *dbregs) 743 { 744 745 return (ENOSYS); 746 } 747 748 int 749 fill_fpregs(struct thread *td, struct fpreg *fpregs) 750 { 751 752 return (ENOSYS); 753 } 754 755 int 756 set_regs(struct thread *td, struct reg *regs) 757 { 758 759 return (ENOSYS); 760 } 761 762 int 763 set_dbregs(struct thread *td, struct dbreg *dbregs) 764 { 765 766 return (ENOSYS); 767 } 768 769 int 770 set_fpregs(struct thread *td, struct fpreg *fpregs) 771 { 772 773 return (ENOSYS); 774 } 775 776 int 777 ptrace_set_pc(struct thread *td, unsigned long addr) 778 { 779 780 /* XXX: coming soon... */ 781 return (ENOSYS); 782 } 783 784 int 785 ptrace_single_step(struct thread *td) 786 { 787 788 /* XXX: coming soon... */ 789 return (ENOSYS); 790 } 791 792 /* 793 * Initialise a struct pcpu. 794 */ 795 void 796 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 797 { 798 799 pcpu->pc_current_asngen = 1; 800 } 801 802 /* 803 * kcopy(const void *src, void *dst, size_t len); 804 * 805 * Copy len bytes from src to dst, aborting if we encounter a fatal 806 * page fault. 807 * 808 * kcopy() _must_ save and restore the old fault handler since it is 809 * called by uiomove(), which may be in the path of servicing a non-fatal 810 * page fault. 811 */ 812 int 813 kcopy(const void *src, void *dst, size_t len) 814 { 815 struct thread *td; 816 faultbuf env, *oldfault; 817 int rv; 818 819 td = PCPU_GET(curthread); 820 oldfault = td->td_pcb->pcb_onfault; 821 if ((rv = setfault(env)) != 0) { 822 td->td_pcb->pcb_onfault = oldfault; 823 return rv; 824 } 825 826 memcpy(dst, src, len); 827 828 td->td_pcb->pcb_onfault = oldfault; 829 return (0); 830 } 831