The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/machdep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e48e1a26967bea72ac66df4d9f2162b4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.