665 lines
18 KiB
C
665 lines
18 KiB
C
/* $NetBSD: machdep.c,v 1.8 1995/03/30 21:25:23 ragge Exp $ */
|
|
|
|
/* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
|
* Copyright (c) 1993 Adam Glass
|
|
* Copyright (c) 1988 University of Utah.
|
|
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Changed for the VAX port (and for readability) /IC
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* the Systems Programming Group of the University of Utah Computer
|
|
* Science Department.
|
|
*
|
|
* 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.
|
|
*
|
|
* from: Utah Hdr: machdep.c 1.63 91/04/24
|
|
*
|
|
* @(#)machdep.c 7.16 (Berkeley) 6/3/91
|
|
*/
|
|
|
|
#include "sys/param.h"
|
|
#include "vax/include/sid.h"
|
|
#include "sys/map.h"
|
|
#include "buf.h"
|
|
#include "mbuf.h"
|
|
#include "vax/include/pte.h"
|
|
#include "uba.h"
|
|
#include "reboot.h"
|
|
#include "sys/callout.h"
|
|
#include "sys/device.h"
|
|
#include "conf.h"
|
|
#include "sys/proc.h"
|
|
#include "sys/user.h"
|
|
#include "sys/time.h"
|
|
#include "sys/signal.h"
|
|
#include "sys/kernel.h"
|
|
#include "sys/reboot.h"
|
|
#include "sys/msgbuf.h"
|
|
#include "vax/include/mtpr.h"
|
|
#include "vax/include/cpu.h"
|
|
#include "vm/vm.h"
|
|
#include "vm/vm_kern.h"
|
|
#include "vm/vm_page.h"
|
|
#include "vax/include/macros.h"
|
|
#include "vax/include/nexus.h"
|
|
#include "vax/include/trap.h"
|
|
#include "net/netisr.h"
|
|
#ifdef SYSVMSG
|
|
#include "sys/msg.h"
|
|
#endif
|
|
#ifdef SYSVSEM
|
|
#include "sys/sem.h"
|
|
#endif
|
|
#ifdef SYSVSHM
|
|
#include "sys/shm.h"
|
|
#endif
|
|
|
|
/*
|
|
* We do these external declarations here, maybe they should be done
|
|
* somewhere else...
|
|
*/
|
|
int nmcr, nmba, numuba, cold=1;
|
|
caddr_t mcraddr[MAXNMCR];
|
|
int astpending;
|
|
int want_resched;
|
|
char machine[]="VAX";
|
|
char cpu_model[100];
|
|
int msgbufmapped=0;
|
|
struct msgbuf *msgbufp;
|
|
int physmem;
|
|
struct cfdriver nexuscd;
|
|
int todrstopped=0,glurg;
|
|
int dumpsize=0;
|
|
|
|
caddr_t allocsys __P((caddr_t));
|
|
|
|
#define valloclim(name, type, num, lim) \
|
|
(name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
|
|
|
|
#ifdef BUFPAGES
|
|
int bufpages = BUFPAGES;
|
|
#else
|
|
int bufpages = 0;
|
|
#endif
|
|
int nswbuf = 0;
|
|
#ifdef NBUF
|
|
int nbuf = NBUF;
|
|
#else
|
|
int nbuf = 0;
|
|
#endif
|
|
|
|
cpu_startup() {
|
|
caddr_t v,tempaddr;
|
|
extern char version[];
|
|
int base, residual,i,sz;
|
|
vm_offset_t minaddr, maxaddr;
|
|
vm_size_t size;
|
|
extern int cpu_type,boothowto,startpmapdebug;
|
|
extern unsigned int avail_end;
|
|
extern char *panicstr;
|
|
|
|
/*
|
|
* Initialize error message buffer (at end of core).
|
|
* avail_end was pre-decremented in pmap_bootstrap to compensate.
|
|
*/
|
|
#if 0
|
|
for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
|
|
pmap_enter(kernel_pmap, (vm_offset_t)msgbufp,
|
|
avail_end + i * NBPG, VM_PROT_ALL, TRUE);
|
|
msgbufmapped = 1;
|
|
#endif
|
|
#ifdef VAX750
|
|
if(cpunumber==VAX_750)
|
|
if(!mfpr(PR_TODR))
|
|
mtpr(todrstopped=1,PR_TODR);
|
|
#endif
|
|
/*
|
|
* Good {morning,afternoon,evening,night}.
|
|
*/
|
|
printf("%s\n", version);
|
|
printf("realmem = %d\n", avail_end);
|
|
physmem=btoc(avail_end);
|
|
panicstr=NULL;
|
|
mtpr(AST_NO,PR_ASTLVL);
|
|
spl0();
|
|
|
|
dumpsize=physmem+1;
|
|
|
|
/*
|
|
* Find out how much space we need, allocate it,
|
|
* and then give everything true virtual addresses.
|
|
*/
|
|
sz = (int)allocsys((caddr_t)0);
|
|
if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0)
|
|
panic("startup: no room for tables");
|
|
if (allocsys(v) - v != sz)
|
|
panic("startup: table size inconsistency");
|
|
|
|
/*
|
|
* Now allocate buffers proper. They are different than the above
|
|
* in that they usually occupy more virtual memory than physical.
|
|
*/
|
|
size = MAXBSIZE * nbuf;
|
|
buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
|
|
&maxaddr, size, TRUE);
|
|
minaddr = (vm_offset_t)buffers;
|
|
if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
|
|
&minaddr, size, FALSE) != KERN_SUCCESS)
|
|
panic("startup: cannot allocate buffers");
|
|
if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
|
|
/* don't want to alloc more physical mem than needed */
|
|
bufpages = btoc(MAXBSIZE) * nbuf;
|
|
}
|
|
base = bufpages / nbuf;
|
|
residual = bufpages % nbuf;
|
|
for (i = 0; i < nbuf; i++) {
|
|
vm_size_t curbufsize;
|
|
vm_offset_t curbuf;
|
|
|
|
/*
|
|
* First <residual> buffers get (base+1) physical pages
|
|
* allocated for them. The rest get (base) physical pages.
|
|
*
|
|
* The rest of each buffer occupies virtual space,
|
|
* but has no physical memory allocated for it.
|
|
*/
|
|
curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
|
|
curbufsize = CLBYTES * (i < residual ? base+1 : base);
|
|
vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
|
|
vm_map_simplify(buffer_map, curbuf);
|
|
}
|
|
|
|
/*
|
|
* Allocate a submap for exec arguments. This map effectively
|
|
* limits the number of processes exec'ing at any time.
|
|
*/
|
|
exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
|
|
16*NCARGS, TRUE);
|
|
|
|
/*
|
|
* Finally, allocate mbuf pool. Since mclrefcnt is an off-size
|
|
* we use the more space efficient malloc in place of kmem_alloc.
|
|
*/
|
|
|
|
mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
|
|
M_MBUF, M_NOWAIT);
|
|
bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
|
|
mb_map = kmem_suballoc(kernel_map, (vm_offset_t*)&mbutl, &maxaddr,
|
|
VM_MBUF_SIZE, FALSE);
|
|
/*
|
|
* Initialize callouts
|
|
*/
|
|
|
|
callfree = callout;
|
|
for (i = 1; i < ncallout; i++)
|
|
callout[i-1].c_next = &callout[i];
|
|
callout[i-1].c_next = NULL;
|
|
|
|
printf("avail mem = %d\n", ptoa(cnt.v_free_count));
|
|
printf("Using %d buffers containing %d bytes of memory.\n",
|
|
nbuf, bufpages * CLBYTES);
|
|
|
|
/*
|
|
* Set up buffers, so they can be used to read disk labels.
|
|
*/
|
|
|
|
bufinit();
|
|
|
|
/*
|
|
* Configure the system.
|
|
*/
|
|
configure();
|
|
}
|
|
|
|
/*
|
|
* Allocate space for system data structures. We are given
|
|
* a starting virtual address and we return a final virtual
|
|
* address; along the way we set each data structure pointer.
|
|
*
|
|
* We call allocsys() with 0 to find out how much space we want,
|
|
* allocate that much and fill it with zeroes, and then call
|
|
* allocsys() again with the correct base virtual address.
|
|
*/
|
|
caddr_t
|
|
allocsys(v)
|
|
register caddr_t v;
|
|
{
|
|
|
|
#define valloc(name, type, num) \
|
|
v = (caddr_t)(((name) = (type *)v) + (num))
|
|
|
|
#ifdef REAL_CLISTS
|
|
valloc(cfree, struct cblock, nclist);
|
|
#endif
|
|
valloc(callout, struct callout, ncallout);
|
|
valloc(swapmap, struct map, nswapmap = maxproc * 2);
|
|
#ifdef SYSVSHM
|
|
valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
|
|
#endif
|
|
#ifdef SYSVSEM
|
|
valloc(sema, struct semid_ds, seminfo.semmni);
|
|
valloc(sem, struct sem, seminfo.semmns);
|
|
/* This is pretty disgusting! */
|
|
valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
|
#endif
|
|
#ifdef SYSVMSG
|
|
valloc(msgpool, char, msginfo.msgmax);
|
|
valloc(msgmaps, struct msgmap, msginfo.msgseg);
|
|
valloc(msghdrs, struct msg, msginfo.msgtql);
|
|
valloc(msqids, struct msqid_ds, msginfo.msgmni);
|
|
#endif
|
|
|
|
/*
|
|
* Determine how many buffers to allocate (enough to
|
|
* hold 5% of total physical memory, but at least 16).
|
|
* Allocate 1/2 as many swap buffer headers as file i/o buffers.
|
|
*/
|
|
if (bufpages == 0)
|
|
if (physmem < btoc(2 * 1024 * 1024))
|
|
bufpages = (physmem / 10) / CLSIZE;
|
|
else
|
|
bufpages = (physmem / 20) / CLSIZE;
|
|
if (nbuf == 0) {
|
|
nbuf = bufpages;
|
|
if (nbuf < 16)
|
|
nbuf = 16;
|
|
}
|
|
if (nswbuf == 0) {
|
|
nswbuf = (nbuf / 2) &~ 1; /* force even */
|
|
if (nswbuf > 256)
|
|
nswbuf = 256; /* sanity */
|
|
}
|
|
valloc(swbuf, struct buf, nswbuf);
|
|
valloc(buf, struct buf, nbuf);
|
|
return v;
|
|
}
|
|
|
|
int dumplo=0;
|
|
|
|
dumpconf()
|
|
{
|
|
int nblks;
|
|
extern int dumpdev;
|
|
|
|
/*
|
|
* XXX include the final RAM page which is not included in physmem.
|
|
*/
|
|
dumpsize = physmem + 1;
|
|
if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
|
|
nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
|
|
if (dumpsize > btoc(dbtob(nblks - dumplo)))
|
|
dumpsize = btoc(dbtob(nblks - dumplo));
|
|
else if (dumplo == 0)
|
|
dumplo = nblks - btodb(ctob(dumpsize));
|
|
}
|
|
/*
|
|
* Don't dump on the first CLBYTES (why CLBYTES?)
|
|
* in case the dump device includes a disk label.
|
|
*/
|
|
if (dumplo < btodb(CLBYTES))
|
|
dumplo = btodb(CLBYTES);
|
|
}
|
|
|
|
cpu_initclocks(){
|
|
(cpu_calls[cpunumber].cpu_clock)();
|
|
}
|
|
|
|
cpu_sysctl(){
|
|
printf("cpu_sysctl:\n");
|
|
return(EOPNOTSUPP);
|
|
}
|
|
|
|
setstatclockrate(){
|
|
panic("setstatclockrate");
|
|
}
|
|
|
|
consinit(){
|
|
/* cninit(); */
|
|
}
|
|
|
|
struct sigretargs {
|
|
struct sigcontext *cntxp;
|
|
};
|
|
|
|
sigreturn(p, uap, retval)
|
|
struct proc *p;
|
|
struct sigretargs *uap;
|
|
int *retval;
|
|
{
|
|
struct trapframe *scf=p->p_addr->u_pcb.framep;
|
|
struct sigcontext *cntx=uap->cntxp;
|
|
/* Compatibility mode? */
|
|
if((cntx->sc_ps&(PSL_IPL|PSL_IS))||
|
|
((cntx->sc_ps&(PSL_U|PSL_PREVU))!=(PSL_U|PSL_PREVU))||
|
|
(cntx->sc_ps&PSL_CM)){
|
|
return(EINVAL);
|
|
}
|
|
if (cntx->sc_onstack & 01)
|
|
p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
|
|
else
|
|
p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
|
|
p->p_sigmask = cntx->sc_mask &~ sigcantmask;
|
|
|
|
scf->fp=cntx->sc_fp;
|
|
scf->ap=cntx->sc_ap;
|
|
scf->pc=cntx->sc_pc;
|
|
scf->psl=cntx->sc_ps;
|
|
mtpr(cntx->sc_sp,PR_USP);
|
|
return(EJUSTRETURN);
|
|
}
|
|
|
|
struct trampframe {
|
|
u_int sig; /* Signal number */
|
|
u_int code; /* Info code */
|
|
u_int scp; /* Pointer to struct sigcontext */
|
|
u_int r0,r1,r2,r3,r4,r5; /* Registers saved when interrupt */
|
|
u_int pc; /* Address of signal handler */
|
|
u_int arg; /* Pointer to first (and only) sigreturn argument */
|
|
};
|
|
|
|
void
|
|
sendsig(catcher, sig, mask, code)
|
|
sig_t catcher;
|
|
int sig, mask;
|
|
u_long code;
|
|
{
|
|
struct proc *p = curproc;
|
|
struct sigacts *psp = p->p_sigacts;
|
|
struct trapframe *syscf;
|
|
struct sigcontext *sigctx;
|
|
struct trampframe *trampf;
|
|
u_int *cursp;
|
|
int oonstack;
|
|
/*
|
|
* 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'.
|
|
* We shall allocate space on the stack for both
|
|
* struct sigcontext and struct calls...
|
|
*/
|
|
/* First check what stack to work on */
|
|
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
|
(psp->ps_sigonstack & sigmask(sig))) {
|
|
cursp=(u_int *)(psp->ps_sigstk.ss_base+psp->ps_sigstk.ss_size);
|
|
psp->ps_sigstk.ss_flags |= SA_ONSTACK;
|
|
} else
|
|
cursp = (u_int *)mfpr(PR_USP);
|
|
if ((u_int)cursp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
|
|
(void)grow(p, (u_int)cursp);
|
|
|
|
/* Set up positions for structs on stack */
|
|
sigctx=(struct sigcontext *)((u_int)cursp-sizeof(struct sigcontext));
|
|
trampf=(struct trampframe *)((u_int)sigctx-sizeof(struct trampframe));
|
|
cursp=(u_int*)sigctx-2; /* Place for pointer to arg list in sigreturn */
|
|
|
|
syscf=p->p_addr->u_pcb.framep;
|
|
if(useracc((caddr_t)cursp, sizeof(struct sigcontext)+
|
|
sizeof(struct trampframe), B_WRITE)==0) {
|
|
/*
|
|
* 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;
|
|
}
|
|
/* Set up pointers for sigreturn args */
|
|
trampf->arg=(int)sigctx;
|
|
trampf->pc=(u_int)catcher;
|
|
trampf->scp=(int)sigctx;
|
|
trampf->code=code;
|
|
trampf->sig=sig;
|
|
|
|
|
|
sigctx->sc_pc=syscf->pc;
|
|
sigctx->sc_ps=syscf->psl;
|
|
sigctx->sc_ap=syscf->ap;
|
|
sigctx->sc_fp=syscf->fp;
|
|
sigctx->sc_sp=mfpr(PR_USP);
|
|
sigctx->sc_onstack=oonstack;
|
|
sigctx->sc_mask=mask;
|
|
|
|
syscf->pc=(u_int)0x7fffe000; /* XXX signal trampoline code */
|
|
syscf->psl=PSL_U|PSL_PREVU;
|
|
syscf->ap=(u_int)cursp;
|
|
mtpr(cursp,PR_USP);
|
|
}
|
|
|
|
int waittime=-1;
|
|
|
|
boot(howto)
|
|
int howto;
|
|
{
|
|
extern char *panicstr;
|
|
|
|
if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
|
|
register struct buf *bp;
|
|
int iter, nbusy;
|
|
|
|
waittime = 0;
|
|
(void) spl0();
|
|
if(panicstr&&curproc) showstate(curproc);
|
|
|
|
printf("syncing disks... ");
|
|
/*
|
|
* Release vnodes held by texts before sync.
|
|
*/
|
|
if (panicstr == 0)
|
|
vnode_pager_umount(NULL);
|
|
|
|
sync(&proc0, (void *)NULL, (int *)NULL);
|
|
for (iter = 0; iter < 20; iter++) {
|
|
nbusy = 0;
|
|
for (bp = &buf[nbuf]; --bp >= buf; )
|
|
if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
|
|
nbusy++;
|
|
if (nbusy == 0)
|
|
break;
|
|
printf("%d ", nbusy);
|
|
{register int m;
|
|
m=mfpr(PR_TODR)+iter*4;
|
|
while(m!=mfpr(PR_TODR));}
|
|
/* DELAY(400000 * iter); */
|
|
}
|
|
if (nbusy)
|
|
printf("giving up\n");
|
|
else
|
|
printf("done\n");
|
|
/*
|
|
* If we've been adjusting the clock, the todr
|
|
* will be out of synch; adjust it now.
|
|
*/
|
|
resettodr();
|
|
}
|
|
splhigh(); /* extreme priority */
|
|
if (howto&RB_HALT) {
|
|
int *i;
|
|
printf("halting (due to bad scbvector)\n");
|
|
/* This should halt almost every known VAX cpu */
|
|
i=(int *)0x80000008;
|
|
*i+=2;
|
|
asm("movl $0xf0000000,sp;pushl $0;chmk $3");
|
|
} else {
|
|
if (howto & RB_DUMP)
|
|
dumpsys();
|
|
asm("halt"); /* Not good way to do this */
|
|
}
|
|
}
|
|
|
|
netintr()
|
|
{
|
|
#ifdef INET
|
|
if (netisr & (1 << NETISR_ARP)) {
|
|
netisr &= ~(1 << NETISR_ARP);
|
|
arpintr();
|
|
}
|
|
if (netisr & (1 << NETISR_IP)) {
|
|
netisr &= ~(1 << NETISR_IP);
|
|
ipintr();
|
|
}
|
|
#endif
|
|
#ifdef NS
|
|
if (netisr & (1 << NETISR_NS)) {
|
|
netisr &= ~(1 << NETISR_NS);
|
|
nsintr();
|
|
}
|
|
#endif
|
|
#ifdef ISO
|
|
if (netisr & (1 << NETISR_ISO)) {
|
|
netisr &= ~(1 << NETISR_ISO);
|
|
clnlintr();
|
|
}
|
|
#endif
|
|
#ifdef CCITT
|
|
if (netisr & (1 << NETISR_CCITT)) {
|
|
netisr &= ~(1 << NETISR_CCITT);
|
|
ccittintr();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
machinecheck(frame)
|
|
u_int frame;
|
|
{
|
|
if((*cpu_calls[cpunumber].cpu_mchk)(frame)==0)
|
|
return;
|
|
(*cpu_calls[cpunumber].cpu_memerr)();
|
|
panic("machine check");
|
|
}
|
|
|
|
dumpsys()
|
|
{
|
|
extern int dumpdev, dumplo;
|
|
|
|
msgbufmapped = 0;
|
|
if (dumpdev == NODEV)
|
|
return;
|
|
/*
|
|
* For dumps during autoconfiguration,
|
|
* if dump device has already configured...
|
|
*/
|
|
if (dumpsize == 0)
|
|
dumpconf();
|
|
if (dumplo < 0)
|
|
return;
|
|
printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
|
|
printf("dump ");
|
|
switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
|
|
|
|
case ENXIO:
|
|
printf("device bad\n");
|
|
break;
|
|
|
|
case EFAULT:
|
|
printf("device not ready\n");
|
|
break;
|
|
|
|
case EINVAL:
|
|
printf("area improper\n");
|
|
break;
|
|
|
|
case EIO:
|
|
printf("i/o error\n");
|
|
break;
|
|
|
|
default:
|
|
printf("succeeded\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
fuswintr(){
|
|
panic("fuswintr: need to be implemented");
|
|
}
|
|
|
|
suibyte(){
|
|
panic("suibyte: need to be implemented");
|
|
}
|
|
|
|
suswintr(){
|
|
panic("suswintr: need to be implemented");
|
|
}
|
|
|
|
int
|
|
process_set_pc(p, addr)
|
|
struct proc *p;
|
|
caddr_t addr;
|
|
{
|
|
void *ptr;
|
|
struct trapframe *tf;
|
|
|
|
if ((p->p_flag & P_INMEM) == 0)
|
|
return (EIO);
|
|
|
|
ptr = (char *)p->p_addr->u_pcb.framep;
|
|
tf = ptr;
|
|
|
|
tf->pc = (u_int)addr;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
process_sstep(p, sstep)
|
|
struct proc *p;
|
|
{
|
|
void *ptr;
|
|
struct trapframe *tf;
|
|
|
|
if ((p->p_flag & P_INMEM) == 0)
|
|
return (EIO);
|
|
|
|
ptr = p->p_addr->u_pcb.framep;
|
|
tf = ptr;
|
|
|
|
if(sstep)
|
|
tf->psl |= PSL_T;
|
|
else
|
|
tf->psl &= ~PSL_T;
|
|
|
|
return (0);
|
|
}
|
|
|
|
#undef setsoftnet
|
|
setsoftnet(){
|
|
panic("setsoftnet");
|
|
}
|
|
|
|
ns_cksum(){
|
|
panic("ns_cksum");
|
|
}
|