boots, presents shell prompt, and doesn't crash immediately

This commit is contained in:
glass 1994-02-23 08:28:11 +00:00
parent e082e0b31d
commit 8461eac15e
46 changed files with 5245 additions and 208 deletions

View File

@ -1,12 +1,13 @@
<$Revision: 1.7 $>
<$Revision: 1.8 $>
This is to be a summary of the status of code, its problems,
and the directions it should and take in the future.
and the direction it should take in the future.
Summary: Execs SunOS /sbin/init. executes system calls but when it forks, the
new process segfaults immediately. Possibly some bug in
softclock() processing, as scheduling may be muffed.
All this via nfs_diskless since there is no scsi driver.
Summary: Boots via nfsdiskless (due to lack of a scsi driver),
execs /sbin/init (MID_M68K), and because single-user is forced,
provides a /bin/sh. It works, though the console driver is flakey
and there are a bunch of vm/pmap assertions that should be
investigated
nfs_diskless structure is hardwired :)

View File

@ -1,4 +1,116 @@
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.2 $>
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.3 $>
This is a list of things that need to be done for NetBSD/Sun3. Some
of these tasks are small, others are large. Some are extremely
critical, others would be useful to do, and some are fluff. Included
in each description, is a notation of its importance. Please note
however that this is a list of things to do above and beyond fixing
bugs in the existing code base.
In general there are some guidelines for work to be included in
NetBSD. Chief among these are:
(1) Keep GPLed stuff out of the kernel.
(2) Only clean code, that lends itself to further enhancement
(3) Keep architecture dependent code out of architecture independent
directories
The important part of this is that the sun3 stuff better stay in
sys/arch/sun3.
Bootstrapping:
make it easy to do nfs diskless (CRITICAL). currently you have to
hack up the nfs_diskless sturcture. this should be fixed by finishing
porting sys/lib/libnetboot.
native boot blocks (HIGH)
nfs diskless boot blocks (HIGH).
Kernel core tasks (arch/sun3/sun3):
make pmap module modifications necessary so that we can turn
on MACHINE_NONCONTIG,a kernel config option that allows for
non-contiguous physical memory. This work is necessitated by the
the frame buffer on the 3/50 which is plop in the middle of physical
ram. (CRITICAL)
kernel text is not protected. (CRITICAL..for debugging)
find out why kernel has to be linked with such wierd options. (HIGH)
test virtual addressed cache support on non-desktop machines. (HIGH)
need support for the sun eeprom, including a non-sun
copyrighted header file describing its structure. Needed
at least for console handling. (MEDIUM)
ddb support (MEDIUM) (mycroft is working on this, for 68ks in general,
and it may actually work some now)
locore.s got split into many pieces as part of a bit of research
by the author into how much of it was truly sun-dependent vs
68k-dependent. Needs to be re-integrated into a standard
locore.s so that we can benefit from changes to the hp300, and
amiga ports, and vice-versa. (MEDIUM, will be fixed by glass)
FPUCOPROC support needs to be better integrated and triggered
by something other than this awful define. Also need
FPU emulation code (see briggs). (MEDIUM)
msgbuf should be allocated later, using the pmap stuff, same with
high_segment crud. see the dvma_alloc code for an example of
how much cleaner this is. (LOW..it works now)
compute idprom checksum, and check it (was lazy) (LOW)
HPUX compatibility support (make it hang off p_emul like our
COMPAT_SUNOS support). (LOW)
pmap module should keep a 3-level cache of ptes instead of 2. (LOW)
need /dev/eeprom driver functionality added to mem.c (LOW)
support for sun3x architecture (LOW, but we have the 030 code)
Device-driver related tasks:
scsi driver - use the scsi infrastructure in sys/scsi.
See config-file component in sys/arch/i386/conf
For host-adapter driver examples look
in sys/arch/{386/isa,mac68k/dev}
host adapter chip is NCR 5380.
dma chip is amd 9516.
secondary sources in: mac port, sprite, mach3
(SUPER_DUPER_CRITICAL)
prom console can accept input, though it does so lamely
make zs, ms, kbd driver as incorporated from torek's code actually
work. Then re-engineer such that it isn't so ugly. (CRITICAL)
intel ether - driver for 'ie' intel 82586-based ethernet.
see mach3, sprite, and i386 port (CRITICAL)
VME support (CRITICAL)
console handling (choice, detection, etc.) (MEDIUM)
OBIO probe support needed. support for handling the traps is
already present in the form of pcb_onfault. (MEDIUM)
Better OBIO configuration architecture, less re-computation of
default parameters. device-conflict notification. Requires
mycroft's autoconfig fix. (MEDIUM)
bw?, cg*,fb - must have same external interface as sun's to
keep X happy.
see sparc, and sprite code. (MEDIUM)
lance - switch to sparc code as a base instead of hp300. (LOW)
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.3 $>
This is a list of things that need to be done for NetBSD/Sun3. Some
of these tasks are small, others are large. Some are extremely

View File

@ -1,31 +1,45 @@
#
# new config file for GENERIC
#
machine "sun3"
cpu "SUN3_160"
cpu "SUN3_50"
cpu "SUN3_260"
cpu "SUN3_110"
cpu "SUN3_60"
cpu "SUN3_E"
cpu "SUN3_60"
ident SOLIPSIST
include "std.sun3"
timezone 8 dst
maxusers 16
options "SUN3_50"
options "SUN3_60"
makeoptions DEBUG = "-g"
maxusers 4
options TIMEZONE = 480, DST = 2, MAXFDESCS=2048
# Standard options
options "COMPAT_43"
options "TCP_COMPAT_42"
options FOO=3
# Options for all SUN3 machines
options SWAPPAGER, VNODEPAGER, DEVPAGER
options KTRACE
options INET
options FFS
options NFSSERVER
options NFSCLIENT
#sun3-specific options
options COMPAT_SUNOS
# sun3 debug options
#options CONTEXT_DEBUG
#options VMFAULT_TRACE
#options EXEC_DEBUG
#options LAME_ZS
config netbsd swap generic
le0 at obio? addr ? level 3
#zs0 at obio? addr 0x00000 level 3
#zs1 at obio? addr 0x20000 level 3
pseudo-device swappager
pseudo-device vnodepager
pseudo-device devpager
idprom0 at obctl? addr ? size ?
prom0 at mainbus0
pseudo-device loop

View File

@ -1,4 +1,4 @@
# $Id: Makefile.sun3,v 1.13 1994/02/04 08:19:41 glass Exp $
# $Id: Makefile.sun3,v 1.14 1994/02/23 08:28:21 glass Exp $
# Makefile for 4.4 BSD
#
# This makefile is constructed from a machine description:
@ -33,7 +33,7 @@ S= ../../../..
SUN3= ../..
LIBKERN=../libkern.a
INCLUDES= -I. -I$S -I$S/sys
INCLUDES= -I. -I../.. -I$S -I$S/sys
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -Dmc68020 -Dsun3
CFLAGS= ${COPTS}

View File

@ -27,9 +27,10 @@ options NFSCLIENT
options COMPAT_SUNOS
# sun3 debug options
options CONTEXT_DEBUG
options VMFAULT_TRACE
options EXEC_DEBUG
#options CONTEXT_DEBUG
#options VMFAULT_TRACE
#options EXEC_DEBUG
#options LAME_ZS
include "TIMESINK.nfsdiskless" #mega sad

View File

@ -1,4 +1,4 @@
# $Id: files.sun3.newconf,v 1.8 1994/02/04 08:19:43 glass Exp $
# $Id: files.sun3.newconf,v 1.9 1994/02/23 08:28:24 glass Exp $
# sun3-specific configuration info
maxusers 2 8 64
@ -18,12 +18,38 @@ device le at obio: ifnet, ether
file arch/sun3/dev/if_le.c le
file arch/sun3/dev/if_le_subr.c le
device zs at obio: tty
device zs at obio: tty, lame_zs
file arch/sun3/dev/zs.c zs needs-count
device clock at obio
file arch/sun3/sun3/clock.c clock
# define scsi {}
#
# #device si at obio: scsi
# #file arch/sun3/dev/si.c si
# device si at obio: scsi
# file arch/sun3/dev/scsi.c si
#
# device scsibus at scsi { target = -1, lun = -1 }
# file arch/sun3/scsi/scsiconf.c scsibus needs-flag
# file arch/sun3/scsi/scsi_base.c scsi
# file arch/sun3/scsi/scsi_ioctl.c scsi
#
# device cd at scsibus: disk
# file arch/sun3/scsi/cd.c cd needs-flag
# major {cd=6}
# device ch at scsibus: disk
# file arch/sun3/scsi/ch.c ch needs-flag
# device sd at scsibus: disk
# file arch/sun3/scsi/sd.c sd needs-flag
# major {sd=4}
# device st at scsibus: tape
# file arch/sun3/scsi/st.c st needs-flag
# major {st=5}
# file arch/sun3/scsi/uk.c uk needs-flag
# file arch/sun3/scsi/su.c su needs-flag
#
device bwtwo at obmem: sunfb
file arch/sun3/dev/bwtwo.c bwtwo
@ -60,3 +86,7 @@ file compat/sunos/sun_ioctl.c compat_sunos
file compat/sunos/sun_misc.c compat_sunos
file compat/sunos/sun_syscalls.c compat_sunos
file compat/sunos/sun_sysent.c compat_sunos
file arch/sun3/dev/kbd.c lame_zs
file arch/sun3/dev/event.c lame_zs
file arch/sun3/dev/ms.c lame_zs

View File

@ -1,9 +1,10 @@
# $Id: std.sun3,v 1.5 1994/02/04 08:19:44 glass Exp $
# $Id: std.sun3,v 1.6 1994/02/23 08:28:26 glass Exp $
# Standard information for sun3's.
machine sun3 m68k
options NEWCONFIG
options FPCOPROC
mainbus0 at root

172
sys/arch/sun3/dev/event.c Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)event.c 8.1 (Berkeley) 6/11/93
*
* from: Header: event.c,v 1.5 92/11/26 01:10:44 torek Exp (LBL)
* $Id: event.c,v 1.1 1994/02/23 08:28:33 glass Exp $
*/
/*
* Internal `Firm_event' interface for the keyboard and mouse drivers.
*/
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/vnode.h>
#include "vuid_event.h"
#include "event_var.h"
/*
* Initialize a firm_event queue.
*/
void
ev_init(ev)
register struct evvar *ev;
{
ev->ev_get = ev->ev_put = 0;
ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
M_DEVBUF, M_WAITOK);
bzero((caddr_t)ev->ev_q, EV_QSIZE * sizeof(struct firm_event));
}
/*
* Tear down a firm_event queue.
*/
void
ev_fini(ev)
register struct evvar *ev;
{
free(ev->ev_q, M_DEVBUF);
}
/*
* User-level interface: read, select.
* (User cannot write an event queue.)
*/
int
ev_read(ev, uio, flags)
register struct evvar *ev;
struct uio *uio;
int flags;
{
int s, n, cnt, error;
/*
* Make sure we can return at least 1.
*/
if (uio->uio_resid < sizeof(struct firm_event))
return (EMSGSIZE); /* ??? */
s = splev();
while (ev->ev_get == ev->ev_put) {
if (flags & IO_NDELAY) {
splx(s);
return (EWOULDBLOCK);
}
ev->ev_wanted = 1;
error = tsleep((caddr_t)ev, PEVENT | PCATCH, "firm_event", 0);
if (error) {
splx(s);
return (error);
}
}
/*
* Move firm_events from tail end of queue (there is at least one
* there).
*/
if (ev->ev_put < ev->ev_get)
cnt = EV_QSIZE - ev->ev_get; /* events in [get..QSIZE) */
else
cnt = ev->ev_put - ev->ev_get; /* events in [get..put) */
splx(s);
n = howmany(uio->uio_resid, sizeof(struct firm_event));
if (cnt > n)
cnt = n;
error = uiomove((caddr_t)&ev->ev_q[ev->ev_get],
cnt * sizeof(struct firm_event), uio);
n -= cnt;
/*
* If we do not wrap to 0, used up all our space, or had an error,
* stop. Otherwise move from front of queue to put index, if there
* is anything there to move.
*/
if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
n == 0 || error || (cnt = ev->ev_put) == 0)
return (error);
if (cnt > n)
cnt = n;
error = uiomove((caddr_t)&ev->ev_q[0],
cnt * sizeof(struct firm_event), uio);
ev->ev_get = cnt;
return (error);
}
int
ev_select(ev, rw, p)
register struct evvar *ev;
int rw;
struct proc *p;
{
int s = splev();
switch (rw) {
case FREAD:
/* succeed if there is something to read */
if (ev->ev_get != ev->ev_put) {
splx(s);
return (1);
}
selrecord(p, &ev->ev_sel);
break;
case FWRITE:
return (1); /* always fails => never blocks */
}
splx(s);
return (0);
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)event_var.h 8.1 (Berkeley) 6/11/93
*
* from: Header: event_var.h,v 1.5 92/11/26 01:11:51 torek Exp (LBL)
* $Id: event_var.h,v 1.1 1994/02/23 08:28:36 glass Exp $
*/
/*
* Internal `Firm_event' interface for the keyboard and mouse drivers.
* The drivers are expected not to place events in the queue above spltty(),
* i.e., are expected to run off serial ports.
*/
/* EV_QSIZE should be a power of two so that `%' is fast */
#define EV_QSIZE 256 /* may need tuning; this uses 2k */
struct evvar {
u_int ev_get; /* get (read) index (modified synchronously) */
volatile u_int ev_put; /* put (write) index (modified by interrupt) */
struct selinfo ev_sel; /* process selecting */
struct proc *ev_io; /* process that opened queue (can get SIGIO) */
char ev_wanted; /* wake up on input ready */
char ev_async; /* send SIGIO on input ready */
struct firm_event *ev_q;/* circular buffer (queue) of events */
};
#define splev() spltty()
#define EV_WAKEUP(ev) { \
selwakeup(&(ev)->ev_sel); \
if ((ev)->ev_wanted) { \
(ev)->ev_wanted = 0; \
wakeup((caddr_t)(ev)); \
} \
if ((ev)->ev_async) \
psignal((ev)->ev_io, SIGIO); \
}
void ev_init __P((struct evvar *));
void ev_fini __P((struct evvar *));
int ev_read __P((struct evvar *, struct uio *, int));
int ev_select __P((struct evvar *, int, struct proc *));
/*
* PEVENT is set just above PSOCK, which is just above TTIPRI, on the
* theory that mouse and keyboard `user' input should be quick.
*/
#define PEVENT 23

View File

@ -89,7 +89,7 @@
#include "if_le.h"
#include "if_le_subr.h"
int ledebug = 1; /* console error messages */
int ledebug = 0; /* console error messages */
int leintr(), leioctl(), ether_output();
void lestart(), leinit();
@ -335,7 +335,7 @@ leintr(unit)
ler1 = le->sc_r1;
LERDWR(le, ler1->ler1_rdp, stat);
if (ledebug)
printf("[le%d: stat %b]", unit, stat, LE_STATUS_BITS);
printf("[le%d: stat %b]\n", unit, stat, LE_STATUS_BITS);
if (stat & LE_SERR) {
leerror(unit, stat);
if (stat & LE_MERR) {

View File

@ -1,24 +1,57 @@
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/protosw.h"
#include "sys/socket.h"
#include "sys/device.h"
#include "net/if.h"
/*
* Copyright (c) 1993 Adam Glass
* 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 by Adam Glass.
* 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 Adam Glass ``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 Adam Glass 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.
*
* $Header: /cvsroot/src/sys/arch/sun3/dev/Attic/if_le_subr.c,v 1.3 1994/02/23 08:28:42 glass Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <net/if.h>
#ifdef INET
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/in_var.h"
#include "netinet/ip.h"
#include "netinet/if_ether.h"
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#endif
#include "machine/autoconf.h"
#include "machine/cpu.h"
#include "machine/isr.h"
#include "machine/mtpr.h"
#include "machine/obio.h"
#include "machine/idprom.h"
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/isr.h>
#include <machine/mtpr.h>
#include <machine/obio.h>
#include <machine/idprom.h>
#include "bpfilter.h"

669
sys/arch/sun3/dev/kbd.c Normal file
View File

@ -0,0 +1,669 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)kbd.c 8.1 (Berkeley) 6/11/93
*
* from: Header: kbd.c,v 1.16 92/11/26 01:28:44 torek Exp (LBL)
* $Id: kbd.c,v 1.1 1994/02/23 08:28:43 glass Exp $
*/
/*
* Keyboard driver (/dev/kbd -- note that we do not have minor numbers
* [yet?]). Translates incoming bytes to ASCII or to `firm_events' and
* passes them up to the appropriate reader.
*/
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/tty.h>
#include <machine/autoconf.h>
#include "vuid_event.h"
#include "event_var.h"
#include "kbd.h"
#include "kbio.h"
/*
* Sun keyboard definitions (from Sprite).
* These apply to type 2, 3 and 4 keyboards.
*/
#define KEY_CODE(c) ((c) & KBD_KEYMASK) /* keyboard code index */
#define KEY_UP(c) ((c) & KBD_UP) /* true => key went up */
/*
* Each KEY_CODE(x) can be translated via the tables below.
* The result is either a valid ASCII value in [0..0x7f] or is one
* of the following `magic' values saying something interesting
* happened. If LSHIFT or RSHIFT has changed state the next
* lookup should come from the appropriate table; if ALLUP is
* sent all keys (including both shifts and the control key) are
* now up, and the next byte is the keyboard ID code.
*
* These tables ignore all function keys (on the theory that if you
* want these keys, you should use a window system). Note that
* `caps lock' is just mapped as `ignore' (so there!). (Only the
* type 3 and 4 keyboards have a caps lock key anyway.)
*/
#define KEY_MAGIC 0x80 /* flag => magic value */
#define KEY_IGNORE 0x80
#define KEY_L1 KEY_IGNORE
#define KEY_CAPSLOCK KEY_IGNORE
#define KEY_LSHIFT 0x81
#define KEY_RSHIFT 0x82
#define KEY_CONTROL 0x83
#define KEY_ALLUP 0x84 /* all keys are now up; also reset */
/*
* Decode tables for type 2, 3, and 4 keyboards
* (stolen from Sprite; see also kbd.h).
*/
static const u_char kbd_unshifted[] = {
/* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE,
/* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 28 */ KEY_IGNORE, '\033', '1', '2',
/* 32 */ '3', '4', '5', '6',
/* 36 */ '7', '8', '9', '0',
/* 40 */ '-', '=', '`', '\b',
/* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 52 */ KEY_IGNORE, '\t', 'q', 'w',
/* 56 */ 'e', 'r', 't', 'y',
/* 60 */ 'u', 'i', 'o', 'p',
/* 64 */ '[', ']', '\177', KEY_IGNORE,
/* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 76 */ KEY_CONTROL, 'a', 's', 'd',
/* 80 */ 'f', 'g', 'h', 'j',
/* 84 */ 'k', 'l', ';', '\'',
/* 88 */ '\\', '\r', KEY_IGNORE, KEY_IGNORE,
/* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT,
/* 100 */ 'z', 'x', 'c', 'v',
/* 104 */ 'b', 'n', 'm', ',',
/* 108 */ '.', '/', KEY_RSHIFT, '\n',
/* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK,
/* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE,
/* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP,
};
static const u_char kbd_shifted[] = {
/* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE,
/* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 28 */ KEY_IGNORE, '\033', '!', '@',
/* 32 */ '#', '$', '%', '^',
/* 36 */ '&', '*', '(', ')',
/* 40 */ '_', '+', '~', '\b',
/* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 52 */ KEY_IGNORE, '\t', 'Q', 'W',
/* 56 */ 'E', 'R', 'T', 'Y',
/* 60 */ 'U', 'I', 'O', 'P',
/* 64 */ '{', '}', '\177', KEY_IGNORE,
/* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 76 */ KEY_CONTROL, 'A', 'S', 'D',
/* 80 */ 'F', 'G', 'H', 'J',
/* 84 */ 'K', 'L', ':', '"',
/* 88 */ '|', '\r', KEY_IGNORE, KEY_IGNORE,
/* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT,
/* 100 */ 'Z', 'X', 'C', 'V',
/* 104 */ 'B', 'N', 'M', '<',
/* 108 */ '>', '?', KEY_RSHIFT, '\n',
/* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
/* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK,
/* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE,
/* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP,
};
/*
* We need to remember the state of the keyboard's shift and control
* keys, and we need a per-type translation table.
*/
struct kbd_state {
const u_char *kbd_unshifted; /* unshifted keys */
const u_char *kbd_shifted; /* shifted keys */
const u_char *kbd_cur; /* current keys (either of the preceding) */
union {
char c[2]; /* left and right shift keys */
short s; /* true => either shift key */
} kbd_shift;
#define kbd_lshift kbd_shift.c[0]
#define kbd_rshift kbd_shift.c[1]
#define kbd_anyshift kbd_shift.s
char kbd_control; /* true => ctrl down */
char kbd_click; /* true => keyclick enabled */
char kbd_takeid; /* take next byte as ID */
u_char kbd_id; /* a place to store the ID */
};
/*
* Keyboard driver state. The ascii and kbd links go up and down and
* we just sit in the middle doing translation. Note that it is possible
* to get just one of the two links, in which case /dev/kbd is unavailable.
* The downlink supplies us with `internal' open and close routines which
* will enable dataflow across the downlink. We promise to call open when
* we are willing to take keystrokes, and to call close when we are not.
* If /dev/kbd is not the console tty input source, we do this whenever
* /dev/kbd is in use; otherwise we just leave it open forever.
*/
struct kbd_softc {
struct tty *k_cons; /* uplink for ASCII data to console */
struct tty *k_kbd; /* downlink for output to keyboard */
void (*k_open) __P((struct tty *)); /* enable dataflow */
void (*k_close) __P((struct tty *)); /* disable dataflow */
int k_evmode; /* set if we should produce events */
struct kbd_state k_state; /* ASCII decode state */
struct evvar k_events; /* event queue state */
} kbd_softc;
/* Prototypes */
void kbd_ascii(struct tty *);
void kbd_serial(struct tty *, void (*)(), void (*)());
static void kbd_getid(void *);
void kbd_reset(struct kbd_state *);
static int kbd_translate(int, struct kbd_state *);
void kbd_rint(int);
int kbdopen(dev_t, int, int, struct proc *);
int kbdclose(dev_t, int, int, struct proc *);
int kbdread(dev_t, struct uio *, int);
int kbdwrite(dev_t, struct uio *, int);
int kbdioctl(dev_t, int, caddr_t, int, struct proc *);
int kbdselect(dev_t, int, struct proc *);
int kbd_docmd(int, int);
/*
* Attach the console keyboard ASCII (up-link) interface.
* This happens before kbd_serial.
*/
void
kbd_ascii(struct tty *tp)
{
kbd_softc.k_cons = tp;
}
/*
* Attach the console keyboard serial (down-link) interface.
* We pick up the initial keyboard clock state here as well.
*/
void
kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)())
{
register struct kbd_softc *k;
register char *cp;
k = &kbd_softc;
k->k_kbd = tp;
k->k_open = iopen;
k->k_close = iclose;
#if 0
cp = getpropstring(optionsnode, "keyboard-click?");
if (cp && strcmp(cp, "true") == 0)
k->k_state.kbd_click = 1;
#endif
if (k->k_cons) {
/*
* We supply keys for /dev/console. Before we can
* do so, we have to ``open'' the line. We also need
* the type, got by sending a RESET down the line ...
* but clists are not yet set up, so we use a timeout
* to try constantly until we can get the ID. (gag)
*/
(*iopen)(tp); /* never to be closed */
kbd_getid(NULL);
}
}
/*
* Initial keyboard reset, to obtain ID and thus a translation table.
* We have to try again and again until the tty subsystem works.
*/
static void
kbd_getid(void *arg)
{
register struct kbd_softc *k;
register struct tty *tp;
register int retry;
extern int cold; /* XXX */
k = &kbd_softc;
if (k->k_state.kbd_cur != NULL)
return;
tp = k->k_kbd;
if (cold || ttyoutput(KBD_CMD_RESET, tp) >= 0)
retry = 1;
else {
(*tp->t_oproc)(tp);
retry = 2 * hz;
}
timeout((timeout_t)kbd_getid, (caddr_t)NULL, retry);
}
void
kbd_reset(register struct kbd_state *ks)
{
/*
* On first identification, wake up anyone waiting for type
* and set up the table pointers.
*/
if (ks->kbd_unshifted == NULL) {
wakeup((caddr_t)ks);
ks->kbd_unshifted = kbd_unshifted;
ks->kbd_shifted = kbd_shifted;
ks->kbd_cur = ks->kbd_unshifted;
}
/* Restore keyclick, if necessary */
switch (ks->kbd_id) {
case KB_SUN2:
/* Type 2 keyboards don't support keyclick */
break;
case KB_SUN3:
/* Type 3 keyboards come up with keyclick on */
if (!ks->kbd_click)
(void) kbd_docmd(KBD_CMD_NOCLICK, 0);
break;
case KB_SUN4:
/* Type 4 keyboards come up with keyclick off */
if (ks->kbd_click)
(void) kbd_docmd(KBD_CMD_CLICK, 0);
break;
}
}
/*
* Turn keyboard up/down codes into ASCII.
*/
static int
kbd_translate(register int c, register struct kbd_state *ks)
{
register int down;
if (ks->kbd_cur == NULL) {
/*
* Do not know how to translate yet.
* We will find out when a RESET comes along.
*/
return (-1);
}
down = !KEY_UP(c);
c = ks->kbd_cur[KEY_CODE(c)];
if (c & KEY_MAGIC) {
switch (c) {
case KEY_LSHIFT:
ks->kbd_lshift = down;
break;
case KEY_RSHIFT:
ks->kbd_rshift = down;
break;
case KEY_ALLUP:
ks->kbd_anyshift = 0;
ks->kbd_control = 0;
break;
case KEY_CONTROL:
ks->kbd_control = down;
/* FALLTHROUGH */
case KEY_IGNORE:
return (-1);
default:
panic("kbd_translate");
}
if (ks->kbd_anyshift)
ks->kbd_cur = ks->kbd_shifted;
else
ks->kbd_cur = ks->kbd_unshifted;
return (-1);
}
if (!down)
return (-1);
if (ks->kbd_control) {
/* control space and unshifted control atsign return null */
if (c == ' ' || c == '2')
return (0);
/* unshifted control hat */
if (c == '6')
return ('^' & 0x1f);
/* standard controls */
if (c >= '@' && c < 0x7f)
return (c & 0x1f);
}
return (c);
}
void
kbd_rint(register int c)
{
register struct kbd_softc *k = &kbd_softc;
register struct firm_event *fe;
register int put;
/*
* Reset keyboard after serial port overrun, so we can resynch.
* The printf below should be shortened and/or replaced with a
* call to log() after this is tested (and how will we test it?!).
*/
if (c & (TTY_FE|TTY_PE)) {
printf("keyboard input parity or framing error (0x%x)\n", c);
(void) ttyoutput(KBD_CMD_RESET, k->k_kbd);
(*k->k_kbd->t_oproc)(k->k_kbd);
return;
}
/* Read the keyboard id if we read a KBD_RESET last time */
if (k->k_state.kbd_takeid) {
k->k_state.kbd_takeid = 0;
k->k_state.kbd_id = c;
kbd_reset(&k->k_state);
return;
}
/* If we have been reset, setup to grab the keyboard id next time */
if (c == KBD_RESET) {
k->k_state.kbd_takeid = 1;
return;
}
/*
* If /dev/kbd is not connected in event mode, but we are sending
* data to /dev/console, translate and send upstream. Note that
* we will get this while opening /dev/kbd if it is not already
* open and we do not know its type.
*/
if (!k->k_evmode) {
c = kbd_translate(c, &k->k_state);
if (c >= 0 && k->k_cons != NULL)
ttyinput(c, k->k_cons);
return;
}
/*
* IDLEs confuse the MIT X11R4 server badly, so we must drop them.
* This is bad as it means the server will not automatically resync
* on all-up IDLEs, but I did not drop them before, and the server
* goes crazy when it comes time to blank the screen....
*/
if (c == KBD_IDLE)
return;
/*
* Keyboard is generating events. Turn this keystroke into an
* event and put it in the queue. If the queue is full, the
* keystroke is lost (sorry!).
*/
put = k->k_events.ev_put;
fe = &k->k_events.ev_q[put];
put = (put + 1) % EV_QSIZE;
if (put == k->k_events.ev_get) {
log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */
return;
}
fe->id = KEY_CODE(c);
fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
fe->time = time;
k->k_events.ev_put = put;
EV_WAKEUP(&k->k_events);
}
int
kbdopen(dev_t dev, int flags, int mode, struct proc *p)
{
int s, error;
if (kbd_softc.k_events.ev_io)
return (EBUSY);
kbd_softc.k_events.ev_io = p;
/*
* If no console keyboard, tell the device to open up, maybe for
* the first time. Then make sure we know what kind of keyboard
* it is.
*/
if (kbd_softc.k_cons == NULL)
(*kbd_softc.k_open)(kbd_softc.k_kbd);
error = 0;
s = spltty();
if (kbd_softc.k_state.kbd_cur == NULL) {
(void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd);
error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH,
devopn, hz);
if (error == EWOULDBLOCK) /* no response */
error = ENXIO;
}
splx(s);
if (error) {
kbd_softc.k_events.ev_io = NULL;
return (error);
}
ev_init(&kbd_softc.k_events);
return (0);
}
int
kbdclose(dev_t dev, int flags, int mode, struct proc *p)
{
/*
* Turn off event mode, dump the queue, and close the keyboard
* unless it is supplying console input.
*/
kbd_softc.k_evmode = 0;
ev_fini(&kbd_softc.k_events);
if (kbd_softc.k_cons == NULL)
(*kbd_softc.k_close)(kbd_softc.k_kbd);
kbd_softc.k_events.ev_io = NULL;
return (0);
}
int
kbdread(dev_t dev, struct uio *uio, int flags)
{
return (ev_read(&kbd_softc.k_events, uio, flags));
}
/* this routine should not exist, but is convenient to write here for now */
int
kbdwrite(dev_t dev, struct uio *uio, int flags)
{
return (EOPNOTSUPP);
}
int
kbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p)
{
register struct kbd_softc *k = &kbd_softc;
switch (cmd) {
case KIOCTRANS:
if (*(int *)data == TR_UNTRANS_EVENT)
return (0);
break;
case KIOCGTRANS:
/*
* Get translation mode
*/
*(int *)data = TR_UNTRANS_EVENT;
return (0);
case KIOCGETKEY:
if (((struct kiockey *)data)->kio_station == 118) {
/*
* This is X11 asking if a type 3 keyboard is
* really a type 3 keyboard. Say yes.
*/
((struct kiockey *)data)->kio_entry = HOLE;
return (0);
}
break;
case KIOCCMD:
/*
* ``unimplemented commands are ignored'' (blech)
* so cannot check return value from kbd_docmd
*/
#ifdef notyet
while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/
(void) sleep((caddr_t)&lbolt, TTOPRI);
#else
(void) kbd_docmd(*(int *)data, 1);
#endif
return (0);
case KIOCTYPE:
*(int *)data = k->k_state.kbd_id;
return (0);
case KIOCSDIRECT:
k->k_evmode = *(int *)data;
return (0);
case FIONBIO: /* we will remove this someday (soon???) */
return (0);
case FIOASYNC:
k->k_events.ev_async = *(int *)data != 0;
return (0);
case TIOCSPGRP:
if (*(int *)data != k->k_events.ev_io->p_pgid)
return (EPERM);
return (0);
default:
return (ENOTTY);
}
/*
* We identified the ioctl, but we do not handle it.
*/
return (EOPNOTSUPP); /* misuse, but what the heck */
}
int
kbdselect(dev_t dev, int rw, struct proc *p)
{
return (ev_select(&kbd_softc.k_events, rw, p));
}
/*
* Execute a keyboard command; return 0 on success.
* If `isuser', force a small delay before output if output queue
* is flooding. (The keyboard runs at 1200 baud, or 120 cps.)
*/
int
kbd_docmd(int cmd, int isuser)
{
register struct tty *tp = kbd_softc.k_kbd;
register struct kbd_softc *k = &kbd_softc;
int s;
if (tp == NULL)
return (ENXIO); /* ??? */
switch (cmd) {
case KBD_CMD_BELL:
case KBD_CMD_NOBELL:
/* Supported by type 2, 3, and 4 keyboards */
break;
case KBD_CMD_CLICK:
/* Unsupported by type 2 keyboards */
if (k->k_state.kbd_id != KB_SUN2) {
k->k_state.kbd_click = 1;
break;
}
return (EINVAL);
case KBD_CMD_NOCLICK:
/* Unsupported by type 2 keyboards */
if (k->k_state.kbd_id != KB_SUN2) {
k->k_state.kbd_click = 0;
break;
}
return (EINVAL);
default:
return (EINVAL); /* ENOTTY? EOPNOTSUPP? */
}
if (isuser) {
s = spltty();
if (tp->t_outq.c_cc > 120)
(void) tsleep((caddr_t)&lbolt, TTIPRI,
ttyout, 0);
splx(s);
}
if (ttyoutput(cmd, tp) >= 0)
return (ENOSPC); /* ERESTART? */
(*tp->t_oproc)(tp);
return (0);
}

81
sys/arch/sun3/dev/kbd.h Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)kbd.h 8.1 (Berkeley) 6/11/93
*
* from: Header: kbd.h,v 1.5 92/11/26 01:15:33 torek Exp (LBL)
* $Id: kbd.h,v 1.1 1994/02/23 08:28:45 glass Exp $
*/
/*
* Keyboard `registers'. (This should be called kbd_reg.h but we need to
* be compatible.)
*/
/*
* Control codes sent from type 2, 3, and 4 keyboards.
*
* Note that KBD_RESET is followed by a keyboard ID, while KBD_IDLE is not.
* KBD_IDLE does not take the place of any `up' transitions (it merely occurs
* after them).
*/
#define KBD_RESET 0xff /* keyboard `reset' response */
#define KBD_IDLE 0x7f /* keyboard `all keys are up' code */
/* Keyboard IDs */
#define KB_SUN2 2 /* type 2 keyboard */
#define KB_SUN3 3 /* type 3 keyboard */
#define KB_SUN4 4 /* type 4 keyboard */
/* Key codes are in 0x00..0x7e; KBD_UP is set if the key goes up */
#define KBD_KEYMASK 0x7f /* keyboard key mask */
#define KBD_UP 0x80 /* keyboard `up' transition */
/* Keyboard codes needed to recognize the L1-A sequence */
#define KBD_L1 1 /* keyboard code for `L1' key */
#define KBD_A 77 /* keyboard code for `A' key */
/* Control codes sent to the various keyboards */
#define KBD_CMD_RESET 1 /* reset keyboard */
#define KBD_CMD_BELL 2 /* turn bell on */
#define KBD_CMD_NOBELL 3 /* turn bell off */
#define KBD_CMD_CLICK 10 /* turn keyclick on */
#define KBD_CMD_NOCLICK 11 /* turn keyclick off */

87
sys/arch/sun3/dev/kbio.h Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)kbio.h 8.1 (Berkeley) 6/11/93
*
* from: Header: kbio.h,v 1.4 92/11/26 01:16:32 torek Exp (LBL)
* $Id: kbio.h,v 1.1 1994/02/23 08:28:47 glass Exp $
*/
/*
* The following is a minimal emulation of Sun's `kio' structures
* and related operations necessary to make X11 happy (i.e., make it
* compile, and make old X11 binaries run).
*/
/*
* The kiockey structure apparently gets and/or sets keyboard mappings.
* It seems to be kind of useless, but X11 uses it (according to the
* comments) to figure out when a Sun 386i has a type-4 keyboard but
* claims to have a type-3 keyboard. We need just enough to cause the
* appropriate ioctl to return the appropriate magic value.
*
* KIOCGETKEY fills in kio_entry from kio_station. Not sure what tablemask
* is for; X sets it before the call, so it is not an output, but we do not
* care anyway. KIOCSDIRECT is supposed to tell the kernel whether to send
* keys to the console or to X; we just send them to X whenever the keyboard
* is open at all. (XXX may need to change this later)
*
* Keyboard commands and types are defined in kbd.h as they are actually
* real hardware commands and type numbers.
*/
struct kiockey {
int kio_tablemask; /* whatever */
u_char kio_station; /* key number */
u_char kio_entry; /* HOLE if not present */
char kio_text[10]; /* the silly escape sequences (unsupported) */
};
#define HOLE 0x302 /* value for kio_entry to say `really type 3' */
#define KIOCTRANS _IOW('k', 0, int) /* set translation mode */
/* (we only accept TR_UNTRANS_EVENT) */
#define KIOCGETKEY _IOWR('k', 2, struct kiockey) /* fill in kio_entry */
#define KIOCGTRANS _IOR('k', 5, int) /* get translation mode */
#define KIOCCMD _IOW('k', 8, int) /* X uses this to ring bell */
#define KIOCTYPE _IOR('k', 9, int) /* get keyboard type */
#define KIOCSDIRECT _IOW('k', 10, int) /* keys to console? */
#define TR_UNTRANS_EVENT 3

337
sys/arch/sun3/dev/ms.c Normal file
View File

@ -0,0 +1,337 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)ms.c 8.1 (Berkeley) 6/11/93
*
* from: Header: ms.c,v 1.5 92/11/26 01:28:47 torek Exp (LBL)
* $Id: ms.c,v 1.1 1994/02/23 08:28:49 glass Exp $
*/
/*
* Mouse driver.
*/
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/tty.h>
#include "vuid_event.h"
#include "event_var.h"
/*
* Mouse state. A Mouse Systems mouse is a fairly simple device,
* producing five-byte blobs of the form:
*
* b dx dy dx dy
*
* where b is the button state, encoded as 0x80|(~buttons)---there are
* three buttons (4=left, 2=middle, 1=right)---and dx,dy are X and Y
* delta values, none of which have are in [0x80..0x87]. (This lets
* us sync up with the mouse after an error.)
*/
struct ms_softc {
short ms_byteno; /* input byte number, for decode */
char ms_mb; /* mouse button state */
char ms_ub; /* user button state */
int ms_dx; /* delta-x */
int ms_dy; /* delta-y */
struct tty *ms_mouse; /* downlink for output to mouse */
void (*ms_open) __P((struct tty *)); /* enable dataflow */
void (*ms_close) __P((struct tty *));/* disable dataflow */
volatile int ms_ready; /* event queue is ready */
struct evvar ms_events; /* event queue state */
} ms_softc;
/*
* Attach the mouse serial (down-link) interface.
* Do we need to set it to 1200 baud, 8 bits?
* Test by power cycling and not booting SunOS before BSD?
*/
void
ms_serial(tp, iopen, iclose)
struct tty *tp;
void (*iopen)(), (*iclose)();
{
ms_softc.ms_mouse = tp;
ms_softc.ms_open = iopen;
ms_softc.ms_close = iclose;
}
void
ms_rint(c)
register int c;
{
register struct firm_event *fe;
register struct ms_softc *ms = &ms_softc;
register int mb, ub, d, get, put, any;
static const char to_one[] = { 1, 2, 2, 4, 4, 4, 4 };
static const int to_id[] = { MS_RIGHT, MS_MIDDLE, 0, MS_LEFT };
/*
* Discard input if not ready. Drop sync on parity or framing
* error; gain sync on button byte.
*/
if (ms->ms_ready == 0)
return;
if (c & (TTY_FE|TTY_PE)) {
log(LOG_WARNING,
"mouse input parity or framing error (0x%x)\n", c);
ms->ms_byteno = -1;
return;
}
if ((unsigned)(c - 0x80) < 8) /* if in 0x80..0x87 */
ms->ms_byteno = 0;
/*
* Run the decode loop, adding to the current information.
* We add, rather than replace, deltas, so that if the event queue
* fills, we accumulate data for when it opens up again.
*/
switch (ms->ms_byteno) {
case -1:
return;
case 0:
/* buttons */
ms->ms_byteno = 1;
ms->ms_mb = (~c) & 0x7;
return;
case 1:
/* first delta-x */
ms->ms_byteno = 2;
ms->ms_dx += (char)c;
return;
case 2:
/* first delta-y */
ms->ms_byteno = 3;
ms->ms_dy += (char)c;
return;
case 3:
/* second delta-x */
ms->ms_byteno = 4;
ms->ms_dx += (char)c;
return;
case 4:
/* second delta-x */
ms->ms_byteno = -1; /* wait for button-byte again */
ms->ms_dy += (char)c;
break;
default:
panic("ms_rint");
/* NOTREACHED */
}
/*
* We have at least one event (mouse button, delta-X, or
* delta-Y; possibly all three, and possibly three separate
* button events). Deliver these events until we are out
* of changes or out of room. As events get delivered,
* mark them `unchanged'.
*/
any = 0;
get = ms->ms_events.ev_get;
put = ms->ms_events.ev_put;
fe = &ms->ms_events.ev_q[put];
/* NEXT prepares to put the next event, backing off if necessary */
#define NEXT \
if ((++put) % EV_QSIZE == get) { \
put--; \
goto out; \
}
/* ADVANCE completes the `put' of the event */
#define ADVANCE \
fe++; \
if (put >= EV_QSIZE) { \
put = 0; \
fe = &ms->ms_events.ev_q[0]; \
} \
any = 1
mb = ms->ms_mb;
ub = ms->ms_ub;
while ((d = mb ^ ub) != 0) {
/*
* Mouse button change. Convert up to three changes
* to the `first' change, and drop it into the event queue.
*/
NEXT;
d = to_one[d - 1]; /* from 1..7 to {1,2,4} */
fe->id = to_id[d - 1]; /* from {1,2,4} to ID */
fe->value = mb & d ? VKEY_DOWN : VKEY_UP;
fe->time = time;
ADVANCE;
ub ^= d;
}
if (ms->ms_dx) {
NEXT;
fe->id = LOC_X_DELTA;
fe->value = ms->ms_dx;
fe->time = time;
ADVANCE;
ms->ms_dx = 0;
}
if (ms->ms_dy) {
NEXT;
fe->id = LOC_Y_DELTA;
fe->value = ms->ms_dy;
fe->time = time;
ADVANCE;
ms->ms_dy = 0;
}
out:
if (any) {
ms->ms_ub = ub;
ms->ms_events.ev_put = put;
EV_WAKEUP(&ms->ms_events);
}
}
int
msopen(dev, flags, mode, p)
dev_t dev;
int flags, mode;
struct proc *p;
{
int s, error;
if (ms_softc.ms_events.ev_io)
return (EBUSY);
ms_softc.ms_events.ev_io = p;
ev_init(&ms_softc.ms_events); /* may cause sleep */
ms_softc.ms_ready = 1; /* start accepting events */
(*ms_softc.ms_open)(ms_softc.ms_mouse);
return (0);
}
int
msclose(dev, flags, mode, p)
dev_t dev;
int flags, mode;
struct proc *p;
{
ms_softc.ms_ready = 0; /* stop accepting events */
ev_fini(&ms_softc.ms_events);
(*ms_softc.ms_close)(ms_softc.ms_mouse);
ms_softc.ms_events.ev_io = NULL;
return (0);
}
int
msread(dev, uio, flags)
dev_t dev;
struct uio *uio;
int flags;
{
return (ev_read(&ms_softc.ms_events, uio, flags));
}
/* this routine should not exist, but is convenient to write here for now */
int
mswrite(dev, uio, flags)
dev_t dev;
struct uio *uio;
int flags;
{
return (EOPNOTSUPP);
}
int
msioctl(dev, cmd, data, flag, p)
dev_t dev;
int cmd;
register caddr_t data;
int flag;
struct proc *p;
{
int s;
switch (cmd) {
case FIONBIO: /* we will remove this someday (soon???) */
return (0);
case FIOASYNC:
ms_softc.ms_events.ev_async = *(int *)data != 0;
return (0);
case TIOCSPGRP:
if (*(int *)data != ms_softc.ms_events.ev_io->p_pgid)
return (EPERM);
return (0);
case VUIDGFORMAT:
/* we only do firm_events */
*(int *)data = VUID_FIRM_EVENT;
return (0);
case VUIDSFORMAT:
if (*(int *)data != VUID_FIRM_EVENT)
return (EINVAL);
return (0);
}
return (ENOTTY);
}
int
msselect(dev, rw, p)
dev_t dev;
int rw;
struct proc *p;
{
return (ev_select(&ms_softc.ms_events, rw, p));
}

View File

@ -1,67 +1,84 @@
#include "sys/param.h"
#include "sys/proc.h"
#include "sys/systm.h"
#include "sys/buf.h"
#include "sys/ioctl.h"
#include "sys/tty.h"
#include "sys/file.h"
#include "sys/conf.h"
#include "device.h"
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/file.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/mon.h>
#include "machine/autoconf.h"
#include "machine/mon.h"
#include "../sun3/cons.h"
#include "../sun3/interreg.h"
#include "prom.h"
/*
* cleanup:
* get autoconfiguration right, right style
* not a true serial driver but a tty driver, i.e no carrier
* make sure start is non-blocking
* add read support via timeouts
*/
void promattach __P((struct device *, struct device *, void *));
struct prom_softc {
struct device prom_dev;
int prom_flags;
int prom_nopen;
struct tty *prom_t;
struct device sc_dev;
int sc_flags;
int sc_nopen;
struct tty *sc_tty;
};
struct cfdriver promcd =
{ NULL, "prom", always_match, promattach,
DV_TTY, sizeof(struct prom_softc), 0};
{ NULL, "prom", always_match, promattach, DV_TTY,
sizeof(struct prom_softc), 0};
#define PROM_CHECK(unit) \
if (unit >= promcd.cd_ndevs || (promcd.cd_devs[unit] == NULL)) \
return ENXIO
#define UNIT_TO_PROMP(unit) promcd.cd_devs[unit]
#define UNIT_TO_PROM_SC(unit) promcd.cd_devs[unit]
int promopen __P((dev_t, int, int, struct proc *));
int promclose __P((dev_t, int, int, struct proc *));
int promread __P((dev_t, struct uio *, int));
int promwrite __P((dev_t, struct uio *, int));
int promioctl __P((dev_t, int, caddr_t, int, struct proc *));
int promstop __P((struct tty *, int));
static int promparam __P((struct tty *, struct termios *));
static void promstart __P((struct tty *));
static void promreceive __P((caddr_t));
void promattach(parent, self, args)
struct device *parent;
struct device *self;
void *args;
{
struct prom_softc *promp = (struct prom_softc *) self;
printf("\n");
}
void promstart __P((struct tty *));
int promopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
struct tty *tp;
struct prom_softc *promp;
int unit;
int s,error=0;
struct prom_softc *prom_sc;
int unit, s, result;
unit = minor(dev);
PROM_CHECK(unit);
promp = UNIT_TO_PROMP(unit);
if (!promp->prom_t)
tp = promp->prom_t = ttymalloc();
prom_sc = UNIT_TO_PROM_SC(unit);
if (prom_sc->sc_tty == NULL)
tp = prom_sc->sc_tty = ttymalloc();
else
tp = promp->prom_t;
tp = prom_sc->sc_tty;
tp->t_addr = (caddr_t) tp;
tp->t_oproc = promstart;
tp->t_param = promparam;
tp->t_dev = dev;
if ((tp->t_state & TS_ISOPEN) == 0) {
tp->t_state |= TS_WOPEN;
@ -73,23 +90,17 @@ int promopen(dev, flag, mode, p)
tp->t_lflag = TTYDEF_LFLAG;
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
}
promparam(tp, &tp->t_termios);
ttsetwater(tp);
}
else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
return (EBUSY);
s = spltty();
while ((flag & O_NONBLOCK) == 0 && (tp->t_cflag &CLOCAL) == 0 &&
(tp->t_state & TS_CARR_ON) == 0) {
tp->t_state |= TS_WOPEN;
if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
ttopen, 0))
break;
}
splx(s);
if (error == 0)
error = (*linesw[tp->t_line].l_open)(dev, tp);
return (error);
return EBUSY;
tp->t_state |= TS_CARR_ON;
result = (*linesw[tp->t_line].l_open)(dev, tp);
if (result)
return result;
timeout((timeout_t) promreceive, (caddr_t) tp, hz/2);
return 0;
}
promclose(dev, flag, mode, p)
@ -99,15 +110,14 @@ promclose(dev, flag, mode, p)
{
struct tty *tp;
int unit;
struct prom_softc *promp;
struct prom_softc *prom_sc;
unit = minor(dev);
PROM_CHECK(unit);
promp = UNIT_TO_PROMP(unit);
tp = promp->prom_t;
prom_sc = UNIT_TO_PROM_SC(unit);
tp = prom_sc->sc_tty;
(*linesw[tp->t_line].l_close)(tp, flag);
ttyclose(tp);
return 0;
return ttyclose(tp);
}
promread(dev, uio, flag)
@ -116,12 +126,12 @@ promread(dev, uio, flag)
{
int unit;
register struct tty *tp;
struct prom_softc *promp;
struct prom_softc *prom_sc;
unit = minor(dev);
PROM_CHECK(unit);
promp = UNIT_TO_PROMP(unit);
tp = promp->prom_t;
prom_sc = UNIT_TO_PROM_SC(unit);
tp = prom_sc->sc_tty;
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
promwrite(dev, uio, flag)
@ -130,31 +140,30 @@ promwrite(dev, uio, flag)
{
int unit;
register struct tty *tp;
struct prom_softc *promp;
struct prom_softc *prom_sc;
unit = minor(dev);
PROM_CHECK(unit);
promp = UNIT_TO_PROMP(unit);
tp = promp->prom_t;
prom_sc = UNIT_TO_PROM_SC(unit);
tp = prom_sc->sc_tty;
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
int promioctl(dev, cmd, data, flag)
int promioctl(dev, cmd, data, flag, p)
dev_t dev;
int cmd;
caddr_t data;
int flag;
struct proc *p;
{
int unit;
register struct tty *tp;
struct prom_softc *promp;
struct prom_softc *prom_sc;
int error;
unit = minor(dev);
PROM_CHECK(unit);
promp = UNIT_TO_PROMP(unit);
tp = promp->prom_t;
prom_sc = UNIT_TO_PROM_SC(unit);
tp = prom_sc->sc_tty;
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
if (error >= 0)
@ -162,22 +171,19 @@ int promioctl(dev, cmd, data, flag)
error = ttioctl(tp, cmd, data, flag);
if (error >= 0)
return error;
switch (cmd) {
default:
return ENOTTY;
}
return 0;
return ENOTTY;
}
void promstart(tp)
struct tty *tp;
{
int s;
int c;
int s, c, count;
u_char outbuf[50];
u_char *bufp;
s = spltty();
if (tp->t_state & (TS_BUSY | TS_TTSTOP)) goto out;
if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT)) goto out;
tp->t_state |= TS_BUSY;
if (tp->t_outq.c_cc <= tp->t_lowat) {
if (tp->t_state & TS_ASLEEP) {
tp->t_state &=~ TS_ASLEEP;
@ -185,30 +191,64 @@ void promstart(tp)
}
selwakeup(&tp->t_wsel);
}
if (tp->t_outq.c_cc == 0)
goto out;
tp->t_state |= TS_BUSY;
c = getc(&tp->t_outq);
mon_putchar(c);
count = q_to_b(&tp->t_outq, outbuf, 49);
if (count) {
outbuf[count] = '\0';
(void) splhigh();
mon_printf("%s", outbuf);
(void) spltty();
}
tp->t_state &= ~TS_BUSY;
out:
splx(s);
}
/*
* Stop output on a line.
*/
promstop(tp, flag)
register struct tty *tp;
static int promparam(tp, t)
struct tty *tp;
struct termios *t;
{
register int s;
struct prom_softc *prom_sc;
s = spltty();
if (tp->t_state & TS_BUSY) {
if ((tp->t_state&TS_TTSTOP)==0)
tp->t_state |= TS_FLUSH;
}
splx(s);
if (!t->c_ispeed || (t->c_ispeed != t->c_ospeed))
return EINVAL;
tp->t_ispeed = t->c_ispeed;
tp->t_ospeed = t->c_ospeed;
tp->t_cflag = t->c_cflag;
return 0;
}
static void promreceive(arg)
caddr_t arg;
{
struct tty *tp;
int c, s;
tp = (struct tty *) arg;
s = spltty();
if (tp->t_state & TS_ISOPEN) {
if ((tp->t_state & TS_BUSY) == 0) {
extern unsigned int orig_nmi_vector;
extern int nmi_intr();
set_clk_mode(0,IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5,0);
isr_add_custom(7, orig_nmi_vector);
set_clk_mode(IREG_CLOCK_ENAB_7,0,1);
c = mon_may_getchar();
set_clk_mode(0,IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5,0);
isr_add_custom(7, nmi_intr);
set_clk_mode(IREG_CLOCK_ENAB_5,0,1);
if (c != -1) {
(*linesw[tp->t_line].l_rint)(c, tp);
}
}
timeout((timeout_t) promreceive, (caddr_t) tp, hz/3);
}
else {
}
splx(s);
}
/* prom console support */
@ -223,7 +263,7 @@ promcnprobe(cp)
break;
cp->cn_dev = makedev(prommajor, 0);
cp->cn_pri = CN_NORMAL; /* will always exist but you don't
cp->cn_pri = CN_INTERNAL; /* will always exist but you don't
* want to use it unless you have to
*/
}
@ -248,7 +288,11 @@ promcnputc(dev, c)
dev_t dev;
int c;
{
int s;
s = splhigh();
if (minor(dev) != 0)
mon_printf("non unit 0 prom console???\n");
mon_putchar(c);
splx(s);
}

View File

@ -0,0 +1,146 @@
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* HISTORY
* $Log: scsi_5380.h,v $
* Revision 1.1 1994/02/23 08:28:53 glass
* boots, presents shell prompt, and doesn't crash immediately
*
* Revision 1.1 94/02/22 23:38:09 glass
* hey, it gets to a shell prompt
*
* Revision 2.3 91/08/24 12:25:10 af
* Moved padding of regmap in impl file.
* [91/08/02 04:22:39 af]
*
* Revision 2.2 91/06/19 16:28:35 rvb
* From the NCR data sheets
* "NCR 5380 Family, SCSI Protocol Controller Data Manual"
* NCR Microelectronics Division, Colorado Spring, 6/98 T01891L
* [91/04/21 af]
*
*/
/*
* File: scsi_5380.h
* Author: Alessandro Forin, Carnegie Mellon University
* Date: 5/91
*
* Defines for the NCR 5380 (SCSI chip), aka Am5380
*/
/*
* Register map
*/
typedef struct {
volatile unsigned char sci_data; /* r: Current data */
#define sci_odata sci_data /* w: Out data */
volatile unsigned char sci_icmd; /* rw: Initiator command */
volatile unsigned char sci_mode; /* rw: Mode */
volatile unsigned char sci_tcmd; /* rw: Target command */
volatile unsigned char sci_bus_csr; /* r: Bus Status */
#define sci_sel_enb sci_bus_csr /* w: Select enable */
volatile unsigned char sci_csr; /* r: Status */
#define sci_dma_send sci_csr /* w: Start dma send data */
volatile unsigned char sci_idata; /* r: Input data */
#define sci_trecv sci_idata /* w: Start dma receive, target */
volatile unsigned char sci_iack; /* r: Interrupt Acknowledge */
#define sci_irecv sci_iack /* w: Start dma receive, initiator */
} sci_regmap_t;
/*
* Initiator command register
*/
#define SCI_ICMD_DATA 0x01 /* rw: Assert data bus */
#define SCI_ICMD_ATN 0x02 /* rw: Assert ATN signal */
#define SCI_ICMD_SEL 0x04 /* rw: Assert SEL signal */
#define SCI_ICMD_BSY 0x08 /* rw: Assert BSY signal */
#define SCI_ICMD_ACK 0x10 /* rw: Assert ACK signal */
#define SCI_ICMD_LST 0x20 /* r: Lost arbitration */
#define SCI_ICMD_DIFF SCI_ICMD_LST /* w: Differential cable */
#define SCI_ICMD_AIP 0x40 /* r: Arbitration in progress */
#define SCI_ICMD_TEST SCI_ICMD_AIP /* w: Test mode */
#define SCI_ICMD_RST 0x80 /* rw: Assert RST signal */
/*
* Mode register
*/
#define SCI_MODE_ARB 0x01 /* rw: Start arbitration */
#define SCI_MODE_DMA 0x02 /* rw: Enable DMA xfers */
#define SCI_MODE_MONBSY 0x04 /* rw: Monitor BSY signal */
#define SCI_MODE_DMA_IE 0x08 /* rw: Enable DMA complete interrupt */
#define SCI_MODE_PERR_IE 0x10 /* rw: Interrupt on parity errors */
#define SCI_MODE_PAR_CHK 0x20 /* rw: Check parity */
#define SCI_MODE_TARGET 0x40 /* rw: Target mode (Initiator if 0) */
#define SCI_MODE_BLOCKDMA 0x80 /* rw: Block-mode DMA handshake (MBZ) */
/*
* Target command register
*/
#define SCI_TCMD_IO 0x01 /* rw: Assert I/O signal */
#define SCI_TCMD_CD 0x02 /* rw: Assert C/D signal */
#define SCI_TCMD_MSG 0x04 /* rw: Assert MSG signal */
#define SCI_TCMD_PHASE_MASK 0x07 /* r: Mask for current bus phase */
#define SCI_TCMD_REQ 0x08 /* rw: Assert REQ signal */
#define SCI_TCMD_LAST_SENT 0x80 /* ro: Last byte was xferred
* (not on 5380/1) */
#define SCI_PHASE(x) SCSI_PHASE(x)
/*
* Current (SCSI) Bus status
*/
#define SCI_BUS_DBP 0x01 /* r: Data Bus parity */
#define SCI_BUS_SEL 0x02 /* r: SEL signal */
#define SCI_BUS_IO 0x04 /* r: I/O signal */
#define SCI_BUS_CD 0x08 /* r: C/D signal */
#define SCI_BUS_MSG 0x10 /* r: MSG signal */
#define SCI_BUS_REQ 0x20 /* r: REQ signal */
#define SCI_BUS_BSY 0x40 /* r: BSY signal */
#define SCI_BUS_RST 0x80 /* r: RST signal */
#define SCI_CUR_PHASE(x) SCSI_PHASE((x)>>2)
/*
* Bus and Status register
*/
#define SCI_CSR_ACK 0x01 /* r: ACK signal */
#define SCI_CSR_ATN 0x02 /* r: ATN signal */
#define SCI_CSR_DISC 0x04 /* r: Disconnected (BSY==0) */
#define SCI_CSR_PHASE_MATCH 0x08 /* r: Bus and SCI_TCMD match */
#define SCI_CSR_INT 0x10 /* r: Interrupt request */
#define SCI_CSR_PERR 0x20 /* r: Parity error */
#define SCI_CSR_DREQ 0x40 /* r: DMA request */
#define SCI_CSR_DONE 0x80 /* r: DMA count is zero */

View File

@ -0,0 +1,58 @@
/*-
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
* Michael L. Finch, Bradley A. Grantham, and
* Lawrence A. Kesteloot
* 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 by the Alice Group.
* 4. The names of the Alice Group or any of its members may not be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
*
* $Id: scsi_defs.h,v 1.1 1994/02/23 08:28:55 glass Exp $
*
*/
#ifndef _SCSI_DEFS_H
#define _SCSI_DEFS_H
#define SCSI_PHASE_DATA_OUT 0x0
#define SCSI_PHASE_DATA_IN 0x1
#define SCSI_PHASE_CMD 0x2
#define SCSI_PHASE_STATUS 0x3
#define SCSI_PHASE_UNSPEC1 0x4
#define SCSI_PHASE_UNSPEC2 0x5
#define SCSI_PHASE_MESSAGE_OUT 0x6
#define SCSI_PHASE_MESSAGE_IN 0x7
#define SCSI_PHASE(x) ((x)&0x7)
/* These should be fixed up. */
#define SCSI_RET_SUCCESS 0
#define SCSI_RET_RETRY 1
#define SCSI_RET_DEVICE_DOWN 2
#define SCSI_RET_COMMAND_FAIL 3
#endif

968
sys/arch/sun3/dev/si.c Normal file
View File

@ -0,0 +1,968 @@
/*
* Copyright (C) 1994 Adam Glass
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
* Michael L. Finch, Bradley A. Grantham, and
* Lawrence A. Kesteloot
* 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 by the Alice Group.
* 4. The names of the Alice Group or any of its members may not be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
*
* $Id: si.c,v 1.1 1994/02/23 08:28:56 glass Exp $
*
*/
#define PSEUDO_DMA 1
static int pdebug=0;
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/isr.h>
#include <machine/mtpr.h>
#include <machine/obio.h>
#include "../scsi/scsi_all.h"
#include "../scsi/scsi_debug.h"
#include "../scsi/scsiconf.h"
#include "scsi_defs.h"
#include "scsi_5380.h"
#define SCI_PHASE_DISC 0 /* sort of ... */
#define SCI_CLR_INTR(regs) {register int temp = regs->sci_iack;}
#define SCI_ACK(ptr,phase) (ptr)->sci_tcmd = (phase)
#define SCSI_TIMEOUT_VAL 10000000
#define WAIT_FOR_NOT_REQ(ptr) { \
int scsi_timeout = SCSI_TIMEOUT_VAL; \
while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
(--scsi_timeout) ); \
if (!scsi_timeout) { \
printf("scsi timeout--WAIT_FOR_NOT_REQ---scsi.c, line %d.\n", __LINE__); \
goto scsi_timeout_error; \
} \
}
#define WAIT_FOR_REQ(ptr) { \
int scsi_timeout = SCSI_TIMEOUT_VAL; \
while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
(--scsi_timeout) ); \
if (!scsi_timeout) { \
printf("scsi timeout--WAIT_FOR_REQ---scsi.c, line %d.\n", __LINE__); \
goto scsi_timeout_error; \
} \
}
#define WAIT_FOR_BSY(ptr) { \
int scsi_timeout = SCSI_TIMEOUT_VAL; \
while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
(--scsi_timeout) ); \
if (!scsi_timeout) { \
printf("scsi timeout--WAIT_FOR_BSY---scsi.c, line %d.\n", __LINE__); \
goto scsi_timeout_error; \
} \
}
#ifdef DDB
int Debugger();
#else
#define Debugger() panic("Should call Debugger here (sun3/dev/scsi.c).")
#endif
struct ncr5380_softc {
struct device sc_dev;
void *sc_regs;
int sc_adapter_target;
struct scsi_link sc_link;
};
#if 0
In your dreams dude...
/* From Guide to Mac II family hardware, p. 137 */
static volatile sci_padded_regmap_t *ncr = (sci_regmap_t *) 0x50F10000;
static volatile long *sci_4byte_addr= (long *) 0x50F06000;
static volatile u_char *sci_1byte_addr=(u_char *) 0x50F12000;
#endif
static unsigned int ncr5380_adapter_info(struct ncr5380_softc *ncr5380);
static void ncr5380_minphys(struct buf *bp);
static int ncr5380_scsi_cmd(struct scsi_xfer *xs);
static int ncr5380_show_scsi_cmd(struct scsi_xfer *xs);
static int ncr5380_reset_target(int adapter, int target);
static int ncr5380_poll(int adapter, int timeout);
static int ncr5380_send_cmd(struct scsi_xfer *xs);
extern void ncr5380_intr(int adapter);
extern void spinwait(int);
static void delay(int);
static int scsi_gen(int adapter, int id, int lun,
struct scsi_generic *cmd, int cmdlen,
void *databuf, int datalen);
static int scsi_group0(int adapter, int id, int lun,
int opcode, int addr, int len,
int flags, caddr_t databuf, int datalen);
static char scsi_name[] = "si";
struct scsi_adapter ncr5380_switch = {
ncr5380_scsi_cmd, /* scsi_cmd() */
ncr5380_minphys, /* scsi_minphys() */
0, /* open_target_lu() */
0, /* close_target_lu() */
ncr5380_adapter_info, /* adapter_info() */
scsi_name, /* name */
{0, 0} /* spare[3] */
};
/* This is copied from julian's bt driver */
/* "so we have a default dev struct for our link struct." */
struct scsi_device ncr_dev = {
NULL, /* Use default error handler. */
NULL, /* have a queue, served by this (?) */
NULL, /* have no async handler. */
NULL, /* Use default "done" routine. */
"si",
0,
0, 0
};
extern int matchbyname();
static int ncrprobe();
static void ncrattach();
struct cfdriver ncrcd =
{ NULL, "si", ncrprobe, ncrattach,
DV_DULL, sizeof(struct ncr5380_softc), NULL, 0 };
static int
ncr_print(aux, name)
void *aux;
char *name;
{
/* printf("%s: (sc_link = 0x%x)", name, (int) aux);
return UNCONF;*/
}
static int
ncrprobe(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
caddr_t si_addr;
struct obio_cf_loc *obio_loc = (struct obio_cf_loc *) CFDATA_LOC(cf);
si_addr = OBIO_DEFAULT_PARAM(caddr_t, obio_loc->obio_addr, OBIO_NCR_SCSI);
return /* !obio_probe_byte(si_addr)*/ 1;
}
static void
ncrattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
caddr_t dvma_malloc(), si_addr;
int level, ncr_intr(), unit = DEVICE_UNIT(self);
struct ncr5380_softc *ncr5380 = (struct ncr5380_softc *) self;
struct obio_cf_loc *obio_loc = OBIO_LOC(self);
si_addr = OBIO_DEFAULT_PARAM(caddr_t, obio_loc->obio_addr, OBIO_NCR_SCSI);
ncr5380->sc_regs = (sci_regmap_t *)
obio_alloc(si_addr, OBIO_AMD_ETHER_SIZE, OBIO_WRITE);
level = OBIO_DEFAULT_PARAM(int, obio_loc->obio_level, 3);
ncr5380->sc_link.scsibus = unit;
ncr5380->sc_link.adapter_targ = 7;
ncr5380->sc_link.adapter = &ncr5380_switch;
ncr5380->sc_link.device = &ncr_dev;
obio_print(si_addr, level);
printf("\n");
config_found(self, &(ncr5380->sc_link), ncr_print);
}
static unsigned int
ncr5380_adapter_info(struct ncr5380_softc *ncr5380)
{
return 1;
}
#define MIN_PHYS 65536 /*BARF!!!!*/
static void
ncr5380_minphys(struct buf *bp)
{
if (bp->b_bcount > MIN_PHYS) {
printf("Uh-oh... ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS);
bp->b_bcount = MIN_PHYS;
}
}
#undef MIN_PHYS
static int
ncr5380_scsi_cmd(struct scsi_xfer *xs)
{
int flags, s, r;
flags = xs->flags;
if (xs->bp) flags |= (SCSI_NOSLEEP);
if ( flags & ITSDONE ) {
printf("Already done?");
xs->flags &= ~ITSDONE;
}
if ( ! ( flags & INUSE ) ) {
printf("Not in use?");
xs->flags |= INUSE;
}
if ( flags & SCSI_RESET ) {
printf("flags & SCSIRESET.\n");
if ( ! ( flags & SCSI_NOSLEEP ) ) {
s = splbio();
ncr5380_reset_target(xs->sc_link->scsibus, xs->sc_link->target);
splx(s);
return(SUCCESSFULLY_QUEUED);
} else {
ncr5380_reset_target(xs->sc_link->scsibus, xs->sc_link->target);
if (ncr5380_poll(xs->sc_link->scsibus, xs->timeout)) {
return (HAD_ERROR);
}
return (COMPLETE);
}
}
/*
* OK. Now that that's over with, let's pack up that
* SCSI puppy and send it off. If we can, we'll just
* queue and go; otherwise, we'll wait for the command
* to finish.
if ( ! ( flags & SCSI_NOSLEEP ) ) {
s = splbio();
ncr5380_send_cmd(xs);
splx(s);
return(SUCCESSFULLY_QUEUED);
}
*/
r = ncr5380_send_cmd(xs);
xs->flags |= ITSDONE;
scsi_done(xs);
switch(r) {
case COMPLETE: case SUCCESSFULLY_QUEUED:
r = SUCCESSFULLY_QUEUED;
if (xs->flags&SCSI_NOMASK)
r = COMPLETE;
break;
default:
break;
}
return r;
/*
do {
if (ncr5380_poll(xs->sc_link->scsibus, xs->timeout)) {
if ( ! ( xs->flags & SCSI_SILENT ) )
printf("cmd fail.\n");
cmd_cleanup
xs->error = XS_DRIVER_STUFFUP;
splx(s);
}
} while ( ! ( xs->flags & ITSDONE ) );
*/
}
static int
ncr5380_show_scsi_cmd(struct scsi_xfer *xs)
{
u_char *b = (u_char *) xs->cmd;
int i = 0;
if ( ! ( xs->flags & SCSI_RESET ) ) {
printf("si(%d:%d:%d)-",
xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun);
while (i < xs->cmdlen) {
if (i) printf(",");
printf("%x",b[i++]);
}
printf("-\n");
} else {
printf("si(%d:%d:%d)-RESET-\n",
xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun);
}
}
/*
* Actual chip control.
*/
static void
delay(int timeo)
{
int len;
for (len=0;len<timeo*2;len++);
}
extern void
spinwait(int ms)
{
while (ms--)
delay(500);
}
extern void
ncr5380_intr(int adapter)
{
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
SCI_CLR_INTR(regs);
regs->sci_mode = 0x00;
}
#if 0
extern int
scsi_irq_intr(void)
{
register volatile sci_regmap_t *regs = ncr;
/* if (regs->sci_csr != SCI_CSR_PHASE_MATCH)
printf("scsi_irq_intr called (not just phase match -- "
"csr = 0x%x, bus_csr = 0x%x).\n",
regs->sci_csr, regs->sci_bus_csr);
ncr5380_intr(0); */
return 1;
}
#endif
#if 0
extern int
scsi_drq_intr(void)
{
/* printf("scsi_drq_intr called.\n"); */
/* ncr5380_intr(0); */
return 1;
}
#endif
static int
ncr5380_reset_target(int adapter, int target)
{
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
int dummy;
regs->sci_icmd = SCI_ICMD_TEST;
regs->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST;
delay(2500);
regs->sci_icmd = 0;
regs->sci_mode = 0;
regs->sci_tcmd = SCI_PHASE_DISC;
regs->sci_sel_enb = 0;
SCI_CLR_INTR(regs);
SCI_CLR_INTR(regs);
}
static int
ncr5380_poll(int adapter, int timeout)
{
}
static int
ncr5380_send_cmd(struct scsi_xfer *xs)
{
int s;
int sense;
/* ncr5380_show_scsi_cmd(xs); */
s = splbio();
sense = scsi_gen( xs->sc_link->scsibus, xs->sc_link->target,
xs->sc_link->lun, xs->cmd, xs->cmdlen,
xs->data, xs->datalen );
splx(s);
if (sense) {
switch (sense) {
case 0x02: /* Check condition */
/* printf("check cond. target %d.\n", xs->targ);*/
s = splbio();
scsi_group0(xs->sc_link->scsibus,
xs->sc_link->target,
xs->sc_link->lun,
0x3, 0x0,
sizeof(struct scsi_sense_data),
0, (caddr_t) &(xs->sense),
sizeof(struct scsi_sense_data));
splx(s);
xs->error = XS_SENSE;
return HAD_ERROR;
case 0x08: /* Busy */
xs->error = XS_BUSY;
return HAD_ERROR;
default:
xs->error = XS_DRIVER_STUFFUP;
return HAD_ERROR;
}
}
xs->error = XS_NOERROR;
return (COMPLETE);
}
static int
select_target(register volatile sci_regmap_t *regs,
u_char myid, u_char tid, int with_atn)
{
register u_char bid, icmd;
int ret = SCSI_RET_RETRY;
if ((regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
(regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
(regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
return ret;
/* for our purposes.. */
myid = 1 << myid;
tid = 1 << tid;
regs->sci_sel_enb = 0; /*myid; we don't want any interrupts. */
regs->sci_odata = myid;
regs->sci_mode = SCI_MODE_ARB;
/* regs->sci_mode |= SCI_MODE_ARB; */
/* AIP might not set if BSY went true after we checked */
for (bid = 0; bid < 20; bid++) /* 20usec circa */
if (regs->sci_icmd & SCI_ICMD_AIP)
break;
if ((regs->sci_icmd & SCI_ICMD_AIP) == 0) {
goto lost;
}
spinwait(2); /* 2.2us arb delay */
if (regs->sci_icmd & SCI_ICMD_LST) {
goto lost;
}
regs->sci_mode &= ~SCI_MODE_PAR_CHK;
bid = regs->sci_data;
if ((bid & ~myid) > myid) {
goto lost;
}
if (regs->sci_icmd & SCI_ICMD_LST) {
goto lost;
}
/* Won arbitration, enter selection phase now */
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
icmd |= SCI_ICMD_BSY;
regs->sci_icmd = icmd;
if (regs->sci_icmd & SCI_ICMD_LST) {
goto nosel;
}
/* XXX a target that violates specs might still drive the bus XXX */
/* XXX should put our id out, and after the delay check nothi XXX */
/* XXX ng else is out there. XXX */
delay(0);
regs->sci_tcmd = 0;
regs->sci_odata = myid | tid;
regs->sci_sel_enb = 0;
/* regs->sci_mode &= ~SCI_MODE_ARB; 2 deskew delays, too */
regs->sci_mode = 0; /* 2 deskew delays, too */
icmd |= SCI_ICMD_DATA;
icmd &= ~(SCI_ICMD_BSY);
regs->sci_icmd = icmd;
/* bus settle delay, 400ns */
delay(2); /* too much (was 2) ? */
/* regs->sci_mode |= SCI_MODE_PAR_CHK; */
{
register int timeo = 2500;/* 250 msecs in 100 usecs chunks */
while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
if (--timeo > 0) {
delay(100);
} else {
goto nodev;
}
}
}
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
regs->sci_icmd = icmd;
/* regs->sci_sel_enb = myid;*/ /* looks like we should NOT have it */
return SCSI_RET_SUCCESS;
nodev:
ret = SCSI_RET_DEVICE_DOWN;
regs->sci_sel_enb = myid;
nosel:
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL|SCI_ICMD_ATN);
regs->sci_icmd = icmd;
lost:
regs->sci_mode = 0;
return ret;
}
sci_data_out(regs, phase, count, data)
register sci_regmap_t *regs;
unsigned char *data;
{
register unsigned char icmd;
register int cnt=0;
/* ..checks.. */
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
loop:
if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
return cnt;
WAIT_FOR_REQ(regs);
icmd |= SCI_ICMD_DATA;
regs->sci_icmd = icmd;
regs->sci_odata = *data++;
icmd |= SCI_ICMD_ACK;
regs->sci_icmd = icmd;
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
WAIT_FOR_NOT_REQ(regs);
regs->sci_icmd = icmd;
++cnt;
if (--count > 0)
goto loop;
scsi_timeout_error:
return cnt;
}
sci_data_in(regs, phase, count, data)
register sci_regmap_t *regs;
unsigned char *data;
{
register unsigned char icmd;
register int cnt=0;
/* ..checks.. */
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
loop:
if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
return cnt;
WAIT_FOR_REQ(regs);
*data++ = regs->sci_data;
icmd |= SCI_ICMD_ACK;
regs->sci_icmd = icmd;
icmd &= ~SCI_ICMD_ACK;
WAIT_FOR_NOT_REQ(regs);
regs->sci_icmd = icmd;
++cnt;
if (--count > 0)
goto loop;
scsi_timeout_error:
return cnt;
}
static int
command_transfer(register volatile sci_regmap_t *regs,
int maxlen, u_char *data, u_char *status, u_char *msg)
{
int xfer=0, phase;
/* printf("command_transfer called for 0x%x.\n", *data); */
regs->sci_icmd = 0;
while (1) {
WAIT_FOR_REQ(regs);
phase = SCI_CUR_PHASE(regs->sci_bus_csr);
switch (phase) {
case SCSI_PHASE_CMD:
SCI_ACK(regs,SCSI_PHASE_CMD);
xfer += sci_data_out(regs, SCSI_PHASE_CMD,
maxlen, data);
return xfer;
case SCSI_PHASE_DATA_IN:
printf("Data in phase in command_transfer?\n");
return 0;
case SCSI_PHASE_DATA_OUT:
printf("Data out phase in command_transfer?\n");
return 0;
case SCSI_PHASE_STATUS:
SCI_ACK(regs,SCSI_PHASE_STATUS);
printf("status in command_transfer.\n");
sci_data_in(regs, SCSI_PHASE_STATUS,
1, status);
break;
case SCSI_PHASE_MESSAGE_IN:
SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
printf("msgin in command_transfer.\n");
sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
1, msg);
break;
case SCSI_PHASE_MESSAGE_OUT:
SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
1, msg);
break;
default:
printf("Unexpected phase 0x%x in "
"command_transfer().\n", phase);
scsi_timeout_error:
return xfer;
break;
}
}
}
static int
data_transfer(register volatile sci_regmap_t *regs,
int maxlen, u_char *data, u_char *status, u_char *msg)
{
int retlen = 0, xfer, phase;
regs->sci_icmd = 0;
*status = 0;
while (1) {
WAIT_FOR_REQ(regs);
phase = SCI_CUR_PHASE(regs->sci_bus_csr);
switch (phase) {
case SCSI_PHASE_CMD:
printf("Command phase in data_transfer().\n");
return retlen;
case SCSI_PHASE_DATA_IN:
SCI_ACK(regs,SCSI_PHASE_DATA_IN);
#if PSEUDO_DMA
xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
maxlen, data);
#else
xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
maxlen, data);
#endif
retlen += xfer;
maxlen -= xfer;
break;
case SCSI_PHASE_DATA_OUT:
SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
#if PSEUDO_DMA
xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
maxlen, data);
#else
xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
maxlen, data);
#endif
retlen += xfer;
maxlen -= xfer;
break;
case SCSI_PHASE_STATUS:
SCI_ACK(regs,SCSI_PHASE_STATUS);
sci_data_in(regs, SCSI_PHASE_STATUS,
1, status);
break;
case SCSI_PHASE_MESSAGE_IN:
SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
1, msg);
if (*msg == 0) {
return retlen;
} else {
printf( "message 0x%x in "
"data_transfer.\n", *msg);
}
break;
case SCSI_PHASE_MESSAGE_OUT:
SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
1, msg);
break;
default:
printf( "Unexpected phase 0x%x in "
"data_transfer().\n", phase);
scsi_timeout_error:
return retlen;
break;
}
}
}
static int
scsi_request(register volatile sci_regmap_t *regs,
int target, int lun, u_char *cmd, int cmdlen,
char *databuf, int datalen, int *sent, int *ret)
{
/* Returns 0 on success, -1 on internal error, or the status byte */
int cmd_bytes_sent, r;
u_char stat, msg, c;
*sent = 0;
if ( ( r = select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
*ret = r;
SCI_CLR_INTR(regs);
switch (r) {
case SCSI_RET_RETRY:
return 0x08;
default:
printf("select_target(target %d, lun %d) failed(%d).\n",
target, lun, r);
case SCSI_RET_DEVICE_DOWN:
return -1;
}
}
c = 0x80 | lun;
if ((cmd_bytes_sent = command_transfer(regs, cmdlen,
(u_char *) cmd, &stat, &c))
!= cmdlen) {
SCI_CLR_INTR(regs);
*ret = SCSI_RET_COMMAND_FAIL;
printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
cmd_bytes_sent, cmdlen);
return -1;
}
*sent=data_transfer(regs, datalen, (u_char *)databuf,
&stat, &msg);
*ret = 0;
return stat;
}
static int
scsi_gen(int adapter, int id, int lun, struct scsi_generic *cmd,
int cmdlen, void *databuf, int datalen)
{
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
int i,j,sent,ret;
cmd->bytes[0] = ((u_char) lun << 5);
i = scsi_request(regs, id, lun, (u_char *) cmd, cmdlen,
databuf, datalen, &sent, &ret);
return i;
}
static int
scsi_group0(int adapter, int id, int lun, int opcode, int addr, int len,
int flags, caddr_t databuf, int datalen)
{
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
unsigned char cmd[6];
int i,j,sent,ret;
cmd[0] = opcode; /* Operation code */
cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F); /* Lun & MSB of addr */
cmd[2] = (addr >> 8) & 0xFF; /* addr */
cmd[3] = addr & 0xFF; /* LSB of addr */
cmd[4] = len; /* Allocation length */
cmd[5] = flags; /* Link/Flag */
i = scsi_request(regs, id, lun, cmd, 6, databuf, datalen, &sent, &ret);
return i;
}
/* pseudo-dma action */
#if PSEUDO_DMA
#define TIMEOUT 1000000
#define READY(poll) \
i = TIMEOUT; \
while ((regs->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \
!=(SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \
if ( !(regs->sci_csr & SCI_CSR_PHASE_MATCH) \
|| !(regs->sci_bus_csr & SCI_BUS_BSY) \
|| (i-- < 0) ) { \
printf("scsi.c: timeout counter = %d, len = %d count=%d (count-len %d).\n", \
i, len,count,count-len); \
printf("pdebug = %d, 1=out, 2=in",pdebug); \
/*dump_regs();*/ \
if (poll && !(regs->sci_csr & SCI_CSR_PHASE_MATCH)) { \
regs->sci_icmd &= ~SCI_ICMD_DATA; \
len--; \
} else { \
regs->sci_mode &= ~SCI_MODE_DMA; \
} \
return count-len; \
}
#define W1 *byte_data = *data++
#define W4 W1; W1; W1; W1;
/*#define W4 *long_data = *((long*)data)++*/
sci_pdma_out(regs, phase, count, data)
register volatile sci_regmap_t *regs;
int phase;
int count;
u_char *data;
{
register volatile u_char *byte_data = (u_char *)&regs->sci_data;
register int len = count, i;
pdebug=1;
if (count < 128)
return sci_data_out(regs, phase, count, data);
WAIT_FOR_BSY(regs);
regs->sci_mode |= SCI_MODE_DMA;
regs->sci_icmd |= SCI_ICMD_DATA;
regs->sci_dma_send = 0;
while ( len >= 64 ) {
READY(1); W1; READY(1); W1; READY(1); W1; READY(1); W1;
READY(1);
W4;W4;W4; W4;W4;W4;W4; W4;W4;W4;W4; W4;W4;W4;W4;
len -= 64;
}
while (len) {
READY(1);
W1;
len--;
}
i = TIMEOUT;
while ( ((regs->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
== SCI_CSR_PHASE_MATCH) && --i);
if (!i)
printf("scsi.c:%d: timeout waiting for SCI_CSR_DREQ.\n", __LINE__);
*byte_data = 0;
scsi_timeout_error:
regs->sci_mode &= ~SCI_MODE_DMA;
return count-len;
}
#undef W1
#undef W4
#define R1 *data++ = *byte_data
#define R4 R1; R1; R1; R1;
/*#define R4 (*((long *)data)++ = *long_data*/
sci_pdma_in(regs, phase, count, data)
register volatile sci_regmap_t *regs;
int phase;
int count;
u_char *data;
{
register volatile u_char *byte_data = (u_char *) &regs->sci_data;
register int len = count, i;
pdebug=2;
if (count < 128)
return sci_data_in(regs, phase, count, data);
/* printf("Called sci_pdma_in(0x%x, 0x%x, %d, 0x%x.\n", regs, phase, count, data); */
WAIT_FOR_BSY(regs);
regs->sci_mode |= SCI_MODE_DMA;
regs->sci_icmd |= SCI_ICMD_DATA;
regs->sci_irecv = 0;
while (len >= 1024) {
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 128 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 256 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 384 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 512 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 640 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 768 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 896 */
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /*1024 */
len -= 1024;
}
while (len >= 128) {
READY(0);
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 128 */
len -= 128;
}
while (len) {
READY(0);
R1;
len--;
}
scsi_timeout_error:
regs->sci_mode &= ~SCI_MODE_DMA;
return count - len;
}
#undef R4
#undef R1
#endif

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)vuid_event.h 8.1 (Berkeley) 6/11/93
*
* from: Header: vuid_event.h,v 1.4 92/11/26 01:20:27 torek Exp (LBL)
* $Id: vuid_event.h,v 1.1 1994/02/23 08:28:58 glass Exp $
*/
/*
* The following is a minimal emulation of Sun's `Firm_event' structures
* and related operations necessary to make X11 happy (i.e., make it
* compile, and make old X11 binaries run).
*/
typedef struct firm_event {
u_short id; /* key or MS_* or LOC_[XY]_DELTA */
u_short pad; /* unused, at least by X11 */
int value; /* VKEY_{UP,DOWN} or locator delta */
struct timeval time;
} Firm_event;
/*
* Special `id' fields. These weird numbers simply match the old binaries.
* Others are in 0..0x7f and are keyboard key numbers (keyboard dependent!).
*/
#define MS_LEFT 0x7f20 /* left mouse button */
#define MS_MIDDLE 0x7f21 /* middle mouse button */
#define MS_RIGHT 0x7f22 /* right mouse button */
#define LOC_X_DELTA 0x7f80 /* mouse delta-X */
#define LOC_Y_DELTA 0x7f81 /* mouse delta-Y */
/*
* Special `value' fields. These apply to keys and mouse buttons. The
* value of a mouse delta is the delta. Note that positive deltas are
* left and up (not left and down as you might expect).
*/
#define VKEY_UP 0 /* key or button went up */
#define VKEY_DOWN 1 /* key or button went down */
/*
* The following ioctls are clearly intended to take things in and out
* of `firm event' mode. Since we always run in this mode (as far as
* /dev/kbd and /dev/mouse are concerned, anyway), we always claim to
* be in this mode and reject anything else.
*/
#define VUIDSFORMAT _IOW('v', 1, int)
#define VUIDGFORMAT _IOR('v', 2, int)
#define VUID_FIRM_EVENT 1 /* the only format we support */

1341
sys/arch/sun3/dev/zs.c Normal file

File diff suppressed because it is too large Load Diff

433
sys/arch/sun3/dev/zsreg.h Normal file
View File

@ -0,0 +1,433 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)zsreg.h 8.1 (Berkeley) 6/11/93
*
* from: Header: zsreg.h,v 1.7 92/11/26 01:27:18 torek Exp (LBL)
* $Id: zsreg.h,v 1.1 1994/02/23 08:29:03 glass Exp $
*/
/*
* Zilog SCC registers, as implemented on the Sun-4c.
*
* Each Z8530 implements two channels (called `a' and `b').
*
* The damnable chip was designed to fit on Z80 I/O ports, and thus
* has everything multiplexed out the wazoo. We have to select
* a register, then read or write the register, and so on. Worse,
* the parameter bits are scattered all over the register space.
* This thing is full of `miscellaneous' control registers.
*
* Worse yet, the registers have incompatible functions on read
* and write operations. We describe the registers below according
* to whether they are `read registers' (RR) or `write registers' (WR).
* As if this were not enough, some of the channel B status bits show
* up in channel A, and vice versa. The blasted thing shares write
* registers 2 and 9 across both channels, and reads registers 2 and 3
* differently for the two channels. We can, however, ignore this much
* of the time.
*/
#ifndef LOCORE
struct zschan {
u_char zc_csr; /* control and status, and indirect access */
u_char zc_xxx0;
u_char zc_data; /* data */
u_char zc_xxx1;
};
/*
* N.B.: the keyboard is channel 1, the mouse channel 0; ttyb is 1, ttya
* is 0. In other words, the things are BACKWARDS.
*/
struct zsdevice {
struct zschan zs_chan[2]; /* channel A = 1, B = 0 */
};
#define CHAN_A 1
#define CHAN_B 0
#endif
/*
* Some of the names in this files were chosen to make the hsis driver
* work unchanged (which means that they will match some in SunOS).
*
* `S.C.' stands for Special Condition, which is any of these:
* receiver overrun (aka silo overflow)
* framing error (missing stop bit, etc)
* end of frame (in synchronous modes)
* parity error (when `parity error is S.C.' is set)
*/
/*
* Registers with only a single `numeric value' get a name.
* Other registers hold bits and are only numbered; the bit
* definitions imply the register number (see below).
*
* We never use the receive and transmit data registers as
* indirects (choosing instead the zc_data register), so they
* are not defined here.
*/
#define ZSRR_IVEC 2 /* interrupt vector (channel 0) */
#define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */
#define ZSRR_BAUDLO 12 /* baud rate generator (low half) */
#define ZSRR_BAUDHI 13 /* baud rate generator (high half) */
#define ZSWR_IVEC 2 /* interrupt vector (shared) */
#define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */
#define ZSWR_RXSYNC 7 /* sync receive char (monosync mode) */
#define ZSWR_SYNCLO 6 /* sync low byte (bisync mode) */
#define ZSWR_SYNCHI 7 /* sync high byte (bisync mode) */
#define ZSWR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
#define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
#define ZSWR_BAUDLO 12 /* baud rate generator (low half) */
#define ZSWR_BAUDHI 13 /* baud rate generator (high half) */
/*
* Registers 0 through 7 may be written with any one of the 8 command
* modifiers, and/or any one of the 4 reset modifiers, defined below.
* To write registers 8 through 15, however, the command modifier must
* always be `point high'. Rather than track this bizzareness all over
* the driver, we try to avoid using any modifiers, ever (but they are
* defined here if you want them).
*/
#define ZSM_RESET_TXUEOM 0xc0 /* reset xmit underrun / eom latch */
#define ZSM_RESET_TXCRC 0x80 /* reset xmit crc generator */
#define ZSM_RESET_RXCRC 0x40 /* reset recv crc checker */
#define ZSM_NULL 0x00 /* nothing special */
#define ZSM_RESET_IUS 0x38 /* reset interrupt under service */
#define ZSM_RESET_ERR 0x30 /* reset error cond */
#define ZSM_RESET_TXINT 0x28 /* reset xmit interrupt pending */
#define ZSM_EI_NEXTRXC 0x20 /* enable int. on next rcvd char */
#define ZSM_SEND_ABORT 0x18 /* send abort (SDLC) */
#define ZSM_RESET_STINT 0x10 /* reset external/status interrupt */
#define ZSM_POINTHIGH 0x08 /* `point high' (use r8-r15) */
#define ZSM_NULL 0x00 /* nothing special */
/*
* Commands for Write Register 0 (`Command Register').
* These are just the command modifiers or'ed with register number 0
* (which of course equals the command modifier).
*/
#define ZSWR0_RESET_EOM ZSM_RESET_TXUEOM
#define ZSWR0_RESET_TXCRC ZSM_RESET_TXCRC
#define ZSWR0_RESET_RXCRC ZSM_RESET_RXCRC
#define ZSWR0_CLR_INTR ZSM_RESET_IUS
#define ZSWR0_RESET_ERRORS ZSM_RESET_ERR
#define ZSWR0_EI_NEXTRXC ZSM_EI_NEXTRXC
#define ZSWR0_SEND_ABORT ZSM_SEND_ABORT
#define ZSWR0_RESET_STATUS ZSM_RESET_STINT
#define ZSWR0_RESET_TXINT ZSM_RESET_TXINT
/*
* Bits in Write Register 1 (`Transmit/Receive Interrupt and Data
* Transfer Mode Definition'). Note that bits 3 and 4 are taken together
* as a single unit, and bits 5 and 6 are useful only if bit 7 is set.
*/
#define ZSWR1_REQ_WAIT 0x80 /* WAIT*-REQ* pin gives WAIT* */
#define ZSWR1_REQ_REQ 0xc0 /* WAIT*-REQ* pin gives REQ* */
#define ZSWR1_REQ_TX 0x00 /* WAIT*-REQ* pin follows xmit buf */
#define ZSWR1_REQ_RX 0x20 /* WAIT*-REQ* pin follows recv buf */
#define ZSWR1_RIE_NONE 0x00 /* disable rxint entirely */
#define ZSWR1_RIE_FIRST 0x08 /* rxint on first char & on S.C. */
#define ZSWR1_RIE 0x10 /* rxint per char & on S.C. */
#define ZSWR1_RIE_SPECIAL_ONLY 0x18 /* rxint on S.C. only */
#define ZSWR1_PE_SC 0x04 /* parity error is special condition */
#define ZSWR1_TIE 0x02 /* transmit interrupt enable */
#define ZSWR1_SIE 0x01 /* external/status interrupt enable */
/* HSIS compat */
#define ZSWR1_REQ_ENABLE (ZSWR1_REQ_WAIT | ZSWR1_REQ_TX)
/*
* Bits in Write Register 3 (`Receive Parameters and Control').
* Bits 7 and 6 are taken as a unit. Note that the receive bits
* per character ordering is insane.
*
* Here `hardware flow control' means CTS enables the transmitter
* and DCD enables the receiver. The latter is neither interesting
* nor useful, and gets in our way, making it almost unusable.
*/
#define ZSWR3_RX_5 0x00 /* receive 5 bits per char */
#define ZSWR3_RX_7 0x40 /* receive 7 bits per char */
#define ZSWR3_RX_6 0x80 /* receive 6 bits per char */
#define ZSWR3_RX_8 0xc0 /* receive 8 bits per char */
#define ZSWR3_HFC 0x20 /* hardware flow control */
#define ZSWR3_HUNT 0x10 /* enter hunt mode */
#define ZSWR3_RXCRC_ENABLE 0x08 /* enable recv crc calculation */
#define ZSWR3_ADDR_SEARCH_MODE 0x04 /* address search mode (SDLC only) */
#define ZSWR3_SYNC_LOAD_INH 0x02 /* sync character load inhibit */
#define ZSWR3_RX_ENABLE 0x01 /* receiver enable */
/*
* Bits in Write Register 4 (`Transmit/Receive Miscellaneous Parameters
* and Modes'). Bits 7&6, 5&4, and 3&2 are taken as units.
*/
#define ZSWR4_CLK_X1 0x00 /* clock divisor = 1 */
#define ZSWR4_CLK_X16 0x40 /* clock divisor = 16 */
#define ZSWR4_CLK_X32 0x80 /* clock divisor = 32 */
#define ZSWR4_CLK_X64 0xc0 /* clock divisor = 64 */
#define ZSWR4_MONOSYNC 0x00 /* 8 bit sync char (sync only) */
#define ZSWR4_BISYNC 0x10 /* 16 bit sync char (sync only) */
#define ZSWR4_SDLC 0x20 /* SDLC mode */
#define ZSWR4_EXTSYNC 0x30 /* external sync mode */
#define ZSWR4_SYNCMODE 0x00 /* one of the above sync modes */
#define ZSWR4_ONESB 0x04 /* 1 stop bit */
#define ZSWR4_1P5SB 0x08 /* 1.5 stop bits (clk cannot be 1x) */
#define ZSWR4_TWOSB 0x0c /* 2 stop bits */
#define ZSWR4_EVENP 0x02 /* check for even parity */
#define ZSWR4_PARENB 0x01 /* enable parity checking */
/*
* Bits in Write Register 5 (`Transmit Parameter and Controls').
* Bits 6 and 5 are taken as a unit; the ordering is, as with RX
* bits per char, not sensible.
*/
#define ZSWR5_DTR 0x80 /* assert (set to -12V) DTR */
#define ZSWR5_TX_5 0x00 /* transmit 5 or fewer bits */
#define ZSWR5_TX_7 0x20 /* transmit 7 bits */
#define ZSWR5_TX_6 0x40 /* transmit 6 bits */
#define ZSWR5_TX_8 0x60 /* transmit 8 bits */
#define ZSWR5_BREAK 0x10 /* send break (continuous 0s) */
#define ZSWR5_TX_ENABLE 0x08 /* enable transmitter */
#define ZSWR5_CRC16 0x04 /* use CRC16 (off => use SDLC) */
#define ZSWR5_RTS 0x02 /* assert RTS */
#define ZSWR5_TXCRC_ENABLE 0x01 /* enable xmit crc calculation */
#ifdef not_done_here
/*
* Bits in Write Register 7 when the chip is in SDLC mode.
*/
#define ZSWR7_SDLCFLAG 0x7e /* this value makes SDLC mode work */
#endif
/*
* Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6
* are taken as a unit and indicate the type of reset; 00 means no reset
* (and is not defined here).
*/
#define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */
#define ZSWR9_A_RESET 0x80 /* reset channel A (0) */
#define ZSWR9_B_RESET 0x40 /* reset channel B (1) */
/* 0x20 unused */
#define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */
#define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */
#define ZSWR9_DLC 0x04 /* disable lower chain */
#define ZSWR9_NO_VECTOR 0x02 /* no vector */
#define ZSWR9_VECTOR_INCL_STAT 0x01 /* vector includes status */
/*
* Bits in Write Register 10 (`Miscellaneous Transmitter/Receiver Control
* Bits'). Bits 6 & 5 are taken as a unit, and some of the bits are
* meaningful only in certain modes. Bleah.
*/
#define ZSWR10_PRESET_ONES 0x80 /* preset CRC to all 1 (else all 0) */
#define ZSWR10_NRZ 0x00 /* NRZ encoding */
#define ZSWR10_NRZI 0x20 /* NRZI encoding */
#define ZSWR10_FM1 0x40 /* FM1 encoding */
#define ZSWR10_FM0 0x60 /* FM0 encoding */
#define ZSWR10_GA_ON_POLL 0x10 /* go active on poll (loop mode) */
#define ZSWR10_MARK_IDLE 0x08 /* all 1s (vs flag) when idle (SDLC) */
#define ZSWR10_ABORT_ON_UNDERRUN 0x4 /* abort on xmit underrun (SDLC) */
#define ZSWR10_LOOP_MODE 0x02 /* loop mode (SDLC) */
#define ZSWR10_6_BIT_SYNC 0x01 /* 6 bits per sync char (sync modes) */
/*
* Bits in Write Register 11 (`Clock Mode Control'). Bits 6&5, 4&3, and
* 1&0 are taken as units. Various bits depend on other bits in complex
* ways; see the Zilog manual.
*/
#define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */
/* (else have TTL oscil. on RTxC*) */
#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from TRxC* pin */
#define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */
#define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */
#define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */
#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from TRxC* pin */
#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from RTxC* pin */
#define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */
#define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */
#define ZSWR11_TRXC_OUT_ENA 0x04 /* TRxC* pin will be an output */
/* (unless it is being used above) */
#define ZSWR11_TRXC_XTAL 0x00 /* TRxC output from xtal oscillator */
#define ZSWR11_TRXC_XMIT 0x01 /* TRxC output from xmit clock */
#define ZSWR11_TRXC_BAUD 0x02 /* TRxC output from BRG */
#define ZSWR11_TRXC_DPLL 0x03 /* TRxC output from DPLL */
/*
* Formula for Write Registers 12 and 13 (`Lower Byte of Baud Rate
* Generator Time Constant' and `Upper Byte of ...'). Inputs:
*
* f BRG input clock frequency (in Hz) AFTER division
* by 1, 16, 32, or 64 (per clock divisor in WR4)
* bps desired rate in bits per second (9600, etc)
*
* We want
*
* f
* ----- + 0.5 - 2
* 2 bps
*
* rounded down to an integer. This can be computed entirely
* in integer arithemtic as:
*
* f + bps
* ------- - 2
* 2 bps
*/
#define BPS_TO_TCONST(f, bps) ((((f) + (bps)) / (2 * (bps))) - 2)
/* inverse of above: given a BRG Time Constant, return Bits Per Second */
#define TCONST_TO_BPS(f, tc) ((f) / 2 / ((tc) + 2))
/*
* Bits in Write Register 14 (`Miscellaneous Control Bits').
* Bits 7 through 5 are taken as a unit and make up a `DPLL command'.
*/
#define ZSWR14_DPLL_NOOP 0x00 /* leave DPLL alone */
#define ZSWR14_DPLL_SEARCH 0x20 /* enter search mode */
#define ZSWR14_DPLL_RESET_CM 0x40 /* reset `clock missing' in RR10 */
#define ZSWR14_DPLL_DISABLE 0x60 /* disable DPLL (continuous search) */
#define ZSWR14_DPLL_SRC_BAUD 0x80 /* set DPLL src = BRG */
#define ZSWR14_DPLL_SRC_RTXC 0xa0 /* set DPLL src = RTxC* or xtal osc */
#define ZSWR14_DPLL_FM 0xc0 /* operate in FM mode */
#define ZSWR14_DPLL_NRZI 0xe0 /* operate in NRZI mode */
#define ZSWR14_LOCAL_LOOPBACK 0x10 /* set local loopback mode */
#define ZSWR14_AUTO_ECHO 0x08 /* set auto echo mode */
#define ZSWR14_DTR_REQ 0x04 /* DTR*/REQ* pin gives REQ* */
#define ZSWR14_BAUD_FROM_PCLK 0x02 /* BRG clock taken from PCLK */
/* (else from RTxC* pin or xtal osc) */
#define ZSWR14_BAUD_ENA 0x01 /* enable BRG countdown */
/*
* Bits in Write Register 15 (`External/Status Interrupt Control').
* Most of these cause status interrupts whenever the corresponding
* bit or pin changes state (i.e., any rising or falling edge).
*/
#define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */
#define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */
#define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */
#define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */
#define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */
/* 0x04 unused, must be zero */
#define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */
/* 0x01 unused, must be zero */
/*
* Bits in Read Register 0 (`Transmit/Receive Buffer Status and External
* Status').
*/
#define ZSRR0_BREAK 0x80 /* break/abort detected */
#define ZSRR0_TXUNDER 0x40 /* transmit underrun/EOM (sync) */
#define ZSRR0_CTS 0x20 /* clear to send */
#define ZSRR0_SYNC_HUNT 0x10 /* sync/hunt (sync mode) */
#define ZSRR0_DCD 0x08 /* data carrier detect */
#define ZSRR0_TX_READY 0x04 /* transmit buffer empty */
#define ZSRR0_ZERO_COUNT 0x02 /* zero count in baud clock */
#define ZSRR0_RX_READY 0x01 /* received character ready */
/*
* Bits in Read Register 1 (the Zilog book does not name this one).
*/
#define ZSRR1_EOF 0x80 /* end of frame (SDLC mode) */
#define ZSRR1_FE 0x40 /* CRC/framing error */
#define ZSRR1_DO 0x20 /* data (receiver) overrun */
#define ZSRR1_PE 0x10 /* parity error */
#define ZSRR1_RC0 0x08 /* residue code 0 (SDLC mode) */
#define ZSRR1_RC1 0x04 /* residue code 1 (SDLC mode) */
#define ZSRR1_RC2 0x02 /* residue code 2 (SDLC mode) */
#define ZSRR1_ALL_SENT 0x01 /* all chars out of xmitter (async) */
/*
* Read Register 2 in B channel contains status bits if VECTOR_INCL_STAT
* is set.
*/
/*
* Bits in Read Register 3 (`Interrupt Pending'). Only channel A
* has an RR3.
*/
/* 0x80 unused, returned as 0 */
/* 0x40 unused, returned as 0 */
#define ZSRR3_IP_A_RX 0x20 /* channel A recv int pending */
#define ZSRR3_IP_A_TX 0x10 /* channel A xmit int pending */
#define ZSRR3_IP_A_STAT 0x08 /* channel A status int pending */
#define ZSRR3_IP_B_RX 0x04 /* channel B recv int pending */
#define ZSRR3_IP_B_TX 0x02 /* channel B xmit int pending */
#define ZSRR3_IP_B_STAT 0x01 /* channel B status int pending */
/*
* Bits in Read Register 10 (`contains some miscellaneous status bits').
*/
#define ZSRR10_1_CLOCK_MISSING 0x80 /* 1 clock edge missing (FM mode) */
#define ZSRR10_2_CLOCKS_MISSING 0x40 /* 2 clock edges missing (FM mode) */
/* 0x20 unused */
#define ZSRR10_LOOP_SENDING 0x10 /* xmitter controls loop (SDLC loop) */
/* 0x08 unused */
/* 0x04 unused */
#define ZSRR10_ON_LOOP 0x02 /* SCC is on loop (SDLC/X.21 modes) */
/*
* Bits in Read Register 15. This register is one of the few that
* simply reads back the corresponding Write Register.
*/
#define ZSRR15_BREAK_IE 0x80 /* break/abort status int enable */
#define ZSRR15_TXUEOM_IE 0x40 /* TX underrun/EOM status int enable */
#define ZSRR15_CTS_IE 0x20 /* CTS* pin status int enable */
#define ZSRR15_SYNCHUNT_IE 0x10 /* SYNC* pin/hunt status int enable */
#define ZSRR15_DCD_IE 0x08 /* DCD* pin status int enable */
/* 0x04 unused, returned as zero */
#define ZSRR15_ZERO_COUNT_IE 0x02 /* BRG-counter = 0 status int enable */
/* 0x01 unused, returned as zero */

146
sys/arch/sun3/dev/zsvar.h Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* 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, Lawrence Berkeley Laboratory.
*
* 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.
*
* @(#)zsvar.h 8.1 (Berkeley) 6/11/93
*
* from: Header: zsvar.h,v 1.7 92/11/26 01:28:04 torek Exp (LBL)
* $Id: zsvar.h,v 1.1 1994/02/23 08:29:05 glass Exp $
*/
/*
* Software state, per zs channel.
*
* The zs chip has insufficient buffering, so we provide a software
* buffer using a two-level interrupt scheme. The hardware (high priority)
* interrupt simply grabs the `cause' of the interrupt and stuffs it into
* a ring buffer. It then schedules a software interrupt; the latter
* empties the ring as fast as it can, hoping to avoid overflow.
*
* Interrupts can happen because of:
* - received data;
* - transmit pseudo-DMA done; and
* - status change.
* These are all stored together in the (single) ring. The size of the
* ring is a power of two, to make % operations fast. Since we need two
* bits to distinguish the interrupt type, and up to 16 for the received
* data plus RR1 status, we use 32 bits per ring entry.
*
* When the value is a character + RR1 status, the character is in the
* upper 8 bits of the RR1 status.
*/
#define ZLRB_RING_SIZE 256 /* ZS line ring buffer size */
#define ZLRB_RING_MASK 255 /* mask for same */
/* 0 is reserved (means "no interrupt") */
#define ZRING_RINT 1 /* receive data interrupt */
#define ZRING_XINT 2 /* transmit done interrupt */
#define ZRING_SINT 3 /* status change interrupt */
#define ZRING_TYPE(x) ((x) & 3)
#define ZRING_VALUE(x) ((x) >> 8)
#define ZRING_MAKE(t, v) ((t) | (v) << 8)
struct zs_chanstate {
struct zs_chanstate *cs_next; /* linked list for zshard() */
volatile struct zschan *cs_zc; /* points to hardware regs */
int cs_unit; /* unit number */
struct tty *cs_ttyp; /* ### */
/*
* We must keep a copy of the write registers as they are
* mostly write-only and we sometimes need to set and clear
* individual bits (e.g., in WR3). Not all of these are
* needed but 16 bytes is cheap and this makes the addressing
* simpler. Unfortunately, we can only write to some registers
* when the chip is not actually transmitting, so whenever
* we are expecting a `transmit done' interrupt the preg array
* is allowed to `get ahead' of the current values. In a
* few places we must change the current value of a register,
* rather than (or in addition to) the pending value; for these
* cs_creg[] contains the current value.
*/
u_char cs_creg[16]; /* current values */
u_char cs_preg[16]; /* pending values */
u_char cs_heldchange; /* change pending (creg != preg) */
u_char cs_rr0; /* last rr0 processed */
/* pure software data, per channel */
char cs_softcar; /* software carrier */
char cs_conk; /* is console keyboard, decode L1-A */
char cs_brkabort; /* abort (as if via L1-A) on BREAK */
char cs_kgdb; /* enter debugger on frame char */
char cs_consio; /* port does /dev/console I/O */
char cs_xxx; /* (spare) */
int cs_speed; /* default baud rate (from ROM) */
/*
* The transmit byte count and address are used for pseudo-DMA
* output in the hardware interrupt code. PDMA can be suspended
* to get pending changes done; heldtbc is used for this. It can
* also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
*/
int cs_tbc; /* transmit byte count */
caddr_t cs_tba; /* transmit buffer address */
int cs_heldtbc; /* held tbc while xmission stopped */
/*
* Printing an overrun error message often takes long enough to
* cause another overrun, so we only print one per second.
*/
long cs_rotime; /* time of last ring overrun */
long cs_fotime; /* time of last fifo overrun */
/*
* The ring buffer.
*/
u_int cs_rbget; /* ring buffer `get' index */
volatile u_int cs_rbput; /* ring buffer `put' index */
int cs_rbuf[ZLRB_RING_SIZE];/* type, value pairs */
};
/*
* Macros to read and write individual registers (except 0) in a channel.
*
* On the SparcStation the 1.6 microsecond recovery time is
* handled in hardware.
*/
#define ZS_READ(c, r) ((c)->zc_csr = (r), zsdelay(5), (c)->zc_csr, zsdelay(5))
#define ZS_WRITE(c, r, v) ((c)->zc_csr = (r), zsdelay(5), (c)->zc_csr = (v), zsdelay(5))

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/control.h,v 1.8 1994/02/04 08:19:51 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/control.h,v 1.9 1994/02/23 08:29:13 glass Exp $
*/
/*
@ -69,6 +69,15 @@
#define CONTEXT_NUM 0x8
#define CONTEXT_MASK 0x7
#define SYSTEM_ENAB_DIAG 0x01
#define SYSTEM_ENAB_FPA 0x02
#define SYSTEM_ENAB_COPY 0x04
#define SYSTEM_ENAB_VIDEO 0x08
#define SYSTEM_ENAB_CACHE 0x10
#define SYSTEM_ENAB_SVDMA 0x20
#define SYSTEM_ENAB_FPP 0x40
#define SYSTEM_ENAB_BOOT 0x80
#include <sys/types.h>
void control_copy_byte __P((char *, char *, int ));

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/include/mon.h,v 1.11 1994/02/04 08:20:00 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/include/mon.h,v 1.12 1994/02/23 08:29:15 glass Exp $
*/
/*
* This file derived from kernel/mach/sun3.md/machMon.h from the
@ -357,6 +357,7 @@ extern void Mach_MonTrap _ARGS_((Address address_to_trap_to));
#define mon_printf (romVectorPtr->printf)
#define mon_putchar (romVectorPtr->putChar)
#define mon_may_getchar (romVectorPtr->mayGet)
#define mon_exit_to_mon (romVectorPtr->exitToMon)
#define mon_reboot (romVectorPtr->exitToMon)
#define mon_panic(x) { mon_printf(x); mon_exit_to_mon();}

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/obio.h,v 1.6 1994/02/04 08:20:02 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/obio.h,v 1.7 1994/02/23 08:29:17 glass Exp $
*/
/*
@ -39,7 +39,6 @@
*
*/
#define OBIO_KEYBD_MS 0x00000000
#define OBIO_ZS 0x00020000
#define OBIO_EEPROM 0x00040000

View File

@ -175,7 +175,8 @@
#define splnet() spl3()
#define splbio() spl2()
#define splimp() spl6()
#define spltty() spl6()
#define spltty() spl2()
#define splzs( ) spl6()
#define splclock() spl5()
#define splstatclock() splclock()
#define splvm() spl2()

View File

@ -175,7 +175,8 @@
#define splnet() spl3()
#define splbio() spl2()
#define splimp() spl6()
#define spltty() spl6()
#define spltty() spl2()
#define splzs( ) spl6()
#define splclock() spl5()
#define splstatclock() splclock()
#define splvm() spl2()

View File

@ -1,5 +1,11 @@
/*
* $Id: ptrace.h,v 1.1 1994/01/08 19:08:52 cgd Exp $
* $Id: ptrace.h,v 1.2 1994/02/23 08:29:22 glass Exp $
*/
/* Just use the common m68k definition */
#include <m68k/ptrace.h>
/*
* $Id: ptrace.h,v 1.2 1994/02/23 08:29:22 glass Exp $
*/
/* Just use the common m68k definition */

View File

@ -1,5 +1,11 @@
/*
* $Id: varargs.h,v 1.1 1994/01/27 15:26:31 mycroft Exp $
* $Id: varargs.h,v 1.2 1994/02/23 08:29:24 glass Exp $
*/
/* Just use the common m68k definition */
#include <m68k/varargs.h>
/*
* $Id: varargs.h,v 1.2 1994/02/23 08:29:24 glass Exp $
*/
/* Just use the common m68k definition */

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/autoconf.c,v 1.5 1994/02/04 08:20:19 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/autoconf.c,v 1.6 1994/02/23 08:29:31 glass Exp $
*/
/*
* Setup the system to run on the current machine.
@ -90,8 +90,8 @@ void configure()
{
int root_found;
boothowto = RB_SINGLE;
isr_init();
root_found = config_rootfound("mainbus", NULL);
if (!root_found)
panic("configure: autoconfig failed, no device tree root found");

View File

@ -1 +1 @@
revision 1.7 intentionally removed
revision 1.8 intentionally removed

View File

@ -56,12 +56,17 @@
#include "prom.h"
#include "zs.h"
int promcnprobe(), promcninit(), promcngetc(), promcnputc();
int zscnprobe(), zscninit(), zscngetc(), zscnputc();
struct consdev constab[] = {
#if NPROM
{promcnprobe, promcninit, promcngetc, promcnputc},
#endif
#if NZS
{zscnprobe, zscninit, zscngetc, zscnputc},
#endif
{ 0 },
};

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/control.h,v 1.8 1994/02/04 08:19:51 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/control.h,v 1.9 1994/02/23 08:29:13 glass Exp $
*/
/*
@ -69,6 +69,15 @@
#define CONTEXT_NUM 0x8
#define CONTEXT_MASK 0x7
#define SYSTEM_ENAB_DIAG 0x01
#define SYSTEM_ENAB_FPA 0x02
#define SYSTEM_ENAB_COPY 0x04
#define SYSTEM_ENAB_VIDEO 0x08
#define SYSTEM_ENAB_CACHE 0x10
#define SYSTEM_ENAB_SVDMA 0x20
#define SYSTEM_ENAB_FPP 0x40
#define SYSTEM_ENAB_BOOT 0x80
#include <sys/types.h>
void control_copy_byte __P((char *, char *, int ));

View File

@ -95,6 +95,8 @@ main()
printf("#define\tCONTEXT_0 %d\n", CONTEXT_0);
printf("#define\tCONTEXT_REG %d\n", CONTEXT_REG);
printf("#define\tCONTEXT_NUM %d\n", CONTEXT_NUM);
printf("#define\tSYSTEM_ENAB %d\n", SYSTEM_ENAB);
printf("#define\tSYSTEM_ENAB_FPP %d\n", SYSTEM_ENAB_FPP);
printf("#define\tSEGMAP_BASE %d\n", SEGMAP_BASE);
printf("#define\tNBPG %d\n", NBPG);
printf("#define\tNBSG %d\n", NBSG);

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/isr.c,v 1.4 1994/02/04 08:20:58 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/isr.c,v 1.5 1994/02/23 08:29:40 glass Exp $
*/
#include "param.h"
@ -39,6 +39,7 @@
#include "machine/isr.h"
#include "vector.h"
#include "interreg.h"
/*
* Justification:
@ -49,6 +50,7 @@
*
*/
extern char *interrupt_reg;
extern void level0intr(), level1intr(), level2intr(), level3intr(),
level4intr(), level5intr(), level6intr(), level7intr();
@ -131,6 +133,60 @@ void isr_add(level, handler, arg)
isr_activate(level);
}
void isr_soft_request(level)
int level;
{
u_char bit, reg_val;
int s;
if ((level < 1) || (level > 3))
panic("isr_soft_request");
s = splhigh();
reg_val = *interrupt_reg;
*interrupt_reg &= ~IREG_ALL_ENAB;
switch(level) {
case 1:
bit = IREG_SOFT_ENAB_1;
break;
case 2:
bit = IREG_SOFT_ENAB_2;
break;
case 3:
bit = IREG_SOFT_ENAB_3;
break;
}
*interrupt_reg |= bit;
*interrupt_reg |= IREG_ALL_ENAB;
splx(s);
}
void isr_soft_clear(level)
int level;
{
u_char bit, reg_val;
int s;
if ((level < 1) || (level > 3))
panic("isr_soft_clear");
s = splhigh();
reg_val = *interrupt_reg;
*interrupt_reg &= ~IREG_ALL_ENAB;
switch(level) {
case 1:
bit = IREG_SOFT_ENAB_1;
break;
case 2:
bit = IREG_SOFT_ENAB_2;
break;
case 3:
bit = IREG_SOFT_ENAB_3;
break;
}
*interrupt_reg &= ~bit;
*interrupt_reg |= IREG_ALL_ENAB;
splx(s);
}
void intrhand(sr)
int sr;
{

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore.s,v 1.14 1994/02/04 08:21:00 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore.s,v 1.15 1994/02/23 08:29:42 glass Exp $
*/
#include "assym.s"
#include "../include/asm.h"
@ -100,6 +100,11 @@ bsszero: clrl a0@
cmpl a0, a1
bne bsszero
fpu_setup:
movsb SYSTEM_ENAB, d0 | read enable register
orb #SYSTEM_ENAB_FPP, d0 | set fpu bit
movsb d0, SYSTEM_ENAB
final_before_main:
lea tmpstk, sp | switch to tmpstack

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore2.c,v 1.15 1994/02/04 08:21:07 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore2.c,v 1.16 1994/02/23 08:29:50 glass Exp $
*/
#include "systm.h"
@ -533,8 +533,6 @@ void pte_print(pte)
mon_printf("pte: ");
if (pte & PG_VALID) {
mon_printf("Valid ");
if (pte & PG_WRITE)
mon_printf("Write ");
if (pte & PG_WRITE)
mon_printf("Write ");
if (pte & PG_SYSTEM)
@ -594,13 +592,10 @@ void sun3_bootstrap()
initialize_vector_table(); /* point interrupts/exceptions to our table */
sun3_vm_init(); /* handle kernel mapping problems, etc */
printf("sun3 vm initialization complete\n");
pmap_bootstrap(); /* */
printf("pmap module bootstrapped\n");
internal_configure(); /* stuff that can't wait for configure() */
astpending =0;
printf("calling main()\n");
}

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/m68k.s,v 1.10 1994/02/04 08:21:01 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/m68k.s,v 1.11 1994/02/23 08:29:43 glass Exp $
*/
ENTRY(getvbr)
@ -187,3 +187,30 @@ ENTRY(longjmp)
movl a0@,sp@
moveq #1,d0
rts
#ifdef FPCOPROC
/*
* Save and restore 68881 state.
* Pretty awful looking since our assembler does not
* recognize FP mnemonics.
*/
ENTRY(m68881_save)
movl sp@(4),a0 | save area pointer
fsave a0@ | save state
tstb a0@ | null state frame?
jeq Lm68881sdone | yes, all done
fmovem fp0-fp7,a0@(216) | save FP general registers
fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers
Lm68881sdone:
rts
ENTRY(m68881_restore)
movl sp@(4),a0 | save area pointer
tstb a0@ | null state frame?
jeq Lm68881rdone | yes, easy
fmovem a0@(312),fpcr/fpsr/fpi | restore FP control registers
fmovem a0@(216),fp0-fp7 | restore FP general registers
Lm68881rdone:
frestore a0@ | restore state
rts
#endif

View File

@ -106,7 +106,7 @@ int bufpages = 0;
int *nofault;
extern vm_offset_t u_area_va;
caddr_t allocsys();
caddr_t allocsys __P((caddr_t));
void identifycpu()
{
@ -229,19 +229,18 @@ void cpu_startup()
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(vm_page_free_count));
printf("using %d buffers containing %d bytes of memory\n",
nbuf, bufpages * CLBYTES);
printf("avail mem = %d\n", ptoa(vm_page_free_count));
/* initcpu();*/
/*
* Set up buffers, so they can be used to read disk labels.
*/
bufinit();
/*
* Configure the system.
*/
@ -267,6 +266,7 @@ allocsys(v)
#define valloc(name, type, num) \
v = (caddr_t)(((name) = (type *)v) + (num))
#ifdef REAL_CLISTS
valloc(cfree, struct cblock, nclist);
#endif
@ -651,7 +651,8 @@ sendsig(catcher, sig, mask, code)
kfp->sf_scp = hkfp->hsf_scp;
}
#endif
(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
if (copyout((caddr_t)kfp, (caddr_t)fp, fsize))
panic("sendsig: unable to copyout sigframe\n");
frame->f_regs[SP] = (int)fp;
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
@ -748,7 +749,8 @@ sun_sendsig(catcher, sig, mask, code)
kfp.ssf_sc.sc_sp = frame->f_regs[SP];
kfp.ssf_sc.sc_pc = frame->f_pc;
kfp.ssf_sc.sc_ps = frame->f_sr;
(void) copyout((caddr_t)&kfp, (caddr_t)fp, fsize);
if (copyout((caddr_t)&kfp, (caddr_t)fp, fsize))
panic("sendsig: copying out signal context\n");
frame->f_regs[SP] = (int)fp;
#ifdef DEBUG
@ -862,9 +864,11 @@ sigreturn(p, uap, retval)
p->p_sigmask = scp->sc_mask &~ sigcantmask;
frame = (struct frame *) p->p_regs;
frame->f_regs[SP] = scp->sc_sp;
#ifdef COMPAT_SUNOS
#ifndef COMPAT_SUNOS
frame->f_regs[A6] = scp->sc_fp;
#else
if (p->p_emul != EMUL_SUNOS)
frame->f_regs[A6] = scp->sc_fp;
frame->f_regs[A6] = scp->sc_fp;
#endif
frame->f_pc = scp->sc_pc;
frame->f_sr = scp->sc_ps;

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/obio.h,v 1.6 1994/02/04 08:20:02 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/obio.h,v 1.7 1994/02/23 08:29:17 glass Exp $
*/
/*
@ -39,7 +39,6 @@
*
*/
#define OBIO_KEYBD_MS 0x00000000
#define OBIO_ZS 0x00020000
#define OBIO_EEPROM 0x00040000

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/pmap.c,v 1.17 1994/02/04 08:21:04 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/pmap.c,v 1.18 1994/02/23 08:29:48 glass Exp $
*/
#include "systm.h"
#include "param.h"
@ -104,13 +104,8 @@ vm_offset_t avail_start, avail_end;
#define splpmap splbio
#ifdef CONFUSED
#define PMAP_LOCK() s = splpmap()
#define PMAP_UNLOCK() splx(s)
#else
#define PMAP_LOCK() /* pmap lock */
#define PMAP_UNLOCK() /* pmap unlock */
#endif
#define dequeue_first(val, type, queue) { \
val = (type) queue_first(queue); \
@ -541,6 +536,8 @@ pmeg_t pmeg_allocate_invalid(pmap, va)
pmegp->pmeg_reserved = 0;
pmegp->pmeg_vpages = 0;
enqueue_tail(&pmeg_active_queue, pmegp);
if (pmap != kernel_pmap)
pmap->pm_segmap[VA_SEGNUM(va)] = pmegp->pmeg_index;
return pmegp;
}
@ -573,21 +570,21 @@ pmeg_t pmeg_cache(pmap, va, update)
if (!pmap->pm_segmap || (pmap == kernel_pmap)) return PMEG_NULL;
seg = VA_SEGNUM(va);
if (seg < NUSEG)
if (seg > NUSEG) /* out of range */
return PMEG_NULL;
if (pmap->pm_segmap[seg] == SEGINV)
if (pmap->pm_segmap[seg] == SEGINV) /* nothing cached */
return PMEG_NULL;
if (update)
pmap->pm_segmap[seg] = SEGINV;
pmegp = pmeg_p(pmap->pm_segmap[seg]);
if ((pmegp->pmeg_owner != pmap) ||
(pmegp->pmeg_owner_version != pmap->pm_version) ||
(pmegp->pmeg_va != va)) return PMEG_NULL; /* cache lookup failed */
(pmegp->pmeg_va != va)) {
if (update)
pmap->pm_segmap[seg] = SEGINV;
return PMEG_NULL; /* cache lookup failed */
}
remqueue(&pmeg_inactive_queue, pmegp);
enqueue_tail(&pmeg_active_queue, pmegp);
if (update)
pmap->pm_segmap[seg] = pmegp->pmeg_index;
return pmegp;
}
@ -700,12 +697,15 @@ unsigned char pv_link(pmap, pa, va, flags)
pv->pv_next = NULL;
pv->pv_flags = flags;
force_cache_flags(pa, flags);
PMAP_UNLOCK();
return flags & PV_NC;
}
for (npv = pv ; npv != NULL; last= npv, npv = npv->pv_next ) {
if ((npv->pv_pmap != pmap) || (npv->pv_va != va)) continue;
if (flags == npv->pv_flags) /* no change */
if (flags == npv->pv_flags) {/* no change */
PMAP_UNLOCK();
return get_cache_flags(pa);
}
npv->pv_flags = flags;
goto recompute;
}
@ -722,11 +722,13 @@ unsigned char pv_link(pmap, pa, va, flags)
if (flags & PV_NC) { /* being NCed, wasn't before */
force_cache_flags(pa, flags);
pv_change_pte(head, MAKE_PV_REAL(PV_NC), 0);
PMAP_UNLOCK();
return flags & PV_NC;
}
nflags = pv_compute_cache(head);
force_cache_flags(pa, nflags);
pv_change_pte(head, MAKE_PV_REAL(nflags), 0); /* */
PMAP_UNLOCK();
return nflags & PV_NC;
}
void pv_change_pte(pv_list, set_bits, clear_bits)
@ -772,7 +774,9 @@ void pv_unlink(pmap, pa, va)
if (!pv_initialized) return;
pv_list = pa_to_pvp(pa);
if (pv_list->pv_pmap == NULL) {
#ifdef PMAP_DEBUG
printf("pv_unlinking too many times\n");
#endif
return;
}
@ -813,7 +817,9 @@ void pv_unlink(pmap, pa, va)
}
return;
}
panic("pv_unlink: couldn't find entry");
#ifdef PMAP_DEBUG
printf("pv_unlink: couldn't find entry");
#endif
}
void pv_init()
{
@ -994,6 +1000,9 @@ pmap_destroy(pmap)
{
int count;
#ifdef PMAP_DEBUG
printf("pmap_destroy(%x)\n", pmap);
#endif
if (pmap == NULL) return;
if (pmap == kernel_pmap)
panic("pmap: attempted to destroy kernel_pmap");
@ -1005,6 +1014,9 @@ pmap_destroy(pmap)
free((caddr_t)pmap, M_VMPMAP); /* XXXX -- better make sure we
it this way allocate */
}
#ifdef PMAP_DEBUG
printf("pmap_successful(%x)\n", pmap);
#endif
}
/*
@ -1019,6 +1031,9 @@ pmap_page_protect(pa, prot)
{
int s;
#ifdef PMAP_DEBUG
printf("pmap_page_protect(%x, %x)\n", pa, prot);
#endif
PMAP_LOCK();
switch (prot) {
case VM_PROT_ALL:
@ -1067,7 +1082,7 @@ void pmap_remove_range_mmu(pmap, sva, eva)
sme = get_segmap(sva);
if (sme == SEGINV) {
if (pmap == kernel_pmap) return;
pmegp = pmeg_cache(pmap, VA_SEGNUM(sva), PM_UPDATE_CACHE);
pmegp = pmeg_cache(pmap, sun3_trunc_seg(va), PM_UPDATE_CACHE);
if (!pmegp) goto outta_here;
set_segmap(sva, pmegp->pmeg_index);
}
@ -1150,7 +1165,10 @@ void pmap_remove_range(pmap, sva, eva)
*/
if ((pmap != kernel_pmap))
if (get_pmeg_cache(pmap, VA_SEGNUM(sva)) == SEGINV) return;
if (get_pmeg_cache(pmap, VA_SEGNUM(sva)) == SEGINV) {
return;
}
if ((pmap == kernel_pmap) ||
(pmap->pm_context)) {
pmap_remove_range_mmu(pmap, sva, eva);
@ -1183,6 +1201,9 @@ void pmap_remove(pmap, sva, eva)
if (pmap == NULL)
return;
#ifdef PMAP_DEBUG
printf("pmap_remove(%x, %x, %x)\n", pmap, sva, eva);
#endif
/* do something about contexts */
if (pmap == kernel_pmap) {
if (sva < VM_MIN_KERNEL_ADDRESS)
@ -1191,8 +1212,8 @@ void pmap_remove(pmap, sva, eva)
eva = VM_MAX_KERNEL_ADDRESS;
}
else {
if (eva > VM_MAX_ADDRESS)
eva = VM_MAX_ADDRESS;
if (eva > VM_MAXUSER_ADDRESS)
eva = VM_MAXUSER_ADDRESS;
}
PMAP_LOCK();
va = sva;
@ -1320,6 +1341,7 @@ void pmap_enter_user(pmap, va, pa, prot, wired, pte_proto, mem_type)
panic("pmap: user trying to allocate virtual space above itself\n");
if (wired)
printf("pmap_enter_user: attempt to wire user page, ignored\n");
pte_proto |= MAKE_PGTYPE(PG_MMEM); /* unnecessary */
PMAP_LOCK();
saved_context = get_context();
@ -1332,7 +1354,7 @@ void pmap_enter_user(pmap, va, pa, prot, wired, pte_proto, mem_type)
if (sme == SEGINV) {
pmegp = pmeg_cache(pmap, sun3_trunc_seg(va),PM_UPDATE_CACHE);
if (!pmegp) /* no cached pmeg */
pmegp = pmeg_allocate_invalid(pmap, va);
pmegp = pmeg_allocate_invalid(pmap, sun3_trunc_seg(va));
set_segmap(va,pmegp->pmeg_index);
} else
pmegp = pmeg_p(sme);
@ -1386,7 +1408,10 @@ pmap_enter(pmap, va, pa, prot, wired)
int s;
if (pmap == NULL) return;
#if defined(PMAP_ENTER_DEBUG) || defined(PMAP_DEBUG)
printf("pmap_enter(%x, %x, %x, %x, %x)\n",
pmap, va, pa, prot, wired);
#endif
mem_type = pa & PMAP_MEMMASK;
pte_proto = PG_VALID | pmap_pte_prot(prot) | (pa & PMAP_NC ? PG_NC : 0);
pa &= ~PMAP_SPECMASK;
@ -1413,7 +1438,9 @@ pmap_clear_modify(pa)
int s;
if (!pv_initialized) return;
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
printf("pmap_clear_modified: %x\n", pa);
#endif
PMAP_LOCK();
pv_modified_table[PA_PGNUM(pa)] = 0;
pv_change_pte(&pv_head_table[PA_PGNUM(pa)], 0, PG_MOD);
@ -1425,6 +1452,9 @@ pmap_is_modified(pa)
{
int s;
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
printf("pmap_is_modified: %x\n", pa);
#endif
if (!pv_initialized) return 0;
if (pv_modified_table[PA_PGNUM(pa)]) return 1;
PMAP_LOCK();
@ -1439,6 +1469,9 @@ void pmap_clear_reference(pa)
int s;
if (!pv_initialized) return;
#ifdef PMAP_DEBUG
printf("pmap_clear_referenced: %x\n", pa);
#endif
PMAP_LOCK();
pv_remove_all(pa);
PMAP_UNLOCK();
@ -1448,6 +1481,7 @@ boolean_t
pmap_is_referenced(pa)
vm_offset_t pa;
{
printf("pmap_is_referenced: %x\n", pa);
return FALSE;
}
@ -1458,20 +1492,33 @@ void pmap_activate(pmap, pcbp)
{
int s;
PMAP_LOCK();
#ifdef PMAP_DEBUG
printf("pmap_activate(%x, %x)\n", pmap, pcbp);
#endif
if (pmap->pm_context) {
#ifdef PMAP_DEBUG
printf("pmap_activate(%x, %x) switching to context %d\n", pmap, pcbp,
pmap->pm_context->context_num);
#endif
set_context(pmap->pm_context->context_num);
PMAP_UNLOCK();
#ifdef PMAP_DEBUG
printf("pmap_activate(%x, %x) completed\n", pmap, pcbp);
#endif
return;
}
context_allocate(pmap);
set_context(pmap->pm_context->context_num);
PMAP_UNLOCK();
#ifdef PMAP_DEBUG
printf("pmap_activate(%x, %x) completed\n", pmap, pcbp);
#endif
}
void pmap_deactivate(pmap, pcbp)
pmap_t pmap;
struct pcb *pcbp;
{
#ifdef PMAP_DEBUG
printf("pmap_deactivate(%x, %x)\n", pmap, pcbp);
#endif
enqueue_tail(&context_active_queue,
(queue_entry_t) pmap->pm_context);
}
@ -1489,7 +1536,9 @@ pmap_change_wiring(pmap, va, wired)
vm_offset_t va;
boolean_t wired;
{
#ifdef PMAP_DEBUG
printf("pmap: call to pmap_change_wiring(). ignoring.\n");
#endif
}
/*
* Copy the range specified by src_addr/len
@ -1519,6 +1568,9 @@ void pmap_copy_page(src, dst)
vm_offset_t pte;
int s;
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
printf("pmap_copy_page: %x -> %x\n", src, dst);
#endif
PMAP_LOCK();
pte = PG_VALID |PG_SYSTEM|PG_WRITE|PG_NC|PG_MMEM| PA_PGNUM(src);
set_pte(tmp_vpages[0], pte);
@ -1545,6 +1597,7 @@ pmap_extract(pmap, va)
vm_offset_t pte;
int s;
PMAP_LOCK();
if (pmap == kernel_pmap) {
sme = get_segmap(va);
if (sme == SEGINV)
@ -1723,6 +1776,9 @@ pmap_protect(pmap, sva, eva, prot)
if (eva > VM_MAX_ADDRESS)
eva = VM_MAX_ADDRESS;
}
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
printf("pmap_protect(%x, %x, %x, %x)\n", pmap, sva, eva, prot);
#endif
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
pmap_remove(pmap, sva, eva);
return;
@ -1763,6 +1819,9 @@ void pmap_zero_page(pa)
vm_offset_t pte;
int s;
#if defined(PMAP_DEBUG) || defined(PMAP_COW_DEBUG)
printf("pmap_zero_page: %x\n", pa);
#endif
PMAP_LOCK();
pte = PG_VALID |PG_SYSTEM|PG_WRITE|PG_NC|PG_MMEM| PA_PGNUM(pa);
set_pte(tmp_vpages[0], pte);

View File

@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/sun3_startup.c,v 1.15 1994/02/04 08:21:07 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/sun3_startup.c,v 1.16 1994/02/23 08:29:50 glass Exp $
*/
#include "systm.h"
@ -533,8 +533,6 @@ void pte_print(pte)
mon_printf("pte: ");
if (pte & PG_VALID) {
mon_printf("Valid ");
if (pte & PG_WRITE)
mon_printf("Write ");
if (pte & PG_WRITE)
mon_printf("Write ");
if (pte & PG_SYSTEM)
@ -594,13 +592,10 @@ void sun3_bootstrap()
initialize_vector_table(); /* point interrupts/exceptions to our table */
sun3_vm_init(); /* handle kernel mapping problems, etc */
printf("sun3 vm initialization complete\n");
pmap_bootstrap(); /* */
printf("pmap module bootstrapped\n");
internal_configure(); /* stuff that can't wait for configure() */
astpending =0;
printf("calling main()\n");
}

View File

@ -73,6 +73,12 @@
#include "compat/sunos/sun_syscall.h"
#endif
/*
* TODO:
* Chris's new syscall debug stuff
*/
struct sysent sysent[];
int nsysent;
#ifdef COMPAT_SUNOS
@ -517,6 +523,8 @@ syscall(code, frame)
int rval[2];
struct timeval syst;
struct sysent *systab;
extern char *syscallnames[];
char **sysnames;
#ifdef HPUXCOMPAT
extern struct sysent hpuxsysent[];
extern int hpuxnsysent, notimp();
@ -535,7 +543,7 @@ syscall(code, frame)
systab = sun_sysent;
numsys = nsun_sysent;
sysnames = sun_syscallnames;
/* SunOS passes the syscall-number on the stack, whereas
BSD passes it in D0. So, we have to get the real "code"
from the stack, and clean up the stack, as SunOS glue
@ -559,6 +567,7 @@ syscall(code, frame)
case EMUL_HPUX:
systab = hpuxsysent;
numsys = hpuxnsysent;
sysnames = hpuxnsyscallnames;
break;
#endif
@ -566,7 +575,7 @@ syscall(code, frame)
default:
systab = sysent;
numsys = nsysent;
sysnames = syscallnames;
}
params = (caddr_t)frame.f_regs[SP] + sizeof(int);
if (code == 0) { /* indir */

View File

@ -119,7 +119,11 @@ Lbe10:
*/
sun3_mmu_specific:
clrl d0 | make sure top bits are cleard too
movl d1, sp@- | save d1
moveq #FC_CONTROL, d1 | need to set source to control space
movc d1, sfc | control space source established
movsb BUSERR_REG, d0 | get value of bus error register
movl sp@+, d1 | restore d1
btst #5, d0 | test to timeout bit
jne Lisberr | if bus error, do it
Lismerr:

View File

@ -125,9 +125,6 @@ cpu_exit(p)
/* NOTREACHED */
}
extern vm_map_t phys_map;
/*