Use genassym for the first time in vax port history. Rewrite cpu_exit,
cpu_switch, setrunqueue and remrunqueue in assembler for efficiency.
This commit is contained in:
parent
64c0cead8c
commit
fd48076569
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.vax,v 1.34 1997/10/03 07:17:49 lukem Exp $
|
||||
# $NetBSD: Makefile.vax,v 1.35 1997/11/03 20:00:31 ragge Exp $
|
||||
|
||||
# Makefile for NetBSD
|
||||
#
|
||||
|
@ -102,6 +102,11 @@ LINKFLAGS+= -S
|
|||
|
||||
%LOAD
|
||||
|
||||
assym.h: $S/kern/genassym.sh ${VAX}/vax/genassym.cf
|
||||
sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} \
|
||||
< ${VAX}/vax/genassym.cf > assym.h.tmp && \
|
||||
mv -f assym.h.tmp assym.h
|
||||
|
||||
param.c: $S/conf/param.c
|
||||
rm -f param.c
|
||||
cp $S/conf/param.c .
|
||||
|
@ -148,7 +153,7 @@ links:
|
|||
SRCS= ${VAX}/vax/intvec.s ${VAX}/vax/subr.s \
|
||||
param.c ioconf.c ${CFILES} ${SFILES}
|
||||
depend: .depend
|
||||
.depend: ${SRCS} param.c
|
||||
.depend: ${SRCS} assym.h param.c
|
||||
${MKDEP} ${AFLAGS} ${CPPFLAGS} ${VAX}/vax/intvec.s ${VAX}/vax/subr.s
|
||||
${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
|
||||
${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
|
||||
|
@ -171,7 +176,7 @@ machdep.o sbi.o subr.o uvaxII.o: Makefile
|
|||
intvec.o: ${VAX}/vax/intvec.s
|
||||
${NORMAL_S}
|
||||
|
||||
subr.o: ${VAX}/vax/subr.s
|
||||
subr.o: ${VAX}/vax/subr.s assym.h
|
||||
${NORMAL_S}
|
||||
|
||||
%RULES
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: macros.h,v 1.11 1997/03/15 15:08:23 ragge Exp $ */
|
||||
/* $NetBSD: macros.h,v 1.12 1997/11/03 20:00:27 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
|
@ -212,4 +212,13 @@ static __inline__ void blkclr(void *blk, int len) {
|
|||
: "r0","r1","r2","r3","r4","r5", "r6" );
|
||||
}
|
||||
|
||||
#define setrunqueue(p) \
|
||||
asm __volatile("movl %0,r0;jsb Setrq":: "g"(p):"r0","r1","r2");
|
||||
|
||||
#define remrunqueue(p) \
|
||||
asm __volatile("movl %0,r0;jsb Remrq":: "g"(p):"r0","r1","r2");
|
||||
|
||||
#define cpu_switch(p) \
|
||||
asm __volatile("movl %0,r0;movpsl -(sp);jsb Swtch" \
|
||||
::"g"(p):"r0","r1","r2","r3");
|
||||
#endif /* _VAX_MACROS_H_ */
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# $NetBSD: genassym.cf,v 1.1 1997/11/03 20:00:24 ragge Exp $
|
||||
#
|
||||
# Copyright (c) 1997 Ludd, University of Lule}, Sweden.
|
||||
# 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 at Ludd, University of
|
||||
# Lule}, Sweden and its contributors.
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
include <sys/param.h>
|
||||
include <sys/proc.h>
|
||||
include <sys/errno.h>
|
||||
include <sys/syscall.h>
|
||||
|
||||
include <machine/mtpr.h>
|
||||
|
||||
define P_PRIORITY offsetof(struct proc, p_priority)
|
||||
define P_ADDR offsetof(struct proc, p_addr)
|
||||
define P_VMSPACE offsetof(struct proc, p_vmspace)
|
||||
|
||||
define PR_PCBB PR_PCBB
|
||||
define PR_IPL PR_IPL
|
||||
|
||||
define USPACE USPACE
|
||||
|
||||
define ENAMETOOLONG ENAMETOOLONG
|
||||
|
||||
define SYS_sigreturn SYS_sigreturn
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr.s,v 1.18 1997/03/22 23:02:13 ragge Exp $ */
|
||||
/* $NetBSD: subr.s,v 1.19 1997/11/03 20:00:21 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
|
@ -30,17 +30,11 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* All bugs are subject to removal without further notice */
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <machine/mtpr.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/nexus.h>
|
||||
#include "assym.h"
|
||||
|
||||
#define JSBENTRY(x) .globl x ; .align 2 ; x :
|
||||
|
||||
.text
|
||||
|
||||
|
@ -84,10 +78,7 @@ _fubyte: .word 0x0
|
|||
movzbl (r0),r0
|
||||
ret
|
||||
|
||||
|
||||
.globl _badaddr
|
||||
_badaddr: .word 0x0
|
||||
# Called with addr,b/w/l
|
||||
ENTRY(badaddr,0) # Called with addr,b/w/l
|
||||
mfpr $0x12,r0
|
||||
mtpr $0x1f,$0x12
|
||||
movl 4(ap),r2 # First argument, the address
|
||||
|
@ -218,30 +209,21 @@ cs: ret
|
|||
movl $ENAMETOOLONG, r0
|
||||
ret
|
||||
|
||||
|
||||
_loswtch: .globl _loswtch
|
||||
mtpr _curpcb,$PR_PCBB
|
||||
svpctx
|
||||
mtpr _nypcb,$PR_PCBB
|
||||
ldpctx
|
||||
rei
|
||||
|
||||
.data
|
||||
|
||||
_memtest: .long 0 ; .globl _memtest # Memory test in progress.
|
||||
|
||||
# Have bcopy and bzero here to be sure that system files that not gets
|
||||
# macros.h included will not complain.
|
||||
_bcopy: .globl _bcopy
|
||||
.word 0x0
|
||||
|
||||
ENTRY(bcopy,0)
|
||||
movl 4(ap), r0
|
||||
movl 8(ap), r1
|
||||
movl 0xc(ap), r2
|
||||
movc3 r2, (r0), (r1)
|
||||
ret
|
||||
|
||||
_bzero: .globl _bzero
|
||||
.word 0x0
|
||||
ENTRY(bzero,0)
|
||||
movl 4(ap), r0
|
||||
movl 8(ap), r1
|
||||
movc5 $0, (r0), $0, r1, (r0)
|
||||
|
@ -269,3 +251,133 @@ _longjmp:.word 0
|
|||
movl 12(r1), sp
|
||||
jmp *8(r1)
|
||||
#endif
|
||||
|
||||
#
|
||||
# setrunqueue/remrunqueue fast variants.
|
||||
#
|
||||
|
||||
JSBENTRY(Setrq)
|
||||
#ifdef DIAGNOSTIC
|
||||
tstl 4(r0) # Check that process actually are off the queue
|
||||
beql 1f
|
||||
pushab setrq
|
||||
calls $1,_panic
|
||||
setrq: .asciz "setrunqueue"
|
||||
#endif
|
||||
1: extzv $2,$6,P_PRIORITY(r0),r1 # get priority
|
||||
movaq _qs[r1],r2 # get address of queue
|
||||
insque (r0),*4(r2) # put proc last in queue
|
||||
bbss r1,_whichqs,1f # set queue bit.
|
||||
1: rsb
|
||||
|
||||
JSBENTRY(Remrq)
|
||||
extzv $2,$6,P_PRIORITY(r0),r1
|
||||
#ifdef DIAGNOSTIC
|
||||
bbs r1,_whichqs,1f
|
||||
pushab remrq
|
||||
calls $1,_panic
|
||||
remrq: .asciz "remrunqueue"
|
||||
#endif
|
||||
1: remque (r0),r2
|
||||
bneq 1f # Not last process on queue
|
||||
bbsc r1,_whichqs,1f
|
||||
1: clrl 4(r0) # saftey belt
|
||||
rsb
|
||||
|
||||
#
|
||||
# Idle loop. Here we could do something fun, maybe, like calculating
|
||||
# pi or something.
|
||||
#
|
||||
idle: mtpr $0,$PR_IPL # Enable all types of interrupts
|
||||
1: tstl _whichqs # Anything ready to run?
|
||||
beql 1b # no, continue to loop
|
||||
brb Swtch # Yes, goto switch again.
|
||||
|
||||
#
|
||||
# cpu_switch, cpu_exit and the idle loop implemented in assembler
|
||||
# for efficiency. r0 contains pointer to last process.
|
||||
#
|
||||
_pcbvirt: .long 0
|
||||
noque: .asciz "swtch"
|
||||
|
||||
JSBENTRY(Swtch)
|
||||
clrl _curproc # Stop process accounting
|
||||
mtpr $0x1f,$PR_IPL # block all interrupts
|
||||
ffs $0,$32,_whichqs,r3 # Search for bit set
|
||||
beql idle # no bit set, go to idle loop
|
||||
|
||||
movaq _qs[r3],r1 # get address of queue head
|
||||
remque *(r1),r2 # remove proc pointed to by queue head
|
||||
#ifdef DIAGNOSTIC
|
||||
bvc 1f # check if something on queue
|
||||
pushab noque
|
||||
calls $1,_panic
|
||||
#endif
|
||||
1: bneq 2f # more processes on queue?
|
||||
bbsc r3,_whichqs,2f # no, clear bit in whichqs
|
||||
2: clrl 4(r2) # clear proc backpointer
|
||||
clrl _want_resched # we are now changing process
|
||||
movl r2,_curproc # set new process running
|
||||
cmpl r0,r2 # Same process?
|
||||
bneq 1f # No, continue
|
||||
rsb
|
||||
1: movl P_ADDR(r2),r0 # Get pointer to new pcb.
|
||||
movl r0,_pcbvirt # Save for copy* functions.
|
||||
|
||||
#
|
||||
# Nice routine to get physical from virtual adresses.
|
||||
#
|
||||
extzv $9,$21,r0,r1 # extract offset
|
||||
movl *_Sysmap[r1],r2 # get pte
|
||||
ashl $9,r2,r3 # shift to get phys address.
|
||||
|
||||
#
|
||||
# Do the actual process switch. pc + psl are already on stack, from
|
||||
# the calling routine.
|
||||
#
|
||||
svpctx
|
||||
mtpr r3,$PR_PCBB
|
||||
ldpctx
|
||||
rei
|
||||
|
||||
#
|
||||
# the last routine called by a process.
|
||||
#
|
||||
|
||||
ENTRY(cpu_exit,0)
|
||||
movl 4(ap),r6 # Process pointer in r0
|
||||
pushl P_VMSPACE(r6) # free current vm space
|
||||
calls $1,_vmspace_free
|
||||
mtpr $0x18,$PR_IPL # Block almost everything
|
||||
addl3 $512,_scratch,sp # Change stack, we will free it now
|
||||
pushl $USPACE # stack size
|
||||
pushl P_ADDR(r6) # pointer to stack space
|
||||
pushl _kernel_map # the correct vm map
|
||||
calls $3,_kmem_free
|
||||
clrl r0 # No process to switch from
|
||||
bicl3 $0xc0000000,_scratch,r1
|
||||
mtpr r1,$PR_PCBB
|
||||
brw Swtch
|
||||
|
||||
|
||||
#ifdef notyet
|
||||
|
||||
#
|
||||
# They both are the same.
|
||||
#
|
||||
.globl _copyin, _copyout
|
||||
_copyout:
|
||||
_copyin:.word 0x40 # save r6
|
||||
mfpr $PR_PCBB, r6
|
||||
addl2 0x80000064, r6
|
||||
moval 1f, (r6)
|
||||
movl 4(ap), r1
|
||||
movl 8(ap), r2
|
||||
movc3 12(ap), (r1), (r2)
|
||||
1: clrl (r6)
|
||||
ret
|
||||
|
||||
Idealet inline:
|
||||
movl _curpcb,r6;moval 1f,64(r6);movc3 %1,(%2),(%3);clrl (r6);movl r0,%0
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vm_machdep.c,v 1.34 1997/11/02 14:25:26 ragge Exp $ */
|
||||
/* $NetBSD: vm_machdep.c,v 1.35 1997/11/03 20:00:17 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
|
@ -30,8 +30,6 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* All bugs are subject to removal without further notice */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -83,10 +81,6 @@ pagemove(from, to, size)
|
|||
mtpr(0, PR_TBIA);
|
||||
}
|
||||
|
||||
#define VIRT2PHYS(x) \
|
||||
(((*(int *)((((((int)x) & 0x7fffffff) >> 9) * 4) + \
|
||||
(unsigned int)Sysmap)) & 0x1fffff) << 9)
|
||||
|
||||
/*
|
||||
* cpu_fork() copies parent process trapframe directly into child PCB
|
||||
* so that when we swtch() to the child process it will go directly
|
||||
|
@ -179,118 +173,6 @@ cpu_set_kpc(p, pc)
|
|||
nyproc->PC = (unsigned)pc + 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put in a process on the correct run queue based on it's priority
|
||||
* and set the bit corresponding to the run queue.
|
||||
*/
|
||||
void
|
||||
setrunqueue(p)
|
||||
struct proc *p;
|
||||
{
|
||||
struct prochd *q;
|
||||
int knummer;
|
||||
|
||||
if (p->p_back)
|
||||
panic("sket sig i setrunqueue");
|
||||
|
||||
knummer = (p->p_priority >> 2);
|
||||
bitset(knummer, whichqs);
|
||||
q = &qs[knummer];
|
||||
|
||||
_insque(p, q);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a process from the run queue. If this is the last process
|
||||
* on that queue, clear the queue bit in whichqs.
|
||||
*/
|
||||
void
|
||||
remrunqueue(p)
|
||||
struct proc *p;
|
||||
{
|
||||
struct proc *qp;
|
||||
int bitnr;
|
||||
|
||||
bitnr = (p->p_priority >> 2);
|
||||
if (bitisclear(bitnr, whichqs))
|
||||
panic("remrunqueue: Process not in queue");
|
||||
|
||||
_remque(p);
|
||||
|
||||
qp = (struct proc *)&qs[bitnr];
|
||||
if (qp->p_forw == qp)
|
||||
bitclear(bitnr, whichqs);
|
||||
}
|
||||
|
||||
volatile caddr_t curpcb, nypcb;
|
||||
|
||||
/*
|
||||
* Machine dependent part of switch function. Find the next process
|
||||
* with the highest priority to run. If the process queues are empty,
|
||||
* sleep waiting for something to happen. The idle loop resides here.
|
||||
*/
|
||||
void
|
||||
cpu_switch(pp)
|
||||
struct proc *pp;
|
||||
{
|
||||
int i,s;
|
||||
struct proc *p, *q;
|
||||
extern unsigned int scratch;
|
||||
|
||||
again:
|
||||
/* First: Search for a queue. */
|
||||
s = splhigh();
|
||||
if ((i = ffs(whichqs) -1 ) < 0)
|
||||
goto idle;
|
||||
|
||||
/*
|
||||
* A queue with runnable processes found.
|
||||
* Get first process from queue.
|
||||
*/
|
||||
asm(".data;savpsl: .long 0;.text;movpsl savpsl");
|
||||
q = (struct proc *)&qs[i];
|
||||
if (q->p_forw == q)
|
||||
panic("swtch: no process queued");
|
||||
|
||||
/* Remove process from queue */
|
||||
bitclear(i, whichqs);
|
||||
p = q->p_forw;
|
||||
_remque(p);
|
||||
|
||||
if (q->p_forw != q)
|
||||
bitset(i, whichqs);
|
||||
if (curproc)
|
||||
(u_int)curpcb = VIRT2PHYS(&curproc->p_addr->u_pcb);
|
||||
else
|
||||
(u_int)curpcb = scratch & 0x7fffffff;
|
||||
(u_int)nypcb = VIRT2PHYS(&p->p_addr->u_pcb);
|
||||
|
||||
if (p == 0)
|
||||
panic("switch: null proc pointer");
|
||||
want_resched = 0;
|
||||
curproc = p;
|
||||
|
||||
/* Don't change process if it's the same that we'r already running */
|
||||
if (curpcb == nypcb)
|
||||
return;
|
||||
|
||||
asm("pushl savpsl");
|
||||
asm("jsb _loswtch");
|
||||
|
||||
return; /* New process! */
|
||||
|
||||
idle:
|
||||
p = curproc;
|
||||
curproc = NULL; /* This is nice. /BQT */
|
||||
spl0();
|
||||
while (whichqs == 0)
|
||||
;
|
||||
curproc = p;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* Should check that values is in bounds XXX */
|
||||
int
|
||||
copyinstr(from, to, maxlen, lencopied)
|
||||
|
@ -440,24 +322,6 @@ reno_zmagic(p, epp)
|
|||
return exec_aout_setup_stack(p, epp);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_exit(p)
|
||||
struct proc *p;
|
||||
{
|
||||
extern unsigned int scratch;
|
||||
|
||||
if (p == 0)
|
||||
panic("cpu_exit from null process");
|
||||
vmspace_free(p->p_vmspace);
|
||||
|
||||
(void) splimp();
|
||||
/* Must change kernel stack before freeing */
|
||||
mtpr(scratch + NBPG, PR_KSP);
|
||||
kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES));
|
||||
cpu_switch(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
suword(ptr, val)
|
||||
void *ptr;
|
||||
|
|
Loading…
Reference in New Issue