* the Systems Programming Group of the University of Utah Computer
* Science Department.
*
- * %sccs.include.redist.c%
+ * 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.
*
- * from: Utah $Hdr: machdep.c 1.51 89/11/28$
+ * 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.
*
- * @(#)machdep.c 7.10 (Berkeley) %G%
+ * from: Utah $Hdr: machdep.c 1.63 91/04/24$
+ *
+ * @(#)machdep.c 7.16 (Berkeley) 6/3/91
*/
-#include "sys/param.h"
-#include "sys/systm.h"
-#include "sys/user.h"
-#include "sys/kernel.h"
-#include "sys/map.h"
-#include "sys/proc.h"
-#include "sys/buf.h"
-#include "sys/reboot.h"
-#include "sys/conf.h"
-#include "sys/file.h"
-#include "sys/clist.h"
-#include "sys/callout.h"
-#include "sys/malloc.h"
-#include "sys/mbuf.h"
-#include "sys/msgbuf.h"
+#include "param.h"
+#include "systm.h"
+#include "signalvar.h"
+#include "kernel.h"
+#include "map.h"
+#include "proc.h"
+#include "buf.h"
+#include "reboot.h"
+#include "conf.h"
+#include "file.h"
+#include "clist.h"
+#include "callout.h"
+#include "malloc.h"
+#include "mbuf.h"
+#include "msgbuf.h"
+#include "user.h"
#ifdef SYSVSHM
-#include "sys/shm.h"
+#include "shm.h"
#endif
#ifdef HPUXCOMPAT
#include "../hpux/hpux.h"
#include "../include/reg.h"
#include "../include/psl.h"
#include "isr.h"
+#include "pte.h"
#include "net/netisr.h"
#define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */
#include "vm/vm_object.h"
#include "vm/vm_kern.h"
#include "vm/vm_page.h"
+
vm_map_t buffer_map;
extern vm_offset_t avail_end;
int bufpages = 0;
#endif
int msgbufmapped; /* set when safe to use msgbuf */
+int maxmem; /* max memory per process */
int physmem = MAXMEM; /* max supported memory, changes to actual */
/*
* safepri is a safe priority for sleep to set for a spin-wait
* during autoconfiguration or after a panic.
*/
-int safepri = PSL_LOWIPL;
+int safepri = PSL_LOWIPL;
extern u_int lowram;
/*
- * Machine-dependent startup code
+ * Console initialization: called early on from main,
+ * before vm init or startup. Do enough configuration
+ * to choose and initialize a console.
*/
-startup(firstaddr)
- int firstaddr;
+consinit()
{
- register unsigned i;
- register caddr_t v;
- int base, residual;
- extern long Usrptsize;
- extern struct map *useriomap;
-#ifdef DEBUG
- extern int pmapdebug;
- int opmapdebug = pmapdebug;
-#endif
- vm_offset_t minaddr, maxaddr;
- vm_size_t size;
/*
* Set cpuspeed immediately since cninit() called routines
cpuspeed = MHZ_50;
break;
}
-#ifndef DEBUG
/*
* Find what hardware is attached to this machine.
*/
find_devs();
+
/*
* Initialize the console before we print anything out.
*/
cninit();
+}
+
+/*
+ * cpu_startup: allocate memory for variable-sized tables,
+ * initialize cpu, and do autoconfiguration.
+ */
+cpu_startup()
+{
+ register unsigned i;
+ register caddr_t v, firstaddr;
+ int base, residual;
+ extern long Usrptsize;
+ extern struct map *useriomap;
+#ifdef DEBUG
+ extern int pmapdebug;
+ int opmapdebug = pmapdebug;
#endif
+ vm_offset_t minaddr, maxaddr;
+ vm_size_t size;
+
/*
* Initialize error message buffer (at end of core).
*/
(name) = (type *)v; v = (caddr_t)((name)+(num))
#define valloclim(name, type, num, lim) \
(name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
- valloclim(file, struct file, nfile, fileNFILE);
- valloclim(proc, struct proc, nproc, procNPROC);
valloc(cfree, struct cblock, nclist);
valloc(callout, struct callout, ncallout);
- valloc(swapmap, struct map, nswapmap = nproc * 2);
+ valloc(swapmap, struct map, nswapmap = maxproc * 2);
#ifdef SYSVSHM
valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
#endif
*/
if (firstaddr == 0) {
size = (vm_size_t)(v - firstaddr);
- firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
+ firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size));
if (firstaddr == 0)
panic("startup: no room for tables");
goto again;
/*
* Set up buffers, so they can be used to read disk labels.
*/
- bhinit();
- binit();
+ bufinit();
/*
* Configure the system.
configure();
}
-#ifdef PGINPROF
-/*
- * Return the difference (in microseconds)
- * between the current time and a previous
- * time as represented by the arguments.
- */
-/*ARGSUSED*/
-vmtime(otime, olbolt, oicr)
- register int otime, olbolt, oicr;
-{
-
- return (((time.tv_sec-otime)*100 + lbolt-olbolt)*10000);
-}
-#endif
-
/*
- * Clear registers on exec
+ * Set registers on exec.
+ * XXX Should clear registers except sp, pc,
+ * but would break init; should be fixed soon.
*/
-setregs(entry, retval)
+setregs(p, entry, retval)
+ register struct proc *p;
u_long entry;
int retval[2];
{
- u.u_ar0[PC] = entry & ~1;
+ p->p_regs[PC] = entry & ~1;
#ifdef FPCOPROC
/* restore a null state frame */
- u.u_pcb.pcb_fpregs.fpf_null = 0;
- m68881_restore(&u.u_pcb.pcb_fpregs);
+ p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
+ m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
#endif
#ifdef HPUXCOMPAT
- if (u.u_procp->p_flag & SHPUX) {
+ if (p->p_flag & SHPUX) {
- u.u_ar0[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
+ p->p_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
retval[0] = 0; /* no float card */
#ifdef FPCOPROC
retval[1] = 1; /* yes 68881 */
* I didn't want to muck up kern_exec.c with this code, so I
* stuck it here.
*/
- if ((u.u_procp->p_pptr->p_flag & SHPUX) &&
- (u.u_procp->p_flag & STRC)) {
+ if ((p->p_pptr->p_flag & SHPUX) &&
+ (p->p_flag & STRC)) {
tweaksigcode(1);
- u.u_pcb.pcb_flags |= PCB_HPUXTRACE;
- } else if (u.u_pcb.pcb_flags & PCB_HPUXTRACE) {
+ p->p_addr->u_pcb.pcb_flags |= PCB_HPUXTRACE;
+ } else if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXTRACE) {
tweaksigcode(0);
- u.u_pcb.pcb_flags &= ~PCB_HPUXTRACE;
+ p->p_addr->u_pcb.pcb_flags &= ~PCB_HPUXTRACE;
}
#endif
}
identifycpu()
{
+
printf("HP9000/");
switch (machineid) {
case HP_320:
tweaksigcode(ishpux)
{
static short *sigtrap = NULL;
+ extern short sigcode[], esigcode[];
/* locate trap instruction in pcb_sigc */
if (sigtrap == NULL) {
- register struct pcb *pcp = &u.u_pcb;
-
- sigtrap = &pcp->pcb_sigc[sizeof(pcp->pcb_sigc)/sizeof(short)];
- while (--sigtrap >= pcp->pcb_sigc)
+ sigtrap = esigcode;
+ while (--sigtrap >= sigcode)
if ((*sigtrap & 0xFFF0) == 0x4E40)
break;
- if (sigtrap < pcp->pcb_sigc)
+ if (sigtrap < sigcode)
panic("bogus sigcode\n");
}
*sigtrap = ishpux ? 0x4E42 : 0x4E41;
/*
* Send an interrupt to process.
*/
+void
sendsig(catcher, sig, mask, code)
sig_t catcher;
int sig, mask;
unsigned code;
{
- register struct proc *p = u.u_procp;
+ register struct proc *p = curproc;
register struct sigframe *fp, *kfp;
register struct frame *frame;
+ register struct sigacts *ps = p->p_sigacts;
register short ft;
int oonstack, fsize;
+ extern short exframesize[];
+ extern char sigcode[], esigcode[];
- frame = (struct frame *)u.u_ar0;
+ frame = (struct frame *)p->p_regs;
ft = frame->f_format;
- oonstack = u.u_onstack;
+ oonstack = ps->ps_onstack;
/*
* Allocate and validate space for the signal handler
* context. Note that if the stack is in P0 space, the
else
#endif
fsize = sizeof(struct sigframe);
- if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
- fp = (struct sigframe *)(u.u_sigsp - fsize);
- u.u_onstack = 1;
+ if (!ps->ps_onstack && (ps->ps_sigonstack & sigmask(sig))) {
+ fp = (struct sigframe *)(ps->ps_sigsp - fsize);
+ ps->ps_onstack = 1;
} else
fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
- if ((unsigned)fp <= USRSTACK - ctob(u.u_ssize))
- (void)grow((unsigned)fp);
+ 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",
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,
- (ft == FMT9) ? FMT9SIZE :
- (ft == FMTA) ? FMTASIZE : FMTBSIZE);
+ (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
/*
- * Gag! 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. "bexit" in locore
- * will then know that it must compress the kernel stack
- * and create a normal four word stack frame.
+ * 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 = -1;
+ 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,
- (ft == FMT9) ? FMT9SIZE :
- (ft == FMTA) ? FMTASIZE : FMTBSIZE, ft);
+ p->p_pid, exframesize[ft], ft);
#endif
}
#ifdef FPCOPROC
/*
* Signal trampoline code is at base of user stack.
*/
- frame->f_pc = USRSTACK - sizeof(u.u_pcb.pcb_sigc);
+ frame->f_pc = USRSTACK - (esigcode - sigcode);
#ifdef DEBUG
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): sig %d returns\n",
struct sigcontext tsigc;
struct sigstate tstate;
int flags;
+ extern short exframesize[];
scp = uap->sigcntxp;
#ifdef DEBUG
(scp = hscp->hsc_realsc) == 0 ||
useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) {
- u.u_onstack = hscp->hsc_onstack & 01;
+ p->p_sigacts->ps_onstack = hscp->hsc_onstack & 01;
p->p_sigmask = hscp->hsc_mask &~ sigcantmask;
- frame = (struct frame *) u.u_ar0;
+ frame = (struct frame *) p->p_regs;
frame->f_regs[SP] = hscp->hsc_sp;
frame->f_pc = hscp->hsc_pc;
frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR;
/*
* Restore the user supplied information
*/
- u.u_onstack = scp->sc_onstack & 01;
+ p->p_sigacts->ps_onstack = scp->sc_onstack & 01;
p->p_sigmask = scp->sc_mask &~ sigcantmask;
- frame = (struct frame *) u.u_ar0;
+ frame = (struct frame *) p->p_regs;
frame->f_regs[SP] = scp->sc_sp;
frame->f_regs[A6] = scp->sc_fp;
frame->f_pc = scp->sc_pc;
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
/* grab frame type and validate */
sz = tstate.ss_frame.f_format;
- if (sz == FMT9)
- sz = FMT9SIZE;
- else if (sz == FMTA)
- sz = FMTASIZE;
- else if (sz == FMTB) {
- sz = FMTBSIZE;
- /* no k-stack adjustment necessary */
- frame->f_stackadj = 0;
- } else
+ 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);
register int howto;
{
/* take a snap shot before clobbering any registers */
- if (u.u_procp)
- resume((u_int)pcbb(u.u_procp));
+ if (curproc)
+ savectx(curproc->p_addr, 0);
boothowto = howto;
if ((howto&RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) {
*/
if (panicstr == 0)
vnode_pager_umount(NULL);
+#ifdef notdef
#include "fd.h"
#if NFD > 0
fdshutdown();
#endif
- sync((struct sigcontext *)0);
+#endif
+ sync(&proc0, (void *)NULL, (int *)NULL);
for (iter = 0; iter < 20; iter++) {
nbusy = 0;
int dumpmag = 0x8fca0101; /* magic number for savecore */
int dumpsize = 0; /* also for savecore */
+long dumplo = 0;
dumpconf()
{
parityenable();
}
-straytrap(addr)
- register int addr;
+straytrap(pc, evec)
+ int pc;
+ u_short evec;
{
- printf("stray trap, addr 0x%x\n", addr);
+ printf("unexpected trap (vector offset %x) from %x\n",
+ evec & 0xFFF, pc);
}
int *nofault;
{
if (kbdnmi()) {
#ifdef PANICBUTTON
- printf("Got a keyboard NMI\n");
+ static int innmihand = 0;
+
+ /*
+ * Attempt to reduce the window of vulnerability for recursive
+ * NMIs (e.g. someone holding down the keyboard reset button).
+ */
+ if (innmihand == 0) {
+ innmihand = 1;
+ printf("Got a keyboard NMI\n");
+ innmihand = 0;
+ }
if (panicbutton) {
if (crashandburn) {
crashandburn = 0;
/*
* Parity error section. Contains magic.
*/
-#define PARREG ((volatile short *)IOV(0x5B0000))
+#define PARREG ((volatile short *)IIOV(0x5B0000))
static int gotparmem = 0;
#ifdef DEBUG
int ignorekperr = 0; /* ignore kernel parity errors */
if (!findparerror())
printf("WARNING: transient parity error ignored\n");
else if (USERMODE(fp->f_sr)) {
- printf("pid %d: parity error\n", u.u_procp->p_pid);
+ printf("pid %d: parity error\n", curproc->p_pid);
uprintf("sorry, pid %d killed due to memory parity error\n",
- u.u_procp->p_pid);
- psignal(u.u_procp, SIGKILL);
+ curproc->p_pid);
+ psignal(curproc, SIGKILL);
#ifdef DEBUG
} else if (ignorekperr) {
printf("WARNING: kernel parity error ignored\n");
return;
s = splhigh();
doingdump = 1;
- printf("pid = %d, pc = %s, ", u.u_procp->p_pid, hexstr(rp[PC], 8));
+ printf("pid = %d, pc = %s, ", curproc->p_pid, hexstr(rp[PC], 8));
printf("ps = %s, ", hexstr(rp[PS], 4));
printf("sfc = %s, ", hexstr(getsfc(), 4));
printf("dfc = %s\n", hexstr(getdfc(), 4));
splx(s);
}
-#define KSADDR ((int *)&(((char *)&u)[(UPAGES-1)*NBPG]))
+extern char kstack[];
+#define KSADDR ((int *)&(kstack[(UPAGES-1)*NBPG]))
dumpmem(ptr, sz, ustack)
- register int *ptr;
- int sz;
+ register int *ptr;
+ int sz;
{
register int i, val;
extern char *hexstr();
if ((val = fuword(ptr++)) == -1)
break;
} else {
- if (ustack == 0 && (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
+ if (ustack == 0 &&
+ (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
break;
val = *ptr++;
}