Deleted Added
full compact
aim_machdep.c (209613) aim_machdep.c (209950)
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:

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

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>
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:

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

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: head/sys/powerpc/aim/machdep.c 209613 2010-06-30 18:03:42Z jhb $");
58__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 209950 2010-07-12 16:08:07Z nwhitehorn $");
59
60#include "opt_compat.h"
61#include "opt_ddb.h"
62#include "opt_kstack_pages.h"
63#include "opt_msgbuf.h"
64
65#include <sys/param.h>
66#include <sys/proc.h>

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

150
151int save_ofw_mapping(void);
152int restore_ofw_mapping(void);
153
154void install_extint(void (*)(void));
155
156int setfault(faultbuf); /* defined in locore.S */
157
59
60#include "opt_compat.h"
61#include "opt_ddb.h"
62#include "opt_kstack_pages.h"
63#include "opt_msgbuf.h"
64
65#include <sys/param.h>
66#include <sys/proc.h>

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

150
151int save_ofw_mapping(void);
152int restore_ofw_mapping(void);
153
154void install_extint(void (*)(void));
155
156int setfault(faultbuf); /* defined in locore.S */
157
158static int grab_mcontext(struct thread *, mcontext_t *, int);
159
160void asm_panic(char *);
161
162long Maxmem = 0;
163long realmem = 0;
164
165struct pmap ofw_pmap;
166extern int ofmsr;
167

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

575
576 while (len) {
577 *p++ = 0;
578 len--;
579 }
580}
581
582void
158void asm_panic(char *);
159
160long Maxmem = 0;
161long realmem = 0;
162
163struct pmap ofw_pmap;
164extern int ofmsr;
165

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

573
574 while (len) {
575 *p++ = 0;
576 len--;
577 }
578}
579
580void
583sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
584{
585 struct trapframe *tf;
586 struct sigframe *sfp;
587 struct sigacts *psp;
588 struct sigframe sf;
589 struct thread *td;
590 struct proc *p;
591 int oonstack, rndfsize;
592 int sig;
593 int code;
594
595 td = curthread;
596 p = td->td_proc;
597 PROC_LOCK_ASSERT(p, MA_OWNED);
598 sig = ksi->ksi_signo;
599 code = ksi->ksi_code;
600 psp = p->p_sigacts;
601 mtx_assert(&psp->ps_mtx, MA_OWNED);
602 tf = td->td_frame;
603 oonstack = sigonstack(tf->fixreg[1]);
604
605 rndfsize = ((sizeof(sf) + 15) / 16) * 16;
606
607 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
608 catcher, sig);
609
610 /*
611 * Save user context
612 */
613 memset(&sf, 0, sizeof(sf));
614 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
615 sf.sf_uc.uc_sigmask = *mask;
616 sf.sf_uc.uc_stack = td->td_sigstk;
617 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
618 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
619
620 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
621
622 /*
623 * Allocate and validate space for the signal handler context.
624 */
625 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
626 SIGISMEMBER(psp->ps_sigonstack, sig)) {
627 sfp = (struct sigframe *)(td->td_sigstk.ss_sp +
628 td->td_sigstk.ss_size - rndfsize);
629 } else {
630 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
631 }
632
633 /*
634 * Translate the signal if appropriate (Linux emu ?)
635 */
636 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
637 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
638
639 /*
640 * Save the floating-point state, if necessary, then copy it.
641 */
642 /* XXX */
643
644 /*
645 * Set up the registers to return to sigcode.
646 *
647 * r1/sp - sigframe ptr
648 * lr - sig function, dispatched to by blrl in trampoline
649 * r3 - sig number
650 * r4 - SIGINFO ? &siginfo : exception code
651 * r5 - user context
652 * srr0 - trampoline function addr
653 */
654 tf->lr = (register_t)catcher;
655 tf->fixreg[1] = (register_t)sfp;
656 tf->fixreg[FIRSTARG] = sig;
657 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
658 if (SIGISMEMBER(psp->ps_siginfo, sig)) {
659 /*
660 * Signal handler installed with SA_SIGINFO.
661 */
662 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
663
664 /*
665 * Fill siginfo structure.
666 */
667 sf.sf_si = ksi->ksi_info;
668 sf.sf_si.si_signo = sig;
669 sf.sf_si.si_addr = (void *)((tf->exc == EXC_DSI) ?
670 tf->cpu.aim.dar : tf->srr0);
671 } else {
672 /* Old FreeBSD-style arguments. */
673 tf->fixreg[FIRSTARG+1] = code;
674 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
675 tf->cpu.aim.dar : tf->srr0;
676 }
677 mtx_unlock(&psp->ps_mtx);
678 PROC_UNLOCK(p);
679
680 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
681
682 /*
683 * copy the frame out to userland.
684 */
685 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
686 /*
687 * Process has trashed its stack. Kill it.
688 */
689 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
690 PROC_LOCK(p);
691 sigexit(td, SIGILL);
692 }
693
694 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
695 tf->srr0, tf->fixreg[1]);
696
697 PROC_LOCK(p);
698 mtx_lock(&psp->ps_mtx);
699}
700
701int
702sigreturn(struct thread *td, struct sigreturn_args *uap)
703{
704 ucontext_t uc;
705 int error;
706
707 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
708
709 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
710 CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
711 return (EFAULT);
712 }
713
714 error = set_mcontext(td, &uc.uc_mcontext);
715 if (error != 0)
716 return (error);
717
718 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
719
720 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
721 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
722
723 return (EJUSTRETURN);
724}
725
726#ifdef COMPAT_FREEBSD4
727int
728freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
729{
730
731 return sigreturn(td, (struct sigreturn_args *)uap);
732}
733#endif
734
735/*
736 * Construct a PCB from a trapframe. This is called from kdb_trap() where
737 * we want to start a backtrace from the function that caused us to enter
738 * the debugger. We have the context in the trapframe, but base the trace
739 * on the PCB. The PCB doesn't have to be perfect, as long as it contains
740 * enough for a backtrace.
741 */
742void
743makectx(struct trapframe *tf, struct pcb *pcb)
744{
745
746 pcb->pcb_lr = tf->srr0;
747 pcb->pcb_sp = tf->fixreg[1];
748}
749
750/*
751 * get_mcontext/sendsig helper routine that doesn't touch the
752 * proc lock
753 */
754static int
755grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
756{
757 struct pcb *pcb;
758
759 pcb = td->td_pcb;
760
761 memset(mcp, 0, sizeof(mcontext_t));
762
763 mcp->mc_vers = _MC_VERSION;
764 mcp->mc_flags = 0;
765 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe));
766 if (flags & GET_MC_CLEAR_RET) {
767 mcp->mc_gpr[3] = 0;
768 mcp->mc_gpr[4] = 0;
769 }
770
771 /*
772 * This assumes that floating-point context is *not* lazy,
773 * so if the thread has used FP there would have been a
774 * FP-unavailable exception that would have set things up
775 * correctly.
776 */
777 if (pcb->pcb_flags & PCB_FPU) {
778 KASSERT(td == curthread,
779 ("get_mcontext: fp save not curthread"));
780 critical_enter();
781 save_fpu(td);
782 critical_exit();
783 mcp->mc_flags |= _MC_FP_VALID;
784 memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
785 memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double));
786 }
787
788 /*
789 * Repeat for Altivec context
790 */
791
792 if (pcb->pcb_flags & PCB_VEC) {
793 KASSERT(td == curthread,
794 ("get_mcontext: fp save not curthread"));
795 critical_enter();
796 save_vec(td);
797 critical_exit();
798 mcp->mc_flags |= _MC_AV_VALID;
799 mcp->mc_vscr = pcb->pcb_vec.vscr;
800 mcp->mc_vrsave = pcb->pcb_vec.vrsave;
801 memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec));
802 }
803
804 mcp->mc_len = sizeof(*mcp);
805
806 return (0);
807}
808
809int
810get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
811{
812 int error;
813
814 error = grab_mcontext(td, mcp, flags);
815 if (error == 0) {
816 PROC_LOCK(curthread->td_proc);
817 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
818 PROC_UNLOCK(curthread->td_proc);
819 }
820
821 return (error);
822}
823
824int
825set_mcontext(struct thread *td, const mcontext_t *mcp)
826{
827 struct pcb *pcb;
828 struct trapframe *tf;
829
830 pcb = td->td_pcb;
831 tf = td->td_frame;
832
833 if (mcp->mc_vers != _MC_VERSION ||
834 mcp->mc_len != sizeof(*mcp))
835 return (EINVAL);
836
837 /*
838 * Don't let the user set privileged MSR bits
839 */
840 if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) {
841 return (EINVAL);
842 }
843
844 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
845
846 if (mcp->mc_flags & _MC_FP_VALID) {
847 if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) {
848 critical_enter();
849 enable_fpu(td);
850 critical_exit();
851 }
852 memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
853 memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double));
854 }
855
856 if (mcp->mc_flags & _MC_AV_VALID) {
857 if ((pcb->pcb_flags & PCB_VEC) != PCB_VEC) {
858 critical_enter();
859 enable_vec(td);
860 critical_exit();
861 }
862 pcb->pcb_vec.vscr = mcp->mc_vscr;
863 pcb->pcb_vec.vrsave = mcp->mc_vrsave;
864 memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec));
865 }
866
867
868 return (0);
869}
870
871void
872cpu_boot(int howto)
873{
874}
875
876/*
877 * Flush the D-cache for non-DMA I/O so that the I-cache can
878 * be made coherent later.
879 */

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

943
944int
945cpu_idle_wakeup(int cpu)
946{
947
948 return (0);
949}
950
581cpu_boot(int howto)
582{
583}
584
585/*
586 * Flush the D-cache for non-DMA I/O so that the I-cache can
587 * be made coherent later.
588 */

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

652
653int
654cpu_idle_wakeup(int cpu)
655{
656
657 return (0);
658}
659
951/*
952 * Set set up registers on exec.
953 */
954void
955exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
956{
957 struct trapframe *tf;
958 struct ps_strings arginfo;
959
960 tf = trapframe(td);
961 bzero(tf, sizeof *tf);
962 tf->fixreg[1] = -roundup(-stack + 8, 16);
963
964 /*
965 * XXX Machine-independent code has already copied arguments and
966 * XXX environment to userland. Get them back here.
967 */
968 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo));
969
970 /*
971 * Set up arguments for _start():
972 * _start(argc, argv, envp, obj, cleanup, ps_strings);
973 *
974 * Notes:
975 * - obj and cleanup are the auxilliary and termination
976 * vectors. They are fixed up by ld.elf_so.
977 * - ps_strings is a NetBSD extention, and will be
978 * ignored by executables which are strictly
979 * compliant with the SVR4 ABI.
980 *
981 * XXX We have to set both regs and retval here due to different
982 * XXX calling convention in trap.c and init_main.c.
983 */
984 /*
985 * XXX PG: these get overwritten in the syscall return code.
986 * execve() should return EJUSTRETURN, like it does on NetBSD.
987 * Emulate by setting the syscall return value cells. The
988 * registers still have to be set for init's fork trampoline.
989 */
990 td->td_retval[0] = arginfo.ps_nargvstr;
991 td->td_retval[1] = (register_t)arginfo.ps_argvstr;
992 tf->fixreg[3] = arginfo.ps_nargvstr;
993 tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
994 tf->fixreg[5] = (register_t)arginfo.ps_envstr;
995 tf->fixreg[6] = 0; /* auxillary vector */
996 tf->fixreg[7] = 0; /* termination vector */
997 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
998
999 tf->srr0 = imgp->entry_addr;
1000 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
1001 td->td_pcb->pcb_flags = 0;
1002}
1003
1004int
660int
1005fill_regs(struct thread *td, struct reg *regs)
1006{
1007 struct trapframe *tf;
1008
1009 tf = td->td_frame;
1010 memcpy(regs, tf, sizeof(struct reg));
1011
1012 return (0);
1013}
1014
1015int
1016fill_dbregs(struct thread *td, struct dbreg *dbregs)
1017{
1018 /* No debug registers on PowerPC */
1019 return (ENOSYS);
1020}
1021
1022int
1023fill_fpregs(struct thread *td, struct fpreg *fpregs)
1024{
1025 struct pcb *pcb;
1026
1027 pcb = td->td_pcb;
1028
1029 if ((pcb->pcb_flags & PCB_FPU) == 0)
1030 memset(fpregs, 0, sizeof(struct fpreg));
1031 else
1032 memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
1033
1034 return (0);
1035}
1036
1037int
1038set_regs(struct thread *td, struct reg *regs)
1039{
1040 struct trapframe *tf;
1041
1042 tf = td->td_frame;
1043 memcpy(tf, regs, sizeof(struct reg));
1044
1045 return (0);
1046}
1047
1048int
1049set_dbregs(struct thread *td, struct dbreg *dbregs)
1050{
1051 /* No debug registers on PowerPC */
1052 return (ENOSYS);
1053}
1054
1055int
1056set_fpregs(struct thread *td, struct fpreg *fpregs)
1057{
1058 struct pcb *pcb;
1059
1060 pcb = td->td_pcb;
1061 if ((pcb->pcb_flags & PCB_FPU) == 0)
1062 enable_fpu(td);
1063 memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
1064
1065 return (0);
1066}
1067
1068int
1069ptrace_set_pc(struct thread *td, unsigned long addr)
1070{
1071 struct trapframe *tf;
1072
1073 tf = td->td_frame;
1074 tf->srr0 = (register_t)addr;
1075
1076 return (0);

--- 127 unchanged lines hidden ---
661ptrace_set_pc(struct thread *td, unsigned long addr)
662{
663 struct trapframe *tf;
664
665 tf = td->td_frame;
666 tf->srr0 = (register_t)addr;
667
668 return (0);

--- 127 unchanged lines hidden ---