Deleted Added
full compact
machdep.c (209908) machdep.c (209950)
1/*-
2 * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 65 unchanged lines hidden (view full) ---

74 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
75 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
76 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
77 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
78 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 */
80
81#include <sys/cdefs.h>
1/*-
2 * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 65 unchanged lines hidden (view full) ---

74 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
75 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
76 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
77 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
78 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 */
80
81#include <sys/cdefs.h>
82__FBSDID("$FreeBSD: head/sys/powerpc/booke/machdep.c 209908 2010-07-11 21:08:29Z raj $");
82__FBSDID("$FreeBSD: head/sys/powerpc/booke/machdep.c 209950 2010-07-12 16:08:07Z nwhitehorn $");
83
84#include "opt_compat.h"
85#include "opt_ddb.h"
86#include "opt_kstack_pages.h"
87#include "opt_msgbuf.h"
88
89#include <sys/cdefs.h>
90#include <sys/types.h>

--- 362 unchanged lines hidden (view full) ---

453
454 ptr = &tlb0_miss_locks[cpuid * words_per_gran];
455 pcpu->pc_booke_tlb_lock = ptr;
456 *ptr = MTX_UNOWNED;
457 *(ptr + 1) = 0; /* recurse counter */
458#endif
459}
460
83
84#include "opt_compat.h"
85#include "opt_ddb.h"
86#include "opt_kstack_pages.h"
87#include "opt_msgbuf.h"
88
89#include <sys/cdefs.h>
90#include <sys/types.h>

--- 362 unchanged lines hidden (view full) ---

453
454 ptr = &tlb0_miss_locks[cpuid * words_per_gran];
455 pcpu->pc_booke_tlb_lock = ptr;
456 *ptr = MTX_UNOWNED;
457 *(ptr + 1) = 0; /* recurse counter */
458#endif
459}
460
461/* Set set up registers on exec. */
462void
463exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
464{
465 struct trapframe *tf;
466 struct ps_strings arginfo;
467
468 tf = trapframe(td);
469 bzero(tf, sizeof *tf);
470 tf->fixreg[1] = -roundup(-stack + 8, 16);
471
472 /*
473 * XXX Machine-independent code has already copied arguments and
474 * XXX environment to userland. Get them back here.
475 */
476 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo));
477
478 /*
479 * Set up arguments for _start():
480 * _start(argc, argv, envp, obj, cleanup, ps_strings);
481 *
482 * Notes:
483 * - obj and cleanup are the auxilliary and termination
484 * vectors. They are fixed up by ld.elf_so.
485 * - ps_strings is a NetBSD extention, and will be
486 * ignored by executables which are strictly
487 * compliant with the SVR4 ABI.
488 *
489 * XXX We have to set both regs and retval here due to different
490 * XXX calling convention in trap.c and init_main.c.
491 */
492 /*
493 * XXX PG: these get overwritten in the syscall return code.
494 * execve() should return EJUSTRETURN, like it does on NetBSD.
495 * Emulate by setting the syscall return value cells. The
496 * registers still have to be set for init's fork trampoline.
497 */
498 td->td_retval[0] = arginfo.ps_nargvstr;
499 td->td_retval[1] = (register_t)arginfo.ps_argvstr;
500 tf->fixreg[3] = arginfo.ps_nargvstr;
501 tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
502 tf->fixreg[5] = (register_t)arginfo.ps_envstr;
503 tf->fixreg[6] = 0; /* auxillary vector */
504 tf->fixreg[7] = 0; /* termination vector */
505 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
506
507 tf->srr0 = imgp->entry_addr;
508 tf->srr1 = PSL_USERSET;
509 td->td_pcb->pcb_flags = 0;
510}
511
512int
513fill_regs(struct thread *td, struct reg *regs)
514{
515 struct trapframe *tf;
516
517 tf = td->td_frame;
518 memcpy(regs, tf, sizeof(struct reg));
519
520 return (0);
521}
522
523int
524fill_fpregs(struct thread *td, struct fpreg *fpregs)
525{
526
527 return (0);
528}
529
530/*
531 * Flush the D-cache for non-DMA I/O so that the I-cache can
532 * be made coherent later.
533 */
534void
535cpu_flush_dcache(void *ptr, size_t len)
536{
537 /* TBD */
538}
539
540/*
461/*
462 * Flush the D-cache for non-DMA I/O so that the I-cache can
463 * be made coherent later.
464 */
465void
466cpu_flush_dcache(void *ptr, size_t len)
467{
468 /* TBD */
469}
470
471/*
541 * Construct a PCB from a trapframe. This is called from kdb_trap() where
542 * we want to start a backtrace from the function that caused us to enter
543 * the debugger. We have the context in the trapframe, but base the trace
544 * on the PCB. The PCB doesn't have to be perfect, as long as it contains
545 * enough for a backtrace.
546 */
547void
548makectx(struct trapframe *tf, struct pcb *pcb)
549{
550
551 pcb->pcb_lr = tf->srr0;
552 pcb->pcb_sp = tf->fixreg[1];
553}
554
555/*
556 * get_mcontext/sendsig helper routine that doesn't touch the
557 * proc lock.
558 */
559static int
560grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
561{
562 struct pcb *pcb;
563
564 pcb = td->td_pcb;
565 memset(mcp, 0, sizeof(mcontext_t));
566
567 mcp->mc_vers = _MC_VERSION;
568 mcp->mc_flags = 0;
569 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe));
570 if (flags & GET_MC_CLEAR_RET) {
571 mcp->mc_gpr[3] = 0;
572 mcp->mc_gpr[4] = 0;
573 }
574
575 /* XXX Altivec context ? */
576
577 mcp->mc_len = sizeof(*mcp);
578 return (0);
579}
580
581int
582get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
583{
584 int error;
585
586 error = grab_mcontext(td, mcp, flags);
587 if (error == 0) {
588 PROC_LOCK(curthread->td_proc);
589 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
590 PROC_UNLOCK(curthread->td_proc);
591 }
592
593 return (error);
594}
595
596int
597set_mcontext(struct thread *td, const mcontext_t *mcp)
598{
599 struct pcb *pcb;
600 struct trapframe *tf;
601
602 pcb = td->td_pcb;
603 tf = td->td_frame;
604
605 if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp))
606 return (EINVAL);
607
608 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
609
610 /* XXX Altivec context? */
611
612 return (0);
613}
614
615int
616sigreturn(struct thread *td, struct sigreturn_args *uap)
617{
618 ucontext_t uc;
619 int error;
620
621 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
622
623 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
624 CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
625 return (EFAULT);
626 }
627
628 error = set_mcontext(td, &uc.uc_mcontext);
629 if (error != 0)
630 return (error);
631
632 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
633
634 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
635 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
636
637 return (EJUSTRETURN);
638}
639
640#ifdef COMPAT_FREEBSD4
641int
642freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
643{
644
645 return sigreturn(td, (struct sigreturn_args *)uap);
646}
647#endif
648
649/*
650 * cpu_idle
651 *
652 * Set Wait state enable.
653 */
654void
655cpu_idle (int busy)
656{
657 register_t msr;

--- 49 unchanged lines hidden (view full) ---

707cpu_halt(void)
708{
709
710 mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE));
711 while (1);
712}
713
714int
472 * cpu_idle
473 *
474 * Set Wait state enable.
475 */
476void
477cpu_idle (int busy)
478{
479 register_t msr;

--- 49 unchanged lines hidden (view full) ---

529cpu_halt(void)
530{
531
532 mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE));
533 while (1);
534}
535
536int
715set_regs(struct thread *td, struct reg *regs)
716{
717 struct trapframe *tf;
718
719 tf = td->td_frame;
720 memcpy(tf, regs, sizeof(struct reg));
721 return (0);
722}
723
724int
725fill_dbregs(struct thread *td, struct dbreg *dbregs)
726{
727
728 /* No debug registers on PowerPC */
729 return (ENOSYS);
730}
731
732int
733set_dbregs(struct thread *td, struct dbreg *dbregs)
734{
735
736 /* No debug registers on PowerPC */
737 return (ENOSYS);
738}
739
740int
741set_fpregs(struct thread *td, struct fpreg *fpregs)
742{
743
744 return (0);
745}
746
747int
748ptrace_set_pc(struct thread *td, unsigned long addr)
749{
750 struct trapframe *tf;
751
752 tf = td->td_frame;
753 tf->srr0 = (register_t)addr;
754
755 return (0);

--- 37 unchanged lines hidden (view full) ---

793 register_t r;
794
795 r = mfspr(SPR_DBCR0);
796 mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM);
797 kdb_frame->srr1 |= PSL_DE;
798}
799
800void
537ptrace_set_pc(struct thread *td, unsigned long addr)
538{
539 struct trapframe *tf;
540
541 tf = td->td_frame;
542 tf->srr0 = (register_t)addr;
543
544 return (0);

--- 37 unchanged lines hidden (view full) ---

582 register_t r;
583
584 r = mfspr(SPR_DBCR0);
585 mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM);
586 kdb_frame->srr1 |= PSL_DE;
587}
588
589void
801sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
802{
803 struct trapframe *tf;
804 struct sigframe *sfp;
805 struct sigacts *psp;
806 struct sigframe sf;
807 struct thread *td;
808 struct proc *p;
809 int oonstack, rndfsize;
810 int sig, code;
811
812 td = curthread;
813 p = td->td_proc;
814 PROC_LOCK_ASSERT(p, MA_OWNED);
815 sig = ksi->ksi_signo;
816 code = ksi->ksi_code;
817 psp = p->p_sigacts;
818 mtx_assert(&psp->ps_mtx, MA_OWNED);
819 tf = td->td_frame;
820 oonstack = sigonstack(tf->fixreg[1]);
821
822 rndfsize = ((sizeof(sf) + 15) / 16) * 16;
823
824 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
825 catcher, sig);
826
827 /*
828 * Save user context
829 */
830 memset(&sf, 0, sizeof(sf));
831 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
832 sf.sf_uc.uc_sigmask = *mask;
833 sf.sf_uc.uc_stack = td->td_sigstk;
834 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
835 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
836
837 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
838
839 /*
840 * Allocate and validate space for the signal handler context.
841 */
842 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
843 SIGISMEMBER(psp->ps_sigonstack, sig)) {
844 sfp = (struct sigframe *)((caddr_t)td->td_sigstk.ss_sp +
845 td->td_sigstk.ss_size - rndfsize);
846 } else {
847 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
848 }
849
850 /*
851 * Translate the signal if appropriate (Linux emu ?)
852 */
853 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
854 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
855
856 /*
857 * Save the floating-point state, if necessary, then copy it.
858 */
859 /* XXX */
860
861 /*
862 * Set up the registers to return to sigcode.
863 *
864 * r1/sp - sigframe ptr
865 * lr - sig function, dispatched to by blrl in trampoline
866 * r3 - sig number
867 * r4 - SIGINFO ? &siginfo : exception code
868 * r5 - user context
869 * srr0 - trampoline function addr
870 */
871 tf->lr = (register_t)catcher;
872 tf->fixreg[1] = (register_t)sfp;
873 tf->fixreg[FIRSTARG] = sig;
874 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
875 if (SIGISMEMBER(psp->ps_siginfo, sig)) {
876 /*
877 * Signal handler installed with SA_SIGINFO.
878 */
879 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
880
881 /*
882 * Fill siginfo structure.
883 */
884 sf.sf_si = ksi->ksi_info;
885 sf.sf_si.si_signo = sig;
886 sf.sf_si.si_addr = (void *) ((tf->exc == EXC_DSI) ?
887 tf->cpu.booke.dear : tf->srr0);
888 } else {
889 /* Old FreeBSD-style arguments. */
890 tf->fixreg[FIRSTARG+1] = code;
891 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
892 tf->cpu.booke.dear : tf->srr0;
893 }
894 mtx_unlock(&psp->ps_mtx);
895 PROC_UNLOCK(p);
896
897 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
898
899 /*
900 * copy the frame out to userland.
901 */
902 if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) {
903 /*
904 * Process has trashed its stack. Kill it.
905 */
906 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
907 PROC_LOCK(p);
908 sigexit(td, SIGILL);
909 }
910
911 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
912 tf->srr0, tf->fixreg[1]);
913
914 PROC_LOCK(p);
915 mtx_lock(&psp->ps_mtx);
916}
917
918void
919bzero(void *buf, size_t len)
920{
921 caddr_t p;
922
923 p = buf;
924
925 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
926 *p++ = 0;

--- 37 unchanged lines hidden ---
590bzero(void *buf, size_t len)
591{
592 caddr_t p;
593
594 p = buf;
595
596 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
597 *p++ = 0;

--- 37 unchanged lines hidden ---