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

Cache object: 322a12e5113737fc20e7ddcb35ff43cd


[ 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.