summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/hp300/DOC/Options8
-rw-r--r--sys/arch/hp300/conf/Makefile.hp3004
-rw-r--r--sys/arch/hp300/conf/files.hp3006
-rw-r--r--sys/arch/hp300/dev/hil.c8
-rw-r--r--sys/arch/hp300/hp300/genassym.c5
-rw-r--r--sys/arch/hp300/hp300/genassym.cf219
-rw-r--r--sys/arch/hp300/hp300/hpux_machdep.c500
-rw-r--r--sys/arch/hp300/hp300/locore.s809
-rw-r--r--sys/arch/hp300/hp300/machdep.c497
-rw-r--r--sys/arch/hp300/hp300/mem.c36
-rw-r--r--sys/arch/hp300/hp300/pmap.c15
-rw-r--r--sys/arch/hp300/hp300/trap.c8
-rw-r--r--sys/arch/hp300/hp300/vm_machdep.c31
-rw-r--r--sys/arch/hp300/include/hpux_machdep.h37
-rw-r--r--sys/arch/hp300/include/pmap.h7
-rw-r--r--sys/arch/hp300/include/proc.h5
16 files changed, 1090 insertions, 1105 deletions
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 <sys/param.h>
+include <sys/buf.h>
+include <sys/map.h>
+include <sys/proc.h>
+include <sys/mbuf.h>
+include <sys/msgbuf.h>
+include <sys/syscall.h>
+include <sys/user.h>
+
+include <vm/vm.h>
+
+include <machine/cpu.h>
+include <machine/psl.h>
+include <machine/reg.h>
+include <machine/pte.h>
+
+include <hp300/hp300/clockreg.h>
+include <hp300/hp300/led.h>
+
+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 <machine/hpux_machdep.h>
+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 <machine/trap.h>
#define MMUADDR(ar) movl _MMUbase,ar
#define CLKADDR(ar) movl _CLKbase,ar
@@ -106,15 +107,346 @@ tmpstk:
.text
/*
- * Do a dump.
- * Called by auto-restart.
+ * Macro to relocate a symbol, used before MMU is enabled.
*/
- .globl _dumpsys
- .globl _doadump
-_doadump:
- jbsr _dumpsys
- jbsr _doboot
- /*NOTREACHED*/
+#define RELOC(var, ar) \
+ lea var,ar; \
+ addl a5,ar
+
+/*
+ * 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).
+ */
+ .comm _lowram,4
+ .comm _esym,4
+
+ .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)
+
+/* 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:
+
+ RELOC(_boothowto, a0) | save reboot flags
+ movl d7,a0@
+ RELOC(_bootdev, a0) | and boot device
+ movl d6,a0@
+
+ /*
+ * 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.
+ */
+
+/* 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
+
+/*
+ * 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!
+
+ /*
+ * 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.
+ */
+
+Lhighcode:
+ /*
+ * Set up the vector table, and race to get the MMU
+ * enabled.
+ */
+ movl #_vectab,d0 | set Vector Base Register
+ movc d0,vbr
+
+ 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:
+
+ /*
+ * END MMU TRAMPOLINE. Address register a5 is now free.
+ */
+
+/*
+ * 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
+
+ tstl _fputype | Have an FPU?
+ jeq Lenab2 | No, skip.
+ clrl a1@(PCB_FPCTX) | ensure null FP context
+ movl a1,sp@-
+ jbsr _m68881_restore | restore it (does not kill a1)
+ addql #4,sp
+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
+
+/*
+ * 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 | restore most user regs
+ addql #8,sp | toss SP and stack adjust
+ jra rei | and return
+
/*
* Trap/interrupt vector routines
@@ -298,34 +630,41 @@ Lstkadj:
*/
_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
-#else
+#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
-#endif
#else
jra _illinst
#endif
_fpunsupp: /* XXXthorpej - candidate for vector patch */
#if defined(M68040)
- cmpl #MMU_68040,_mmutype | 68040?
+ cmpl #FPU_68040,_fputype | 68040 FPU?
jne _illinst | no, treat as illinst
#ifdef FPSP
.globl fpsp_unsupp
jmp fpsp_unsupp | yes, go handle it
-#else
+#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
-#endif
#else
jra _illinst
#endif
@@ -338,7 +677,6 @@ _fpunsupp: /* XXXthorpej - candidate for vector patch */
*/
.globl _fpfault
_fpfault:
-#ifdef FPCOPROC
clrl sp@- | stack adjust count
moveml #0xFFFF,sp@- | save user registers
movl usp,a0 | and save
@@ -349,7 +687,7 @@ _fpfault:
fsave a0@ | save state
#if defined(M68040) || defined(M68060)
/* always null state frame on 68040, 68060 */
- cmpl #MMU_68040,_mmutype
+ cmpl #CPU_68040,_cputype
jle Lfptnull
#endif
tstb a0@ | null state frame?
@@ -362,9 +700,6 @@ Lfptnull:
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
@@ -475,21 +810,16 @@ Ltrap1:
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.
+ * Trap 1 - sigreturn
*/
_trap1:
- btst #MDP_TRCB,mdpflag | being traced by an HPUX process?
- jeq sigreturn | no, trap1 is sigreturn
- jra _trace | yes, trap1 is breakpoint
+ jra sigreturn
+/*
+ * Trap 2 - trace trap
+ */
_trap2:
- btst #MDP_TRCB,mdpflag | being traced by an HPUX process?
- jeq _trace | no, trap2 is breakpoint
- jra sigreturn | yes, trap2 is sigreturn
+ jra _trace
/*
* Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
@@ -806,343 +1136,6 @@ Ldorte:
rte | real return
/*
- * Macro to relocate a symbol, used before MMU is enabled.
- */
-#define RELOC(var, ar) \
- lea var,ar; \
- addl a5,ar
-
-/*
- * 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).
- */
- .comm _lowram,4
- .comm _esym,4
-
- .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)
-
-/* 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:
-
- RELOC(_boothowto, a0) | save reboot flags
- movl d7,a0@
- RELOC(_bootdev, a0) | and boot device
- movl d6,a0@
-
- /*
- * 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.
- */
-
-/* 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@
-
-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
-
-/*
- * 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!
-
- /*
- * 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.
- */
-
-Lhighcode:
- /*
- * Set up the vector table, and race to get the MMU
- * enabled.
- */
- movl #_vectab,d0 | set Vector Base Register
- movc d0,vbr
-
- 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:
-
- /*
- * END MMU TRAMPOLINE. Address register a5 is now free.
- */
-
-/*
- * 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
-#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
-#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
-
-/*
- * 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 | restore most user regs
- addql #8,sp | toss SP and stack adjust
- jra rei | and return
-
-/*
* Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig().
*
* Stack looks like:
@@ -1170,43 +1163,15 @@ _sigcode:
_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
*/
#include <machine/asm.h>
/*
- * 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 <m68k/m68k/support.s>
/*
* 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 <vm/vm.h>
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) */