From: downsj Date: Wed, 26 Mar 1997 08:32:36 +0000 (+0000) Subject: Merge changes from NetBSD, up to 3/19/97; undoes some local changes. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c76d4dae685e80408f8a636f6b4c999d93123142;p=openbsd Merge changes from NetBSD, up to 3/19/97; undoes some local changes. Changed to match new arch/m68k code. genassym.cf is currently just a place holder. --- diff --git a/sys/arch/hp300/DOC/Options b/sys/arch/hp300/DOC/Options index ff2ef258736..04ec092f1f3 100644 --- a/sys/arch/hp300/DOC/Options +++ b/sys/arch/hp300/DOC/Options @@ -1,4 +1,4 @@ -$OpenBSD: Options,v 1.3 1997/02/04 07:15:22 downsj Exp $ +$OpenBSD: Options,v 1.4 1997/03/26 08:32:36 downsj Exp $ $NetBSD: Options,v 1.6 1997/01/31 23:01:21 carrel Exp $ Here is a list of hp300 specific kernel compilation options and what they @@ -79,12 +79,6 @@ COMPAT_HPUX COMPAT_OHPUX Compile in old 4.2-ish HP-UX (pre-6.0?) compatibility code. -FPCOPROC - Compile in code to support the 68881 and above FPU. Should always - be defined, since all supported SPUs have one. Don't even know if - it will compile, much less work, without this option. Defined in - the prototype makefile (hp300/conf/Makefile.hp300). - DCMSTATS Compile in code to collect a variety of transmit/receive statistics for the 98642 4-port MUX. diff --git a/sys/arch/hp300/conf/Makefile.hp300 b/sys/arch/hp300/conf/Makefile.hp300 index c85387065b7..631c7ae9f8b 100644 --- a/sys/arch/hp300/conf/Makefile.hp300 +++ b/sys/arch/hp300/conf/Makefile.hp300 @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.hp300,v 1.12 1997/02/03 04:47:06 downsj Exp $ +# $OpenBSD: Makefile.hp300,v 1.13 1997/03/26 08:32:38 downsj Exp $ # $NetBSD: Makefile.hp300,v 1.45 1996/12/01 06:12:30 jonathan Exp $ # Makefile for OpenBSD @@ -34,7 +34,7 @@ HP300= ../.. INCLUDES= -I. -I$S/arch -I$S -nostdinc CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL \ - -Dmc68020 -Dhp300 -DFPCOPROC + -Dmc68020 -Dhp300 CWARNFLAGS= -Werror CFLAGS= ${DEBUG} ${COPTS} ${CWARNFLAGS} -msoft-float AFLAGS= -x assembler-with-cpp -traditional-cpp -D_LOCORE diff --git a/sys/arch/hp300/conf/files.hp300 b/sys/arch/hp300/conf/files.hp300 index 6a3851f8b42..391bb1dab8f 100644 --- a/sys/arch/hp300/conf/files.hp300 +++ b/sys/arch/hp300/conf/files.hp300 @@ -1,5 +1,5 @@ -# $OpenBSD: files.hp300,v 1.7 1997/02/24 01:16:07 downsj Exp $ -# $NetBSD: files.hp300,v 1.22 1997/01/30 22:11:19 scottr Exp $ +# $OpenBSD: files.hp300,v 1.8 1997/03/26 08:32:38 downsj Exp $ +# $NetBSD: files.hp300,v 1.23 1997/03/17 19:46:43 gwr Exp $ # # hp300-specific configuration info @@ -180,8 +180,6 @@ file arch/hp300/hp300/vm_machdep.c file arch/hp300/hp300/disksubr.c file arch/hp300/dev/dma.c -file arch/m68k/m68k/copy.s - file dev/cons.c file dev/cninit.c diff --git a/sys/arch/hp300/dev/hil.c b/sys/arch/hp300/dev/hil.c index fc159f1fe9d..8817d393416 100644 --- a/sys/arch/hp300/dev/hil.c +++ b/sys/arch/hp300/dev/hil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hil.c,v 1.8 1997/01/12 15:12:41 downsj Exp $ */ +/* $OpenBSD: hil.c,v 1.9 1997/03/26 08:32:39 downsj Exp $ */ /* $NetBSD: hil.c,v 1.29 1996/10/14 07:09:41 thorpej Exp $ */ /* @@ -112,8 +112,8 @@ hilsoftinit(unit, hilbase) register int i; /* XXX ITE interface */ - extern char *us_keymap, *us_shiftmap, *us_ctrlmap, - *us_ctrlshiftmap, **us_stringmap; + extern char us_keymap[], us_shiftmap[], us_ctrlmap[], + us_ctrlshiftmap[], *us_stringmap[]; #ifdef DEBUG if (hildebug & HDB_FOLLOW) @@ -1183,7 +1183,7 @@ kbdcninit() u_char lang; /* XXX from hil_keymaps.c */ - extern char *us_keymap, *us_shiftmap, *us_ctrlmap; + extern char us_keymap[], us_shiftmap[], us_ctrlmap[]; hilkbd_cn_device = h; diff --git a/sys/arch/hp300/hp300/genassym.c b/sys/arch/hp300/hp300/genassym.c index 2c94d54928f..b7dea5e32ea 100644 --- a/sys/arch/hp300/hp300/genassym.c +++ b/sys/arch/hp300/hp300/genassym.c @@ -1,4 +1,4 @@ -/* $OpenBSD: genassym.c,v 1.6 1997/02/04 06:21:29 downsj Exp $ */ +/* $OpenBSD: genassym.c,v 1.7 1997/03/26 08:32:40 downsj Exp $ */ /* $NetBSD: genassym.c,v 1.22 1997/02/02 07:53:16 thorpej Exp $ */ /* @@ -278,9 +278,6 @@ main() def("CLKMSB1", CLKMSB1); def("CLKMSB3", CLKMSB3); - /* HP-UX trace bit */ - def("MDP_TRCB", ffs(MDP_HPUXTRACE) - 1); - #ifdef USELEDS /* LEDs */ def("LED_PULSE", LED_PULSE); diff --git a/sys/arch/hp300/hp300/genassym.cf b/sys/arch/hp300/hp300/genassym.cf new file mode 100644 index 00000000000..ff1cfb36a96 --- /dev/null +++ b/sys/arch/hp300/hp300/genassym.cf @@ -0,0 +1,219 @@ +# $NetBSD: genassym.cf,v 1.5 1997/03/16 09:40:01 thorpej Exp $ + +# +# Copyright (c) 1982, 1990, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# @(#)genassym.c 8.3 (Berkeley) 1/4/94 +# + +include +include +include +include +include +include +include +include + +include + +include +include +include +include + +include +include + +define __XXX_BUG_FODDER 0 + +# CPU options +ifdef M68020 +define M68020 1 +endif +ifdef M68030 +define M68030 1 +endif +ifdef M68040 +define M68040 1 +endif + +# MMU options +ifdef M68K_MMU_MOTOROLA +define M68K_MMU_MOTOROLA 1 +endif +ifdef M68K_MMU_HP +define M68K_MMU_HP 1 +endif + +# values for mmutype +define MMU_68040 MMU_68040 +define MMU_68030 MMU_68030 +define MMU_HP MMU_HP +define MMU_68851 MMU_68851 + +# values for cputype +define CPU_68020 CPU_68020 +define CPU_68030 CPU_68030 +define CPU_68040 CPU_68040 + +# values for fputype +define FPU_68881 FPU_68881 +define FPU_68040 FPU_68040 + +# values for machineid +define HP_320 HP_320 +define HP_330 HP_330 +define HP_350 HP_350 +define HP_360 HP_360 +define HP_370 HP_370 +define HP_340 HP_340 +define HP_375 HP_375 +define HP_380 HP_380 +define HP_433 HP_433 + +# values for ectype +define EC_PHYS EC_PHYS +define EC_NONE EC_NONE +define EC_VIRT EC_VIRT + +# general constants +define UPAGES UPAGES +define USPACE USPACE +define NBPG NBPG +define PGSHIFT PGSHIFT +define USRSTACK USRSTACK +define MAXADDR MAXADDR + +# proc fields and values +define P_FORW offsetof(struct proc, p_forw) +define P_BACK offsetof(struct proc, p_back) +define P_VMSPACE offsetof(struct proc, p_vmspace) +define P_ADDR offsetof(struct proc, p_addr) +define P_PRIORITY offsetof(struct proc, p_priority) +define P_STAT offsetof(struct proc, p_stat) +define P_WCHAN offsetof(struct proc, p_wchan) +define P_MD_FLAGS offsetof(struct proc, p_md.md_flags) +define P_MD_REGS offsetof(struct proc, p_md.md_regs) +define SSLEEP SSLEEP +define SRUN SRUN + +# VM structure fields +define VM_PMAP offsetof(struct vmspace, vm_pmap) +define PM_STCHG offsetof(struct pmap, pm_stchanged) + +# interrupt/fault metering +define V_INTR offsetof(struct vmmeter, v_intr) + +# PSL values (should just include psl.h?) +define PSL_S PSL_S +define PSL_IPL7 PSL_IPL7 +define PSL_LOWIPL PSL_LOWIPL +define PSL_HIGHIPL PSL_HIGHIPL +define PSL_USER PSL_USER +define SPL1 PSL_S | PSL_IPL1 +define SPL2 PSL_S | PSL_IPL2 +define SPL3 PSL_S | PSL_IPL3 +define SPL4 PSL_S | PSL_IPL4 +define SPL5 PSL_S | PSL_IPL5 +define SPL6 PSL_S | PSL_IPL6 + +# magic +define FC_USERD FC_USERD +define FC_PURGE FC_PURGE +define INTIOBASE INTIOBASE +define MMUBASE MMUBASE +define MMUSTAT MMUSTAT +define MMUCMD MMUCMD +define MMUSSTP MMUSSTP +define MMUUSTP MMUUSTP +define MMUTBINVAL MMUTBINVAL +define MMU_BERR MMU_BERR +define MMU_ENAB MMU_ENAB +define MMU_FAULT MMU_FAULT +define MMU_CEN MMU_CEN +define MMU_IEN MMU_IEN +define MMU_FPE MMU_FPE +define CACHE_ON CACHE_ON +define CACHE_OFF CACHE_OFF +define CACHE_CLR CACHE_CLR +define IC_CLEAR IC_CLEAR +define DC_CLEAR DC_CLEAR + +# pte/ste bits +define PG_V PG_V +define PG_NV PG_NV +define PG_RO PG_RO +define PG_RW PG_RW +define PG_CI PG_CI +define PG_PROT PG_PROT +define PG_FRAME PG_FRAME +define SG_V SG_V +define SG_NV SG_NV +define SG_RW SG_RW +define SG_FRAME SG_FRAME +define SG_ISHIFT SG_ISHIFT + +# pcb fields +define PCB_PS offsetof(struct pcb, pcb_ps) +define PCB_USTP offsetof(struct pcb, pcb_ustp) +define PCB_USP offsetof(struct pcb, pcb_usp) +define PCB_REGS offsetof(struct pcb, pcb_regs) +define PCB_ONFAULT offsetof(struct pcb, pcb_onfault) +define PCB_FPCTX offsetof(struct pcb, pcb_fpregs) +define SIZEOF_PCB sizeof(struct pcb) + +# exception frame offset/sizes +define FR_SP offsetof(struct frame, f_regs[15]) +define FR_HW offsetof(struct frame, f_sr) +define FR_ADJ offsetof(struct frame, f_stackadj) +define FR_SIZE sizeof(struct trapframe) + +# system calls +define SYS_exit SYS_exit +define SYS_execve SYS_execve +define SYS_sigreturn SYS_sigreturn + +# errno +define EFAULT EFAULT +define ENAMETOOLONG ENAMETOOLONG + +# clock registers +define CLKSR CLKSR +define CLKMSB1 CLKMSB1 +define CLKMSB3 CLKMSB3 + +# LED stuff +define LED_PULSE LED_PULSE +define LED_DISK LED_DISK +define LED_LANRCV LED_LANRCV +define LED_LANXMT LED_LANXMT diff --git a/sys/arch/hp300/hp300/hpux_machdep.c b/sys/arch/hp300/hp300/hpux_machdep.c index 0133d4fe14d..c7cb54e0a56 100644 --- a/sys/arch/hp300/hp300/hpux_machdep.c +++ b/sys/arch/hp300/hp300/hpux_machdep.c @@ -1,8 +1,8 @@ -/* $OpenBSD: hpux_machdep.c,v 1.3 1997/01/12 15:13:16 downsj Exp $ */ -/* $NetBSD: hpux_machdep.c,v 1.5 1996/10/14 06:51:50 thorpej Exp $ */ +/* $OpenBSD: hpux_machdep.c,v 1.4 1997/03/26 08:32:41 downsj Exp $ */ +/* $NetBSD: hpux_machdep.c,v 1.9 1997/03/16 10:00:45 thorpej Exp $ */ /* - * Copyright (c) 1995, 1996 Jason R. Thorpe. All rights reserved. + * Copyright (c) 1995, 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1988 University of Utah. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -88,6 +88,8 @@ #include +extern short exframesize[]; + #define NHIL 1 /* XXX */ #include "grf.h" @@ -99,10 +101,12 @@ extern int grfopen __P((dev_t dev, int oflags, int devtype, struct proc *p)); extern int hilopen __P((dev_t dev, int oflags, int devtype, struct proc *p)); #endif -static struct { - int machine_id; - char *machine_str; -} machine_table[] = { +struct valtostr { + int val; + const char *str; +}; + +static struct valtostr machine_table[] = { { HP_320, "320" }, { HP_330, "330" }, /* includes 318 and 319 */ { HP_340, "340" }, @@ -115,18 +119,23 @@ static struct { { -1, "3?0" }, /* unknown system (???) */ }; -/* 6.0 and later style context */ -#ifdef M68040 -static char hpux_040context[] = - "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default"; -#endif -#ifdef FPCOPROC -static char hpux_context[] = - "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default"; -#else -static char hpux_context[] = - "standalone HP-MC68020 HP-MC68010 localroot default"; -#endif +/* + * 6.0 and later context. + * XXX what are the HP-UX "localroot" semantics? Should we handle + * XXX diskless systems here? + */ +static struct valtostr context_table[] = { + { FPU_68040, + "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default" + }, + { FPU_68881, + "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default" + }, + { FPU_NONE, + "standalone HP-MC68020 HP-MC68010 localroot default" + }, + { 0, NULL }, +}; #define UOFF(f) ((int)&((struct user *)0)->f) #define HPUOFF(f) ((int)&((struct hpux_user *)0)->f) @@ -223,11 +232,11 @@ hpux_cpu_uname(ut) * Find the current machine-ID in the table and * copy the string into the uname. */ - for (i = 0; machine_table[i].machine_id != -1; ++i) - if (machine_table[i].machine_id == machineid) + for (i = 0; machine_table[i].val != -1; ++i) + if (machine_table[i].val == machineid) break; - sprintf(ut->machine, "9000/%s", machine_table[i].machine_str); + sprintf(ut->machine, "9000/%s", machine_table[i].str); } /* @@ -303,25 +312,28 @@ hpux_sys_getcontext(p, v, retval) register_t *retval; { struct hpux_sys_getcontext_args *uap = v; - int error = 0; + int l, i, error = 0; register int len; -#ifdef M68040 - if ((machineid == HP_380) || (machineid == HP_433)) { - len = min(SCARG(uap, len), sizeof(hpux_040context)); - if (len) - error = copyout(hpux_040context, SCARG(uap, buf), len); - if (error == 0) - *retval = sizeof(hpux_040context); - return (error); + for (i = 0; context_table[i].str != NULL; i++) + if (context_table[i].val == fputype) + break; + if (context_table[i].str == NULL) { + /* + * XXX What else? It's not like this can happen... + */ + return (EINVAL); } -#endif - len = min(SCARG(uap, len), sizeof(hpux_context)); + + /* + 1 ... count the terminating \0. */ + l = strlen(context_table[i].str) + 1; + len = min(SCARG(uap, len), l); + if (len) - error = copyout(hpux_context, SCARG(uap, buf), (u_int)len); + error = copyout(context_table[i].str, SCARG(uap, buf), len); if (error == 0) - *retval = sizeof(hpux_context); - return (error); + *retval = l; + return (0); } /* @@ -344,18 +356,17 @@ hpux_to_bsd_uoff(off, isps, p) if ((int)off == HPUOFF(hpuxu_ar0)) return(UOFF(U_ar0)); + if (fputype) { + /* FP registers from PCB */ + hp = (struct hpux_fp *)HPUOFF(hpuxu_fp); + bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs); -#ifdef FPCOPROC - /* FP registers from PCB */ - hp = (struct hpux_fp *)HPUOFF(hpuxu_fp); - bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs); - - if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3]) - return((int)&bp->ctrl[off - hp->hpfp_ctrl]); + if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3]) + return((int)&bp->ctrl[off - hp->hpfp_ctrl]); - if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24]) - return((int)&bp->reg[off - hp->hpfp_reg]); -#endif + if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24]) + return((int)&bp->reg[off - hp->hpfp_reg]); + } /* * Everything else we recognize comes from the kernel stack, @@ -407,89 +418,372 @@ hpux_to_bsd_uoff(off, isps, p) return (-1); } +#define HSS_RTEFRAME 0x01 +#define HSS_FPSTATE 0x02 +#define HSS_USERREGS 0x04 + +struct hpuxsigstate { + int hss_flags; /* which of the following are valid */ + struct frame hss_frame; /* original exception frame */ + struct fpframe hss_fpstate; /* 68881/68882 state info */ +}; + /* - * Kludge up a uarea dump so that HP-UX debuggers can find out - * what they need. IMPORTANT NOTE: we do not EVEN attempt to - * convert the entire user struct. + * WARNING: code in locore.s assumes the layout shown here for hsf_signum + * thru hsf_handler so... don't screw with them! */ -int -hpux_dumpu(vp, cred) - struct vnode *vp; - struct ucred *cred; +struct hpuxsigframe { + int hsf_signum; /* signo for handler */ + int hsf_code; /* additional info for handler */ + struct hpuxsigcontext *hsf_scp; /* context ptr for handler */ + sig_t hsf_handler; /* handler addr for u_sigc */ + struct hpuxsigstate hsf_sigstate; /* state of the hardware */ + struct hpuxsigcontext hsf_sc; /* actual context */ +}; + +#ifdef DEBUG +int hpuxsigdebug = 0; +int hpuxsigpid = 0; +#define SDB_FOLLOW 0x01 +#define SDB_KSTACK 0x02 +#define SDB_FPSTATE 0x04 +#endif + +/* + * Send an interrupt to process. + */ +/* ARGSUSED */ +void +hpux_sendsig(catcher, sig, mask, code, type, val) + sig_t catcher; + int sig, mask; + u_long code; + int type; + union sigval val; { - int error = 0; - struct proc *p = curproc; - struct hpux_user *faku; - struct bsdfp *bp; - short *foop; + register struct proc *p = curproc; + register struct hpuxsigframe *kfp, *fp; + register struct frame *frame; + register struct sigacts *psp = p->p_sigacts; + register short ft; + int oonstack, fsize; + extern char sigcode[], esigcode[]; + + frame = (struct frame *)p->p_md.md_regs; + ft = frame->f_format; + oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; /* - * Make sure there is no mistake about this being a real - * user structure. + * Allocate and validate space for the signal handler + * context. Note that if the stack is in P0 space, the + * call to grow() is a nop, and the useracc() check + * will fail if the process has not already allocated + * the space with a `brk'. */ - faku = (struct hpux_user *)malloc((u_long)ctob(1), M_TEMP, M_WAITOK); - bzero((caddr_t)faku, ctob(1)); + fsize = sizeof(struct hpuxsigframe); + if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && + (psp->ps_sigonstack & sigmask(sig))) { + fp = (struct hpuxsigframe *)(psp->ps_sigstk.ss_sp + + psp->ps_sigstk.ss_size - fsize); + psp->ps_sigstk.ss_flags |= SS_ONSTACK; + } else + fp = (struct hpuxsigframe *)(frame->f_regs[SP] - fsize); + if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) + (void)grow(p, (unsigned)fp); + +#ifdef DEBUG + if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid) + printf("hpux_sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n", + p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft); +#endif - /* Fill in the process sizes. */ - faku->hpuxu_tsize = p->p_vmspace->vm_tsize; - faku->hpuxu_dsize = p->p_vmspace->vm_dsize; - faku->hpuxu_ssize = p->p_vmspace->vm_ssize; + if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) { +#ifdef DEBUG + if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid) + printf("hpux_sendsig(%d): useracc failed on sig %d\n", + p->p_pid, sig); +#endif + /* + * Process has trashed its stack; give it an illegal + * instruction to halt it in its tracks. + */ + SIGACTION(p, SIGILL) = SIG_DFL; + sig = sigmask(SIGILL); + p->p_sigignore &= ~sig; + p->p_sigcatch &= ~sig; + p->p_sigmask &= ~sig; + psignal(p, SIGILL); + return; + } + kfp = (struct hpuxsigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK); + + /* + * Build the argument list for the signal handler. + */ + kfp->hsf_signum = bsdtohpuxsig(sig); + kfp->hsf_code = code; + kfp->hsf_scp = &fp->hsf_sc; + kfp->hsf_handler = catcher; /* - * Fill in the exec header for CDB. - * This was saved back in exec(). As far as I can tell CDB - * only uses this information to verify that a particular - * core file goes with a particular binary. + * Save necessary hardware state. Currently this includes: + * - general registers + * - original exception frame (if not a "normal" frame) + * - FP coprocessor state */ - bcopy((caddr_t)p->p_addr->u_md.md_exec, - (caddr_t)&faku->hpuxu_exdata, sizeof (struct hpux_exec)); + kfp->hsf_sigstate.hss_flags = HSS_USERREGS; + bcopy((caddr_t)frame->f_regs, + (caddr_t)kfp->hsf_sigstate.hss_frame.f_regs, sizeof frame->f_regs); + if (ft >= FMT7) { +#ifdef DEBUG + if (ft > 15 || exframesize[ft] < 0) + panic("hpux_sendsig: bogus frame type"); +#endif + kfp->hsf_sigstate.hss_flags |= HSS_RTEFRAME; + kfp->hsf_sigstate.hss_frame.f_format = frame->f_format; + kfp->hsf_sigstate.hss_frame.f_vector = frame->f_vector; + bcopy((caddr_t)&frame->F_u, + (caddr_t)&kfp->hsf_sigstate.hss_frame.F_u, exframesize[ft]); + + /* + * Leave an indicator that we need to clean up the kernel + * stack. We do this by setting the "pad word" above the + * hardware stack frame to the amount the stack must be + * adjusted by. + * + * N.B. we increment rather than just set f_stackadj in + * case we are called from syscall when processing a + * sigreturn. In that case, f_stackadj may be non-zero. + */ + frame->f_stackadj += exframesize[ft]; + frame->f_format = frame->f_vector = 0; +#ifdef DEBUG + if (hpuxsigdebug & SDB_FOLLOW) + printf("hpux_sendsig(%d): copy out %d of frame %d\n", + p->p_pid, exframesize[ft], ft); +#endif + } + if (fputype) { + kfp->hsf_sigstate.hss_flags |= HSS_FPSTATE; + m68881_save(&kfp->hsf_sigstate.hss_fpstate); + } + +#ifdef DEBUG + if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate) + printf("hpux_sendsig(%d): copy out FP state (%x) to %x\n", + p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate, + &kfp->sf_state.ss_fpstate); +#endif /* - * Adjust user's saved registers (on kernel stack) to reflect - * HP-UX order. Note that HP-UX saves the SR as 2 bytes not 4 - * so we have to move it up. + * Build the signal context to be used by hpux_sigreturn. */ - faku->hpuxu_ar0 = p->p_md.md_regs; - foop = (short *) p->p_md.md_regs; - foop[32] = foop[33]; - foop[33] = foop[34]; - foop[34] = foop[35]; + kfp->hsf_sc.hsc_syscall = 0; /* XXX */ + kfp->hsf_sc.hsc_action = 0; /* XXX */ + kfp->hsf_sc.hsc_pad1 = kfp->hsf_sc.hsc_pad2 = 0; + kfp->hsf_sc.hsc_onstack = oonstack; + kfp->hsf_sc.hsc_mask = mask; + kfp->hsf_sc.hsc_sp = frame->f_regs[SP]; + kfp->hsf_sc.hsc_ps = frame->f_sr; + kfp->hsf_sc.hsc_pc = frame->f_pc; + + /* How amazingly convenient! */ + kfp->hsf_sc._hsc_pad = 0; + kfp->hsf_sc._hsc_ap = (int)&fp->hsf_sigstate; + + (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize); + frame->f_regs[SP] = (int)fp; + +#ifdef DEBUG + if (hpuxsigdebug & SDB_FOLLOW) { + printf( + "hpux_sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n", + p->p_pid, sig, kfp->sf_scp, fp, + kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap); + } +#endif -#ifdef FPCOPROC /* - * Copy 68881 registers from our PCB format to HP-UX format + * Signal trampoline code is at base of user stack. */ - bp = (struct bsdfp *) &p->p_addr->u_pcb.pcb_fpregs; - bcopy((caddr_t)bp->save, (caddr_t)faku->hpuxu_fp.hpfp_save, - sizeof(bp->save)); - bcopy((caddr_t)bp->ctrl, (caddr_t)faku->hpuxu_fp.hpfp_ctrl, - sizeof(bp->ctrl)); - bcopy((caddr_t)bp->reg, (caddr_t)faku->hpuxu_fp.hpfp_reg, - sizeof(bp->reg)); + frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode); +#ifdef DEBUG + if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid) + printf("hpux_sendsig(%d): sig %d returns\n", + p->p_pid, sig); +#endif + free((caddr_t)kfp, M_TEMP); +} + +/* + * System call to cleanup state after a signal + * has been taken. Reset signal mask and + * stack state from context left by sendsig (above). + * Return to previous pc and psl as specified by + * context left by sendsig. Check carefully to + * make sure that the user has not modified the + * psl to gain improper priviledges or to cause + * a machine fault. + */ +/* ARGSUSED */ +int +hpux_sys_sigreturn(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct hpux_sys_sigreturn_args /* { + syscallarg(struct hpuxsigcontext *) sigcntxp; + } */ *uap = v; + register struct hpuxsigcontext *scp; + register struct frame *frame; + register int rf; + struct hpuxsigcontext tsigc; + struct hpuxsigstate tstate; + int flags; + + scp = SCARG(uap, sigcntxp); +#ifdef DEBUG + if (hpuxsigdebug & SDB_FOLLOW) + printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); #endif + if ((int)scp & 1) + return (EINVAL); /* - * Slay the dragon + * Fetch and test the HP-UX context structure. + * We grab it all at once for speed. */ - faku->hpuxu_dragon = -1; + if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || + copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) + return (EINVAL); + scp = &tsigc; + if ((scp->hsc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) + return (EINVAL); /* - * Dump this artfully constructed page in place of the - * user struct page. + * Restore the user supplied information */ - error = vn_rdwr(UIO_WRITE, vp, (caddr_t)faku, ctob(1), (off_t)0, - UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p); + if (scp->hsc_onstack & 01) + p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; + else + p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; + p->p_sigmask = scp->hsc_mask &~ sigcantmask; + frame = (struct frame *) p->p_md.md_regs; + frame->f_regs[SP] = scp->hsc_sp; + frame->f_pc = scp->hsc_pc; + frame->f_sr = scp->hsc_ps; /* - * Dump the remaining UPAGES-1 pages normally - * XXX Spot the wild guess. + * Grab a pointer to the hpuxsigstate. + * If zero, the user is probably doing a longjmp. + * (This will never happen, really, since HP-UX doesn't + * know/care about the state pointer.) */ - if (error == 0) - error = vn_rdwr(UIO_WRITE, vp, (caddr_t)p->p_addr + ctob(1), - ctob(UPAGES-1), (off_t)ctob(1), UIO_SYSSPACE, - IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p); + if ((rf = scp->_hsc_ap) == 0) + return (EJUSTRETURN); + + /* + * See if there is anything to do before we go to the + * expense of copying in close to 1/2K of data + */ + flags = fuword((caddr_t)rf); +#ifdef DEBUG + if (hpuxsigdebug & SDB_FOLLOW) + printf("sigreturn(%d): sc_ap %x flags %x\n", + p->p_pid, rf, flags); +#endif + /* + * fuword failed (bogus _hsc_ap value). + */ + if (flags == -1) + return (EINVAL); + if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate)) + return (EJUSTRETURN); +#ifdef DEBUG + if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid) + printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n", + p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp), + (flags & HSS_RTEFRAME) ? tstate.ss_frame.f_format : -1); +#endif + /* + * Restore most of the users registers except for A6 and SP + * which were handled above. + */ + if (flags & HSS_USERREGS) + bcopy((caddr_t)tstate.hss_frame.f_regs, + (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW); + + /* + * Restore long stack frames. Note that we do not copy + * back the saved SR or PC, they were picked up above from + * the sigcontext structure. + */ + if (flags & HSS_RTEFRAME) { + register int sz; + + /* grab frame type and validate */ + sz = tstate.hss_frame.f_format; + if (sz > 15 || (sz = exframesize[sz]) < 0) + return (EINVAL); + frame->f_stackadj -= sz; + frame->f_format = tstate.hss_frame.f_format; + frame->f_vector = tstate.hss_frame.f_vector; + bcopy((caddr_t)&tstate.hss_frame.F_u, + (caddr_t)&frame->F_u, sz); +#ifdef DEBUG + if (hpuxsigdebug & SDB_FOLLOW) + printf("sigreturn(%d): copy in %d of frame type %d\n", + p->p_pid, sz, tstate.ss_frame.f_format); +#endif + } - free((caddr_t)faku, M_TEMP); + /* + * Finally we restore the original FP context + */ + if (flags & HSS_FPSTATE) + m68881_restore(&tstate.hss_fpstate); + +#ifdef DEBUG + if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate) + printf("sigreturn(%d): copied in FP state (%x) at %x\n", + p->p_pid, *(u_int *)&tstate.ss_fpstate, + &tstate.ss_fpstate); + + if ((hpuxsigdebug & SDB_FOLLOW) || + ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)) + printf("sigreturn(%d): returns\n", p->p_pid); +#endif + return (EJUSTRETURN); +} - return (error); +/* + * Set registers on exec. + * XXX Should clear registers except sp, pc. + */ +void +hpux_setregs(p, pack, stack, retval) + register struct proc *p; + struct exec_package *pack; + u_long stack; + register_t *retval; +{ + struct frame *frame = (struct frame *)p->p_md.md_regs; + + frame->f_pc = pack->ep_entry & ~1; + frame->f_regs[SP] = stack; + frame->f_regs[A2] = (int)PS_STRINGS; + + /* restore a null state frame */ + p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; + if (fputype) + m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); + + p->p_md.md_flags &= ~MDP_HPUXMMAP; + frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */ + retval[0] = 0; /* no float card */ + if (fputype) + retval[1] = 1; /* yes 68881 */ + else + retval[1] = 0; /* no 68881 */ } diff --git a/sys/arch/hp300/hp300/locore.s b/sys/arch/hp300/hp300/locore.s index befe5387c3c..f491e6f8316 100644 --- a/sys/arch/hp300/hp300/locore.s +++ b/sys/arch/hp300/hp300/locore.s @@ -1,5 +1,5 @@ -/* $OpenBSD: locore.s,v 1.12 1997/02/23 21:42:54 downsj Exp $ */ -/* $NetBSD: locore.s,v 1.63 1997/02/02 07:55:52 thorpej Exp $ */ +/* $OpenBSD: locore.s,v 1.13 1997/03/26 08:32:41 downsj Exp $ */ +/* $NetBSD: locore.s,v 1.67 1997/03/16 10:49:43 thorpej Exp $ */ /* * Copyright (c) 1997 Theo de Raadt @@ -74,6 +74,7 @@ */ #include "assym.h" +#include #define MMUADDR(ar) movl _MMUbase,ar #define CLKADDR(ar) movl _CLKbase,ar @@ -106,663 +107,513 @@ tmpstk: .text /* - * Do a dump. - * Called by auto-restart. - */ - .globl _dumpsys - .globl _doadump -_doadump: - jbsr _dumpsys - jbsr _doboot - /*NOTREACHED*/ - -/* - * Trap/interrupt vector routines - */ - - .globl _trap, _nofault, _longjmp -_buserr: - /* - * XXX TODO: look at the mac68k _buserr and generalize - * XXX the saving of the fault address so this routine - * XXX can be shared. - */ - tstl _nofault | device probe? - jeq Lberr | no, handle as usual - movl _nofault,sp@- | yes, - jbsr _longjmp | longjmp(nofault) -Lberr: -#if defined(M68040) -#if defined(M68020) || defined(M68030) - cmpl #MMU_68040,_mmutype | 68040? - jne _addrerr | no, skip -#endif - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save user registers - movl usp,a0 | save the user SP - movl a0,sp@(FR_SP) | in the savearea - lea sp@(FR_HW),a1 | grab base of HW berr frame - moveq #0,d0 - movw a1@(12),d0 | grab SSW - movl a1@(20),d1 | and fault VA - btst #11,d0 | check for mis-aligned access - jeq Lberr2 | no, skip - addl #3,d1 | yes, get into next page - andl #PG_FRAME,d1 | and truncate -Lberr2: - movl d1,sp@- | push fault VA - movl d0,sp@- | and padded SSW - btst #10,d0 | ATC bit set? - jeq Lisberr | no, must be a real bus error - movc dfc,d1 | yes, get MMU fault - movc d0,dfc | store faulting function code - movl sp@(4),a0 | get faulting address - .word 0xf568 | ptestr a0@ - movc d1,dfc - .long 0x4e7a0805 | movc mmusr,d0 - movw d0,sp@ | save (ONLY LOW 16 BITS!) - jra Lismerr -#endif -_addrerr: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save user registers - movl usp,a0 | save the user SP - movl a0,sp@(FR_SP) | in the savearea - lea sp@(FR_HW),a1 | grab base of HW berr frame -#if defined(M68040) -#if defined(M68020) || defined(M68030) - cmpl #MMU_68040,_mmutype | 68040? - jne Lbenot040 | no, skip -#endif - movl a1@(8),sp@- | yes, push fault address - clrl sp@- | no SSW for address fault - jra Lisaerr | go deal with it -Lbenot040: -#endif - moveq #0,d0 - movw a1@(10),d0 | grab SSW for fault processing - btst #12,d0 | RB set? - jeq LbeX0 | no, test RC - bset #14,d0 | yes, must set FB - movw d0,a1@(10) | for hardware too -LbeX0: - btst #13,d0 | RC set? - jeq LbeX1 | no, skip - bset #15,d0 | yes, must set FC - movw d0,a1@(10) | for hardware too -LbeX1: - btst #8,d0 | data fault? - jeq Lbe0 | no, check for hard cases - movl a1@(16),d1 | fault address is as given in frame - jra Lbe10 | thats it -Lbe0: - btst #4,a1@(6) | long (type B) stack frame? - jne Lbe4 | yes, go handle - movl a1@(2),d1 | no, can use save PC - btst #14,d0 | FB set? - jeq Lbe3 | no, try FC - addql #4,d1 | yes, adjust address - jra Lbe10 | done -Lbe3: - btst #15,d0 | FC set? - jeq Lbe10 | no, done - addql #2,d1 | yes, adjust address - jra Lbe10 | done -Lbe4: - movl a1@(36),d1 | long format, use stage B address - btst #15,d0 | FC set? - jeq Lbe10 | no, all done - subql #2,d1 | yes, adjust address -Lbe10: - movl d1,sp@- | push fault VA - movl d0,sp@- | and padded SSW - movw a1@(6),d0 | get frame format/vector offset - andw #0x0FFF,d0 | clear out frame format - cmpw #12,d0 | address error vector? - jeq Lisaerr | yes, go to it -#if defined(M68K_MMU_MOTOROLA) -#if defined(M68K_MMU_HP) - tstl _mmutype | HP MMU? - jeq Lbehpmmu | yes, skip -#endif - movl d1,a0 | fault address - movl sp@,d0 | function code from ssw - btst #8,d0 | data fault? - jne Lbe10a - movql #1,d0 | user program access FC - | (we dont separate data/program) - btst #5,a1@ | supervisor mode? - jeq Lbe10a | if no, done - movql #5,d0 | else supervisor program access -Lbe10a: - ptestr d0,a0@,#7 | do a table search - pmove psr,sp@ | save result - movb sp@,d1 - btst #2,d1 | invalid? (incl. limit viol and berr) - jeq Lmightnotbemerr | no -> wp check - btst #7,d1 | is it MMU table berr? - jeq Lismerr | no, must be fast - jra Lisberr1 | real bus err needs not be fast -Lmightnotbemerr: - btst #3,d1 | write protect bit set? - jeq Lisberr1 | no, must be bus error - movl sp@,d0 | ssw into low word of d0 - andw #0xc0,d0 | write protect is set on page: - cmpw #0x40,d0 | was it read cycle? - jeq Lisberr1 | yes, was not WPE, must be bus err - jra Lismerr | no, must be mem err -Lbehpmmu: -#endif -#if defined(M68K_MMU_HP) - MMUADDR(a0) - movl a0@(MMUSTAT),d0 | read status - btst #3,d0 | MMU fault? - jeq Lisberr | no, just a non-MMU bus error so skip - andl #~MMU_FAULT,a0@(MMUSTAT)| yes, clear fault bits - movw d0,sp@ | pass MMU stat in upper half of code -#endif -Lismerr: - movl #T_MMUFLT,sp@- | show that we are an MMU fault - jra Ltrapnstkadj | and deal with it -Lisaerr: - movl #T_ADDRERR,sp@- | mark address error - jra Ltrapnstkadj | and deal with it -Lisberr1: - clrw sp@ | re-clear pad word -Lisberr: - movl #T_BUSERR,sp@- | mark bus error -Ltrapnstkadj: - jbsr _trap | handle the error - lea sp@(12),sp | pop value args - movl sp@(FR_SP),a0 | restore user SP - movl a0,usp | from save area - movw sp@(FR_ADJ),d0 | need to adjust stack? - jne Lstkadj | yes, go to it - moveml sp@+,#0x7FFF | no, restore most user regs - addql #8,sp | toss SSP and stkadj - jra rei | all done -Lstkadj: - lea sp@(FR_HW),a1 | pointer to HW frame - addql #8,a1 | source pointer - movl a1,a0 | source - addw d0,a0 | + hole size = dest pointer - movl a1@-,a0@- | copy - movl a1@-,a0@- | 8 bytes - movl a0,sp@(FR_SP) | new SSP - moveml sp@+,#0x7FFF | restore user registers - movl sp@,sp | and our SP - jra rei | all done - -/* - * FP exceptions. - */ -_fpfline: /* XXXthorpej - candidate for vector patch */ -#if defined(M68040) - cmpw #0x202c,sp@(6) | format type 2? - jne _illinst | no, not an FP emulation -#ifdef FPSP - .globl fpsp_unimp - jmp fpsp_unimp | yes, go handle it -#else - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save registers - moveq #T_FPEMULI,d0 | denote as FP emulation trap - jra fault | do it -#endif -#else - jra _illinst -#endif - -_fpunsupp: /* XXXthorpej - candidate for vector patch */ -#if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? - jne _illinst | no, treat as illinst -#ifdef FPSP - .globl fpsp_unsupp - jmp fpsp_unsupp | yes, go handle it -#else - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save registers - moveq #T_FPEMULD,d0 | denote as FP emulation trap - jra fault | do it -#endif -#else - jra _illinst -#endif - -/* - * Handles all other FP coprocessor exceptions. - * Note that since some FP exceptions generate mid-instruction frames - * and may cause signal delivery, we need to test for stack adjustment - * after the trap call. - */ - .globl _fpfault -_fpfault: -#ifdef FPCOPROC - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save user registers - movl usp,a0 | and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - movl _curpcb,a0 | current pcb - lea a0@(PCB_FPCTX),a0 | address of FP savearea - fsave a0@ | save state -#if defined(M68040) || defined(M68060) - /* always null state frame on 68040, 68060 */ - cmpl #MMU_68040,_mmutype - jle Lfptnull -#endif - tstb a0@ | null state frame? - jeq Lfptnull | yes, safe - clrw d0 | no, need to tweak BIU - movb a0@(1),d0 | get frame size - bset #3,a0@(0,d0:w) | set exc_pend bit of BIU -Lfptnull: - fmovem fpsr,sp@- | push fpsr as code argument - frestore a0@ | restore state - movl #T_FPERR,sp@- | push type arg - jra Ltrapnstkadj | call trap and deal with stack cleanup -#else - jra _badtrap | treat as an unexpected trap -#endif - -/* - * Coprocessor and format errors can generate mid-instruction stack - * frames and cause signal delivery hence we need to check for potential - * stack adjustment. - */ -_coperr: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl #T_COPERR,sp@- | push trap type - jra Ltrapnstkadj | call trap and deal with stack adjustments - -_fmterr: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl #T_FMTERR,sp@- | push trap type - jra Ltrapnstkadj | call trap and deal with stack adjustments - -/* - * Other exceptions only cause four and six word stack frame and require - * no post-trap stack adjustment. - */ -_illinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_ILLINST,d0 - jra fault - -_zerodiv: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_ZERODIV,d0 - jra fault - -_chkinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_CHKINST,d0 - jra fault - -_trapvinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_TRAPVINST,d0 - jra fault - -_privinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_PRIVINST,d0 - jra fault - - .globl fault -fault: - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl d0,sp@- | push trap type - jbsr _trap | handle trap - lea sp@(12),sp | pop value args - movl sp@(FR_SP),a0 | restore - movl a0,usp | user SP - moveml sp@+,#0x7FFF | restore most user regs - addql #8,sp | pop SP and stack adjust - jra rei | all done - - .globl _straytrap -_badtrap: - moveml #0xC0C0,sp@- | save scratch regs - movw sp@(22),sp@- | push exception vector info - clrw sp@- - movl sp@(22),sp@- | and PC - jbsr _straytrap | report - addql #8,sp | pop args - moveml sp@+,#0x0303 | restore regs - jra rei | all done - - .globl _syscall -_trap0: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- | save user registers - movl usp,a0 | save the user SP - movl a0,sp@(FR_SP) | in the savearea - movl d0,sp@- | push syscall number - jbsr _syscall | handle it - addql #4,sp | pop syscall arg - tstl _astpending - jne Lrei2 - tstb _ssir - jeq Ltrap1 - movw #SPL1,sr - tstb _ssir - jne Lsir1 -Ltrap1: - movl sp@(FR_SP),a0 | grab and restore - movl a0,usp | user SP - moveml sp@+,#0x7FFF | restore most registers - addql #8,sp | pop SP and stack adjust - rte - -/* - * Routines for traps 1 and 2. The meaning of the two traps depends - * on whether we are an HPUX compatible process or a native 4.3 process. - * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2 - * as a breakpoint trap. HPUX uses trap 1 for a breakpoint, so we have - * to make adjustments so that trap 2 is used for sigreturn. - */ -_trap1: - btst #MDP_TRCB,mdpflag | being traced by an HPUX process? - jeq sigreturn | no, trap1 is sigreturn - jra _trace | yes, trap1 is breakpoint - -_trap2: - btst #MDP_TRCB,mdpflag | being traced by an HPUX process? - jeq _trace | no, trap2 is breakpoint - jra sigreturn | yes, trap2 is sigreturn - -/* - * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) - * cachectl(command, addr, length) - * command in d0, addr in a1, length in d1 - */ - .globl _cachectl -_trap12: - movl d1,sp@- | push length - movl a1,sp@- | push addr - movl d0,sp@- | push command - jbsr _cachectl | do it - lea sp@(12),sp | pop args - jra rei | all done - -/* - * Trace (single-step) trap. Kernel-mode is special. - * User mode traps are simply passed on to trap(). + * Macro to relocate a symbol, used before MMU is enabled. */ -_trace: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- - moveq #T_TRACE,d0 - movw sp@(FR_HW),d1 | get PSW - andw #PSL_S,d1 | from system mode? - jne kbrkpt | yes, kernel breakpoint - jra fault | no, user-mode fault +#define RELOC(var, ar) \ + lea var,ar; \ + addl a5,ar /* - * Trap 15 is used for: - * - GDB breakpoints (in user programs) - * - KGDB breakpoints (in the kernel) - * - trace traps for SUN binaries (not fully supported yet) - * User mode traps are simply passed to trap(). + * Initialization + * + * A4 contains the address of the end of the symtab + * A5 contains physical load point from boot + * VBR contains zero from ROM. Exceptions will continue to vector + * through ROM until MMU is turned on at which time they will vector + * through our table (vectors.s). */ -_trap15: - clrl sp@- | stack adjust count - moveml #0xFFFF,sp@- - moveq #T_TRAP15,d0 - movw sp@(FR_HW),d1 | get PSW - andw #PSL_S,d1 | from system mode? - jne kbrkpt | yes, kernel breakpoint - jra fault | no, user-mode fault + .comm _lowram,4 + .comm _esym,4 -kbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type) - | Save the system sp rather than the user sp. - movw #PSL_HIGHIPL,sr | lock out interrupts - lea sp@(FR_SIZE),a6 | Save stack pointer - movl a6,sp@(FR_SP) | from before trap + .text + .globl _edata + .globl _etext,_end + .globl start +start: + movw #PSL_HIGHIPL,sr | no interrupts + RELOC(tmpstk, a0) + movl a0,sp | give ourselves a temporary stack + RELOC(_esym, a0) +#if 1 + movl a4,a0@ | store end of symbol table +#else + clrl a0@ | no symbol table, yet +#endif + RELOC(_lowram, a0) + movl a5,a0@ | store start of physical memory + movl #CACHE_OFF,d0 + movc d0,cacr | clear and disable on-chip cache(s) - | If were are not on tmpstk switch to it. - | (so debugger can change the stack pointer) - movl a6,d1 - cmpl #tmpstk,d1 - jls Lbrkpt2 | already on tmpstk - | Copy frame to the temporary stack - movl sp,a0 | a0=src - lea tmpstk-96,a1 | a1=dst - movl a1,sp | sp=new frame - moveq #FR_SIZE,d1 -Lbrkpt1: - movl a0@+,a1@+ - subql #4,d1 - bgt Lbrkpt1 +/* check for internal HP-IB in SYSFLAG */ + btst #5,0xfffffed2 | internal HP-IB? + jeq Lhaveihpib | yes, have HP-IB just continue + RELOC(_internalhpib, a0) + movl #0,a0@ | no, clear associated address +Lhaveihpib: -Lbrkpt2: - | Call the trap handler for the kernel debugger. - | Do not call trap() to do it, so that we can - | set breakpoints in trap() if we want. We know - | the trap type is either T_TRACE or T_BREAKPOINT. - | If we have both DDB and KGDB, let KGDB see it first, - | because KGDB will just return 0 if not connected. - | Save args in d2, a2 - movl d0,d2 | trap type - movl sp,a2 | frame ptr -#ifdef KGDB - | Let KGDB handle it (if connected) - movl a2,sp@- | push frame ptr - movl d2,sp@- | push trap type - jbsr _kgdb_trap | handle the trap - addql #8,sp | pop args - cmpl #0,d0 | did kgdb handle it? - jne Lbrkpt3 | yes, done -#endif -#ifdef DDB - | Let DDB handle it - movl a2,sp@- | push frame ptr - movl d2,sp@- | push trap type - jbsr _kdb_trap | handle the trap - addql #8,sp | pop args -#if 0 /* not needed on hp300 */ - cmpl #0,d0 | did ddb handle it? - jne Lbrkpt3 | yes, done -#endif -#endif - /* Sun 3 drops into PROM here. */ -Lbrkpt3: - | The stack pointer may have been modified, or - | data below it modified (by kgdb push call), - | so push the hardware frame at the current sp - | before restoring registers and returning. + RELOC(_boothowto, a0) | save reboot flags + movl d7,a0@ + RELOC(_bootdev, a0) | and boot device + movl d6,a0@ - movl sp@(FR_SP),a0 | modified sp - lea sp@(FR_SIZE),a1 | end of our frame - movl a1@-,a0@- | copy 2 longs with - movl a1@-,a0@- | ... predecrement - movl a0,sp@(FR_SP) | sp = h/w frame - moveml sp@+,#0x7FFF | restore all but sp - movl sp@,sp | ... and sp - rte | all done + /* + * All data registers are now free. All address registers + * except a5 are free. a5 is used by the RELOC() macro, + * and cannot be used until after the MMU is enabled. + */ -/* Use common m68k sigreturn */ -#include +/* determine our CPU/MMU combo - check for all regardless of kernel config */ + movl #INTIOBASE+MMUBASE,a1 + movl #0x200,d0 | data freeze bit + movc d0,cacr | only exists on 68030 + movc cacr,d0 | read it back + tstl d0 | zero? + jeq Lnot68030 | yes, we have 68020/68040 + RELOC(_mmutype, a0) | no, we have 68030 + movl #MMU_68030,a0@ | set to reflect 68030 PMMU + RELOC(_cputype, a0) + movl #CPU_68030,a0@ | and 68030 CPU + RELOC(_machineid, a0) + movl #0x80,a1@(MMUCMD) | set magic cookie + movl a1@(MMUCMD),d0 | read it back + btst #7,d0 | cookie still on? + jeq Lnot370 | no, 360 or 375 + movl #0,a1@(MMUCMD) | clear magic cookie + movl a1@(MMUCMD),d0 | read it back + btst #7,d0 | still on? + jeq Lisa370 | no, must be a 370 + movl #HP_340,a0@ | yes, must be a 340 + jra Lstart1 +Lnot370: + movl #HP_360,a0@ | type is at least a 360 + movl #0,a1@(MMUCMD) | clear magic cookie2 + movl a1@(MMUCMD),d0 | read it back + btst #16,d0 | still on? + jeq Lstart1 | no, must be a 360 + movl #HP_375,a0@ | yes, must be a 345/375 + jra Lhaspac +Lisa370: + movl #HP_370,a0@ | set to 370 +Lhaspac: + RELOC(_ectype, a0) + movl #EC_PHYS,a0@ | also has a physical address cache + jra Lstart1 +Lnot68030: + bset #31,d0 | data cache enable bit + movc d0,cacr | only exists on 68040 + movc cacr,d0 | read it back + tstl d0 | zero? + beq Lis68020 | yes, we have 68020 + moveq #0,d0 | now turn it back off + movec d0,cacr | before we access any data + RELOC(_mmutype, a0) + movl #MMU_68040,a0@ | with a 68040 MMU + RELOC(_cputype, a0) + movl #CPU_68040,a0@ | and a 68040 CPU + RELOC(_fputype, a0) + movl #FPU_68040,a0@ | ...and FPU + RELOC(_ectype, a0) + movl #EC_NONE,a0@ | and no cache (for now XXX) + RELOC(_machineid, a0) + movl a1@(MMUCMD),d0 | read MMU register + lsrl #8,d0 | get apparent ID + cmpb #6,d0 | id == 6? + jeq Lis33mhz | yes, we have a 433s + movl #HP_380,a0@ | no, we have a 380/425t + jra Lstart1 +Lis33mhz: + movl #HP_433,a0@ | 433s (XXX 425s returns same ID, ugh!) + jra Lstart1 +Lis68020: + movl #1,a1@(MMUCMD) | a 68020, write HP MMU location + movl a1@(MMUCMD),d0 | read it back + btst #0,d0 | non-zero? + jne Lishpmmu | yes, we have HP MMU + RELOC(_mmutype, a0) + movl #MMU_68851,a0@ | no, we have PMMU + RELOC(_machineid, a0) + movl #HP_330,a0@ | and 330 CPU + jra Lstart1 +Lishpmmu: + RELOC(_ectype, a0) | 320 or 350 + movl #EC_VIRT,a0@ | both have a virtual address cache + movl #0x80,a1@(MMUCMD) | set magic cookie + movl a1@(MMUCMD),d0 | read it back + btst #7,d0 | cookie still on? + jeq Lis320 | no, just a 320 + RELOC(_machineid, a0) + movl #HP_350,a0@ | yes, a 350 + jra Lstart1 +Lis320: + RELOC(_machineid, a0) + movl #HP_320,a0@ + +Lstart1: + movl #0,a1@(MMUCMD) | clear out MMU again +/* initialize source/destination control registers for movs */ + moveq #FC_USERD,d0 | user space + movc d0,sfc | as source + movc d0,dfc | and destination of transfers +/* initialize memory sizes (for pmap_bootstrap) */ + movl #MAXADDR,d1 | last page + moveq #PGSHIFT,d2 + lsrl d2,d1 | convert to page (click) number + RELOC(_maxmem, a0) + movl d1,a0@ | save as maxmem + movl a5,d0 | lowram value from ROM via boot + lsrl d2,d0 | convert to page number + subl d0,d1 | compute amount of RAM present + RELOC(_physmem, a0) + movl d1,a0@ | and physmem +/* configure kernel and proc0 VA space so we can get going */ + .globl _Sysseg, _pmap_bootstrap, _avail_start +#ifdef DDB + RELOC(_esym,a0) | end of static kernel test/data/syms + movl a0@,d5 + jne Lstart2 +#endif + movl #_end,d5 | end of static kernel text/data +Lstart2: + addl #NBPG-1,d5 + andl #PG_FRAME,d5 | round to a page + movl d5,a4 + addl a5,a4 | convert to PA + pea a5@ | firstpa + pea a4@ | nextpa + RELOC(_pmap_bootstrap,a0) + jbsr a0@ | pmap_bootstrap(firstpa, nextpa) + addql #8,sp /* - * Interrupt handlers. - * All device interrupts are auto-vectored. The CPU provides - * the vector 0x18+level. Note we count spurious interrupts, but - * we don't do anything else with them. + * Prepare to enable MMU. + * Since the kernel is not mapped logical == physical we must insure + * that when the MMU is turned on, all prefetched addresses (including + * the PC) are valid. In order guarentee that, we use the last physical + * page (which is conveniently mapped == VA) and load it up with enough + * code to defeat the prefetch, then we execute the jump back to here. + * + * Is this all really necessary, or am I paranoid?? */ + RELOC(_Sysseg, a0) | system segment table addr + movl a0@,d1 | read value (a KVA) + addl a5,d1 | convert to PA + RELOC(_mmutype, a0) + tstl a0@ | HP MMU? + jeq Lhpmmu2 | yes, skip + cmpl #MMU_68040,a0@ | 68040? + jne Lmotommu1 | no, skip + .long 0x4e7b1807 | movc d1,srp + jra Lstploaddone +Lmotommu1: + RELOC(_protorp, a0) + movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs + movl d1,a0@(4) | + segtable address + pmove a0@,srp | load the supervisor root pointer + movl #0x80000002,a0@ | reinit upper half for CRP loads + jra Lstploaddone | done +Lhpmmu2: + moveq #PGSHIFT,d2 + lsrl d2,d1 | convert to page frame + movl d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register +Lstploaddone: + lea MAXADDR,a2 | PA of last RAM page + RELOC(Lhighcode, a1) | addr of high code + RELOC(Lehighcode, a3) | end addr +Lcodecopy: + movw a1@+,a2@+ | copy a word + cmpl a3,a1 | done yet? + jcs Lcodecopy | no, keep going + jmp MAXADDR | go for it! -#define INTERRUPT_SAVEREG moveml #0xC0C0,sp@- -#define INTERRUPT_RESTOREREG moveml sp@+,#0x0303 + /* + * BEGIN MMU TRAMPOLINE. This section of code is not + * executed in-place. It's copied to the last page + * of RAM (mapped va == pa) and executed there. + */ - /* Externs. */ - .globl _hilint, _isrdispatch, _nmihand - .globl _hardclock, _statintr +Lhighcode: + /* + * Set up the vector table, and race to get the MMU + * enabled. + */ + movl #_vectab,d0 | set Vector Base Register + movc d0,vbr -_spurintr: /* Level 0 */ - addql #1,_intrcnt+0 - addql #1,_cnt+V_INTR - jra rei + RELOC(_mmutype, a0) + tstl a0@ | HP MMU? + jeq Lhpmmu3 | yes, skip + cmpl #MMU_68040,a0@ | 68040? + jne Lmotommu2 | no, skip + movw #0,INTIOBASE+MMUBASE+MMUCMD+2 + movw #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2 + | enable FPU and caches + moveq #0,d0 | ensure TT regs are disabled + .long 0x4e7b0004 | movc d0,itt0 + .long 0x4e7b0005 | movc d0,itt1 + .long 0x4e7b0006 | movc d0,dtt0 + .long 0x4e7b0007 | movc d0,dtt1 + .word 0xf4d8 | cinva bc + .word 0xf518 | pflusha + movl #0x8000,d0 + .long 0x4e7b0003 | movc d0,tc + movl #0x80008000,d0 + movc d0,cacr | turn on both caches + jmp Lenab1 +Lmotommu2: + movl #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD + | enable 68881 and i-cache + RELOC(_prototc, a2) + movl #0x82c0aa00,a2@ | value to load TC with + pmove a2@,tc | load it + jmp Lenab1 +Lhpmmu3: + movl #0,INTIOBASE+MMUBASE+MMUCMD | clear external cache + movl #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU + jmp Lenab1 | jmp to mapped code +Lehighcode: -_lev1intr: /* Level 1: HIL XXX this needs to go away */ - INTERRUPT_SAVEREG - jbsr _hilint - INTERRUPT_RESTOREREG - addql #1,_intrcnt+4 - addql #1,_cnt+V_INTR - jra rei + /* + * END MMU TRAMPOLINE. Address register a5 is now free. + */ -_intrhand: /* Levels 2 through 5 */ - INTERRUPT_SAVEREG - movw sp@(22),sp@- | push exception vector info - clrw sp@- - jbsr _isrdispatch | call dispatch routine - addql #4,sp - INTERRUPT_RESTOREREG - jra rei | all done +/* + * Should be running mapped from this point on + */ +Lenab1: +/* select the software page size now */ + lea tmpstk,sp | temporary stack + jbsr _vm_set_page_size | select software page size +/* set kernel stack, user SP, and initial pcb */ + movl _proc0paddr,a1 | get proc0 pcb addr + lea a1@(USPACE-4),sp | set kernel stack to end of area + lea _proc0,a2 | initialize proc0.p_addr so that + movl a1,a2@(P_ADDR) | we don't deref NULL in trap() + movl #USRSTACK-4,a2 + movl a2,usp | init user SP + movl a1,_curpcb | proc0 is running -_lev6intr: /* Level 6: clock */ - INTERRUPT_SAVEREG - CLKADDR(a0) - movb a0@(CLKSR),d0 | read clock status -Lclkagain: - btst #0,d0 | clear timer1 int immediately to - jeq Lnotim1 | minimize chance of losing another - movpw a0@(CLKMSB1),d1 | due to statintr processing delay -Lnotim1: - btst #2,d0 | timer3 interrupt? - jeq Lnotim3 | no, skip statclock - movpw a0@(CLKMSB3),d1 | clear timer3 interrupt - addql #1,_intrcnt+28 | count clock interrupts - lea sp@(16),a1 | a1 = &clockframe - movl d0,sp@- | save status - movl a1,sp@- - jbsr _statintr | statintr(&frame) - addql #4,sp - movl sp@+,d0 | restore pre-statintr status - CLKADDR(a0) -Lnotim3: - btst #0,d0 | timer1 interrupt? - jeq Lrecheck | no, skip hardclock - addql #1,_intrcnt+24 | count hardclock interrupts - lea sp@(16),a1 | a1 = &clockframe + tstl _fputype | Have an FPU? + jeq Lenab2 | No, skip. + clrl a1@(PCB_FPCTX) | ensure null FP context movl a1,sp@- -#ifdef USELEDS - .globl _ledaddr, _inledcontrol, _ledcontrol, _hz - tstl _ledaddr | using LEDs? - jeq Lnoled0 | no, skip this code - movl heartbeat,d0 | get tick count - addql #1,d0 | increment - movl _hz,d1 - addl #50,d1 | get the timing a little closer - cmpl #0,beatstatus | time to slow down? - jeq SlowThrob - lsrl #3,d1 | fast throb -SlowThrob: - lsrl #1,d1 | slow throb - cmpl d0,d1 | are we there yet? - jne Lnoled1 | no, nothing to do - tstl _inledcontrol | already updating LEDs? - jne Lnoled2 | yes, skip it - addl #1,beatstatus | incr beat status - cmpl #3,beatstatus | time to reset? - ble SkipReset - movl #0,beatstatus | reset the status indicator -SkipReset: - movl #LED_PULSE,sp@- - movl #LED_DISK+LED_LANRCV+LED_LANXMT,sp@- - clrl sp@- - jbsr _ledcontrol | toggle pulse, turn all others off - lea sp@(12),sp -Lnoled2: - movql #0,d0 -Lnoled1: - movl d0,heartbeat -Lnoled0: -#endif - jbsr _hardclock | hardclock(&frame) + jbsr _m68881_restore | restore it (does not kill a1) addql #4,sp - CLKADDR(a0) -Lrecheck: - addql #1,_cnt+V_INTR | chalk up another interrupt - movb a0@(CLKSR),d0 | see if anything happened - jmi Lclkagain | while we were in hardclock/statintr - INTERRUPT_RESTOREREG - jra rei | all done +Lenab2: +/* flush TLB and turn on caches */ + jbsr _TBIA | invalidate TLB + cmpl #MMU_68040,_mmutype | 68040? + jeq Lnocache0 | yes, cache already on + movl #CACHE_ON,d0 + movc d0,cacr | clear cache(s) + tstl _ectype + jeq Lnocache0 + MMUADDR(a0) + orl #MMU_CEN,a0@(MMUCMD) | turn on external cache +Lnocache0: +/* Final setup for call to main(). */ + jbsr _isrinit | initialize interrupt handlers + jbsr _hp300_calibrate_delay | calibrate delay() loop -_lev7intr: /* Level 7: Parity errors, reset key */ - addql #1,_intrcnt+32 - clrl sp@- - moveml #0xFFFF,sp@- | save registers - movl usp,a0 | and save - movl a0,sp@(FR_SP) | the user stack pointer - jbsr _nmihand | call handler - movl sp@(FR_SP),a0 | restore +/* + * Create a fake exception frame so that cpu_fork() can copy it. + * main() nevers returns; we exit to user mode from a forked process + * later on. + */ + clrw sp@- | vector offset/frame type + clrl sp@- | PC - filled in by "execve" + movw #PSL_USER,sp@- | in user mode + clrl sp@- | stack adjust count and padding + lea sp@(-64),sp | construct space for D0-D7/A0-A7 + lea _proc0,a0 | save pointer to frame + movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs + + jra _main | main() + + pea Lmainreturned | Yow! Main returned! + jbsr _panic + /* NOTREACHED */ +Lmainreturned: + .asciz "main() returned" + .even + + .globl _proc_trampoline +_proc_trampoline: + movl a3,sp@- + jbsr a2@ + addql #4,sp + movl sp@(FR_SP),a0 | grab and load movl a0,usp | user SP - moveml sp@+,#0x7FFF | and remaining registers - addql #8,sp | pop SP and stack adjust - jra rei | all done + moveml sp@+,#0x7FFF | restore most user regs + addql #8,sp | toss SP and stack adjust + jra rei | and return + /* - * Emulation of VAX REI instruction. - * - * This code deals with checking for and servicing ASTs - * (profiling, scheduling) and software interrupts (network, softclock). - * We check for ASTs first, just like the VAX. To avoid excess overhead - * the T_ASTFLT handling code will also check for software interrupts so we - * do not have to do it here. After identifing that we need an AST we - * drop the IPL to allow device interrupts. - * - * This code is complicated by the fact that sendsig may have been called - * necessitating a stack cleanup. - */ - .comm _ssir,1 - .globl _astpending - .globl rei -rei: - tstl _astpending | AST pending? - jeq Lchksir | no, go check for SIR -Lrei1: - btst #5,sp@ | yes, are we returning to user mode? - jne Lchksir | no, go check for SIR - movw #PSL_LOWIPL,sr | lower SPL - clrl sp@- | stack adjust - moveml #0xFFFF,sp@- | save all registers - movl usp,a1 | including - movl a1,sp@(FR_SP) | the users SP -Lrei2: - clrl sp@- | VA == none - clrl sp@- | code == none - movl #T_ASTFLT,sp@- | type == async system trap - jbsr _trap | go handle it + * Trap/interrupt vector routines + */ + + .globl _trap, _nofault, _longjmp +_buserr: + /* + * XXX TODO: look at the mac68k _buserr and generalize + * XXX the saving of the fault address so this routine + * XXX can be shared. + */ + tstl _nofault | device probe? + jeq Lberr | no, handle as usual + movl _nofault,sp@- | yes, + jbsr _longjmp | longjmp(nofault) +Lberr: +#if defined(M68040) +#if defined(M68020) || defined(M68030) + cmpl #MMU_68040,_mmutype | 68040? + jne _addrerr | no, skip +#endif + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save user registers + movl usp,a0 | save the user SP + movl a0,sp@(FR_SP) | in the savearea + lea sp@(FR_HW),a1 | grab base of HW berr frame + moveq #0,d0 + movw a1@(12),d0 | grab SSW + movl a1@(20),d1 | and fault VA + btst #11,d0 | check for mis-aligned access + jeq Lberr2 | no, skip + addl #3,d1 | yes, get into next page + andl #PG_FRAME,d1 | and truncate +Lberr2: + movl d1,sp@- | push fault VA + movl d0,sp@- | and padded SSW + btst #10,d0 | ATC bit set? + jeq Lisberr | no, must be a real bus error + movc dfc,d1 | yes, get MMU fault + movc d0,dfc | store faulting function code + movl sp@(4),a0 | get faulting address + .word 0xf568 | ptestr a0@ + movc d1,dfc + .long 0x4e7a0805 | movc mmusr,d0 + movw d0,sp@ | save (ONLY LOW 16 BITS!) + jra Lismerr +#endif +_addrerr: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save user registers + movl usp,a0 | save the user SP + movl a0,sp@(FR_SP) | in the savearea + lea sp@(FR_HW),a1 | grab base of HW berr frame +#if defined(M68040) +#if defined(M68020) || defined(M68030) + cmpl #MMU_68040,_mmutype | 68040? + jne Lbenot040 | no, skip +#endif + movl a1@(8),sp@- | yes, push fault address + clrl sp@- | no SSW for address fault + jra Lisaerr | go deal with it +Lbenot040: +#endif + moveq #0,d0 + movw a1@(10),d0 | grab SSW for fault processing + btst #12,d0 | RB set? + jeq LbeX0 | no, test RC + bset #14,d0 | yes, must set FB + movw d0,a1@(10) | for hardware too +LbeX0: + btst #13,d0 | RC set? + jeq LbeX1 | no, skip + bset #15,d0 | yes, must set FC + movw d0,a1@(10) | for hardware too +LbeX1: + btst #8,d0 | data fault? + jeq Lbe0 | no, check for hard cases + movl a1@(16),d1 | fault address is as given in frame + jra Lbe10 | thats it +Lbe0: + btst #4,a1@(6) | long (type B) stack frame? + jne Lbe4 | yes, go handle + movl a1@(2),d1 | no, can use save PC + btst #14,d0 | FB set? + jeq Lbe3 | no, try FC + addql #4,d1 | yes, adjust address + jra Lbe10 | done +Lbe3: + btst #15,d0 | FC set? + jeq Lbe10 | no, done + addql #2,d1 | yes, adjust address + jra Lbe10 | done +Lbe4: + movl a1@(36),d1 | long format, use stage B address + btst #15,d0 | FC set? + jeq Lbe10 | no, all done + subql #2,d1 | yes, adjust address +Lbe10: + movl d1,sp@- | push fault VA + movl d0,sp@- | and padded SSW + movw a1@(6),d0 | get frame format/vector offset + andw #0x0FFF,d0 | clear out frame format + cmpw #12,d0 | address error vector? + jeq Lisaerr | yes, go to it +#if defined(M68K_MMU_MOTOROLA) +#if defined(M68K_MMU_HP) + tstl _mmutype | HP MMU? + jeq Lbehpmmu | yes, skip +#endif + movl d1,a0 | fault address + movl sp@,d0 | function code from ssw + btst #8,d0 | data fault? + jne Lbe10a + movql #1,d0 | user program access FC + | (we dont separate data/program) + btst #5,a1@ | supervisor mode? + jeq Lbe10a | if no, done + movql #5,d0 | else supervisor program access +Lbe10a: + ptestr d0,a0@,#7 | do a table search + pmove psr,sp@ | save result + movb sp@,d1 + btst #2,d1 | invalid? (incl. limit viol and berr) + jeq Lmightnotbemerr | no -> wp check + btst #7,d1 | is it MMU table berr? + jeq Lismerr | no, must be fast + jra Lisberr1 | real bus err needs not be fast +Lmightnotbemerr: + btst #3,d1 | write protect bit set? + jeq Lisberr1 | no, must be bus error + movl sp@,d0 | ssw into low word of d0 + andw #0xc0,d0 | write protect is set on page: + cmpw #0x40,d0 | was it read cycle? + jeq Lisberr1 | yes, was not WPE, must be bus err + jra Lismerr | no, must be mem err +Lbehpmmu: +#endif +#if defined(M68K_MMU_HP) + MMUADDR(a0) + movl a0@(MMUSTAT),d0 | read status + btst #3,d0 | MMU fault? + jeq Lisberr | no, just a non-MMU bus error so skip + andl #~MMU_FAULT,a0@(MMUSTAT)| yes, clear fault bits + movw d0,sp@ | pass MMU stat in upper half of code +#endif +Lismerr: + movl #T_MMUFLT,sp@- | show that we are an MMU fault + jra Ltrapnstkadj | and deal with it +Lisaerr: + movl #T_ADDRERR,sp@- | mark address error + jra Ltrapnstkadj | and deal with it +Lisberr1: + clrw sp@ | re-clear pad word +Lisberr: + movl #T_BUSERR,sp@- | mark bus error +Ltrapnstkadj: + jbsr _trap | handle the error lea sp@(12),sp | pop value args movl sp@(FR_SP),a0 | restore user SP movl a0,usp | from save area movw sp@(FR_ADJ),d0 | need to adjust stack? - jne Laststkadj | yes, go to it + jne Lstkadj | yes, go to it moveml sp@+,#0x7FFF | no, restore most user regs - addql #8,sp | toss SP and stack adjust - rte | and do real RTE -Laststkadj: + addql #8,sp | toss SSP and stkadj + jra rei | all done +Lstkadj: lea sp@(FR_HW),a1 | pointer to HW frame addql #8,a1 | source pointer movl a1,a0 | source @@ -772,375 +623,517 @@ Laststkadj: movl a0,sp@(FR_SP) | new SSP moveml sp@+,#0x7FFF | restore user registers movl sp@,sp | and our SP - rte | and do real RTE -Lchksir: - tstb _ssir | SIR pending? - jeq Ldorte | no, all done - movl d0,sp@- | need a scratch register - movw sp@(4),d0 | get SR - andw #PSL_IPL7,d0 | mask all but IPL - jne Lnosir | came from interrupt, no can do - movl sp@+,d0 | restore scratch register -Lgotsir: - movw #SPL1,sr | prevent others from servicing int - tstb _ssir | too late? - jeq Ldorte | yes, oh well... - clrl sp@- | stack adjust - moveml #0xFFFF,sp@- | save all registers - movl usp,a1 | including - movl a1,sp@(FR_SP) | the users SP -Lsir1: - clrl sp@- | VA == none - clrl sp@- | code == none - movl #T_SSIR,sp@- | type == software interrupt - jbsr _trap | go handle it - lea sp@(12),sp | pop value args - movl sp@(FR_SP),a0 | restore - movl a0,usp | user SP - moveml sp@+,#0x7FFF | and all remaining registers - addql #8,sp | pop SP and stack adjust - rte -Lnosir: - movl sp@+,d0 | restore scratch register -Ldorte: - rte | real return + jra rei | all done + +/* + * FP exceptions. + */ +_fpfline: /* XXXthorpej - candidate for vector patch */ +#if defined(M68040) + cmpl #FPU_68040,_fputype | 68040 FPU? + jne Lfp_unimp | no, skip FPSP + cmpw #0x202c,sp@(6) | format type 2? + jne _illinst | no, not an FP emulation +Ldofp_unimp: +#ifdef FPSP + .globl fpsp_unimp + jmp fpsp_unimp | yes, go handle it +#endif +Lfp_unimp: +#endif /* M68040 */ +#ifdef FPU_EMULATE + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save registers + moveq #T_FPEMULI,d0 | denote as FP emulation trap + jra fault | do it +#else + jra _illinst +#endif + +_fpunsupp: /* XXXthorpej - candidate for vector patch */ +#if defined(M68040) + cmpl #FPU_68040,_fputype | 68040 FPU? + jne _illinst | no, treat as illinst +#ifdef FPSP + .globl fpsp_unsupp + jmp fpsp_unsupp | yes, go handle it +#endif +Lfp_unsupp: +#endif /* M68040 */ +#ifdef FPU_EMULATE + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save registers + moveq #T_FPEMULD,d0 | denote as FP emulation trap + jra fault | do it +#else + jra _illinst +#endif /* - * Macro to relocate a symbol, used before MMU is enabled. + * Handles all other FP coprocessor exceptions. + * Note that since some FP exceptions generate mid-instruction frames + * and may cause signal delivery, we need to test for stack adjustment + * after the trap call. */ -#define RELOC(var, ar) \ - lea var,ar; \ - addl a5,ar + .globl _fpfault +_fpfault: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save user registers + movl usp,a0 | and save + movl a0,sp@(FR_SP) | the user stack pointer + clrl sp@- | no VA arg + movl _curpcb,a0 | current pcb + lea a0@(PCB_FPCTX),a0 | address of FP savearea + fsave a0@ | save state +#if defined(M68040) || defined(M68060) + /* always null state frame on 68040, 68060 */ + cmpl #CPU_68040,_cputype + jle Lfptnull +#endif + tstb a0@ | null state frame? + jeq Lfptnull | yes, safe + clrw d0 | no, need to tweak BIU + movb a0@(1),d0 | get frame size + bset #3,a0@(0,d0:w) | set exc_pend bit of BIU +Lfptnull: + fmovem fpsr,sp@- | push fpsr as code argument + frestore a0@ | restore state + movl #T_FPERR,sp@- | push type arg + jra Ltrapnstkadj | call trap and deal with stack cleanup /* - * Initialization - * - * A4 contains the address of the end of the symtab - * A5 contains physical load point from boot - * VBR contains zero from ROM. Exceptions will continue to vector - * through ROM until MMU is turned on at which time they will vector - * through our table (vectors.s). + * Coprocessor and format errors can generate mid-instruction stack + * frames and cause signal delivery hence we need to check for potential + * stack adjustment. */ - .comm _lowram,4 - .comm _esym,4 +_coperr: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- + movl usp,a0 | get and save + movl a0,sp@(FR_SP) | the user stack pointer + clrl sp@- | no VA arg + clrl sp@- | or code arg + movl #T_COPERR,sp@- | push trap type + jra Ltrapnstkadj | call trap and deal with stack adjustments - .text - .globl _edata - .globl _etext,_end - .globl start -start: - movw #PSL_HIGHIPL,sr | no interrupts - RELOC(tmpstk, a0) - movl a0,sp | give ourselves a temporary stack - RELOC(_esym, a0) -#if 1 - movl a4,a0@ | store end of symbol table -#else - clrl a0@ | no symbol table, yet -#endif - RELOC(_lowram, a0) - movl a5,a0@ | store start of physical memory - movl #CACHE_OFF,d0 - movc d0,cacr | clear and disable on-chip cache(s) +_fmterr: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- + movl usp,a0 | get and save + movl a0,sp@(FR_SP) | the user stack pointer + clrl sp@- | no VA arg + clrl sp@- | or code arg + movl #T_FMTERR,sp@- | push trap type + jra Ltrapnstkadj | call trap and deal with stack adjustments -/* check for internal HP-IB in SYSFLAG */ - btst #5,0xfffffed2 | internal HP-IB? - jeq Lhaveihpib | yes, have HP-IB just continue - RELOC(_internalhpib, a0) - movl #0,a0@ | no, clear associated address -Lhaveihpib: +/* + * Other exceptions only cause four and six word stack frame and require + * no post-trap stack adjustment. + */ +_illinst: + clrl sp@- + moveml #0xFFFF,sp@- + moveq #T_ILLINST,d0 + jra fault - RELOC(_boothowto, a0) | save reboot flags - movl d7,a0@ - RELOC(_bootdev, a0) | and boot device - movl d6,a0@ +_zerodiv: + clrl sp@- + moveml #0xFFFF,sp@- + moveq #T_ZERODIV,d0 + jra fault - /* - * All data registers are now free. All address registers - * except a5 are free. a5 is used by the RELOC() macro, - * and cannot be used until after the MMU is enabled. - */ +_chkinst: + clrl sp@- + moveml #0xFFFF,sp@- + moveq #T_CHKINST,d0 + jra fault -/* determine our CPU/MMU combo - check for all regardless of kernel config */ - movl #INTIOBASE+MMUBASE,a1 - movl #0x200,d0 | data freeze bit - movc d0,cacr | only exists on 68030 - movc cacr,d0 | read it back - tstl d0 | zero? - jeq Lnot68030 | yes, we have 68020/68040 - RELOC(_mmutype, a0) | no, we have 68030 - movl #MMU_68030,a0@ | set to reflect 68030 PMMU - RELOC(_cputype, a0) - movl #CPU_68030,a0@ | and 68030 CPU - RELOC(_machineid, a0) - movl #0x80,a1@(MMUCMD) | set magic cookie - movl a1@(MMUCMD),d0 | read it back - btst #7,d0 | cookie still on? - jeq Lnot370 | no, 360 or 375 - movl #0,a1@(MMUCMD) | clear magic cookie - movl a1@(MMUCMD),d0 | read it back - btst #7,d0 | still on? - jeq Lisa370 | no, must be a 370 - movl #HP_340,a0@ | yes, must be a 340 - jra Lstart1 -Lnot370: - movl #HP_360,a0@ | type is at least a 360 - movl #0,a1@(MMUCMD) | clear magic cookie2 - movl a1@(MMUCMD),d0 | read it back - btst #16,d0 | still on? - jeq Lstart1 | no, must be a 360 - movl #HP_375,a0@ | yes, must be a 345/375 - jra Lhaspac -Lisa370: - movl #HP_370,a0@ | set to 370 -Lhaspac: - RELOC(_ectype, a0) - movl #EC_PHYS,a0@ | also has a physical address cache - jra Lstart1 -Lnot68030: - bset #31,d0 | data cache enable bit - movc d0,cacr | only exists on 68040 - movc cacr,d0 | read it back - tstl d0 | zero? - beq Lis68020 | yes, we have 68020 - moveq #0,d0 | now turn it back off - movec d0,cacr | before we access any data - RELOC(_mmutype, a0) - movl #MMU_68040,a0@ | with a 68040 MMU - RELOC(_cputype, a0) - movl #CPU_68040,a0@ | and a 68040 CPU - RELOC(_ectype, a0) - movl #EC_NONE,a0@ | and no cache (for now XXX) - RELOC(_machineid, a0) - movl a1@(MMUCMD),d0 | read MMU register - lsrl #8,d0 | get apparent ID - cmpb #6,d0 | id == 6? - jeq Lis33mhz | yes, we have a 433s - movl #HP_380,a0@ | no, we have a 380/425t - jra Lstart1 -Lis33mhz: - movl #HP_433,a0@ | 433s (XXX 425s returns same ID, ugh!) - jra Lstart1 -Lis68020: - movl #1,a1@(MMUCMD) | a 68020, write HP MMU location - movl a1@(MMUCMD),d0 | read it back - btst #0,d0 | non-zero? - jne Lishpmmu | yes, we have HP MMU - RELOC(_mmutype, a0) - movl #MMU_68851,a0@ | no, we have PMMU - RELOC(_machineid, a0) - movl #HP_330,a0@ | and 330 CPU - jra Lstart1 -Lishpmmu: - RELOC(_ectype, a0) | 320 or 350 - movl #EC_VIRT,a0@ | both have a virtual address cache - movl #0x80,a1@(MMUCMD) | set magic cookie - movl a1@(MMUCMD),d0 | read it back - btst #7,d0 | cookie still on? - jeq Lis320 | no, just a 320 - RELOC(_machineid, a0) - movl #HP_350,a0@ | yes, a 350 - jra Lstart1 -Lis320: - RELOC(_machineid, a0) - movl #HP_320,a0@ +_trapvinst: + clrl sp@- + moveml #0xFFFF,sp@- + moveq #T_TRAPVINST,d0 + jra fault -Lstart1: - movl #0,a1@(MMUCMD) | clear out MMU again -/* initialize source/destination control registers for movs */ - moveq #FC_USERD,d0 | user space - movc d0,sfc | as source - movc d0,dfc | and destination of transfers -/* initialize memory sizes (for pmap_bootstrap) */ - movl #MAXADDR,d1 | last page - moveq #PGSHIFT,d2 - lsrl d2,d1 | convert to page (click) number - RELOC(_maxmem, a0) - movl d1,a0@ | save as maxmem - movl a5,d0 | lowram value from ROM via boot - lsrl d2,d0 | convert to page number - subl d0,d1 | compute amount of RAM present - RELOC(_physmem, a0) - movl d1,a0@ | and physmem -/* configure kernel and proc0 VA space so we can get going */ - .globl _Sysseg, _pmap_bootstrap, _avail_start -#ifdef DDB - RELOC(_esym,a0) | end of static kernel test/data/syms - movl a0@,d5 - jne Lstart2 -#endif - movl #_end,d5 | end of static kernel text/data -Lstart2: - addl #NBPG-1,d5 - andl #PG_FRAME,d5 | round to a page - movl d5,a4 - addl a5,a4 | convert to PA - pea a5@ | firstpa - pea a4@ | nextpa - RELOC(_pmap_bootstrap,a0) - jbsr a0@ | pmap_bootstrap(firstpa, nextpa) - addql #8,sp +_privinst: + clrl sp@- + moveml #0xFFFF,sp@- + moveq #T_PRIVINST,d0 + jra fault + + .globl fault +fault: + movl usp,a0 | get and save + movl a0,sp@(FR_SP) | the user stack pointer + clrl sp@- | no VA arg + clrl sp@- | or code arg + movl d0,sp@- | push trap type + jbsr _trap | handle trap + lea sp@(12),sp | pop value args + movl sp@(FR_SP),a0 | restore + movl a0,usp | user SP + moveml sp@+,#0x7FFF | restore most user regs + addql #8,sp | pop SP and stack adjust + jra rei | all done + + .globl _straytrap +_badtrap: + moveml #0xC0C0,sp@- | save scratch regs + movw sp@(22),sp@- | push exception vector info + clrw sp@- + movl sp@(22),sp@- | and PC + jbsr _straytrap | report + addql #8,sp | pop args + moveml sp@+,#0x0303 | restore regs + jra rei | all done + + .globl _syscall +_trap0: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- | save user registers + movl usp,a0 | save the user SP + movl a0,sp@(FR_SP) | in the savearea + movl d0,sp@- | push syscall number + jbsr _syscall | handle it + addql #4,sp | pop syscall arg + tstl _astpending + jne Lrei2 + tstb _ssir + jeq Ltrap1 + movw #SPL1,sr + tstb _ssir + jne Lsir1 +Ltrap1: + movl sp@(FR_SP),a0 | grab and restore + movl a0,usp | user SP + moveml sp@+,#0x7FFF | restore most registers + addql #8,sp | pop SP and stack adjust + rte /* - * Prepare to enable MMU. - * Since the kernel is not mapped logical == physical we must insure - * that when the MMU is turned on, all prefetched addresses (including - * the PC) are valid. In order guarentee that, we use the last physical - * page (which is conveniently mapped == VA) and load it up with enough - * code to defeat the prefetch, then we execute the jump back to here. - * - * Is this all really necessary, or am I paranoid?? + * Trap 1 - sigreturn */ - RELOC(_Sysseg, a0) | system segment table addr - movl a0@,d1 | read value (a KVA) - addl a5,d1 | convert to PA - RELOC(_mmutype, a0) - tstl a0@ | HP MMU? - jeq Lhpmmu2 | yes, skip - cmpl #MMU_68040,a0@ | 68040? - jne Lmotommu1 | no, skip - .long 0x4e7b1807 | movc d1,srp - jra Lstploaddone -Lmotommu1: - RELOC(_protorp, a0) - movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs - movl d1,a0@(4) | + segtable address - pmove a0@,srp | load the supervisor root pointer - movl #0x80000002,a0@ | reinit upper half for CRP loads - jra Lstploaddone | done -Lhpmmu2: - moveq #PGSHIFT,d2 - lsrl d2,d1 | convert to page frame - movl d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register -Lstploaddone: - lea MAXADDR,a2 | PA of last RAM page - RELOC(Lhighcode, a1) | addr of high code - RELOC(Lehighcode, a3) | end addr -Lcodecopy: - movw a1@+,a2@+ | copy a word - cmpl a3,a1 | done yet? - jcs Lcodecopy | no, keep going - jmp MAXADDR | go for it! - - /* - * BEGIN MMU TRAMPOLINE. This section of code is not - * executed in-place. It's copied to the last page - * of RAM (mapped va == pa) and executed there. - */ +_trap1: + jra sigreturn -Lhighcode: - /* - * Set up the vector table, and race to get the MMU - * enabled. - */ - movl #_vectab,d0 | set Vector Base Register - movc d0,vbr +/* + * Trap 2 - trace trap + */ +_trap2: + jra _trace - RELOC(_mmutype, a0) - tstl a0@ | HP MMU? - jeq Lhpmmu3 | yes, skip - cmpl #MMU_68040,a0@ | 68040? - jne Lmotommu2 | no, skip - movw #0,INTIOBASE+MMUBASE+MMUCMD+2 - movw #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2 - | enable FPU and caches - moveq #0,d0 | ensure TT regs are disabled - .long 0x4e7b0004 | movc d0,itt0 - .long 0x4e7b0005 | movc d0,itt1 - .long 0x4e7b0006 | movc d0,dtt0 - .long 0x4e7b0007 | movc d0,dtt1 - .word 0xf4d8 | cinva bc - .word 0xf518 | pflusha - movl #0x8000,d0 - .long 0x4e7b0003 | movc d0,tc - movl #0x80008000,d0 - movc d0,cacr | turn on both caches - jmp Lenab1 -Lmotommu2: - movl #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD - | enable 68881 and i-cache - RELOC(_prototc, a2) - movl #0x82c0aa00,a2@ | value to load TC with - pmove a2@,tc | load it - jmp Lenab1 -Lhpmmu3: - movl #0,INTIOBASE+MMUBASE+MMUCMD | clear external cache - movl #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU - jmp Lenab1 | jmp to mapped code -Lehighcode: +/* + * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) + * cachectl(command, addr, length) + * command in d0, addr in a1, length in d1 + */ + .globl _cachectl +_trap12: + movl d1,sp@- | push length + movl a1,sp@- | push addr + movl d0,sp@- | push command + jbsr _cachectl | do it + lea sp@(12),sp | pop args + jra rei | all done - /* - * END MMU TRAMPOLINE. Address register a5 is now free. - */ +/* + * Trace (single-step) trap. Kernel-mode is special. + * User mode traps are simply passed on to trap(). + */ +_trace: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- + moveq #T_TRACE,d0 + movw sp@(FR_HW),d1 | get PSW + andw #PSL_S,d1 | from system mode? + jne kbrkpt | yes, kernel breakpoint + jra fault | no, user-mode fault /* - * Should be running mapped from this point on + * Trap 15 is used for: + * - GDB breakpoints (in user programs) + * - KGDB breakpoints (in the kernel) + * - trace traps for SUN binaries (not fully supported yet) + * User mode traps are simply passed to trap(). */ -Lenab1: -/* select the software page size now */ - lea tmpstk,sp | temporary stack - jbsr _vm_set_page_size | select software page size -/* set kernel stack, user SP, and initial pcb */ - movl _proc0paddr,a1 | get proc0 pcb addr - lea a1@(USPACE-4),sp | set kernel stack to end of area - lea _proc0,a2 | initialize proc0.p_addr so that - movl a1,a2@(P_ADDR) | we don't deref NULL in trap() - movl #USRSTACK-4,a2 - movl a2,usp | init user SP - movl a1,_curpcb | proc0 is running -#ifdef FPCOPROC - clrl a1@(PCB_FPCTX) | ensure null FP context - movl a1,sp@- - jbsr _m68881_restore | restore it (does not kill a1) - addql #4,sp +_trap15: + clrl sp@- | stack adjust count + moveml #0xFFFF,sp@- + moveq #T_TRAP15,d0 + movw sp@(FR_HW),d1 | get PSW + andw #PSL_S,d1 | from system mode? + jne kbrkpt | yes, kernel breakpoint + jra fault | no, user-mode fault + +kbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type) + | Save the system sp rather than the user sp. + movw #PSL_HIGHIPL,sr | lock out interrupts + lea sp@(FR_SIZE),a6 | Save stack pointer + movl a6,sp@(FR_SP) | from before trap + + | If were are not on tmpstk switch to it. + | (so debugger can change the stack pointer) + movl a6,d1 + cmpl #tmpstk,d1 + jls Lbrkpt2 | already on tmpstk + | Copy frame to the temporary stack + movl sp,a0 | a0=src + lea tmpstk-96,a1 | a1=dst + movl a1,sp | sp=new frame + moveq #FR_SIZE,d1 +Lbrkpt1: + movl a0@+,a1@+ + subql #4,d1 + bgt Lbrkpt1 + +Lbrkpt2: + | Call the trap handler for the kernel debugger. + | Do not call trap() to do it, so that we can + | set breakpoints in trap() if we want. We know + | the trap type is either T_TRACE or T_BREAKPOINT. + | If we have both DDB and KGDB, let KGDB see it first, + | because KGDB will just return 0 if not connected. + | Save args in d2, a2 + movl d0,d2 | trap type + movl sp,a2 | frame ptr +#ifdef KGDB + | Let KGDB handle it (if connected) + movl a2,sp@- | push frame ptr + movl d2,sp@- | push trap type + jbsr _kgdb_trap | handle the trap + addql #8,sp | pop args + cmpl #0,d0 | did kgdb handle it? + jne Lbrkpt3 | yes, done #endif -/* flush TLB and turn on caches */ - jbsr _TBIA | invalidate TLB - cmpl #MMU_68040,_mmutype | 68040? - jeq Lnocache0 | yes, cache already on - movl #CACHE_ON,d0 - movc d0,cacr | clear cache(s) - tstl _ectype - jeq Lnocache0 - MMUADDR(a0) - orl #MMU_CEN,a0@(MMUCMD) | turn on external cache -Lnocache0: -/* Final setup for call to main(). */ - jbsr _isrinit | initialize interrupt handlers - jbsr _hp300_calibrate_delay | calibrate delay() loop +#ifdef DDB + | Let DDB handle it + movl a2,sp@- | push frame ptr + movl d2,sp@- | push trap type + jbsr _kdb_trap | handle the trap + addql #8,sp | pop args +#if 0 /* not needed on hp300 */ + cmpl #0,d0 | did ddb handle it? + jne Lbrkpt3 | yes, done +#endif +#endif + /* Sun 3 drops into PROM here. */ +Lbrkpt3: + | The stack pointer may have been modified, or + | data below it modified (by kgdb push call), + | so push the hardware frame at the current sp + | before restoring registers and returning. + + movl sp@(FR_SP),a0 | modified sp + lea sp@(FR_SIZE),a1 | end of our frame + movl a1@-,a0@- | copy 2 longs with + movl a1@-,a0@- | ... predecrement + movl a0,sp@(FR_SP) | sp = h/w frame + moveml sp@+,#0x7FFF | restore all but sp + movl sp@,sp | ... and sp + rte | all done + +/* Use common m68k sigreturn */ +#include /* - * Create a fake exception frame so that cpu_fork() can copy it. - * main() nevers returns; we exit to user mode from a forked process - * later on. + * Interrupt handlers. + * All device interrupts are auto-vectored. The CPU provides + * the vector 0x18+level. Note we count spurious interrupts, but + * we don't do anything else with them. */ - clrw sp@- | vector offset/frame type - clrl sp@- | PC - filled in by "execve" - movw #PSL_USER,sp@- | in user mode - clrl sp@- | stack adjust count and padding - lea sp@(-64),sp | construct space for D0-D7/A0-A7 - lea _proc0,a0 | save pointer to frame - movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs - jra _main | main() +#define INTERRUPT_SAVEREG moveml #0xC0C0,sp@- +#define INTERRUPT_RESTOREREG moveml sp@+,#0x0303 - pea Lmainreturned | Yow! Main returned! - jbsr _panic - /* NOTREACHED */ -Lmainreturned: - .asciz "main() returned" - .even + /* Externs. */ + .globl _hilint, _isrdispatch, _nmihand + .globl _hardclock, _statintr - .globl _proc_trampoline -_proc_trampoline: - movl a3,sp@- - jbsr a2@ +_spurintr: /* Level 0 */ + addql #1,_intrcnt+0 + addql #1,_cnt+V_INTR + jra rei + +_lev1intr: /* Level 1: HIL XXX this needs to go away */ + INTERRUPT_SAVEREG + jbsr _hilint + INTERRUPT_RESTOREREG + addql #1,_intrcnt+4 + addql #1,_cnt+V_INTR + jra rei + +_intrhand: /* Levels 2 through 5 */ + INTERRUPT_SAVEREG + movw sp@(22),sp@- | push exception vector info + clrw sp@- + jbsr _isrdispatch | call dispatch routine addql #4,sp - movl sp@(FR_SP),a0 | grab and load + INTERRUPT_RESTOREREG + jra rei | all done + +_lev6intr: /* Level 6: clock */ + INTERRUPT_SAVEREG + CLKADDR(a0) + movb a0@(CLKSR),d0 | read clock status +Lclkagain: + btst #0,d0 | clear timer1 int immediately to + jeq Lnotim1 | minimize chance of losing another + movpw a0@(CLKMSB1),d1 | due to statintr processing delay +Lnotim1: + btst #2,d0 | timer3 interrupt? + jeq Lnotim3 | no, skip statclock + movpw a0@(CLKMSB3),d1 | clear timer3 interrupt + addql #1,_intrcnt+28 | count clock interrupts + lea sp@(16),a1 | a1 = &clockframe + movl d0,sp@- | save status + movl a1,sp@- + jbsr _statintr | statintr(&frame) + addql #4,sp + movl sp@+,d0 | restore pre-statintr status + CLKADDR(a0) +Lnotim3: + btst #0,d0 | timer1 interrupt? + jeq Lrecheck | no, skip hardclock + addql #1,_intrcnt+24 | count hardclock interrupts + lea sp@(16),a1 | a1 = &clockframe + movl a1,sp@- +#ifdef USELEDS + .globl _ledaddr, _inledcontrol, _ledcontrol, _hz + tstl _ledaddr | using LEDs? + jeq Lnoled0 | no, skip this code + movl heartbeat,d0 | get tick count + addql #1,d0 | increment + movl _hz,d1 + addl #50,d1 | get the timing a little closer + cmpl #0,beatstatus | time to slow down? + jeq SlowThrob + lsrl #3,d1 | fast throb +SlowThrob: + lsrl #1,d1 | slow throb + cmpl d0,d1 | are we there yet? + jne Lnoled1 | no, nothing to do + tstl _inledcontrol | already updating LEDs? + jne Lnoled2 | yes, skip it + addl #1,beatstatus | incr beat status + cmpl #3,beatstatus | time to reset? + ble SkipReset + movl #0,beatstatus | reset the status indicator +SkipReset: + movl #LED_PULSE,sp@- + movl #LED_DISK+LED_LANRCV+LED_LANXMT,sp@- + clrl sp@- + jbsr _ledcontrol | toggle pulse, turn all others off + lea sp@(12),sp +Lnoled2: + movql #0,d0 +Lnoled1: + movl d0,heartbeat +Lnoled0: +#endif + jbsr _hardclock | hardclock(&frame) + addql #4,sp + CLKADDR(a0) +Lrecheck: + addql #1,_cnt+V_INTR | chalk up another interrupt + movb a0@(CLKSR),d0 | see if anything happened + jmi Lclkagain | while we were in hardclock/statintr + INTERRUPT_RESTOREREG + jra rei | all done + +_lev7intr: /* Level 7: Parity errors, reset key */ + addql #1,_intrcnt+32 + clrl sp@- + moveml #0xFFFF,sp@- | save registers + movl usp,a0 | and save + movl a0,sp@(FR_SP) | the user stack pointer + jbsr _nmihand | call handler + movl sp@(FR_SP),a0 | restore movl a0,usp | user SP - moveml sp@+,#0x7FFF | restore most user regs + moveml sp@+,#0x7FFF | and remaining registers + addql #8,sp | pop SP and stack adjust + jra rei | all done + +/* + * Emulation of VAX REI instruction. + * + * This code deals with checking for and servicing ASTs + * (profiling, scheduling) and software interrupts (network, softclock). + * We check for ASTs first, just like the VAX. To avoid excess overhead + * the T_ASTFLT handling code will also check for software interrupts so we + * do not have to do it here. After identifing that we need an AST we + * drop the IPL to allow device interrupts. + * + * This code is complicated by the fact that sendsig may have been called + * necessitating a stack cleanup. + */ + .comm _ssir,1 + .globl _astpending + .globl rei +rei: + tstl _astpending | AST pending? + jeq Lchksir | no, go check for SIR +Lrei1: + btst #5,sp@ | yes, are we returning to user mode? + jne Lchksir | no, go check for SIR + movw #PSL_LOWIPL,sr | lower SPL + clrl sp@- | stack adjust + moveml #0xFFFF,sp@- | save all registers + movl usp,a1 | including + movl a1,sp@(FR_SP) | the users SP +Lrei2: + clrl sp@- | VA == none + clrl sp@- | code == none + movl #T_ASTFLT,sp@- | type == async system trap + jbsr _trap | go handle it + lea sp@(12),sp | pop value args + movl sp@(FR_SP),a0 | restore user SP + movl a0,usp | from save area + movw sp@(FR_ADJ),d0 | need to adjust stack? + jne Laststkadj | yes, go to it + moveml sp@+,#0x7FFF | no, restore most user regs addql #8,sp | toss SP and stack adjust - jra rei | and return + rte | and do real RTE +Laststkadj: + lea sp@(FR_HW),a1 | pointer to HW frame + addql #8,a1 | source pointer + movl a1,a0 | source + addw d0,a0 | + hole size = dest pointer + movl a1@-,a0@- | copy + movl a1@-,a0@- | 8 bytes + movl a0,sp@(FR_SP) | new SSP + moveml sp@+,#0x7FFF | restore user registers + movl sp@,sp | and our SP + rte | and do real RTE +Lchksir: + tstb _ssir | SIR pending? + jeq Ldorte | no, all done + movl d0,sp@- | need a scratch register + movw sp@(4),d0 | get SR + andw #PSL_IPL7,d0 | mask all but IPL + jne Lnosir | came from interrupt, no can do + movl sp@+,d0 | restore scratch register +Lgotsir: + movw #SPL1,sr | prevent others from servicing int + tstb _ssir | too late? + jeq Ldorte | yes, oh well... + clrl sp@- | stack adjust + moveml #0xFFFF,sp@- | save all registers + movl usp,a1 | including + movl a1,sp@(FR_SP) | the users SP +Lsir1: + clrl sp@- | VA == none + clrl sp@- | code == none + movl #T_SSIR,sp@- | type == software interrupt + jbsr _trap | go handle it + lea sp@(12),sp | pop value args + movl sp@(FR_SP),a0 | restore + movl a0,usp | user SP + moveml sp@+,#0x7FFF | and all remaining registers + addql #8,sp | pop SP and stack adjust + rte +Lnosir: + movl sp@+,d0 | restore scratch register +Ldorte: + rte | real return /* * Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig(). @@ -1169,22 +1162,6 @@ _sigcode: .align 2 _esigcode: -/* - * ..And HPUX versions of the above. Hardcoded to use trap 2. - */ - .globl _hpux_sigcode, _hpux_esigcode - .data -_hpux_sigcode: - movl sp@(12),a0 | signal handler addr (4 bytes) - jsr a0@ | call signal handler (2 bytes) - addql #4,sp | pop signo (2 bytes) - trap #2 | special syscall entry (2 bytes) - movl d0,sp@(4) | save errno (4 bytes) - moveq #1,d0 | syscall == exit (2 bytes) - trap #0 | exit(errno) (2 bytes) - .align 2 -_hpux_esigcode: - /* * Primitives */ @@ -1192,21 +1169,9 @@ _hpux_esigcode: #include /* - * non-local gotos + * Use common m68k support routines. */ -ENTRY(setjmp) - movl sp@(4),a0 | savearea pointer - moveml #0xFCFC,a0@ | save d2-d7/a2-a7 - movl sp@,a0@(48) | and return address - moveq #0,d0 | return 0 - rts - -ENTRY(longjmp) - movl sp@(4),a0 - moveml a0@+,#0xFCFC - movl a0@,sp@ - moveq #1,d0 - rts +#include /* * The following primitives manipulate the run queues. _whichqs tells which @@ -1411,7 +1376,9 @@ Lsw2: moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers movl usp,a2 | grab USP (a2 has been saved) movl a2,a1@(PCB_USP) | and save it -#ifdef FPCOPROC + + tstl _fputype | Do we have an FPU? + jeq Lswnofpsave | No Then don't attempt save. lea a1@(PCB_FPCTX),a2 | pointer to FP save area fsave a2@ | save FP state tstb a2@ | null state frame? @@ -1419,7 +1386,6 @@ Lsw2: fmovem fp0-fp7,a2@(216) | save FP general registers fmovem fpcr/fpsr/fpi,a2@(312) | save FP control registers Lswnofpsave: -#endif #ifdef DIAGNOSTIC tstl a0@(P_WCHAN) @@ -1493,7 +1459,9 @@ Lcxswdone: moveml a1@(PCB_REGS),#0xFCFC | and registers movl a1@(PCB_USP),a0 movl a0,usp | and USP -#ifdef FPCOPROC + + tstl _fputype | If we don't have an FPU, + jeq Lnofprest | don't try to restore it. lea a1@(PCB_FPCTX),a0 | pointer to FP save area tstb a0@ | null state frame? jeq Lresfprest | yes, easy @@ -1510,7 +1478,8 @@ Lresnot040: fmovem a0@(216),fp0-fp7 | restore FP general registers Lresfprest: frestore a0@ | restore state -#endif + +Lnofprest: movw a1@(PCB_PS),sr | no, restore PS moveq #1,d0 | return 1 (for alternate returns) rts @@ -1525,7 +1494,9 @@ ENTRY(savectx) movl usp,a0 | grab USP movl a0,a1@(PCB_USP) | and save it moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers -#ifdef FPCOPROC + + tstl _fputype | Do we have FPU? + jeq Lsvnofpsave | No? Then don't save state. lea a1@(PCB_FPCTX),a0 | pointer to FP save area fsave a0@ | save FP state tstb a0@ | null state frame? @@ -1533,7 +1504,6 @@ ENTRY(savectx) fmovem fp0-fp7,a0@(216) | save FP general registers fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers Lsvnofpsave: -#endif moveq #0,d0 | return 0 rts @@ -1953,30 +1923,6 @@ ENTRY(spl0) Lspldone: rts -ENTRY(_insque) - movw sr,d0 - movw #PSL_HIGHIPL,sr | atomic - movl sp@(8),a0 | where to insert (after) - movl sp@(4),a1 | element to insert (e) - movl a0@,a1@ | e->next = after->next - movl a0,a1@(4) | e->prev = after - movl a1,a0@ | after->next = e - movl a1@,a0 - movl a1,a0@(4) | e->next->prev = e - movw d0,sr - rts - -ENTRY(_remque) - movw sr,d0 - movw #PSL_HIGHIPL,sr | atomic - movl sp@(4),a0 | element to remove (e) - movl a0@,a1 - movl a0@(4),a0 - movl a0,a1@(4) | e->next->prev = e->prev - movl a1,a0@ | e->prev->next = e->next - movw d0,sr - rts - /* * _delay(u_int N) * @@ -1995,7 +1941,6 @@ L_delay: jgt L_delay rts -#ifdef FPCOPROC /* * Save and restore 68881 state. * Pretty awful looking since our assembler does not @@ -2020,7 +1965,6 @@ ENTRY(m68881_restore) Lm68881rdone: frestore a0@ | restore state rts -#endif /* * Handle the nitty-gritty of rebooting the machine. @@ -2098,7 +2042,8 @@ Lebootcode: #undef DOREBOOT .data - .globl _machineid,_mmutype,_cputype,_ectype,_protorp,_prototc + .globl _machineid,_mmutype,_cputype,_ectype,_fputype + .globl _protorp,_prototc _machineid: .long HP_320 | default to 320 _mmutype: @@ -2107,6 +2052,8 @@ _cputype: .long CPU_68020 | default to 68020 CPU _ectype: .long EC_NONE | external cache type, default to none +_fputype: + .long FPU_68881 | default to 68881 FPU _protorp: .long 0,0 | prototype root pointer _prototc: diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c index e14997b5d6f..51dc747bbe5 100644 --- a/sys/arch/hp300/hp300/machdep.c +++ b/sys/arch/hp300/hp300/machdep.c @@ -1,36 +1,7 @@ -/* $OpenBSD: machdep.c,v 1.20 1997/02/24 01:16:09 downsj Exp $ */ -/* $NetBSD: machdep.c,v 1.80 1997/02/02 07:58:49 thorpej Exp $ */ +/* $OpenBSD: machdep.c,v 1.21 1997/03/26 08:32:43 downsj Exp $ */ +/* $NetBSD: machdep.c,v 1.83 1997/03/16 09:12:13 thorpej Exp $ */ /* - * Copyright (c) 1997 Theo de Raadt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed under OpenBSD by - * Theo de Raadt. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -465,11 +436,12 @@ setregs(p, pack, stack, retval) frame->f_pc = pack->ep_entry & ~1; frame->f_regs[SP] = stack; frame->f_regs[A2] = (int)PS_STRINGS; -#ifdef FPCOPROC + /* restore a null state frame */ p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0; - m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); -#endif + if (fputype) + m68881_restore(&p->p_addr->u_pcb.pcb_fpregs); + #ifdef COMPAT_SUNOS /* * SunOS' ld.so does self-modifying code without knowing @@ -481,24 +453,6 @@ setregs(p, pack, stack, retval) else p->p_md.md_flags &= ~MDP_UNCACHE_WX; #endif -#ifdef COMPAT_HPUX - p->p_md.md_flags &= ~MDP_HPUXMMAP; - if (p->p_emul == &emul_hpux) { - frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */ - retval[0] = 0; /* no float card */ -#ifdef FPCOPROC - retval[1] = 1; /* yes 68881 */ -#else - retval[1] = 0; /* no 68881 */ -#endif - - /* Make sure the trace bit is correct. Doesn't belong here. */ - if (p->p_flag & P_TRACED) - p->p_md.md_flags |= MDP_HPUXTRACE; - else - p->p_md.md_flags &= ~MDP_HPUXTRACE; - } -#endif } /* @@ -698,445 +652,6 @@ ledcontrol(ons, offs, togs) } #endif -#define SS_RTEFRAME 1 -#define SS_FPSTATE 2 -#define SS_USERREGS 4 - -struct sigstate { - int ss_flags; /* which of the following are valid */ - struct frame ss_frame; /* original exception frame */ - struct fpframe ss_fpstate; /* 68881/68882 state info */ -}; - -/* - * WARNING: code in locore.s assumes the layout shown for sf_signum - * thru sf_handler so... don't screw with them! - */ -struct sigframe { - int sf_signum; /* signo for handler */ - siginfo_t *sf_sip; /* pointer to siginfo_t */ - struct sigcontext *sf_scp; /* context ptr for handler */ - sig_t sf_handler; /* handler addr for u_sigc */ - struct sigstate sf_state; /* state of the hardware */ - struct sigcontext sf_sc; /* actual context */ - siginfo_t sf_si; -}; - -#ifdef COMPAT_HPUX -struct hpuxsigcontext { - int hsc_syscall; - char hsc_action; - char hsc_pad1; - char hsc_pad2; - char hsc_onstack; - int hsc_mask; - int hsc_sp; - short hsc_ps; - int hsc_pc; -/* the rest aren't part of the context but are included for our convenience */ - short hsc_pad; - u_int hsc_magic; /* XXX sigreturn: cookie */ - struct sigcontext *hsc_realsc; /* XXX sigreturn: ptr to BSD context */ -}; - -/* - * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe. - * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it. - */ -struct hpuxsigframe { - int hsf_signum; - struct sigcontext *hsf_scp; - int hsf_nothing; - struct hpuxsigcontext hsf_sc; - int hsf_regs[15]; -}; -#endif - -#ifdef DEBUG -int sigdebug = 0; -int sigpid = 0; -#define SDB_FOLLOW 0x01 -#define SDB_KSTACK 0x02 -#define SDB_FPSTATE 0x04 -#endif - -/* - * Send an interrupt to process. - */ -void -sendsig(catcher, sig, mask, code, type, val) - sig_t catcher; - int sig, mask; - u_long code; - int type; - union sigval val; -{ - register struct proc *p = curproc; - register struct sigframe *fp, *kfp; - register struct frame *frame; - register struct sigacts *psp = p->p_sigacts; - register short ft; - int oonstack, fsize; - extern char sigcode[], esigcode[]; -#ifdef COMPAT_HPUX - extern char hpux_sigcode[], hpux_esigcode[]; -#endif - - frame = (struct frame *)p->p_md.md_regs; - ft = frame->f_format; - oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; - /* - * Allocate and validate space for the signal handler - * context. Note that if the stack is in P0 space, the - * call to grow() is a nop, and the useracc() check - * will fail if the process has not already allocated - * the space with a `brk'. - */ -#ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) - fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe); - else -#endif - fsize = sizeof(struct sigframe); - if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { - fp = (struct sigframe *)(psp->ps_sigstk.ss_sp + - psp->ps_sigstk.ss_size - fsize); - psp->ps_sigstk.ss_flags |= SS_ONSTACK; - } else - fp = (struct sigframe *)(frame->f_regs[SP] - fsize); - if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) - (void)grow(p, (unsigned)fp); -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n", - p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft); -#endif - if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) { -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sendsig(%d): useracc failed on sig %d\n", - p->p_pid, sig); -#endif - /* - * Process has trashed its stack; give it an illegal - * instruction to halt it in its tracks. - */ - SIGACTION(p, SIGILL) = SIG_DFL; - sig = sigmask(SIGILL); - p->p_sigignore &= ~sig; - p->p_sigcatch &= ~sig; - p->p_sigmask &= ~sig; - psignal(p, SIGILL); - return; - } - kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK); - /* - * Build the argument list for the signal handler. - */ - kfp->sf_signum = sig; - kfp->sf_sip = NULL; - kfp->sf_scp = &fp->sf_sc; - kfp->sf_handler = catcher; - - /* - * Save necessary hardware state. Currently this includes: - * - general registers - * - original exception frame (if not a "normal" frame) - * - FP coprocessor state - */ - kfp->sf_state.ss_flags = SS_USERREGS; - bcopy((caddr_t)frame->f_regs, - (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs); - if (ft >= FMT7) { -#ifdef DEBUG - if (ft > 15 || exframesize[ft] < 0) - panic("sendsig: bogus frame type"); -#endif - kfp->sf_state.ss_flags |= SS_RTEFRAME; - kfp->sf_state.ss_frame.f_format = frame->f_format; - kfp->sf_state.ss_frame.f_vector = frame->f_vector; - bcopy((caddr_t)&frame->F_u, - (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]); - /* - * Leave an indicator that we need to clean up the kernel - * stack. We do this by setting the "pad word" above the - * hardware stack frame to the amount the stack must be - * adjusted by. - * - * N.B. we increment rather than just set f_stackadj in - * case we are called from syscall when processing a - * sigreturn. In that case, f_stackadj may be non-zero. - */ - frame->f_stackadj += exframesize[ft]; - frame->f_format = frame->f_vector = 0; -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sendsig(%d): copy out %d of frame %d\n", - p->p_pid, exframesize[ft], ft); -#endif - } -#ifdef FPCOPROC - kfp->sf_state.ss_flags |= SS_FPSTATE; - m68881_save(&kfp->sf_state.ss_fpstate); -#ifdef DEBUG - if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate) - printf("sendsig(%d): copy out FP state (%x) to %x\n", - p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate, - &kfp->sf_state.ss_fpstate); -#endif -#endif - /* - * Build the signal context to be used by sigreturn. - */ - kfp->sf_sc.sc_onstack = oonstack; - kfp->sf_sc.sc_mask = mask; - kfp->sf_sc.sc_sp = frame->f_regs[SP]; - kfp->sf_sc.sc_fp = frame->f_regs[A6]; - kfp->sf_sc.sc_ap = (int)&fp->sf_state; - kfp->sf_sc.sc_pc = frame->f_pc; - kfp->sf_sc.sc_ps = frame->f_sr; - - if (psp->ps_siginfo & sigmask(sig)) { - kfp->sf_sip = &fp->sf_si; - initsiginfo(&kfp->sf_si, sig, code, type, val); - } - -#ifdef COMPAT_HPUX - /* - * Create an HP-UX style sigcontext structure and associated goo - */ - if (p->p_emul == &emul_hpux) { - register struct hpuxsigframe *hkfp; - - hkfp = (struct hpuxsigframe *)&kfp[1]; - hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum); - hkfp->hsf_scp = (struct sigcontext *) - &((struct hpuxsigframe *)(&fp[1]))->hsf_sc; - hkfp->hsf_sc.hsc_syscall = 0; /* XXX */ - hkfp->hsf_sc.hsc_action = 0; /* XXX */ - hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0; - hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack; - hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask; - hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp; - hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps; - hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc; - hkfp->hsf_sc.hsc_pad = 0; - hkfp->hsf_sc.hsc_magic = 0xdeadbeef; - hkfp->hsf_sc.hsc_realsc = kfp->sf_scp; - bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs, - sizeof (hkfp->hsf_regs)); - - kfp->sf_signum = hkfp->hsf_signum; - kfp->sf_scp = hkfp->hsf_scp; - } -#endif - /* XXX do not copy out siginfo if not needed */ - (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize); - frame->f_regs[SP] = (int)fp; -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n", - p->p_pid, sig, kfp->sf_scp, fp, - kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap); -#endif - /* - * Signal trampoline code is at base of user stack. - */ -#ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) - frame->f_pc = (int)PS_STRINGS - (hpux_esigcode - hpux_sigcode); - else -#endif - frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode); -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sendsig(%d): sig %d returns\n", - p->p_pid, sig); -#endif - free((caddr_t)kfp, M_TEMP); -} - -/* - * System call to cleanup state after a signal - * has been taken. Reset signal mask and - * stack state from context left by sendsig (above). - * Return to previous pc and psl as specified by - * context left by sendsig. Check carefully to - * make sure that the user has not modified the - * psl to gain improper priviledges or to cause - * a machine fault. - */ -/* ARGSUSED */ -int -sys_sigreturn(p, v, retval) - struct proc *p; - void *v; - register_t *retval; -{ - struct sys_sigreturn_args /* { - syscallarg(struct sigcontext *) sigcntxp; - } */ *uap = v; - register struct sigcontext *scp; - register struct frame *frame; - register int rf; - struct sigcontext tsigc; - struct sigstate tstate; - int flags; - - scp = SCARG(uap, sigcntxp); -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp); -#endif - if ((int)scp & 1) - return (EINVAL); -#ifdef COMPAT_HPUX - /* - * Grab context as an HP-UX style context and determine if it - * was one that we contructed in sendsig. - */ - if (p->p_emul == &emul_hpux) { - struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp; - struct hpuxsigcontext htsigc; - - if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 || - copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc)) - return (EINVAL); - /* - * If not generated by sendsig or we cannot restore the - * BSD-style sigcontext, just restore what we can -- state - * will be lost, but them's the breaks. - */ - hscp = &htsigc; - if (hscp->hsc_magic != 0xdeadbeef || - (scp = hscp->hsc_realsc) == 0 || - useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || - copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) { - if (hscp->hsc_onstack & 01) - p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - p->p_sigmask = hscp->hsc_mask &~ sigcantmask; - frame = (struct frame *) p->p_md.md_regs; - frame->f_regs[SP] = hscp->hsc_sp; - frame->f_pc = hscp->hsc_pc; - frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR; - return (EJUSTRETURN); - } - /* - * Otherwise, overlay BSD context with possibly modified - * HP-UX values. - */ - tsigc.sc_onstack = hscp->hsc_onstack; - tsigc.sc_mask = hscp->hsc_mask; - tsigc.sc_sp = hscp->hsc_sp; - tsigc.sc_ps = hscp->hsc_ps; - tsigc.sc_pc = hscp->hsc_pc; - } else -#endif - /* - * Test and fetch the context structure. - * We grab it all at once for speed. - */ - if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || - copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) - return (EINVAL); - scp = &tsigc; - if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) - return (EINVAL); - /* - * Restore the user supplied information - */ - if (scp->sc_onstack & 01) - p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - p->p_sigmask = scp->sc_mask &~ sigcantmask; - frame = (struct frame *) p->p_md.md_regs; - frame->f_regs[SP] = scp->sc_sp; - frame->f_regs[A6] = scp->sc_fp; - frame->f_pc = scp->sc_pc; - frame->f_sr = scp->sc_ps; - /* - * Grab pointer to hardware state information. - * If zero, the user is probably doing a longjmp. - */ - if ((rf = scp->sc_ap) == 0) - return (EJUSTRETURN); - /* - * See if there is anything to do before we go to the - * expense of copying in close to 1/2K of data - */ - flags = fuword((caddr_t)rf); -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sigreturn(%d): sc_ap %x flags %x\n", - p->p_pid, rf, flags); -#endif - /* - * fuword failed (bogus sc_ap value). - */ - if (flags == -1) - return (EINVAL); - if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate)) - return (EJUSTRETURN); -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n", - p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp), - (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1); -#endif - /* - * Restore most of the users registers except for A6 and SP - * which were handled above. - */ - if (flags & SS_USERREGS) - bcopy((caddr_t)tstate.ss_frame.f_regs, - (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW); - /* - * Restore long stack frames. Note that we do not copy - * back the saved SR or PC, they were picked up above from - * the sigcontext structure. - */ - if (flags & SS_RTEFRAME) { - register int sz; - - /* grab frame type and validate */ - sz = tstate.ss_frame.f_format; - if (sz > 15 || (sz = exframesize[sz]) < 0) - return (EINVAL); - frame->f_stackadj -= sz; - frame->f_format = tstate.ss_frame.f_format; - frame->f_vector = tstate.ss_frame.f_vector; - bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz); -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sigreturn(%d): copy in %d of frame type %d\n", - p->p_pid, sz, tstate.ss_frame.f_format); -#endif - } -#ifdef FPCOPROC - /* - * Finally we restore the original FP context - */ - if (flags & SS_FPSTATE) - m68881_restore(&tstate.ss_fpstate); -#ifdef DEBUG - if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate) - printf("sigreturn(%d): copied in FP state (%x) at %x\n", - p->p_pid, *(u_int *)&tstate.ss_fpstate, - &tstate.ss_fpstate); -#endif -#endif -#ifdef DEBUG - if ((sigdebug & SDB_FOLLOW) || - ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) - printf("sigreturn(%d): returns\n", p->p_pid); -#endif - return (EJUSTRETURN); -} - int waittime = -1; void diff --git a/sys/arch/hp300/hp300/mem.c b/sys/arch/hp300/hp300/mem.c index 05a49d51cee..54b87225093 100644 --- a/sys/arch/hp300/hp300/mem.c +++ b/sys/arch/hp300/hp300/mem.c @@ -1,5 +1,5 @@ -/* $OpenBSD: mem.c,v 1.3 1997/02/10 11:13:31 downsj Exp $ */ -/* $NetBSD: mem.c,v 1.14 1997/02/02 07:59:41 thorpej Exp $ */ +/* $OpenBSD: mem.c,v 1.4 1997/03/26 08:32:43 downsj Exp $ */ +/* $NetBSD: mem.c,v 1.15 1997/03/15 23:30:12 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -57,6 +57,7 @@ #include extern u_int lowram; +extern char *extiobase; static caddr_t devzeropage; /*ARGSUSED*/ @@ -117,13 +118,15 @@ mmrw(dev, uio, flags) /* minor device 0 is physical memory */ case 0: v = uio->uio_offset; -#ifndef DEBUG - /* allow reads only in RAM (except for DEBUG) */ + + /* + * Only allow reads in physical RAM. + */ if (v >= 0xFFFFFFFC || v < lowram) { error = EFAULT; goto unlock; } -#endif + pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, trunc_page(v), uio->uio_rw == UIO_READ ? VM_PROT_READ : VM_PROT_WRITE, TRUE); @@ -141,6 +144,17 @@ mmrw(dev, uio, flags) if (!kernacc((caddr_t)v, c, uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) return (EFAULT); + + /* + * Don't allow reading intio or dio + * device space. This could lead to + * corruption of device registers. + */ + if (ISIIOVA(v) || + ((caddr_t)v >= extiobase && + (caddr_t)v < (extiobase + (EIOMAPSIZE * NBPG)))) + return (EFAULT); + error = uiomove((caddr_t)v, c, uio); continue; @@ -159,19 +173,11 @@ mmrw(dev, uio, flags) /* * On the first call, allocate and zero a page * of memory for use with /dev/zero. - * - * XXX on the hp300 we already know where there - * is a global zeroed page, the null segment table. */ if (devzeropage == NULL) { -#if CLBYTES == NBPG - extern caddr_t Segtabzero; - devzeropage = Segtabzero; -#else devzeropage = (caddr_t) malloc(CLBYTES, M_TEMP, M_WAITOK); bzero(devzeropage, CLBYTES); -#endif } c = min(iov->iov_len, CLBYTES); error = uiomove(devzeropage, c, uio); @@ -211,11 +217,9 @@ mmmmap(dev, off, prot) */ if (minor(dev) != 0) return (-1); + /* * Allow access only in RAM. - * - * XXX could be extended to allow access to IO space but must - * be very careful. */ if ((unsigned)off < lowram || (unsigned)off >= 0xFFFFFFFC) return (-1); diff --git a/sys/arch/hp300/hp300/pmap.c b/sys/arch/hp300/hp300/pmap.c index dbf0777361e..9bb24aba9ea 100644 --- a/sys/arch/hp300/hp300/pmap.c +++ b/sys/arch/hp300/hp300/pmap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: pmap.c,v 1.5 1997/02/24 01:16:09 downsj Exp $ */ -/* $NetBSD: pmap.c,v 1.28 1997/02/02 08:01:32 thorpej Exp $ */ +/* $OpenBSD: pmap.c,v 1.6 1997/03/26 08:32:44 downsj Exp $ */ +/* $NetBSD: pmap.c,v 1.30 1997/03/18 14:13:55 mycroft Exp $ */ /* * Copyright (c) 1991, 1993 @@ -908,8 +908,7 @@ pmap_remove(pmap, sva, eva) * 2. if it is a user mapping not for the current process, * it won't be there */ - if (pmap_aliasmask && - (pmap == pmap_kernel() || pmap != curproc->p_vmspace->vm_map.pmap)) + if (pmap_aliasmask && !active_user_pmap(pmap)) needcflush = FALSE; #ifdef DEBUG if (pmap_aliasmask && (pmapvacflush & PVF_REMOVE)) { @@ -2008,8 +2007,7 @@ pmap_remove_mapping(pmap, va, pte, flags) * flush the VAC. Note that the kernel side was flushed * above so we don't worry about non-CI kernel mappings. */ - if (pmap == curproc->p_vmspace->vm_map.pmap && - !pmap_pte_ci(pte)) { + if (active_user_pmap(pmap) && !pmap_pte_ci(pte)) { DCIU(); #ifdef PMAPSTATS remove_stats.uflushes++; @@ -2186,8 +2184,7 @@ pmap_remove_mapping(pmap, va, pte, flags) * pointer for current process so * update now to reload hardware. */ - if (curproc != NULL && - ptpmap == curproc->p_vmspace->vm_map.pmap) + if (active_user_pmap(ptpmap)) PMAP_ACTIVATE(ptpmap, &curproc->p_addr->u_pcb, 1); } @@ -2431,7 +2428,7 @@ pmap_enter_ptpage(pmap, va) * XXX may have changed segment table pointer for current * process so update now to reload hardware. */ - if (pmap == curproc->p_vmspace->vm_map.pmap) + if (active_user_pmap(pmap)) PMAP_ACTIVATE(pmap, &curproc->p_addr->u_pcb, 1); #ifdef DEBUG if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) diff --git a/sys/arch/hp300/hp300/trap.c b/sys/arch/hp300/hp300/trap.c index a2f71854793..74deb73d028 100644 --- a/sys/arch/hp300/hp300/trap.c +++ b/sys/arch/hp300/hp300/trap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: trap.c,v 1.8 1997/02/21 06:07:25 deraadt Exp $ */ -/* $NetBSD: trap.c,v 1.47 1996/10/14 20:06:31 thorpej Exp $ */ +/* $OpenBSD: trap.c,v 1.9 1997/03/26 08:32:45 downsj Exp $ */ +/* $NetBSD: trap.c,v 1.48 1997/03/15 23:34:32 thorpej Exp $ */ /* * Copyright (c) 1997 Theo de Raadt @@ -373,9 +373,7 @@ trap(type, code, v, frame) i = SIGBUS; break; -#ifdef FPCOPROC case T_COPERR: /* kernel coprocessor violation */ -#endif case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ case T_FMTERR: /* ...just in case... */ /* @@ -396,7 +394,6 @@ trap(type, code, v, frame) v = frame.f_pc; break; -#ifdef FPCOPROC case T_COPERR|T_USER: /* user coprocessor violation */ /* What is a proper response here? */ typ = FPE_FLTINV; @@ -419,7 +416,6 @@ trap(type, code, v, frame) i = SIGFPE; v = frame.f_pc; break; -#endif #ifdef M68040 case T_FPEMULI|T_USER: /* unimplemented FP instuction */ diff --git a/sys/arch/hp300/hp300/vm_machdep.c b/sys/arch/hp300/hp300/vm_machdep.c index 3c82ed9c088..e22fbf4e006 100644 --- a/sys/arch/hp300/hp300/vm_machdep.c +++ b/sys/arch/hp300/hp300/vm_machdep.c @@ -1,5 +1,5 @@ -/* $OpenBSD: vm_machdep.c,v 1.7 1997/02/10 11:13:34 downsj Exp $ */ -/* $NetBSD: vm_machdep.c,v 1.31 1997/02/02 08:03:06 thorpej Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.8 1997/03/26 08:32:45 downsj Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.34 1997/03/16 09:59:40 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -79,7 +79,7 @@ cpu_fork(p1, p2) extern struct pcb *curpcb; extern void proc_trampoline(), child_return(); - p2->p_md.md_flags = p1->p_md.md_flags & ~MDP_HPUXTRACE; + p2->p_md.md_flags = p1->p_md.md_flags; /* Sync curpcb (which is presumably p1's PCB) and copy it to p2. */ savectx(curpcb); @@ -149,18 +149,6 @@ cpu_coredump(p, vp, cred, chdr) struct coreseg cseg; int error; -#ifdef COMPAT_HPUX - extern struct emul emul_hpux; - - /* - * If we loaded from an HP-UX format binary file we dump enough - * of an HP-UX style user struct so that the HP-UX debuggers can - * grok it. - */ - if (p->p_emul == &emul_hpux) - return (hpux_dumpu(vp, cred)); -#endif - CORE_SETMAGIC(*chdr, COREMAGIC, MID_M68K, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); chdr->c_seghdrsize = ALIGN(sizeof(cseg)); @@ -171,10 +159,15 @@ cpu_coredump(p, vp, cred, chdr) if (error) return error; - /* Save floating point registers. */ - error = process_read_fpregs(p, &md_core.freg); - if (error) - return error; + if (fputype) { + /* Save floating point registers. */ + error = process_read_fpregs(p, &md_core.freg); + if (error) + return error; + } else { + /* Make sure these are clear. */ + bzero((caddr_t)&md_core.freg, sizeof(md_core.freg)); + } CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_M68K, CORE_CPU); cseg.c_addr = 0; diff --git a/sys/arch/hp300/include/hpux_machdep.h b/sys/arch/hp300/include/hpux_machdep.h index 35dc0172934..7c6f14f1e9e 100644 --- a/sys/arch/hp300/include/hpux_machdep.h +++ b/sys/arch/hp300/include/hpux_machdep.h @@ -1,8 +1,8 @@ -/* $OpenBSD: hpux_machdep.h,v 1.3 1997/01/12 15:13:36 downsj Exp $ */ -/* $NetBSD: hpux_machdep.h,v 1.3 1996/02/28 01:05:57 thorpej Exp $ */ +/* $OpenBSD: hpux_machdep.h,v 1.4 1997/03/26 08:32:46 downsj Exp $ */ +/* $NetBSD: hpux_machdep.h,v 1.6 1997/03/16 10:02:40 thorpej Exp $ */ /*- - * Copyright (c) 1996 The NetBSD Foundation, Inc. + * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -40,12 +40,41 @@ #ifndef _MACHINE_HPUX_MACHDEP_H_ #define _MACHINE_HPUX_MACHDEP_H_ +/* + * Information pushed on stack when a signal is delivered. + * This is used by the kernel to restore state following + * execution of the signal handler. It is also made available + * to the handler to allow it to restore state properly if + * a non-standard exit is performed. + */ +struct hpuxsigcontext { + int hsc_syscall; /* ??? (syscall number?) */ + char hsc_action; /* ??? */ + char hsc_pad1; + char hsc_pad2; + char hsc_onstack; /* sigstack state to restore */ + int hsc_mask; /* signal mask to restore */ + int hsc_sp; /* sp to restore */ + short hsc_ps; /* psl to restore */ + int hsc_pc; /* pc to restore */ + + /* + * The following are not actually used by HP-UX. They exist + * for the convenience of the compatibility code. + */ + short _hsc_pad; + int _hsc_ap; /* pointer to hpuxsigstate */ +}; + int hpux_cpu_makecmds __P((struct proc *, struct exec_package *)); int hpux_cpu_vmcmd __P((struct proc *, struct exec_vmcmd *)); void hpux_cpu_bsd_to_hpux_stat __P((struct stat *, struct hpux_stat *)); void hpux_cpu_uname __P((struct hpux_utsname *)); int hpux_cpu_sysconf_arch __P((void)); int hpux_to_bsd_uoff __P((int *, int *, struct proc *)); -int hpux_dumpu __P((struct vnode *, struct ucred *)); + +void hpux_sendsig __P((sig_t, int, int, u_long, int, union sigval)); +void hpux_setregs __P((struct proc *, struct exec_package *, + u_long, register_t *)); #endif /* ! _MACHINE_HPUX_MACHDEP_H_ */ diff --git a/sys/arch/hp300/include/pmap.h b/sys/arch/hp300/include/pmap.h index 3637780c2a0..a90af0d3711 100644 --- a/sys/arch/hp300/include/pmap.h +++ b/sys/arch/hp300/include/pmap.h @@ -1,5 +1,5 @@ -/* $OpenBSD: pmap.h,v 1.3 1997/01/12 15:13:39 downsj Exp $ */ -/* $NetBSD: pmap.h,v 1.10 1995/12/11 17:09:23 thorpej Exp $ */ +/* $OpenBSD: pmap.h,v 1.4 1997/03/26 08:32:46 downsj Exp $ */ +/* $NetBSD: pmap.h,v 1.12 1997/03/18 16:39:30 mycroft Exp $ */ /* * Copyright (c) 1987 Carnegie-Mellon University @@ -142,6 +142,9 @@ extern struct pmap kernel_pmap_store; #define pmap_kernel() (&kernel_pmap_store) #define active_pmap(pm) \ ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap) +#define active_user_pmap(pm) \ + (curproc && \ + (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap) extern struct pv_entry *pv_table; /* array of entries, one per page */ diff --git a/sys/arch/hp300/include/proc.h b/sys/arch/hp300/include/proc.h index 11c46e2f627..64037824f3e 100644 --- a/sys/arch/hp300/include/proc.h +++ b/sys/arch/hp300/include/proc.h @@ -1,5 +1,5 @@ -/* $OpenBSD: proc.h,v 1.3 1997/02/24 01:16:11 downsj Exp $ */ -/* $NetBSD: proc.h,v 1.6 1994/10/26 07:26:35 cgd Exp $ */ +/* $OpenBSD: proc.h,v 1.4 1997/03/26 08:32:47 downsj Exp $ */ +/* $NetBSD: proc.h,v 1.7 1997/03/16 09:41:36 thorpej Exp $ */ /* * Copyright (c) 1991, 1993 @@ -47,7 +47,6 @@ struct mdproc { /* md_flags */ #define MDP_STACKADJ 0x0002 /* frame SP adjusted; undo when syscall does ERE START */ -#define MDP_HPUXTRACE 0x0004 /* being traced by HP-UX process */ #define MDP_HPUXMMAP 0x0008 /* VA space is multiply mapped */ #define MDP_CCBDATA 0x0010 /* copyback caching of data (68040) */ #define MDP_CCBSTACK 0x0020 /* copyback caching of stack (68040) */