add directory study

This commit is contained in:
gohigh
2024-02-19 00:25:23 -05:00
parent b1306b38b1
commit f3774e2f8c
4001 changed files with 2285787 additions and 0 deletions

View File

@@ -0,0 +1,300 @@
# Makefile for networking kernel using standard Minix directory
# layout and compiler.
# CPP may need changing to /usr/lib/cpp.
# The following nonstandard flags are used:
# -F: run cpp and cem sequentially (used when memory is tight)
# -T.: put temporaries in working directory (when RAM disk is small)
#
# Define AM_KERNEL and NONET to get a networking kernel without
# a network interface (only local transactions). Define
# AM_KERNEL if you have a Western Digital Etherplus card and
# want remote transactions. Define STATISTICS to keep track of
# Amoeba transaction statistics and to bind function key F5 to
# dump them.
#
BIN =.
CC =cc
#CFLAGS =-F -T.
CFLAGS =-DAM_KERNEL -DSTATISTICS -I../../kernel -I. -DNO_NET
CPP =/lib/cpp
CPPFLAGS =-DASLD -P
END =/lib/end.s
LD =asld
LDFLAGS =-i
LIBS =/lib/libc.a
START =start.s
a =$k/kernel.h $h/config.h $h/const.h $h/type.h \
$s/types.h $i/limits.h $i/errno.h \
$k/const.h $k/type.h $k/proto.h $k/glo.h
h =/usr/include/minix
i =/usr/include
k =../../kernel
s =/usr/include/sys
KEROBJS =cstart.s protect.s protect1.s klib.s mpx.s wini.s \
table.s main.s tty.s floppy.s system.s proc.s \
clock.s memory.s console.s rs232.s rs2.s printer.s \
amoeba.s conf.s dp8390.s util.s etherplus.s portcache.s \
trans.s dmp.s exception.s i8259.s misc.s keyboard.s
SOBJS =start.s klib.s mpx.s rs2.s
# Rules.
.SUFFIXES: .x # .x files are .s files which need C-preprocessing
.x.s:
$(CPP) $(CPPFLAGS) $k/$< >$@
# What to make.
dummy: $(BIN)/kernel # this line fixes a bug in RAL's latest make
$(BIN)/kernel: $(START) $(KEROBJS) $(LIBS) $(END)
$(LD) $(LDFLAGS) -o $(BIN)/kernel \
$(START) $(KEROBJS) \
$(LIBS) $(END)
clean:
rm -f $(START) $(KEROBJS) $(SOBJS) *.bak
klib.s: $h/config.h $h/const.h $k/const.h $k/protect.h $k/sconst.h
klib.s: $k/klib.x
$(CPP) $(CPPFLAGS) $k/klib.x >$@
mpx.s: $h/config.h $h/const.h $h/com.h $k/const.h $k/protect.h $k/sconst.h
mpx.s: $k/mpx.x
$(CPP) $(CPPFLAGS) $k/mpx.x >$@
rs2.s: $h/config.h $h/const.h $k/const.h $k/sconst.h
rs2.s: $k/rs2.x
$(CPP) $(CPPFLAGS) $k/rs2.x >$@
start.s: $h/config.h $h/const.h $h/com.h $k/const.h $k/protect.h $k/sconst.h
start.s: $k/start.x
$(CPP) $(CPPFLAGS) $k/start.x >$@
clock.s: $a
clock.s: $i/signal.h
clock.s: $h/callnr.h
clock.s: $h/com.h
clock.s: $k/proc.h
clock.s: $k/clock.c
$(CC) $(CFLAGS) -c $k/clock.c
console.s: $a
console.s: $i/sgtty.h
console.s: $h/callnr.h
console.s: $h/com.h
console.s: $k/protect.h
console.s: $k/tty.h
console.s: $k/console.c
$(CC) $(CFLAGS) -c $k/console.c
cstart.s: $a
cstart.s: $h/boot.h
cstart.s: $k/cstart.c
$(CC) $(CFLAGS) -c $k/cstart.c
dmp.s: $a
dmp.s: $h/callnr.h
dmp.s: $h/com.h
dmp.s: $k/proc.h
dmp.s: $k/dmp.c
$(CC) $(CFLAGS) -c $k/dmp.c
exception.s: $a
exception.s: $i/signal.h
exception.s: $k/proc.h
exception.s: $k/exception.c
$(CC) $(CFLAGS) -c $k/exception.c
floppy.s: $a
floppy.s: $h/callnr.h
floppy.s: $h/com.h
floppy.s: $k/floppy.c
$(CC) $(CFLAGS) -c $k/floppy.c
i8259.s: $a
i8259.s: $k/i8259.c
$(CC) $(CFLAGS) -c $k/i8259.c
keyboard.s: $a
keyboard.s: $i/sgtty.h
keyboard.s: $i/signal.h
keyboard.s: $h/callnr.h
keyboard.s: $h/com.h
keyboard.s: $k/tty.h
keyboard.s: $k/keyboard.c
$(CC) $(CFLAGS) -c $k/keyboard.c
main.s: $a
main.s: $i/signal.h
main.s: $h/callnr.h
main.s: $h/com.h
main.s: $k/proc.h
main.s: $k/main.c
$(CC) $(CFLAGS) -c $k/main.c
memory.s: $a
memory.s: $h/callnr.h
memory.s: $h/com.h
memory.s: $k/memory.c
$(CC) $(CFLAGS) -c $k/memory.c
misc.s: $a
misc.s: $h/com.h
misc.s: $k/misc.c
$(CC) $(CFLAGS) -c $k/misc.c
printer.s: $a
printer.s: $h/callnr.h
printer.s: $h/com.h
printer.s: $k/printer.c
$(CC) $(CFLAGS) -c $k/printer.c
proc.s: $a
proc.s: $h/callnr.h
proc.s: $h/com.h
proc.s: $k/proc.h
proc.s: $k/proc.c
$(CC) $(CFLAGS) -c $k/proc.c
protect.s: $a
protect.s: $k/protect.h
protect.s: $k/protect1.c
protect.s: $k/protect.c
$(CC) $(CFLAGS) -c $k/protect.c
protect1.s: $a
protect1.s: $k/proc.h
protect1.s: $k/protect.h
protect1.s: $k/protect1.c
$(CC) $(CFLAGS) -c $k/protect1.c
rs232.s: $a
rs232.s: $i/sgtty.h
rs232.s: $k/tty.h
rs232.s: $k/rs232.c
$(CC) $(CFLAGS) -c $k/rs232.c
system.s: $a
system.s: $i/signal.h
system.s: $h/boot.h
system.s: $h/callnr.h
system.s: $h/com.h
system.s: $k/proc.h
system.s: $k/protect.h
system.s: $k/system.c
$(CC) $(CFLAGS) -c $k/system.c
table.s: $a
table.s: $h/com.h
table.s: $k/proc.h
table.s: $k/tty.h
table.s: $k/table.c
$(CC) $(CFLAGS) -c $k/table.c
tty.s: $a
tty.s: $i/sgtty.h
tty.s: $i/signal.h
tty.s: $h/callnr.h
tty.s: $h/com.h
tty.s: $k/tty.h
tty.s: $k/tty.c
$(CC) $(CFLAGS) -c $k/tty.c
wini.s: $a
wini.s: $h/callnr.h
wini.s: $h/com.h
wini.s: $h/partition.h
wini.s: $k/wini.c
$(CC) $(CFLAGS) -c $k/wini.c
amoeba.s: $a
amoeba.s: $i/amoeba.h
amoeba.s: $i/host_os.h
amoeba.s: $i/amparam.h
amoeba.s: $i/signal.h
amoeba.s: $i/assert.h
amoeba.s: ./byteorder.h
amoeba.s: ./dp8390info.h
amoeba.s: ./etherformat.h
amoeba.s: ./global.h
amoeba.s: ./internet.h
amoeba.s: ./mpx.H
amoeba.s: ./portcache.H
amoeba.s: $k/proc.h
amoeba.s: ./task.h
amoeba.s: ./trans.H
amoeba.s: amoeba.c
conf.s: $a
conf.s: $i/amoeba.h
conf.s: ./conf.h
conf.s: ./global.h
conf.s: ./mpx.H
conf.s: ./portcache.H
conf.s: ./task.h
conf.s: ./trans.H
conf.s: conf.c
dp8390.s: $a
dp8390.s: $h/com.h
dp8390.s: $i/assert.h
dp8390.s: ./dp8390.h
dp8390.s: ./dp8390info.h
dp8390.s: ./dp8390stat.h
dp8390.s: ./etherformat.h
dp8390.s: ./internet.h
dp8390.s: dp8390.c
etherplus.s: $a
etherplus.s: $h/com.h
etherplus.s: $i/assert.h
etherplus.s: ./dp8390.h
etherplus.s: ./dp8390info.h
etherplus.s: ./eplinfo.h
etherplus.s: ./etherformat.h
etherplus.s: ./etherplus.h
etherplus.s: ./internet.h
etherplus.s: etherplus.c
portcache.s: $a
portcache.s: $i/amoeba.h
portcache.s: $i/host_os.h
portcache.s: ./assert.h
portcache.s: ./conf.h
portcache.s: ./global.h
portcache.s: ./internet.h
portcache.s: ./mpx.H
portcache.s: ./portcache.H
portcache.s: ./task.h
portcache.s: ./trans.H
portcache.s: portcache.c
trans.s: $a
trans.s: $i/amoeba.h
trans.s: $i/host_os.h
trans.s: ./amstat.h
trans.s: ./assert.h
trans.s: ./byteorder.h
trans.s: ./exception.h
trans.s: ./global.h
trans.s: ./internet.h
trans.s: ./mpx.H
trans.s: ./portcache.H
trans.s: ./task.h
trans.s: ./trans.H
trans.s: trans.c
util.s: $a
util.s: $h/com.h
util.s: ./assert.h
util.s: ./dp8390.h
util.s: ./dp8390info.h
util.s: ./eplinfo.h
util.s: $k/proc.h
util.s: util.c

View File

@@ -0,0 +1,302 @@
# Makefile for networking kernel using standard Minix directory
# layout and compiler.
#
# /usr/lib/cpp needs about 50K of stack, which is more than usual
#
# The following nonstandard flags are used:
# -F: run cpp and cem sequentially (used when memory is tight)
# -T.: put temporaries in working directory (when RAM disk is small)
#
# Define AM_KERNEL and NONET to get a networking kernel without
# a network interface (only local transactions). Define
# AM_KERNEL if you have a Western Digital Etherplus card and
# want remote transactions. Define STATISTICS to keep track of
# Amoeba transaction statistics and to bind function key F5 to
# dump them.
#
BIN =.
CC =cc
#CFLAGS =-F -T.
CFLAGS =-DAM_KERNEL -DSTATISTICS -I../../kernel -I. -F
CPP =/usr/lib/cpp
CPPFLAGS =-DASLD -P
END =/usr/lib/end.s
LD =asld
LDFLAGS =-i
LIBS =/usr/lib/libc.a
START =start.s
a =$k/kernel.h $h/config.h $h/const.h $h/type.h \
$s/types.h $i/limits.h $i/errno.h \
$k/const.h $k/type.h $k/proto.h $k/glo.h
h =/usr/include/minix
i =/usr/include
k =../../kernel
s =/usr/include/sys
KEROBJS =cstart.s protect.s protect1.s klib.s mpx.s wini.s \
table.s main.s tty.s floppy.s system.s proc.s \
clock.s memory.s console.s rs232.s rs2.s printer.s \
amoeba.s conf.s dp8390.s util.s etherplus.s portcache.s \
trans.s dmp.s exception.s i8259.s misc.s keyboard.s
SOBJS =start.s klib.s mpx.s rs2.s
# Rules.
.SUFFIXES: .x # .x files are .s files which need C-preprocessing
.x.s:
$(CPP) $(CPPFLAGS) $k/$< >$@
# What to make.
dummy: $(BIN)/kernel # this line fixes a bug in RAL's latest make
$(BIN)/kernel: $(START) $(KEROBJS) $(LIBS) $(END)
$(LD) $(LDFLAGS) -o $(BIN)/kernel \
$(START) $(KEROBJS) \
$(LIBS) $(END)
clean:
rm -f $(START) $(KEROBJS) $(SOBJS) *.bak
klib.s: $h/config.h $h/const.h $k/const.h $k/protect.h $k/sconst.h
klib.s: $k/klib.x
$(CPP) $(CPPFLAGS) $k/klib.x >$@
mpx.s: $h/config.h $h/const.h $h/com.h $k/const.h $k/protect.h $k/sconst.h
mpx.s: $k/mpx.x
$(CPP) $(CPPFLAGS) $k/mpx.x >$@
rs2.s: $h/config.h $h/const.h $k/const.h $k/sconst.h
rs2.s: $k/rs2.x
$(CPP) $(CPPFLAGS) $k/rs2.x >$@
start.s: $h/config.h $h/const.h $h/com.h $k/const.h $k/protect.h $k/sconst.h
start.s: $k/start.x
$(CPP) $(CPPFLAGS) $k/start.x >$@
clock.s: $a
clock.s: $i/signal.h
clock.s: $h/callnr.h
clock.s: $h/com.h
clock.s: $k/proc.h
clock.s: $k/clock.c
$(CC) $(CFLAGS) -c $k/clock.c
console.s: $a
console.s: $i/sgtty.h
console.s: $h/callnr.h
console.s: $h/com.h
console.s: $k/protect.h
console.s: $k/tty.h
console.s: $k/console.c
$(CC) $(CFLAGS) -c $k/console.c
cstart.s: $a
cstart.s: $h/boot.h
cstart.s: $k/cstart.c
$(CC) $(CFLAGS) -c $k/cstart.c
dmp.s: $a
dmp.s: $h/callnr.h
dmp.s: $h/com.h
dmp.s: $k/proc.h
dmp.s: $k/dmp.c
$(CC) $(CFLAGS) -c $k/dmp.c
exception.s: $a
exception.s: $i/signal.h
exception.s: $k/proc.h
exception.s: $k/exception.c
$(CC) $(CFLAGS) -c $k/exception.c
floppy.s: $a
floppy.s: $h/callnr.h
floppy.s: $h/com.h
floppy.s: $k/floppy.c
$(CC) $(CFLAGS) -c $k/floppy.c
i8259.s: $a
i8259.s: $k/i8259.c
$(CC) $(CFLAGS) -c $k/i8259.c
keyboard.s: $a
keyboard.s: $i/sgtty.h
keyboard.s: $i/signal.h
keyboard.s: $h/callnr.h
keyboard.s: $h/com.h
keyboard.s: $k/tty.h
keyboard.s: $k/keyboard.c
$(CC) $(CFLAGS) -c $k/keyboard.c
main.s: $a
main.s: $i/signal.h
main.s: $h/callnr.h
main.s: $h/com.h
main.s: $k/proc.h
main.s: $k/main.c
$(CC) $(CFLAGS) -c $k/main.c
memory.s: $a
memory.s: $h/callnr.h
memory.s: $h/com.h
memory.s: $k/memory.c
$(CC) $(CFLAGS) -c $k/memory.c
misc.s: $a
misc.s: $h/com.h
misc.s: $k/misc.c
$(CC) $(CFLAGS) -c $k/misc.c
printer.s: $a
printer.s: $h/callnr.h
printer.s: $h/com.h
printer.s: $k/printer.c
$(CC) $(CFLAGS) -c $k/printer.c
proc.s: $a
proc.s: $h/callnr.h
proc.s: $h/com.h
proc.s: $k/proc.h
proc.s: $k/proc.c
$(CC) $(CFLAGS) -c $k/proc.c
protect.s: $a
protect.s: $k/protect.h
protect.s: $k/protect1.c
protect.s: $k/protect.c
$(CC) $(CFLAGS) -c $k/protect.c
protect1.s: $a
protect1.s: $k/proc.h
protect1.s: $k/protect.h
protect1.s: $k/protect1.c
$(CC) $(CFLAGS) -c $k/protect1.c
rs232.s: $a
rs232.s: $i/sgtty.h
rs232.s: $k/tty.h
rs232.s: $k/rs232.c
$(CC) $(CFLAGS) -c $k/rs232.c
system.s: $a
system.s: $i/signal.h
system.s: $h/boot.h
system.s: $h/callnr.h
system.s: $h/com.h
system.s: $k/proc.h
system.s: $k/protect.h
system.s: $k/system.c
$(CC) $(CFLAGS) -c $k/system.c
table.s: $a
table.s: $h/com.h
table.s: $k/proc.h
table.s: $k/tty.h
table.s: $k/table.c
$(CC) $(CFLAGS) -c $k/table.c
tty.s: $a
tty.s: $i/sgtty.h
tty.s: $i/signal.h
tty.s: $h/callnr.h
tty.s: $h/com.h
tty.s: $k/tty.h
tty.s: $k/tty.c
$(CC) $(CFLAGS) -c $k/tty.c
wini.s: $a
wini.s: $h/callnr.h
wini.s: $h/com.h
wini.s: $h/partition.h
wini.s: $k/wini.c
$(CC) $(CFLAGS) -c $k/wini.c
amoeba.s: $a
amoeba.s: $i/amoeba.h
amoeba.s: $i/host_os.h
amoeba.s: $i/amparam.h
amoeba.s: $i/signal.h
amoeba.s: $i/assert.h
amoeba.s: ./byteorder.h
amoeba.s: ./dp8390info.h
amoeba.s: ./etherformat.h
amoeba.s: ./global.h
amoeba.s: ./internet.h
amoeba.s: ./mpx.H
amoeba.s: ./portcache.H
amoeba.s: $k/proc.h
amoeba.s: ./task.h
amoeba.s: ./trans.H
amoeba.s: amoeba.c
conf.s: $a
conf.s: $i/amoeba.h
conf.s: ./conf.h
conf.s: ./global.h
conf.s: ./mpx.H
conf.s: ./portcache.H
conf.s: ./task.h
conf.s: ./trans.H
conf.s: conf.c
dp8390.s: $a
dp8390.s: $h/com.h
dp8390.s: $i/assert.h
dp8390.s: ./dp8390.h
dp8390.s: ./dp8390info.h
dp8390.s: ./dp8390stat.h
dp8390.s: ./etherformat.h
dp8390.s: ./internet.h
dp8390.s: dp8390.c
etherplus.s: $a
etherplus.s: $h/com.h
etherplus.s: $i/assert.h
etherplus.s: ./dp8390.h
etherplus.s: ./dp8390info.h
etherplus.s: ./eplinfo.h
etherplus.s: ./etherformat.h
etherplus.s: ./etherplus.h
etherplus.s: ./internet.h
etherplus.s: etherplus.c
portcache.s: $a
portcache.s: $i/amoeba.h
portcache.s: $i/host_os.h
portcache.s: ./assert.h
portcache.s: ./conf.h
portcache.s: ./global.h
portcache.s: ./internet.h
portcache.s: ./mpx.H
portcache.s: ./portcache.H
portcache.s: ./task.h
portcache.s: ./trans.H
portcache.s: portcache.c
trans.s: $a
trans.s: $i/amoeba.h
trans.s: $i/host_os.h
trans.s: ./amstat.h
trans.s: ./assert.h
trans.s: ./byteorder.h
trans.s: ./exception.h
trans.s: ./global.h
trans.s: ./internet.h
trans.s: ./mpx.H
trans.s: ./portcache.H
trans.s: ./task.h
trans.s: ./trans.H
trans.s: trans.c
util.s: $a
util.s: $h/com.h
util.s: ./assert.h
util.s: ./dp8390.h
util.s: ./dp8390info.h
util.s: ./eplinfo.h
util.s: $k/proc.h
util.s: util.c

View File

@@ -0,0 +1,13 @@
struct amstat {
long ams_clfail;
long ams_svfail;
long ams_clcrash;
long ams_rxcl;
long ams_rxsv;
long ams_trans;
long ams_loctrans;
long ams_remtrans;
long ams_getreq;
long ams_putrep;
long ams_naks;
};

View File

@@ -0,0 +1,43 @@
/****************************************************************************
* *
* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands *
* *
* This product is part of the Amoeba distributed operating system. *
* Permission is hereby granted to use it exclusively for educational *
* and research purposes. It may also be freely duplicated and given *
* to others for educational and research purposes only. All other use *
* requires written permission from the copyright owner. *
* *
* Requests for such permissions may be sent to *
* *
* *
* Dr. Andrew S. Tanenbaum *
* Dept. of Mathematics and Computer Science *
* Vrije Universiteit *
* De Boelelaan 1081 *
* 1081 HV Amsterdam *
* The Netherlands *
* *
/****************************************************************************/
#define NDEBUG
#ifdef NDEBUG
#define assert(e) /* NOTHING */
#define compare(a,t,b) /* NOTHING */
#else
#ifdef lint
#define assert(e) use(e)
#define compare(a,t,b) use(a, b)
#else lint
#define assert(x) if (!(x)) printf("assertion failed in %s at %d\n", __FILE__, __LINE__)
#define compare(a,t,b) if (!((a) t (b))) \
printf("comparison failed in %s at %d (%D)\n", \
__FILE__, __LINE__, a)
/*
#define assert(e) do if (!(e)) badassertion(__FILE__,__LINE__); while (0)
#define compare(a,t,b) do if (!((a) t (b))) \
badcompare(__FILE__,__LINE__, (long) (a)); \
while (0)
*/
#endif lint
#endif NDEBUG

View File

@@ -0,0 +1,21 @@
/*
* set of macros to do inplace byteorder changes
* The dec_* routines decode a short (_s) or long (_l) from little endian(_le)
* or bigendian(_be) to native format.
* The enc_* are similar for native to net format
*/
/* littleendian version for ibm pc */
#define dec_s_le(s) /* nothing */
#define dec_s_be(s) (*(s))=((((*(s))>>8)&0xFF)|(((*(s))&0xFF)<<8))
#define dec_l_le(l) /* nothing */
#define dec_l_be(l) (*(l))=((((*(l))>>24)&0xFF)|(((*(l))>>8)&0xFF00)|(((*(l))<<8)&0xFF0000)|(((*(l))<<24)&0xFF000000))
#define enc_s_le(s) /* nothing */
#define enc_s_be(s) dec_s_be(s)
#define enc_l_le(l) /* nothing */
#define enc_l_be(l) dec_l_be(l)

View File

@@ -0,0 +1,40 @@
#include "kernel.h"
#include "amoeba.h"
#include "global.h"
#include "conf.h"
/*
** the following hack is imported from task.c under Amoeba to declare
** a few pointers to the task table
*/
#define extern
#include "task.h"
#undef extern
/************************************************************************/
/* TRANS CONFIGURATION */
/************************************************************************/
/*
** various variables used for transactions
*/
port NULLPORT; /* used in trans.c, declared here for compatability */
long ticker; /* bogus global used by trans.c for statistics */
#ifndef NONET
unshort minloccnt = MINLOCCNT;
unshort maxloccnt = MAXLOCCNT;
unshort retranstime = RETRANSTIME;
unshort crashtime = CRASHTIME;
unshort clientcrash = CLIENTCRASH;
unshort maxretrans = MAXRETRANS;
unshort mincrash = MINCRASH;
unshort maxcrash = MAXCRASH;
#endif NONET

View File

@@ -0,0 +1,15 @@
/*
** constants used for configuring amoeba transactions
*/
#define MINLOCCNT 5 /* locate message sent every dsec */
#define MAXLOCCNT 100 /* locate message sent every MAXLOCCNT dsec */
#define RETRANSTIME 5 /* retransmission time in dsec */
#define CRASHTIME 100 /* crash timer in dsec */
#define CLIENTCRASH 500 /* client must probe within this time */
#define MAXRETRANS 10 /* max. number of transmissions */
#define MINCRASH 5 /* enquiry sent MINCRASH times during recv */
#define MAXCRASH 10 /* enquiry sent MAXCRASH times during serv */
#define NPORTS 16 /* # ports in portcache */

View File

@@ -0,0 +1,344 @@
#include "kernel.h"
#ifndef NONET
#include "minix/com.h"
#include "internet.h"
#include "etherformat.h"
#include "dp8390.h"
#include "dp8390info.h"
#include "dp8390stat.h"
#include "assert.h"
/* macros for device I/O */
#define input(devaddr, dp_register) \
in_byte((vir_bytes)&((union dp8390reg *) devaddr)->dp_pg0rd.dp_register)
#define input1(devaddr, dp_register) \
in_byte((vir_bytes)&((union dp8390reg *) devaddr)->dp_pg1rdwr.dp_register)
#define output(devaddr, dp_register, value) \
out_byte((vir_bytes)&((union dp8390reg *) devaddr)->dp_pg0wr.dp_register, value)
#define output1(devaddr, dp_register, value) \
out_byte((vir_bytes)&((union dp8390reg *) devaddr)->dp_pg1rdwr.dp_register, value)
#define MAX_WAIT 10000
#ifdef DPSTAT
struct dpstat dpstat;
#endif
static int (*bufread)(); /* call when packet came in */
static int (*bufwritten)(); /* call when packet has been written */
static disabled;
static phys_bytes curopacket; /* packet being transmitted */
static phys_bytes Curbuff; /* address of next read buffer to release */
static
chipinit(myaddr)
Eth_addr *myaddr;
{
register vir_bytes device;
device = dp8390info.dpi_devaddr;
output(device, dp_cr, CR_PS_P0|CR_DM_ABORT); /* back to main register set */
output(device, dp_pstart, dp8390info.dpi_pstart);
output(device, dp_pstop, dp8390info.dpi_pstop);
output(device, dp_bnry, dp8390info.dpi_pstart);
output(device, dp_rcr, RCR_MON);
output(device, dp_tcr, TCR_NORMAL);
output(device, dp_dcr, DCR_BYTEWIDE|DCR_8BYTES);
output(device, dp_rbcr0, 0);
output(device, dp_rbcr1, 0);
output(device, dp_isr, 0xFF);
output(device, dp_cr, CR_PS_P1|CR_DM_ABORT); /* switch to register set 1 */
output1(device, dp_par0, myaddr->e[0]);
output1(device, dp_par1, myaddr->e[1]);
output1(device, dp_par2, myaddr->e[2]);
output1(device, dp_par3, myaddr->e[3]);
output1(device, dp_par4, myaddr->e[4]);
output1(device, dp_par5, myaddr->e[5]);
output1(device, dp_curr, dp8390info.dpi_pstart+1);
output1(device, dp_cr, CR_PS_P0|CR_DM_ABORT);
output(device, dp_rcr, RCR_AB);
input(device, dp_cntr0);
input(device, dp_cntr1);
input(device, dp_cntr2);
#ifdef TRMTINT
output(device, dp_imr, IMR_TXEE|IMR_PTXE|IMR_PRXE|IMR_CNTE|IMR_OVWE);
#endif
output(device, dp_imr, IMR_PRXE|IMR_CNTE|IMR_OVWE);
output(device, dp_cr, CR_STA|CR_DM_ABORT); /* fire it up */
}
/*
* Interrupt handling
*/
static
dp_xmit_intr()
#ifdef TRMTINT
{
register tsr;
if (curopacket == 0) {
printf("Bogus transmit interrupt\n");
STINC(ds_btint);
return;
}
tsr = input(dp8390info.dpi_devaddr, dp_tsr);
if (tsr&TSR_PTX)
STINC(ds_written); /* It went OK! */
if (tsr&TSR_DFR)
STINC(ds_deferred);
if (tsr&TSR_COL)
STINC(ds_collisions);
if (tsr&TSR_ABT)
STINC(ds_xcollisions);
if (tsr&TSR_CRS) {
printf("Ethernet carrier sense lost\n");
STINC(ds_carlost);
}
if (tsr&TSR_FU) {
printf("Ethernet Fifo Underrun\n");
STINC(ds_fifo);
}
if (tsr&TSR_CDH) {
printf("Ethernet Heartbeat failure\n");
STINC(ds_heartbeat);
}
if (tsr&TSR_OWC) {
printf("Ethernet late collision\n");
STINC(ds_lcol);
}
(*bufwritten)(curopacket);
curopacket = 0;
}
#else
{}
#endif
static
recvintr()
{
register vir_bytes device;
register phys_bytes paddr;
struct rcvdheader pkthead;
char pageno, curr, next;
int length;
device = dp8390info.dpi_devaddr;
pageno=input(device, dp_bnry)+1;
if (pageno == dp8390info.dpi_pstop)
pageno = dp8390info.dpi_pstart;
while (!(disabled)) {
output(device, dp_cr, CR_PS_P1);/* switch to register set 1 */
curr = input1(device, dp_curr);
output1(device, dp_cr, CR_PS_P0);/* back to main register set*/
if (pageno==curr){
break;
}
STINC(ds_read);
paddr = dp8390info.dpi_membase+(pageno<<8);
getheader(paddr, &pkthead);
next = pkthead.rp_next;
if (pkthead.rp_status&RSR_PRX) {
if (next < pageno && next > dp8390info.dpi_pstart) {
/*
* We copy end of packet to avoid break.
*/
phys_copy(dp8390info.dpi_membase+
(dp8390info.dpi_pstart<<8),
dp8390info.dpi_membase+
(dp8390info.dpi_pstop<<8),
(phys_bytes) (next-dp8390info.dpi_pstart)<<8);
}
length = (pkthead.rp_rbcl&0xFF)|(pkthead.rp_rbch<<8);
Curbuff = paddr + sizeof (pkthead);
disabled = 1;
(*bufread)(Curbuff, length-4);
}
pageno = pkthead.rp_next;
if (pageno >= dp8390info.dpi_pstop ||
pageno < dp8390info.dpi_pstart)
printf("page no %x\n", pageno);
/* assert(pageno >= dp8390info.dpi_pstart);
assert(pageno < dp8390info.dpi_pstop);*/
}
}
static
cntintr()
{
register vir_bytes device;
int n;
printf("dp8390: counter overflow\n"); /*DEBUG*/
device = dp8390info.dpi_devaddr;
n = input(device, dp_cntr0);
STADD(ds_fram, n);
n = input(device, dp_cntr1);
STADD(ds_crc, n);
n =input(device, dp_cntr2);
STADD(ds_lost, n);
}
PUBLIC void
dp8390_int()
{
register isr;
register vir_bytes device;
device = dp8390info.dpi_devaddr;
for(isr=input(device, dp_isr); isr&(ISR_OVW|ISR_PRX|ISR_PTX|ISR_CNT);
isr=input(device, dp_isr)) {
if (isr&ISR_OVW) {
printf("OVW, do something\n");
output(device, dp_isr, ISR_OVW); /* ack */
}
if (isr&ISR_PTX) {
dp_xmit_intr();
output(device, dp_isr, ISR_PTX); /* ack */
}
if (isr&ISR_TXE) {
dp_xmit_intr();
output(device, dp_isr, ISR_TXE); /* ack */
}
if (isr&ISR_PRX) {
/*recvintr();*/
got_packet();
output(device, dp_isr, ISR_PRX); /* ack */
}
if (isr&ISR_CNT) {
cntintr();
output(device, dp_isr, ISR_CNT); /* ack */
}
}
}
eth_init(etheraddr, br, bw)
Eth_addr *etheraddr;
int (*br)(), (*bw)();
{
bufread = br;
bufwritten = bw;
epl_init(); /* activate on board memory */
chipinit(etheraddr); /* start ethernet controller chip */
}
eth_write(bufaddr, bufcnt)
phys_bytes bufaddr;
{
int bpageno;
register vir_bytes device;
device = dp8390info.dpi_devaddr;
/* assert(curopacket==0); */
assert(((bufaddr-dp8390info.dpi_membase)&0xFF)==0);
assert(bufcnt >= 60); /* magic Ethernet requirement */
/* assert(bufcnt <= 1514); /* another one */
bpageno = ((bufaddr-dp8390info.dpi_membase)>>8) & 0xFF;
curopacket = bufaddr;
output(device, dp_tpsr, bpageno);
output(device, dp_tbcr1, bufcnt>>8);
output(device, dp_tbcr0, bufcnt&0xFF);
output(device, dp_cr, CR_TXP); /* there it goes */
}
eth_release(bufaddr)
phys_bytes bufaddr;
{
register vir_bytes device;
register phys_bytes paddr;
struct rcvdheader pkthead;
char pageno;
device = dp8390info.dpi_devaddr;
paddr = bufaddr-sizeof(pkthead);
assert(((paddr-dp8390info.dpi_membase)&0xFF)==0);
getheader(paddr, &pkthead);
pageno = pkthead.rp_next;
if (pageno == dp8390info.dpi_pstart)
pageno = dp8390info.dpi_pstop;
if (bufaddr != Curbuff)
panic("eth_release: bad order", NO_NUM);
output(device, dp_bnry, pageno-1);
disabled = 0;
/* recvintr(); */
}
phys_bytes
eth_getbuf()
{
int t_cnt;
register vir_bytes device;
register tsr;
device = dp8390info.dpi_devaddr;
t_cnt = 0;
while (input(device,dp_cr)&CR_TXP) {
if (t_cnt++ > MAX_WAIT)
printf("transmitter frozen\n");
return (phys_bytes)0;
}
#ifndef TRMTINT
#ifdef DPSTAT
tsr = input(device, dp_tsr);
if (tsr&TSR_PTX)
STINC(ds_written); /* It went OK! */
if (tsr&TSR_DFR)
STINC(ds_deferred);
if (tsr&TSR_COL)
STINC(ds_collisions);
if (tsr&TSR_ABT)
STINC(ds_xcollisions);
if (tsr&TSR_CRS) {
printf("Ethernet carrier sense lost\n");
STINC(ds_carlost);
}
if (tsr&TSR_FU) {
printf("Ethernet Fifo Underrun\n");
STINC(ds_fifo);
}
if (tsr&TSR_CDH) {
printf("Ethernet Heartbeat failure\n");
STINC(ds_heartbeat);
}
if (tsr&TSR_OWC) {
printf("Ethernet late collision\n");
STINC(ds_lcol);
}
#endif
#endif
return dp8390info.dpi_tbuf; /* return pointer to xmit buffer */
}
#else NONET
PUBLIC void
dp8390_int()
{
}
#endif NONET
PUBLIC void
eth_stp()
{
/* called from reboot() (klib88.s) to stop the ethernet */
#ifndef NONET
output(dp8390info.dpi_devaddr, dp_cr, CR_STP|CR_DM_ABORT);
#endif
}

View File

@@ -0,0 +1,165 @@
/*
* National Semiconductor DP8390 Network Interface Controller
*/
typedef
union dp8390reg {
struct pg0rd { /* Page 0, for reading ------------- */
char dp_cr; /* Read side of Command Register */
char dp_clda0; /* Current Local Dma Address 0 */
char dp_clda1; /* Current Local Dma Address 1 */
char dp_bnry; /* Boundary Pointer */
char dp_tsr; /* Transmit Status Register */
char dp_ncr; /* Number of Collisions Register */
char dp_fifo; /* Fifo ?? */
char dp_isr; /* Interrupt Status Register */
char dp_crda0; /* Current Remote Dma Address 0 */
char dp_crda1; /* Current Remote Dma Address 1 */
char dp_dum1; /* unused */
char dp_dum2; /* unused */
char dp_rsr; /* Receive Status Register */
char dp_cntr0; /* Tally Counter 0 */
char dp_cntr1; /* Tally Counter 1 */
char dp_cntr2; /* Tally Counter 2 */
} dp_pg0rd;
struct pg0wr { /* Page 0, for writing ------------- */
char dp_cr; /* Write side of Command Register */
char dp_pstart; /* Page Start Register */
char dp_pstop; /* Page Stop Register */
char dp_bnry; /* Boundary Pointer */
char dp_tpsr; /* Transmit Page Start Register */
char dp_tbcr0; /* Transmit Byte Count Register 0 */
char dp_tbcr1; /* Transmit Byte Count Register 1 */
char dp_isr; /* Interrupt Status Register */
char dp_rsar0; /* Remote Start Address Register 0 */
char dp_rsar1; /* Remote Start Address Register 1 */
char dp_rbcr0; /* Remote Byte Count Register 0 */
char dp_rbcr1; /* Remote Byte Count Register 1 */
char dp_rcr; /* Receive Configuration Register */
char dp_tcr; /* Transmit Configuration Register */
char dp_dcr; /* Data Configuration Register */
char dp_imr; /* Interrupt Mask Register */
} dp_pg0wr;
struct pg1rdwr { /* Page 1, read/write -------------- */
char dp_cr; /* Command Register */
char dp_par0; /* Physical Address Register 0 */
char dp_par1; /* Physical Address Register 1 */
char dp_par2; /* Physical Address Register 2 */
char dp_par3; /* Physical Address Register 3 */
char dp_par4; /* Physical Address Register 4 */
char dp_par5; /* Physical Address Register 5 */
char dp_curr; /* Current Page Register */
char dp_mar0; /* Multicast Address Register 0 */
char dp_mar1; /* Multicast Address Register 1 */
char dp_mar2; /* Multicast Address Register 2 */
char dp_mar3; /* Multicast Address Register 3 */
char dp_mar4; /* Multicast Address Register 4 */
char dp_mar5; /* Multicast Address Register 5 */
char dp_mar6; /* Multicast Address Register 6 */
char dp_mar7; /* Multicast Address Register 7 */
} dp_pg1rdwr;
} dp8390;
/* Bits in dp_cr */
#define CR_STP 0x01 /* Stop: software reset */
#define CR_STA 0x02 /* Start: activate NIC */
#define CR_TXP 0x04 /* Transmit Packet */
#define CR_DMA 0x38 /* Mask for DMA control */
# define CR_DM_NOP 0x00 /* DMA: No Operation */
# define CR_DM_RR 0x08 /* DMA: Remote Read */
# define CR_DM_RW 0x10 /* DMA: Remote Write */
# define CR_DM_SP 0x18 /* DMA: Send Packet */
# define CR_DM_ABORT 0x20 /* DMA: Abort Remote DMA Operation */
#define CR_PS 0xC0 /* Mask for Page Select */
# define CR_PS_P0 0x00 /* Register Page 0 */
# define CR_PS_P1 0x40 /* Register Page 1 */
# define CR_PS_T0 0x80 /* Test Mode Register Map ?? */
# define CR_SP_T1 0xC0 /* Test Mode Register Map ?? */
/* Bits in dp_isr */
#define ISR_PRX 0x01 /* Packet Received with no errors */
#define ISR_PTX 0x02 /* Packet Transmitted with no errors */
#define ISR_RXE 0x04 /* Receive Error */
#define ISR_TXE 0x08 /* Transmit Error */
#define ISR_OVW 0x10 /* Overwrite Warning */
#define ISR_CNT 0x20 /* Counter Overflow */
#define ISR_RDC 0x40 /* Remote DMA Complete */
#define ISR_RST 0x80 /* Reset Status */
/* Bits in dp_imr */
#define IMR_PRXE 0x01 /* Packet Received iEnable */
#define IMR_PTXE 0x02 /* Packet Transmitted iEnable */
#define IMR_RXEE 0x04 /* Receive Error iEnable */
#define IMR_TXEE 0x08 /* Transmit Error iEnable */
#define IMR_OVWE 0x10 /* Overwrite Warning iEnable */
#define IMR_CNTE 0x20 /* Counter Overflow iEnable */
#define IMR_RDCE 0x40 /* DMA Complete iEnable */
/* Bits in dp_dcr */
#define DCR_WTS 0x01 /* Word Transfer Select */
# define DCR_BYTEWIDE 0x00 /* WTS: byte wide transfers */
# define DCR_WORDWIDE 0x01 /* WTS: word wide transfers */
#define DCR_BOS 0x02 /* Byte Order Select */
# define DCR_LTLENDIAN 0x00 /* BOS: Little Endian */
# define DCR_BIGENDIAN 0x02 /* BOS: Big Endian */
#define DCR_LAS 0x04 /* Long Address Select */
#define DCR_BMS 0x08 /* Burst Mode Select */
#define DCR_AR 0x10 /* Autoinitialize Remote */
#define DCR_FTS 0x60 /* Fifo Threshold Select */
# define DCR_2BYTES 0x00 /* 2 bytes */
# define DCR_4BYTES 0x40 /* 4 bytes */
# define DCR_8BYTES 0x20 /* 8 bytes */
# define DCR_12BYTES 0x60 /* 12 bytes */
/* Bits in dp_tcr */
#define TCR_CRC 0x01 /* Inhibit CRC */
#define TCR_ELC 0x06 /* Encoded Loopback Control */
# define TCR_NORMAL 0x00 /* ELC: Normal Operation */
# define TCR_INTERNAL 0x02 /* ELC: Internal Loopback */
# define TCR_0EXTERNAL 0x04 /* ELC: External Loopback LPBK=0 */
# define TCR_1EXTERNAL 0x06 /* ELC: External Loopback LPBK=1 */
#define TCR_ATD 0x08 /* Auto Transmit */
#define TCR_OFST 0x10 /* Collision Offset Enable (be nice) */
/* Bits in dp_tsr */
#define TSR_PTX 0x01 /* Packet Transmitted (without error)*/
#define TSR_DFR 0x02 /* Transmit Deferred */
#define TSR_COL 0x04 /* Transmit Collided */
#define TSR_ABT 0x08 /* Transmit Aborted */
#define TSR_CRS 0x10 /* Carrier Sense Lost */
#define TSR_FU 0x20 /* Fifo Underrun */
#define TSR_CDH 0x40 /* CD Heartbeat */
#define TSR_OWC 0x80 /* Out of Window Collision */
/* Bits in tp_rcr */
#define RCR_SEP 0x01 /* Save Errored Packets */
#define RCR_AR 0x02 /* Accept Runt Packets */
#define RCR_AB 0x04 /* Accept Broadcast */
#define RCR_AM 0x08 /* Accept Multicast */
#define RCR_PRO 0x10 /* Physical Promiscuous */
#define RCR_MON 0x20 /* Monitor Mode */
/* Bits in dp_rsr */
#define RSR_PRX 0x01 /* Packet Received Intact */
#define RSR_CRC 0x02 /* CRC Error */
#define RSR_FAE 0x04 /* Frame Alignment Error */
#define RSR_FO 0x08 /* FIFO Overrun */
#define RSR_MPA 0x10 /* Missed Packet */
#define RSR_PHY 0x20 /* Multicast Address Match !! */
#define RSR_DIS 0x40 /* Receiver Disabled */
struct rcvdheader {
char rp_status; /* Copy of rsr */
char rp_next; /* Pointer to next packet */
char rp_rbcl; /* Receive Byte Count Low */
char rp_rbch; /* Receive Byte Count High */
};

View File

@@ -0,0 +1,14 @@
/*
* parameters for driver for
* National Semiconductor DP8390 Network Interface Controller
*/
extern
struct dp8390info {
vir_bytes dpi_devaddr; /* device address */
char dpi_pstart; /* start of recv ring */
char dpi_pstop; /* end of recv ring */
phys_bytes dpi_membase; /* memory address of page 0 */
phys_bytes dpi_tbuf; /* memory address of transmit buffer */
} dp8390info;

View File

@@ -0,0 +1,23 @@
#ifdef DPSTAT
/* statistics from dp8390 */
struct dpstat {
long ds_read; /* packets read */
long ds_written; /* packets written */
long ds_fram; /* Input framing errors */
long ds_crc; /* Input CRC errors */
long ds_lost; /* Packets lost */
long ds_btint; /* Bogus transmit interrupts */
long ds_deferred; /* Deferred packets */
long ds_collisions; /* Packets collided at least once */
long ds_xcollisions; /* Aborts due to excessive collisions */
long ds_carlost; /* Carrier sense lost */
long ds_fifo; /* Fifo underrun */
long ds_heartbeat; /* Heart beat failure */
long ds_lcol; /* Late collisions */
};
#define STINC(x) dpstat.x++
#define STADD(x,y) dpstat.x += y
#else
#define STINC(x) /* nothing */
#define STADD(x,y) /* nothing */
#endif DPSTAT

View File

@@ -0,0 +1,10 @@
/*
* parameters for initialisation of
* Western Digital Ethercard Plus, or WD8003E
*/
extern
struct eplinfo {
vir_bytes epi_devaddr; /* device address */
} eplinfo;

View File

@@ -0,0 +1,24 @@
/* Format of packets on the Ethernet */
#define AMOEBAPROTO 0x8145 /* Official Ethernet protocol number */
#define ALTAMOEBAPROTO 2222 /* Old Amoeba protocol number */
#define ETHERBITS 0x80 /* These addresses on Ethernet */
typedef struct
{
char e[6];
} Eth_addr;
typedef struct
{
Eth_addr f_dstaddr;
Eth_addr f_srcaddr;
unshort f_proto;
struct pktheader f_ah;
} Framehdr;
typedef struct
{
Framehdr ep_fr;
char ep_data[1490];
} Etherpacket;

View File

@@ -0,0 +1,50 @@
#include "kernel.h"
#include "minix/com.h"
#include "dp8390.h"
#include "internet.h"
#include "etherformat.h"
#include "etherplus.h"
#include "dp8390info.h"
#include "eplinfo.h"
#include "assert.h"
/* macros for device I/O */
#define input(devaddr, ep_register) \
in_byte((vir_bytes)&((struct eplusreg *) devaddr)->ep_register)
#define output(devaddr, ep_register, value) \
out_byte((vir_bytes)&((struct eplusreg *) devaddr)->ep_register, value)
epl_init() {
register vir_bytes device;
register sum;
device = eplinfo.epi_devaddr;
assert((dp8390info.dpi_membase&0x81FFF)==0x80000);
sum =
input(device, epl_ea5) +
input(device, epl_ea4) +
input(device, epl_ea3) +
input(device, epl_ea2) +
input(device, epl_ea1) +
input(device, epl_ea0) +
input(device, epl_res2) +
input(device, epl_chksum);
if ((sum&0xFF) != 0xFF)
panic("No ethernet board", NO_NUM);
output(device, epl_ctlstatus, CTL_RESET);
output(device, epl_ctlstatus, CTL_MENABLE|((dp8390info.dpi_membase>>13)&CTL_MEMADDR));
}
etheraddr(eaddr) Eth_addr *eaddr; {
register vir_bytes device;
device = eplinfo.epi_devaddr;
eaddr->e[0] = input(device, epl_ea0);
eaddr->e[1] = input(device, epl_ea1);
eaddr->e[2] = input(device, epl_ea2);
eaddr->e[3] = input(device, epl_ea3);
eaddr->e[4] = input(device, epl_ea4);
eaddr->e[5] = input(device, epl_ea5);
}

View File

@@ -0,0 +1,27 @@
/*
* Western Digital Ethercard Plus, or WD8003E card
*
* This information seems to be guarded like the crown jewels
*/
struct eplusreg {
char epl_ctlstatus; /* Control(write) and status(read) */
char epl_res1[7];
char epl_ea0; /* Most significant eaddr byte */
char epl_ea1;
char epl_ea2;
char epl_ea3;
char epl_ea4;
char epl_ea5; /* Least significant eaddr byte */
char epl_res2;
char epl_chksum; /* sum from epl_ea0 upto here is 0xFF */
dp8390 epl_dp8390; /* NatSemi chip */
};
/* Bits in epl_ctlstatus */
#define CTL_RESET 0x80 /* Software Reset */
#define CTL_MENABLE 0x40 /* Memory Enable */
#define CTL_MEMADDR 0x3F /* Bits SA18-SA13, SA19 implicit 1 */
#define STA_IIJ 0x7 /* Interrupt Indication Jumpers */

View File

@@ -0,0 +1 @@
#define CRASH ((unshort) 0xFF)

View File

@@ -0,0 +1,44 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
#define KERNEL 0
#define USER 1
typedef unshort address;
typedef int func;
#define bufptr vir_bytes
#define NOWHERE ((address) 0)
#define SOMEWHERE ((address) -1)
#define NILVECTOR ((func (*)()) 0)
#ifdef lint
#define ABSPTR(t, c) (use(c), (t) 0)
#else
#define ABSPTR(t, c) ((t) (c))
#endif
#define bit(b) (1 << (b)) /* simulate type 'bit' */
#define lobyte(x) ((unshort) (x) & 0xFF)
#define hibyte(x) ((unshort) (x) >> 8)
#define concat(x, y) ((unshort) (x) << 8 | (unshort) (y) & 0xFF)
#define sizeoftable(t) (sizeof(t) / sizeof((t)[0]))

View File

@@ -0,0 +1,63 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
#define PACKETSIZE 1490 /* network packet size - sizeof(framehdr) */
#define BROADCAST ((address) 0xFF)
#define TYPE 0x0F /* message types */
#define LOCATE 0x01
#define HERE 0x02
#define REQUEST 0x03
#define REPLY 0x04
#define ACK 0x05
#define NAK 0x06
#define ENQUIRY 0x07
#define ALIVE 0x08
#define DEAD 0x09
#define LAST 0x10 /* flags */
#define RETRANS 0x20
struct pktheader {
char ph_dstnode; /* 0: destination node */
char ph_srcnode; /* 1: source node */
char ph_dsttask; /* 2: destination task */
char ph_srctask; /* 3: source task */
char ph_ident; /* 4: transaction identifier */
char ph_seq; /* 5: fragment no. */
unshort ph_size; /* 6: total size of this packet */
char ph_flags; /* 8: some flags (not used) */
char ph_type; /* 9: locate, here, data, ack or nak (!= 0) */
};
#define ph_signal ph_seq
#define NOSEND 0
#define SEND 1
#define DONTKNOW 0
#define LOCAL 1
#define GLOBAL 2
#define siteaddr(x) lobyte(x)
#define tasknum(x) hibyte(x)
#define pktfrom(ph) ((unshort) (ph->ph_srctask<<8 | ph->ph_srcnode & 0xFF))
#define pktto(ph) ((unshort) (ph->ph_dsttask<<8 | ph->ph_dstnode & 0xFF))

View File

@@ -0,0 +1,43 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
struct mpx {
short MX_active; /* is a transaction in progress */
unshort MX_flags; /* flags - see below */
int MX_proc_nr; /* task identifier */
header MX_hdr; /* storage space for header */
} tk_mpx;
#ifdef MPX
#define mx_flags tk_mpx.MX_flags
#define mx_active tk_mpx.MX_active
#define mx_proc_nr tk_mpx.MX_proc_nr
#define mx_hdr tk_mpx.MX_hdr
/* bits in flags: */
#define RUNNABLE bit(0) /* task is runnable */
#define NESTED bit(1) /* nested getreq, trans or putrep */
#define BETWEEN bit(2) /* between getreq and putrep */
#else
#define tk_mpx tk_dummy /* other modules must not touch it */
#endif

View File

@@ -0,0 +1,40 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
struct portcache {
address PE_location;
struct task *PE_link;
} tk_portcache;
#ifdef PORTCACHE
#define pe_location tk_portcache.PE_location
#define pe_link tk_portcache.PE_link
#else
#define tk_portcache tk_dummy /* other modules must not touch it */
#endif
#define NOWAIT 0
#define WAIT 1
#define LOOK 0
#define DELETE 1

View File

@@ -0,0 +1,492 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
#define NDEBUG
#define PORTCACHE
/*
* This module does the port management. It keeps track of the local servers
* doing a ``getreq'' on a port, local clients waiting for a server on some
* port, and interlocal servers addressed by some port. This last category of
* ports may be forgotten, or may be incorrect.
*
* The following routines are defined:
* portinstall(port, where, wait);
* portlookup(port, wait, delete);
* portremove(port, location);
* portquit(port, task);
*
* ``Portinstall'' is called when a port is assumed to be at location
* ``where.'' If ``wait'' is set, the port is local.
* ``Portlookup'' is called to find a port in the cache. If ``wait'' is
* set, the routine will block until the port is found. If ``delete'' is
* set, the port must be removed when it is found.
* ``Portremove'' removes a port from the cache which is thought
* of to be at the specified location.
* When a port doesn't have to be located anymore for some task, ``portquit''
* takes care of that.
*/
#include "kernel.h"
#include "amoeba.h"
#include "global.h"
#include "task.h"
#include "internet.h"
#include "assert.h"
extern struct task task[];
#ifdef STATISTICS
#include "portstat.h"
struct portstat portstat;
#define STINC(x) portstat.x++
#else
#define STINC(x)
#endif
#include "conf.h"
#define LOGHASH 5 /* log sizeof hash table of local ports */
struct porttab {
port p_port; /* the port this entry is about */
unshort p_idle; /* idle timer */
address p_location; /* where is it? (0 = being located) */
address p_asker; /* address of someone interested */
struct porttab *p_nextport; /* port with same hash value */
struct task *p_tasklist; /* list of tasks */
};
#define NILPORTTAB ((struct porttab *) 0)
#define NHASH (1 << LOGHASH)
#define HASHMASK (NHASH - 1)
#define hash(p) (* (unshort *) (p) & HASHMASK)
/* MINIX can't allocate memory in the kernel at run-time
extern unshort nport;
PRIVATE struct porttab *porttab, *lastport, *hashtab[NHASH], *portfree;
*/
PRIVATE struct porttab porttab[NPORTS];
PRIVATE struct porttab *lastport, *hashtab[NHASH], *portfree;
#ifndef NONET
#ifndef NOCLIENT
#define NLOCATE 8 /* max. number of ports to locate */
PRIVATE port loctab[NLOCATE];
PRIVATE unshort loccnt, loctim, locthissweep;
extern unshort minloccnt, maxloccnt;
#endif
#endif
/* Allocate an entry in the hash table at location ``ht.'' */
static struct porttab *allocate(ht, p)
struct porttab **ht;
port *p;
{
register struct porttab *pt;
STINC(pts_alloc);
if ((pt=portfree) == 0) {
STINC(pts_full);
portpurge(); /* total cleanup, not likely to happen */
if ((pt=portfree) == 0)
return 0;
}
portfree = pt->p_nextport;
pt->p_nextport = *ht;
*ht = pt;
pt->p_port = *p;
return pt;
}
/* Install a port in the hash table. If ``wait'' is set, the location will
* be this machine and is certain. If not, the location is somewhere else
* and uncertain.
*/
portinstall(p, where, wait)
register port *p;
address where;
{
register struct porttab **ht, *pt;
register struct task *t;
extern address local;
ht = &hashtab[hash(p)];
for (pt = *ht; pt != NILPORTTAB; pt = pt->p_nextport)
if (PortCmp(&pt->p_port, p)) {
if (pt->p_location == SOMEWHERE) {
compare(pt->p_tasklist, !=, NILTASK);
do {
t = pt->p_tasklist;
t->pe_location = where;
STINC(pts_wakeup);
wakeup((event_t) &t->pe_location);
} while ((pt->p_tasklist = t->pe_link) != NILTASK);
}
#ifndef NOCLIENT
else if (siteaddr(pt->p_location) == local && !wait &&
pt->p_tasklist != 0)
return;
#endif
break;
}
if (pt == NILPORTTAB && (pt = allocate(ht, p)) == NILPORTTAB)
#ifndef NOCLIENT
if (wait)
#endif
panic("portcache full for servers", 0x8000);
#ifndef NOCLIENT
else /* no room left, so forget it */
return;
#endif
pt->p_location = where;
#ifndef NOCLIENT
if (wait) { /* task is going to await a client, so leave it immortal */
#endif
compare(area(where), ==, LOCAL);
t = &task[tasknum(where)];
t->pe_location = where;
t->pe_link = pt->p_tasklist;
pt->p_tasklist = t;
#ifndef NONET
if (pt->p_asker != NOWHERE) {
STINC(pts_here);
hereport(pt->p_asker, p, (unsigned )1);
pt->p_asker = NOWHERE;
}
#endif
#ifndef NOCLIENT
}
#endif
pt->p_idle = 0;
}
#ifndef NONET
#ifndef NOCLIENT
/* Broadcast a locate message
*/
static sendloc(){
register struct porttab *pt;
register unsigned n = 0;
if (locthissweep) {
/* During this clocktick we already sent out a broadcast packet.
* To prevent buggy userprograms from creating a broadcast storm
* we do not send another one, we just prepare for it to be done
*/
STINC(pts_nolocate);
loccnt = maxloccnt;
return;
}
for (pt = porttab; pt < lastport; pt++)
if (pt->p_location == SOMEWHERE) {
loctab[n++] = pt->p_port;
if (n == NLOCATE)
break;
}
if (n) {
locthissweep = 1;
whereport(loctab, n); /* send out the broadcast locate */
} else
loctim = 0; /* No locates necessary anymore */
loccnt = 0;
}
#endif NOCLIENT
#endif NONET
/* Look whether port p is in the portcache. You can specify whether you
* want to wait for the information and whether you want to delete it.
*/
address portlookup(p, wait, del)
register port *p;
{
register struct porttab **ht, *pt;
register struct task *c, *t;
register address location;
STINC(pts_lookup);
ht = &hashtab[hash(p)];
for (pt = *ht; pt != NILPORTTAB; pt = pt->p_nextport)
if (PortCmp(&pt->p_port, p)) { /* found it */
location = pt->p_location;
switch (area(location)) {
case LOCAL: /* local server */
if (pt->p_tasklist == 0)
break;
if (del) { /* remove it */
pt->p_tasklist = pt->p_tasklist->pe_link;
if ((t = pt->p_tasklist) != NILTASK)
pt->p_location = t->pe_location;
}
pt->p_idle = 0;
STINC(pts_flocal);
return(location);
case GLOBAL: /* remote server */
compare(pt->p_tasklist, ==, NILTASK);
pt->p_idle = 0;
STINC(pts_fglobal);
return(location);
case DONTKNOW: /* somebody else wants to know too */
compare(pt->p_tasklist, !=, NILTASK);
break;
default:
assert(0);
}
break;
}
/* The port wasn't in the port cache */
#ifndef NOCLIENT
if (wait) { /* wait for it */
if (pt == NILPORTTAB && (pt = allocate(ht, p)) == NILPORTTAB)
panic("portcache full for clients", 0x8000);
pt->p_location = SOMEWHERE;
c = curtask;
c->pe_link = pt->p_tasklist;
pt->p_tasklist = c;
#ifndef NONET
STINC(pts_locate);
sendloc();
loctim = minloccnt;
#endif
c->pe_location = SOMEWHERE;
if (sleep((event_t) &c->pe_location))
assert(pt->p_tasklist != c);
pt->p_idle = 0;
return(c->pe_location);
}
else
#endif NOCLIENT
return(NOWHERE);
}
/* Port p isn't at location ``location'' anymore */
portremove(p, location)
port *p;
address location;
{
register struct porttab *pt, **ht;
register struct task *t;
for (ht = &hashtab[hash(p)]; (pt= *ht) != NILPORTTAB; ht = &pt->p_nextport)
if (PortCmp(&pt->p_port, p)) {
if (pt->p_location == location) {
if ((t = pt->p_tasklist) != NILTASK) {
compare(area(location), ==, LOCAL);
compare(t->pe_location, ==, location);
if ((pt->p_tasklist = t->pe_link) != NILTASK) {
pt->p_location =
pt->p_tasklist->pe_location;
break;
}
} else {
*ht = pt->p_nextport;
pt->p_location = NOWHERE; /* for dump */
pt->p_nextport = portfree;
portfree = pt;
}
}
else if ((t = pt->p_tasklist) != NILTASK)
while (t->pe_link != NILTASK)
if (t->pe_link->pe_location == location) {
t->pe_link = t->pe_link->pe_link;
break;
}
else
t = t->pe_link;
return;
}
}
#ifndef NOCLIENT
/* Task ``s'' isn't interested anymore */
portquit(p, s)
register port *p;
register struct task *s;
{
register struct porttab *pt, **ht;
register struct task *t;
for (ht = &hashtab[hash(p)]; (pt= *ht) != NILPORTTAB; ht = &pt->p_nextport)
if (PortCmp(&pt->p_port, p)) {
if (pt->p_location != SOMEWHERE)
return;
if ((t = pt->p_tasklist) == s) {
if ((pt->p_tasklist = s->pe_link) == NILTASK) {
*ht = pt->p_nextport;
pt->p_location = NOWHERE; /* for dump */
pt->p_nextport = portfree;
portfree = pt;
}
s->pe_location = NOWHERE;
wakeup((event_t) &s->pe_location);
}
else {
while (t != NILTASK)
if (t->pe_link == s) {
t->pe_link = s->pe_link;
s->pe_location = NOWHERE;
wakeup((event_t) &s->pe_location);
break;
}
else
t = t->pe_link;
}
return;
}
}
#endif NOCLIENT
#ifndef NONET
#define NHERE 8
PRIVATE port heretab[NHERE];
portask(asker, ptab, nports) /* handle locate request */
address asker;
register port *ptab;
unsigned nports;
{
register port *p,*q;
register struct porttab **ht, *pt;
register unsigned nfound;
STINC(pts_portask);
nfound = 0; q = heretab;
for(p=ptab; nports--; p++) {
ht = &hashtab[hash(p)];
for (pt = *ht; pt != NILPORTTAB; pt = pt->p_nextport)
if (PortCmp(&pt->p_port, p)) { /* found it */
if (area(pt->p_location) == LOCAL) {
if (pt->p_tasklist == 0) {
/* just record someone was interested */
pt->p_asker = asker;
break;
}
if (nfound < NHERE) {
*q++ = *p;
nfound++;
}
pt->p_idle = 0;
}
}
}
if (nfound) {
STINC(pts_portyes);
hereport(asker, heretab, nfound);
}
}
#endif
#ifndef NDEBUG
portdump(){
register struct porttab *pt;
register struct task *t;
printf("\n PORT LOCATION IDLE TASKS\n");
for (pt = porttab; pt < lastport; pt++)
if (pt->p_location != NOWHERE) {
prport(&pt->p_port);
printf(" %4x %4d", pt->p_location, pt->p_idle);
for (t = pt->p_tasklist; t != NILTASK; t = t->pe_link)
printf(" {%d, %x}", t - task, t->pe_location);
printf("\n");
}
}
#endif
/* Initialize tables and free list */
portinit(){
register struct porttab *pt;
/* MINIX can't allocate data in the kernel at run-time
extern char *aalloc();
porttab = (struct porttab *) aalloc(nport * sizeof(struct porttab), 0);
lastport = &porttab[nport];
*/
lastport = &porttab[NPORTS];
for (pt = porttab; pt < lastport; pt++) {
pt->p_nextport = portfree;
portfree = pt;
}
}
/* called when freelist was empty, will throw away all mortal ports */
portpurge() {
register struct porttab *pt,**ht,**htp;
for (htp=hashtab; htp< &hashtab[NHASH]; htp++) {
ht = htp;
while ((pt = *ht) != 0) {
if (pt->p_tasklist == 0){
*ht = pt->p_nextport;
pt->p_location = NOWHERE; /* for dump */
pt->p_nextport = portfree;
portfree = pt;
} else
ht = &pt->p_nextport;
}
}
}
#define MAXSWEEP 3000 /* dseconds maximum idle time for port */
#define SWEEPRESOLUTION 100 /* accuracy */
portsweep() {
register struct porttab *pt,**ht,**htp;
static unshort cnt;
#ifndef NOCLIENT
#ifndef NONET
locthissweep = 0;
if (loctim && ++loccnt > loctim) { /* send a locate message */
STINC(pts_relocate);
sendloc();
loctim <<= 1;
if (loctim > maxloccnt)
loctim = maxloccnt;
locthissweep = 0;
}
#endif NONET
#endif
if (++cnt<SWEEPRESOLUTION)
return;
for (htp=hashtab; htp< &hashtab[NHASH]; htp++) {
ht = htp;
while ((pt = *ht) != 0) {
if (pt->p_tasklist == 0 && (pt->p_idle += cnt) > MAXSWEEP) {
*ht = pt->p_nextport;
pt->p_location = NOWHERE; /* for dump */
pt->p_nextport = portfree;
portfree = pt;
STINC(pts_aged);
} else
ht = &pt->p_nextport;
}
}
cnt=0;
}

View File

@@ -0,0 +1,15 @@
struct portstat {
long pts_alloc;
long pts_aged;
long pts_full;
long pts_wakeup;
long pts_here;
long pts_lookup;
long pts_flocal;
long pts_fglobal;
long pts_portask;
long pts_portyes;
long pts_locate;
long pts_nolocate;
long pts_relocate;
};

View File

@@ -0,0 +1,40 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
#ifdef BUFFERED /* HACK */
#define BUFSIZE 100
#define NETBUF ((buffer) -1)
typedef unshort buffer;
#endif
struct task {
#include "mpx.H" /* mpx module */
#include "trans.H" /* trans module */
#include "portcache.H" /* portcache module */
char *tk_aux; /* auxiliary pointer */
/* really a hack to make process task more efficient */
};
extern struct task *curtask, *uppertask;
extern unshort ntask;
#define NILTASK ((struct task *) 0)

View File

@@ -0,0 +1,110 @@
/****************************************************************************/
/* */
/* (c) Copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands */
/* */
/* This product is part of the Amoeba distributed operating system. */
/* */
/* Permission to use, sell, duplicate or disclose this software must be */
/* obtained in writing. Requests for such permissions may be sent to */
/* */
/* */
/* Dr. Andrew S. Tanenbaum */
/* Dept. of Mathematics and Computer Science */
/* Vrije Universiteit */
/* Postbus 7161 */
/* 1007 MC Amsterdam */
/* The Netherlands */
/* */
/****************************************************************************/
struct trans {
char TS_state; /* see below */
char TS_flags; /* several flags - see below */
char TS_clident; /* ident number for client */
char TS_svident; /* ident number for server */
char TS_ident; /* transaction identifier */
char TS_seq; /* fragment sequence number */
char TS_count; /* max. number timer may expire */
char TS_signal; /* signal being sent to the server */
unshort TS_addr; /* network address of this task */
unshort TS_timer; /* timer, decremented every sweep */
unshort TS_cltim; /* client crash timer */
address TS_client; /* if serving: who's the client */
address TS_server; /* if in trans: who's the server */
port TS_portcache; /* this port was used the last time */
header *TS_rhdr; /* saved param in getreq or trans */
header *TS_xhdr; /* saved param in putrep or trans */
bufptr TS_rbuf; /* receiver buffer */
bufptr TS_xbuf; /* transmitter buffer */
unshort TS_rcnt; /* size of rbuf */
unshort TS_xcnt; /* size of xbuf */
unshort TS_offset; /* offset in buffer */
unshort TS_maxloc; /* max. location time in seconds */
long TS_totloc; /* total location time in ticks */
long TS_totsvr; /* total server time in ticks */
#ifdef BUFFERED
address TS_sender; /* task that sent the buffer */
char *TS_savehdr; /* saved header pointer */
buffer TS_buffer; /* buffer */
unshort TS_bufcnt; /* buffer size */
unshort TS_what; /* REQUEST or REPLY */
#endif
} tk_trans;
#ifdef TRANS
#define ts_state tk_trans.TS_state
#define ts_flags tk_trans.TS_flags
#define ts_clident tk_trans.TS_clident
#define ts_svident tk_trans.TS_svident
#define ts_ident tk_trans.TS_ident
#define ts_seq tk_trans.TS_seq
#define ts_timer tk_trans.TS_timer
#define ts_count tk_trans.TS_count
#define ts_signal tk_trans.TS_signal
#define ts_addr tk_trans.TS_addr
#define ts_cltim tk_trans.TS_cltim
#define ts_client tk_trans.TS_client
#define ts_server tk_trans.TS_server
#define ts_portcache tk_trans.TS_portcache
#define ts_rhdr tk_trans.TS_rhdr
#define ts_xhdr tk_trans.TS_xhdr
#define ts_rbuf tk_trans.TS_rbuf
#define ts_xbuf tk_trans.TS_xbuf
#define ts_rcnt tk_trans.TS_rcnt
#define ts_xcnt tk_trans.TS_xcnt
#define ts_offset tk_trans.TS_offset
#define ts_maxloc tk_trans.TS_maxloc
#define ts_totloc tk_trans.TS_totloc
#define ts_totsvr tk_trans.TS_totsvr
#define ts_sender tk_trans.TS_sender
#define ts_savehdr tk_trans.TS_savehdr
#define ts_buffer tk_trans.TS_buffer
#define ts_bufcnt tk_trans.TS_bufcnt
#define ts_what tk_trans.TS_what
/* possible values of ts_state */
#define IDLE 0
#define SENDING 1
#define DONE 2
#define ACKED 3
#define NACKED 4
#define FAILED 5
#define WAITBUF 6
#define RECEIVING 7
#define ABORT 8
#define MEMFAULT 9
/* possible flags in ts_flags */
#define LOCATING bit(0) /* blocked in trans locating a port */
#define PUTREQ bit(1) /* blocked in trans sending a request */
#define GETREQ bit(2) /* blocked in getreq */
#define PUTREP bit(3) /* blocked in putrep */
#define GETREP bit(4) /* blocked in trans getting a reply */
#define SERVING bit(5) /* running between getreq and putrep */
#else
#define tk_trans tk_dummy /* other modules must not touch it */
#endif

View File

@@ -0,0 +1,50 @@
#include "kernel.h"
#include "minix/com.h"
#include "proc.h"
#include "dp8390.h"
#include "assert.h"
#include "dp8390info.h"
#include "eplinfo.h"
struct eplinfo eplinfo = {0x280};
struct dp8390info dp8390info = {0x290, 6, 27, EPLUS_BASE, EPLUS_BASE};
extern vir_bytes eplus_seg;
#if !NONET
getheader(paddr, pkthead)
phys_bytes paddr;
struct rcvdheader *pkthead;
{
vir_bytes offset;
char get_byte();
offset = (paddr - EPLUS_BASE)&0xFFFF;
pkthead->rp_status = get_byte(eplus_seg, offset);
pkthead->rp_next = get_byte(eplus_seg, offset+1);
pkthead->rp_rbcl = get_byte(eplus_seg, offset+2);
pkthead->rp_rbch = get_byte(eplus_seg, offset+3);
}
short
getbint(paddr)
phys_bytes paddr;
{
vir_bytes offset;
short t;
offset = (paddr - EPLUS_BASE)&0xFFFF;
return (((short)get_byte(eplus_seg, offset) & 0xFF)<<8) +
((short)get_byte(eplus_seg, offset+1) & 0xFF);
}
#endif