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:
ragge 1997-11-03 20:00:17 +00:00
parent 64c0cead8c
commit fd48076569
5 changed files with 209 additions and 167 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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;