diff options
29 files changed, 2246 insertions, 148 deletions
diff --git a/distrib/notes/mvme68k/hardware b/distrib/notes/mvme68k/hardware index 3ed4f2da230..3f3f5a7e8b6 100644 --- a/distrib/notes/mvme68k/hardware +++ b/distrib/notes/mvme68k/hardware @@ -1,7 +1,8 @@ -dnl $OpenBSD: hardware,v 1.17 2009/02/18 20:50:58 miod Exp $ +dnl $OpenBSD: hardware,v 1.18 2009/03/01 21:40:48 miod Exp $ OpenBSD/MACHINE OSREV runs on the following classes of machines: - MVME147 - Motorola with 68030 and 68881 - MVME162 - Motorola with 68040 and IndustryPack slots + - MVME165 - Motorola with 68040 and VSB interface - MVME167 - Motorola with 68040 dnl 172 support is not tested - MVME172 - Motorola with 68060 and IndustryPack slots @@ -22,11 +23,17 @@ MVME147: SCSI: on-board WD33C93 controller (wdsc) VMEbus: - not supported (some cards have issues) + partially supported (some cards have issues) + +MVME165: + serial ports: + on-board ttyd0 - ttyd1 - MC68681 (dart) + VMEbus: + supported MVME162, MVME172: serial ports: - on-board tty00-03 - Zilog Z85230 SCC (zs) + on-board ttya-ttyd - Zilog Z85230 SCC (zs) Ethernet: on-board Intel 82596CA Ethernet (ie) SCSI: diff --git a/etc/etc.mvme68k/MAKEDEV.md b/etc/etc.mvme68k/MAKEDEV.md index 21088546e7c..83d871d0db6 100644 --- a/etc/etc.mvme68k/MAKEDEV.md +++ b/etc/etc.mvme68k/MAKEDEV.md @@ -1,6 +1,6 @@ define(MACHINE,mvme68k)dnl vers(__file__, - {-$OpenBSD: MAKEDEV.md,v 1.22 2009/01/25 17:30:48 miod Exp $-}, + {-$OpenBSD: MAKEDEV.md,v 1.23 2009/03/01 21:40:49 miod Exp $-}, etc.MACHINE)dnl dnl dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org> @@ -57,6 +57,15 @@ _mkdev(cl, {-tty0*-}, {-u=${i#tty0*} ;; *) echo unknown tty device $i ;; esac-})dnl +__devitem(ttyd, ttyd*, MC68681 serial ports,nothing)dnl +_mkdev(ttyd, {-ttyd[01]-}, {-u=${i#ttyd*} + case $u in + 0|1) + M ttyd$u c major_ttyd_c $u 660 dialer uucp + M cuad$u c major_ttyd_c Add($u, 128) 660 dialer uucp + ;; + *) echo unknown tty device $i ;; + esac-})dnl __devitem(ttyw, ttyw*, WG CL-CD2400 serial ports,nothing)dnl _mkdev(ttyw, {-ttyw*-}, {-u=${i#ttyw*} case $u in @@ -111,6 +120,7 @@ target(all, ccd, 0, 1, 2, 3)dnl twrget(all, mvme_tzs, tty, a, b, c, d)dnl twrget(all, mvme_czs, cua, a, b, c, d)dnl twrget(all, cl, tty0, 0, 1, 2, 3)dnl +target(all, ttyd, 0, 1)dnl target(all, ttyw, 0, 1, 2, 3)dnl dnl target(all, lp, 0)dnl _DEV(all) @@ -138,6 +148,7 @@ _TITLE(term) _DEV(mvme_czs, 12) _DEV(mvme_tzs, 12) _DEV(cl, 13) +_DEV(ttyd, 14) _DEV(ttyw, 30) _TITLE(pty) _DEV(ptm, 52) diff --git a/etc/etc.mvme68k/ttys b/etc/etc.mvme68k/ttys index 45a6d3d5ff0..686bb26443e 100644 --- a/etc/etc.mvme68k/ttys +++ b/etc/etc.mvme68k/ttys @@ -1,5 +1,5 @@ # -# $OpenBSD: ttys,v 1.8 2008/01/09 17:39:42 miod Exp $ +# $OpenBSD: ttys,v 1.9 2009/03/01 21:40:49 miod Exp $ # # name getty type status comments # @@ -14,3 +14,5 @@ tty00 "/usr/libexec/getty std.9600" unknown off secure # 167/17x console tty01 "/usr/libexec/getty std.9600" unknown off tty02 "/usr/libexec/getty std.9600" unknown off tty03 "/usr/libexec/getty std.9600" unknown off +ttyd0 "/usr/libexec/getty std.9600" unknown off secure # 165 console +ttyd1 "/usr/libexec/getty std.9600" unknown off diff --git a/share/man/man4/man4.mvme68k/Makefile b/share/man/man4/man4.mvme68k/Makefile index 4cfdc4e32cc..eb855bc5d5b 100644 --- a/share/man/man4/man4.mvme68k/Makefile +++ b/share/man/man4/man4.mvme68k/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.8 2009/02/17 22:32:36 miod Exp $ +# $OpenBSD: Makefile,v 1.9 2009/03/01 21:40:49 miod Exp $ # from: @(#)Makefile 8.2 (Berkeley) 2/16/94 -# TODO: cl clock flash ipic lp mc memc nvram pcc pcctwo sram vme wdsc zs -MAN= autoconf.4 intro.4 le.4 ie.4 mem.4 vs.4 vsbic.4 +# TODO: cl clock dart flash ipic lp mc memc nvram pcc sram vme wdsc zs +MAN= autoconf.4 intro.4 le.4 ie.4 lrc.4 mem.4 pcctwo.4 vs.4 vsbic.4 MLINKS= mem.4 kmem.4 MANSUBDIR=mvme68k diff --git a/share/man/man4/man4.mvme68k/ie.4 b/share/man/man4/man4.mvme68k/ie.4 index 8b9e93cd9d6..33d8b4a249e 100644 --- a/share/man/man4/man4.mvme68k/ie.4 +++ b/share/man/man4/man4.mvme68k/ie.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ie.4,v 1.8 2008/03/27 20:19:33 jmc Exp $ +.\" $OpenBSD: ie.4,v 1.9 2009/03/01 21:40:49 miod Exp $ .\" .\" Copyright (c) 1988 John E. Stone <j.stone@acm.org> .\" @@ -14,21 +14,21 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 27 2008 $ +.Dd $Mdocdate: March 1 2009 $ .Dt IE 4 mvme68k .Os .Sh NAME .Nm ie -.Nd Intel i82586 Ethernet device +.Nd Intel i82596 Ethernet device .Sh SYNOPSIS -.Cd "ie0 at mc0 offset 0x46000 ipl 1" Pq "MVME162" +.Cd "ie0 at mc0 offset 0x46000 ipl 1" Pq "MVME162/172" .Cd "ie0 at pcctwo0 offset 0x46000 ipl 1" Pq "MVME167/177" .Sh DESCRIPTION The .Nm interface provides access to the 10 Mb/s Ethernet network via the .Tn Intel -82586 +82596 Ethernet chip set. .Sh SEE ALSO .Xr arp 4 , diff --git a/share/man/man4/man4.mvme68k/intro.4 b/share/man/man4/man4.mvme68k/intro.4 index c6c9b5ddf7d..7a8e6cbd9e9 100644 --- a/share/man/man4/man4.mvme68k/intro.4 +++ b/share/man/man4/man4.mvme68k/intro.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: intro.4,v 1.25 2009/02/17 22:32:36 miod Exp $ +.\" $OpenBSD: intro.4,v 1.26 2009/03/01 21:40:49 miod Exp $ .\" Copyright (c) 1990, 1991 Regents of the University of California. .\" All rights reserved. .\" @@ -28,7 +28,7 @@ .\" .\" from: @(#)intro.4 5.2 (Berkeley) 3/27/91 .\" -.Dd $Mdocdate: February 17 2009 $ +.Dd $Mdocdate: March 1 2009 $ .Dt INTRO 4 mvme68k .Os .Sh NAME @@ -99,20 +99,25 @@ Not all supported devices are listed. .Bl -tag -width pcctwo(4) -compact -offset indent .It Xr cl Cirrus Logic CL2400 serial controller +.It Xr dart +MC68681 serial controller .It Xr flash MVME162 on-board flash memory .It Xr ie 4 -Intel i82586 Ethernet device +Intel i82596 Ethernet device .It Xr ipic MVME162 Industry Pack ports .It Xr le 4 AMD LANCE Ethernet device .It Xr lp MVME147 printer interface +.It Xr lrc +MVME165 Local Resource Controller .It Xr mc -MVME162 MCchip +MVME1[67]2 MCchip .It Xr memc MVME1[67]x memory controller +.\" nvram .It Xr osiop 4 Symbios/NCR 53C710 SCSI driver .It Xr pcc @@ -120,7 +125,7 @@ MVME147 PCC chip .It Xr pcctwo MVME1[67]7 PCC2 chip .It Xr sram -MVME162 static memory +MVME1[67]2 static memory .It Xr vme VME bus support .It Xr vs 4 diff --git a/share/man/man4/man4.mvme68k/lrc.4 b/share/man/man4/man4.mvme68k/lrc.4 new file mode 100644 index 00000000000..177f5eaadb9 --- /dev/null +++ b/share/man/man4/man4.mvme68k/lrc.4 @@ -0,0 +1,37 @@ +.\" $OpenBSD: lrc.4,v 1.1 2009/03/01 21:40:49 miod Exp $ +.\" +.\" Copyright (c) 2009 Miodrag Vallat. +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: March 1 2009 $ +.Dt LRC 4 mvme68k +.Os +.Sh NAME +.Nm lrc +.Nd Local Resource Controller +.Sh SYNOPSIS +.Cd "lrc0 at mainbus0 addr 0xfff90000" +.Sh DESCRIPTION +The +.Nm +ASIC provides address decoding for the local peripherals, +as well as timers and interrupt handling facilities, +and is found on the MVME165 Single-Board Computers. +.Sh SEE ALSO +.\" .Xr clock 4 , +.\" .Xr dart 4 , +.Xr intro 4 , +.\" .Xr nvram 4 +.\" .Xr vsb 4 +.\" .Xr vme 4 diff --git a/share/man/man4/man4.mvme68k/pcctwo.4 b/share/man/man4/man4.mvme68k/pcctwo.4 new file mode 100644 index 00000000000..5447d52b694 --- /dev/null +++ b/share/man/man4/man4.mvme68k/pcctwo.4 @@ -0,0 +1,70 @@ +.\" $OpenBSD: pcctwo.4,v 1.1 2009/03/01 21:40:49 miod Exp $ +.\" +.\" Copyright (c) 2003 Paul Weissmann +.\" 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. +.\" +.\" 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. +.\" +.Dd $Mdocdate: March 1 2009 $ +.Dt PCCTWO 4 mvme68k +.Os +.Sh NAME +.Nm pcctwo +.Nd PCCchip2 local bus controller +.Sh SYNOPSIS +.Cd "pcctwo0 at mainbus0 addr 0xfff00000" +.Sh DESCRIPTION +The +.Nm +PCCchip2 ASIC provides an interface to the different local bus-attached I/O +devices as found on the MVME166, MVME167, MVME176 and MVME177 +Single-Board Computers. +.Pp +Features Summary: +.Pp +.Bl -bullet -compact +.It +8-bit parallel I/O port +.It +Master/slave interface for +.Xr cl 4 +CD2401 serial controller +.It +Host interface to +.Xr ie 4 +Intel i82596CA LAN coprocessor +.It +Host interface to +.Xr osiop 4 +Symbios/NCR 53C710 SCSI controller +.It +Interface to the +.Xr memc 4 +Memory controller ASIC +.El +.Sh SEE ALSO +.\" .Xr cl 4 , +.Xr ie 4 , +.Xr intro 4 , +.\" .Xr memc 4 , +.Xr osiop 4 diff --git a/sys/arch/mvme68k/conf/GENERIC b/sys/arch/mvme68k/conf/GENERIC index 19643aa1fb6..dc69e0b509b 100644 --- a/sys/arch/mvme68k/conf/GENERIC +++ b/sys/arch/mvme68k/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.30 2009/02/17 22:28:38 miod Exp $ +# $OpenBSD: GENERIC,v 1.31 2009/03/01 21:40:49 miod Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -21,9 +21,10 @@ option M060SP # ...and MC68060 support package option MVME147 # (requires M68030) option MVME162 # (requires M68040, FPSP) +option MVME165 # (requires M68040, FPSP) option MVME167 # includes 166 (requires M68040, FPSP) option MVME172 # (requires M68060, 060SP, FPSP) -option MVME177 # (requires M68060, 060SP, FPSP) +option MVME177 # includes 176 (requires M68060, 060SP, FPSP) option COMPAT_SUNOS option COMPAT_HPUX @@ -44,7 +45,7 @@ wdsc0 at pcc0 offset 0x4000 ipl 2 lp0 at pcc0 ipl 1 vme0 at pcc0 offset 0x2000 -# MVME162 +# MVME162/172 mc0 at mainbus0 addr 0xfff00000 clock0 at mc0 ipl 5 nvram0 at mc0 offset 0xc0000 @@ -62,7 +63,15 @@ sram0 at mainbus0 addr 0xffe00000 # IndustryPack modules #fooip* at ipic? manu 0x11 prod 0x22 ipl 1 -# MVME166/167/177 +# MVME165 +lrc0 at mainbus0 addr 0xfff90000 +clock0 at lrc0 ipl 5 +#vsb0 at lrc0 offset 0x10000 ipl 4 +vme0 at lrc0 offset 0x20000 +nvram0 at lrc0 offset 0x30000 +dart0 at lrc0 offset 0x40000 ipl 5 + +# MVME166/167/176/177 pcctwo0 at mainbus0 addr 0xfff00000 clock0 at pcctwo0 ipl 5 nvram0 at pcctwo0 offset 0xc0000 diff --git a/sys/arch/mvme68k/conf/RAMDISK b/sys/arch/mvme68k/conf/RAMDISK index 6866bd0ff46..ed527fce25d 100644 --- a/sys/arch/mvme68k/conf/RAMDISK +++ b/sys/arch/mvme68k/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.11 2009/02/17 22:28:38 miod Exp $ +# $OpenBSD: RAMDISK,v 1.12 2009/03/01 21:40:49 miod Exp $ machine mvme68k m68k @@ -40,35 +40,43 @@ mainbus0 at root # MVME147 pcc0 at mainbus0 addr 0xfffe0000 clock0 at pcc0 ipl 5 -nvram0 at pcc0 offset 0x0000 +#nvram0 at pcc0 offset 0x0000 zs0 at pcc0 offset 0x3000 ipl 4 zs1 at pcc0 offset 0x3800 ipl 4 le* at pcc0 offset 0x1800 ipl 3 wdsc0 at pcc0 offset 0x4000 ipl 2 -lp0 at pcc0 ipl 1 +#lp0 at pcc0 ipl 1 vme0 at pcc0 offset 0x2000 # MVME162 mc0 at mainbus0 addr 0xfff00000 clock0 at mc0 ipl 5 -nvram0 at mc0 offset 0xc0000 +#nvram0 at mc0 offset 0xc0000 zs0 at mc0 offset 0x45000 ipl 4 zs1 at mc0 offset 0x45801 ipl 4 ie0 at mc0 offset 0x46000 ipl 3 osiop0 at mc0 offset 0x47000 ipl 2 memc0 at mc0 offset 0x43000 memc1 at mc0 offset 0x43100 -ipic0 at mc0 offset 0xbc000 +#ipic0 at mc0 offset 0xbc000 vme0 at mc0 offset 0x40000 -flash0 at mainbus0 addr 0xffa00000 -sram0 at mainbus0 addr 0xffe00000 +#flash0 at mainbus0 addr 0xffa00000 +#sram0 at mainbus0 addr 0xffe00000 #fooip* at ipic? manu 0x11 prod 0x22 ipl 1 +# MVME165 +lrc0 at mainbus0 addr 0xfff90000 +clock0 at lrc0 ipl 5 +#vsb0 at lrc0 offset 0x10000 ipl 4 +vme0 at lrc0 offset 0x20000 +#nvram0 at lrc0 offset 0x30000 +dart0 at lrc0 offset 0x40000 ipl 5 + # MVME166/167/177 pcctwo0 at mainbus0 addr 0xfff00000 clock0 at pcctwo0 ipl 5 -nvram0 at pcctwo0 offset 0xc0000 +#nvram0 at pcctwo0 offset 0xc0000 ie0 at pcctwo0 offset 0x46000 ipl 3 osiop0 at pcctwo0 offset 0x47000 ipl 2 cl0 at pcctwo0 offset 0x45000 ipl 3 @@ -76,7 +84,7 @@ vme0 at pcctwo0 offset 0x40000 #lptwo0 at pcctwo0 ipl 1 memc0 at pcctwo0 offset 0x43000 memc1 at pcctwo0 offset 0x43100 -sram0 at mainbus0 addr 0xffe00000 +#sram0 at mainbus0 addr 0xffe00000 vmes0 at vme0 diff --git a/sys/arch/mvme68k/conf/files.mvme68k b/sys/arch/mvme68k/conf/files.mvme68k index 37313a335ce..f1302209738 100644 --- a/sys/arch/mvme68k/conf/files.mvme68k +++ b/sys/arch/mvme68k/conf/files.mvme68k @@ -1,4 +1,4 @@ -# $OpenBSD: files.mvme68k,v 1.31 2009/02/18 20:48:00 miod Exp $ +# $OpenBSD: files.mvme68k,v 1.32 2009/03/01 21:40:49 miod Exp $ # config file for mvme68k @@ -23,8 +23,12 @@ device mc {[offset = -1], [ipl = 0]} attach mc at mainbus file arch/mvme68k/dev/mc.c mc needs-count +device lrc {[offset = -1], [ipl = 0]} +attach lrc at mainbus +file arch/mvme68k/dev/lrc.c lrc needs-flag + device clock -attach clock at pcc, mc, pcctwo +attach clock at pcc, mc, pcctwo, lrc file arch/mvme68k/dev/clock.c device zs: tty @@ -35,9 +39,13 @@ device cl: tty attach cl at pcctwo file arch/mvme68k/dev/cl.c cl needs-count +device dart: tty +attach dart at lrc with dartlrc +file arch/mvme68k/dev/dart.c dart needs-flag +file arch/mvme68k/dev/dart_lrc.c dartlrc device vme {} -attach vme at pcc, mc, pcctwo +attach vme at pcc, mc, pcctwo, lrc device vmes {[addr = -1], [vec = -1], [ipl = 0]} attach vmes at vme device vmel {[addr = -1], [vec = -1], [ipl = 0]} @@ -46,6 +54,10 @@ file arch/mvme68k/dev/vme.c vme | vmes | vmel file arch/mvme68k/dev/vmes.c vmes needs-count file arch/mvme68k/dev/vmel.c vmel needs-count +#device vsb {} +#attach vsb at lrc +#file arch/mvme68k/dev/vsb.c vsb needs-flag + attach le at pcc, vmes file arch/mvme68k/dev/if_le.c le @@ -82,7 +94,7 @@ file arch/mvme68k/dev/flash.c flash needs-count device sram attach sram at mainbus device nvram -attach nvram at pcc, mc, pcctwo +attach nvram at pcc, mc, pcctwo, lrc file arch/mvme68k/dev/sram.c sram needs-count file arch/mvme68k/dev/nvram.c nvram needs-count file arch/mvme68k/dev/memdevs.c nvram | sram diff --git a/sys/arch/mvme68k/dev/clock.c b/sys/arch/mvme68k/dev/clock.c index c3103cedcbc..92bdce49437 100644 --- a/sys/arch/mvme68k/dev/clock.c +++ b/sys/arch/mvme68k/dev/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.14 2009/02/21 20:32:34 miod Exp $ */ +/* $OpenBSD: clock.c,v 1.15 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -72,10 +72,17 @@ #include <machine/autoconf.h> #include <machine/cpu.h> -#include "pcc.h" +#include "lrc.h" #include "mc.h" +#include "pcc.h" #include "pcctwo.h" +#if NLRC > 0 +#include <mvme68k/dev/lrcreg.h> +#endif +#if NMC > 0 +#include <mvme68k/dev/mcreg.h> +#endif #if NPCC > 0 #include <mvme68k/dev/pccreg.h> #endif @@ -84,9 +91,6 @@ #include <mvme68k/dev/vme.h> extern struct vme2reg *sys_vme2; #endif -#if NMC > 0 -#include <mvme68k/dev/mcreg.h> -#endif /* * Statistics clock interval and variance, in usec. Variance must be a @@ -154,12 +158,13 @@ clockattach(parent, self, args) clockbus = ca->ca_bustype; switch (ca->ca_bustype) { -#if NPCC > 0 - case BUS_PCC: - prof_reset = ca->ca_ipl | PCC_IRQ_IEN | PCC_TIMERACK; - stat_reset = ca->ca_ipl | PCC_IRQ_IEN | PCC_TIMERACK; - pccintr_establish(PCCV_TIMER1, &sc->sc_profih, "clock"); - pccintr_establish(PCCV_TIMER2, &sc->sc_statih, "stat"); +#if NLRC > 0 + case BUS_LRC: + /* + * XXX once we have dynamic ipl levels, put clock at ipl 6, + * move it to timer1, then use timer2/ipl5 for statclock. + */ + lrcintr_establish(LRCVEC_TIMER2, &sc->sc_profih, "clock"); break; #endif #if NMC > 0 @@ -170,6 +175,14 @@ clockattach(parent, self, args) mcintr_establish(MCV_TIMER2, &sc->sc_statih, "stat"); break; #endif +#if NPCC > 0 + case BUS_PCC: + prof_reset = ca->ca_ipl | PCC_IRQ_IEN | PCC_TIMERACK; + stat_reset = ca->ca_ipl | PCC_IRQ_IEN | PCC_TIMERACK; + pccintr_establish(PCCV_TIMER1, &sc->sc_profih, "clock"); + pccintr_establish(PCCV_TIMER2, &sc->sc_statih, "stat"); + break; +#endif #if NPCCTWO > 0 case BUS_PCCTWO: prof_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; @@ -191,9 +204,9 @@ clockintr(arg) void *arg; { switch (clockbus) { -#if NPCC > 0 - case BUS_PCC: - sys_pcc->pcc_t1irq = prof_reset; +#if NLRC > 0 + case BUS_LRC: + /* nothing to do */ break; #endif #if NMC > 0 @@ -201,6 +214,11 @@ clockintr(arg) sys_mc->mc_t1irq = prof_reset; break; #endif +#if NPCC > 0 + case BUS_PCC: + sys_pcc->pcc_t1irq = prof_reset; + break; +#endif #if NPCCTWO > 0 case BUS_PCCTWO: sys_pcc2->pcc2_t1irq = prof_reset; @@ -239,17 +257,16 @@ cpu_initclocks() while (statvar > minint) statvar >>= 1; switch (clockbus) { -#if NPCC > 0 - case BUS_PCC: - sys_pcc->pcc_t1pload = pcc_timer_us2lim(tick); - sys_pcc->pcc_t1ctl = PCC_TIMERCLEAR; - sys_pcc->pcc_t1ctl = PCC_TIMERSTART; - sys_pcc->pcc_t1irq = prof_reset; - - sys_pcc->pcc_t2pload = pcc_timer_us2lim(statint); - sys_pcc->pcc_t2ctl = PCC_TIMERCLEAR; - sys_pcc->pcc_t2ctl = PCC_TIMERSTART; - sys_pcc->pcc_t2irq = stat_reset; +#if NLRC > 0 + case BUS_LRC: + profhz = stathz = 0; + + sys_lrc->lrc_tcr0 = 0; + sys_lrc->lrc_tcr1 = 0; + /* profclock as timer 2 */ + sys_lrc->lrc_t2base = tick + 1; + sys_lrc->lrc_tcr2 = TCR_TLD2; /* reset to one */ + sys_lrc->lrc_tcr2 = TCR_TEN2 | TCR_TCYC2 | TCR_T2IE; break; #endif #if NMC > 0 @@ -269,6 +286,19 @@ cpu_initclocks() sys_mc->mc_t2irq = stat_reset; break; #endif +#if NPCC > 0 + case BUS_PCC: + sys_pcc->pcc_t1pload = pcc_timer_us2lim(tick); + sys_pcc->pcc_t1ctl = PCC_TIMERCLEAR; + sys_pcc->pcc_t1ctl = PCC_TIMERSTART; + sys_pcc->pcc_t1irq = prof_reset; + + sys_pcc->pcc_t2pload = pcc_timer_us2lim(statint); + sys_pcc->pcc_t2ctl = PCC_TIMERCLEAR; + sys_pcc->pcc_t2ctl = PCC_TIMERSTART; + sys_pcc->pcc_t2irq = stat_reset; + break; +#endif #if NPCCTWO > 0 case BUS_PCCTWO: /* profclock */ @@ -375,16 +405,24 @@ delay(us) #endif switch (clockbus) { -#if NPCC > 0 - case BUS_PCC: - /* - * XXX MVME147 doesn't have a 3rd free-running timer, - * so we use a stupid loop. Fix the code to watch t1: - * the profiling timer. - */ - c = 2 * us; - while (--c > 0) +#if NLRC > 0 + case BUS_LRC: + { + struct lrcreg *lrc; + + if (sys_lrc != NULL) + lrc = sys_lrc; + else + lrc = (struct lrcreg *)IIOV(0xfff90000); + + /* use timer0 and wait for it to wrap */ + lrc->lrc_t0base = us + 1; + lrc->lrc_tcr0 = TCR_TLD0; /* reset to one */ + lrc->lrc_stat = STAT_TMR0; /* clear latch */ + lrc->lrc_tcr0 = TCR_TEN0; + while ((lrc->lrc_stat & STAT_TMR0) == 0) ; + } break; #endif #if NMC > 0 @@ -411,6 +449,18 @@ delay(us) } break; #endif +#if NPCC > 0 + case BUS_PCC: + /* + * XXX MVME147 doesn't have a 3rd free-running timer, + * so we use a stupid loop. Fix the code to watch t1: + * the profiling timer. + */ + c = 2 * us; + while (--c > 0) + ; + break; +#endif #if NPCCTWO > 0 case BUS_PCCTWO: /* diff --git a/sys/arch/mvme68k/dev/dart.c b/sys/arch/mvme68k/dev/dart.c new file mode 100644 index 00000000000..c79dacceaad --- /dev/null +++ b/sys/arch/mvme68k/dev/dart.c @@ -0,0 +1,999 @@ +/* $OpenBSD: dart.c,v 1.1 2009/03/01 21:40:49 miod Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1993-1991 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 AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM 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. + */ + +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/proc.h> +#include <sys/tty.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/syslog.h> + +#include <machine/autoconf.h> +#include <machine/bus.h> +#include <machine/conf.h> +#include <machine/cpu.h> + +#include <dev/cons.h> + +#include <mvme68k/dev/dartreg.h> +#include <mvme68k/dev/dartvar.h> + +#ifdef DDB +#include <ddb/db_var.h> +#endif + +struct cfdriver dart_cd = { + NULL, "dart", DV_TTY +}; + +/* console is on the first port */ +#define CONS_PORT A_PORT +struct dart_sv_reg dartcn_sv; + +/* prototypes */ +cons_decl(dart); +int dart_speed(int); +struct tty *darttty(dev_t); +void dartstart(struct tty *); +int dartmctl(struct dartsoftc *, int, int, int); +int dartparam(struct tty *, struct termios *); +void dartmodemtrans(struct dartsoftc *, unsigned int, unsigned int); +void dartrint(struct dartsoftc *, int); +void dartxint(struct dartsoftc *, int); + +/* + * DUART registers are mapped as the least-significant byte of 32-bit + * addresses. The following macros hide this. + */ + +#define dart_read(sc, reg) \ + bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2)) +#define dart_write(sc, reg, val) \ + bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2), (val)) + +#define DART_CHIP(dev) (minor(dev) >> 1) +#define DART_PORT(dev) (minor(dev) & 1) + +void +dart_common_attach(struct dartsoftc *sc) +{ + if (sc->sc_console) { + sc->sc_sv_reg = &dartcn_sv; + + if (A_PORT != CONS_PORT) { + sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8; + sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1; + sc->sc_sv_reg->sv_csr[A_PORT] = BD9600; + sc->sc_sv_reg->sv_cr[A_PORT] = TXEN | RXEN; + sc->sc_sv_reg->sv_opr |= OPDTRA | OPRTSA; + } else { + sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8; + sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1; + sc->sc_sv_reg->sv_csr[B_PORT] = BD9600; + sc->sc_sv_reg->sv_cr[B_PORT] = TXEN | RXEN; + sc->sc_sv_reg->sv_opr |= OPDTRB | OPRTSB; + } + } else { + sc->sc_sv_reg = &sc->sc_sv_reg_storage; + + sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8; + sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1; + sc->sc_sv_reg->sv_csr[A_PORT] = BD9600; + sc->sc_sv_reg->sv_cr[A_PORT] = TXEN | RXEN; + + sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8; + sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1; + sc->sc_sv_reg->sv_csr[B_PORT] = BD9600; + sc->sc_sv_reg->sv_cr[B_PORT] = TXEN | RXEN; + + sc->sc_sv_reg->sv_opr = OPDTRA | OPRTSA | OPDTRB | OPRTSB; + + /* Start out with Tx and RX interrupts disabled */ + /* Enable input port change interrupt */ + sc->sc_sv_reg->sv_imr = IIPCHG; + } + + /* reset port a */ + if (sc->sc_console == 0 || CONS_PORT != A_PORT) { + dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS); +#if 0 + DELAY_CR; +#endif + + dart_write(sc, DART_MR1A, sc->sc_sv_reg->sv_mr1[A_PORT]); + dart_write(sc, DART_MR2A, sc->sc_sv_reg->sv_mr2[A_PORT]); + dart_write(sc, DART_CSRA, sc->sc_sv_reg->sv_csr[A_PORT]); + dart_write(sc, DART_CRA, sc->sc_sv_reg->sv_cr[A_PORT]); + } + + /* reset port b */ + if (sc->sc_console == 0 || CONS_PORT != B_PORT) { + dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS); + DELAY_CR; + dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS); +#if 0 + DELAY_CR; +#endif + + dart_write(sc, DART_MR1B, sc->sc_sv_reg->sv_mr1[B_PORT]); + dart_write(sc, DART_MR2B, sc->sc_sv_reg->sv_mr2[B_PORT]); + dart_write(sc, DART_CSRB, sc->sc_sv_reg->sv_csr[B_PORT]); + dart_write(sc, DART_CRB, sc->sc_sv_reg->sv_cr[B_PORT]); + } + + /* initialize common register of a DUART */ + dart_write(sc, DART_OPRS, sc->sc_sv_reg->sv_opr); + +#if 0 + dart_write(sc, DART_CTUR, SLCTIM >> 8); + dart_write(sc, DART_CTLR, SLCTIM & 0xff); + dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA); +#endif + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); + dart_write(sc, DART_OPCR, OPSET); + + if (sc->sc_vec != 0) + dart_write(sc, DART_IVR, sc->sc_vec); + + sc->sc_dart[A_PORT].tty = sc->sc_dart[B_PORT].tty = NULL; + sc->sc_dart[A_PORT].dart_swflags = sc->sc_dart[B_PORT].dart_swflags = 0; + if (sc->sc_console) + sc->sc_dart[CONS_PORT].dart_swflags |= TIOCFLAG_SOFTCAR; + + printf("\n"); +} + +/* speed tables */ +const struct dart_s { + int kspeed; + int dspeed; +} dart_speeds[] = { + { B0, 0 }, /* 0 baud, special HUP condition */ + { B50, NOBAUD }, /* 50 baud, not implemented */ + { B75, BD75 }, /* 75 baud */ + { B110, BD110 }, /* 110 baud */ + { B134, BD134 }, /* 134.5 baud */ + { B150, BD150 }, /* 150 baud */ + { B200, NOBAUD }, /* 200 baud, not implemented */ + { B300, BD300 }, /* 300 baud */ + { B600, BD600 }, /* 600 baud */ + { B1200, BD1200 }, /* 1200 baud */ + { B1800, BD1800 }, /* 1800 baud */ + { B2400, BD2400 }, /* 2400 baud */ + { B4800, BD4800 }, /* 4800 baud */ + { B9600, BD9600 }, /* 9600 baud */ + { B19200, BD19200 }, /* 19200 baud */ + { -1, NOBAUD }, /* anything more is uncivilized */ +}; + +int +dart_speed(int speed) +{ + const struct dart_s *ds; + + for (ds = dart_speeds; ds->kspeed != -1; ds++) + if (ds->kspeed == speed) + return ds->dspeed; + + return NOBAUD; +} + +struct tty * +darttty(dev_t dev) +{ + u_int port, chip; + struct dartsoftc *sc; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS) + return (NULL); + + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + if (sc == NULL) + return (NULL); + + return sc->sc_dart[port].tty; +} + +void +dartstart(struct tty *tp) +{ + struct dartsoftc *sc; + dev_t dev; + int s; + u_int port, chip; + int c, tries; + bus_addr_t ptaddr; + + if ((tp->t_state & TS_ISOPEN) == 0) + return; + + dev = tp->t_dev; + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; + + s = spltty(); + + if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) + goto bail; + + if (tp->t_outq.c_cc <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t)&tp->t_outq); + } + selwakeup(&tp->t_wsel); + if (tp->t_outq.c_cc == 0) + goto bail; + } + + tp->t_state |= TS_BUSY; + while (tp->t_outq.c_cc != 0) { + + /* load transmitter until it is full */ + for (tries = 10000; tries != 0; tries --) + if (dart_read(sc, ptaddr + DART_SRA) & TXRDY) + break; + + if (tries == 0) { + timeout_add(&tp->t_rstrt_to, 1); + tp->t_state |= TS_TIMEOUT; + break; + } else { + c = getc(&tp->t_outq); + + dart_write(sc, ptaddr + DART_TBA, c & 0xff); + + sc->sc_sv_reg->sv_imr |= + port == A_PORT ? ITXRDYA : ITXRDYB; + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); + } + } + tp->t_state &= ~TS_BUSY; + +bail: + splx(s); +} + +int +dartstop(struct tty *tp, int flag) +{ + int s; + + s = spltty(); + if (tp->t_state & TS_BUSY) { + if ((tp->t_state & TS_TTSTOP) == 0) + tp->t_state |= TS_FLUSH; + } + splx(s); + + return 0; +} + +/* + * To be called at spltty - tty already locked. + * Returns status of carrier. + */ +int +dartmctl(struct dartsoftc *sc, int port, int flags, int how) +{ + int newflags, flagsmask; + struct dart_info *dart; + int s; + + dart = &sc->sc_dart[port]; + + s = spltty(); + + flagsmask = port == A_PORT ? (OPDTRA | OPRTSA) : (OPDTRB | OPRTSB); + newflags = (flags & TIOCM_DTR ? (OPDTRA | OPDTRB) : 0) | + (flags & TIOCM_RTS ? (OPRTSA | OPRTSB) : 0); + newflags &= flagsmask; /* restrict to the port we are acting on */ + + switch (how) { + case DMSET: + dart_write(sc, DART_OPRS, newflags); + dart_write(sc, DART_OPRR, ~newflags); + /* only replace the sv_opr bits for the port we are acting on */ + sc->sc_sv_reg->sv_opr &= ~flagsmask; + sc->sc_sv_reg->sv_opr |= newflags; + break; + case DMBIS: + dart_write(sc, DART_OPRS, newflags); + sc->sc_sv_reg->sv_opr |= newflags; + break; + case DMBIC: + dart_write(sc, DART_OPRR, newflags); + sc->sc_sv_reg->sv_opr &= ~newflags; + break; + case DMGET: + flags = 0; + if (port == A_PORT) { + if (sc->sc_sv_reg->sv_opr & OPDTRA) + flags |= TIOCM_DTR; + if (sc->sc_sv_reg->sv_opr & OPRTSA) + flags |= TIOCM_RTS; + } else { + if (sc->sc_sv_reg->sv_opr & OPDTRB) + flags |= TIOCM_DTR; + if (sc->sc_sv_reg->sv_opr & OPRTSB) + flags |= TIOCM_RTS; + } + break; + } + + splx(s); + return (flags); +} + +int +dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + int error; + u_int port, chip; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + dart = &sc->sc_dart[port]; + + tp = dart->tty; + if (tp == NULL) + return (ENXIO); + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); + if (error >= 0) + return(error); + + error = ttioctl(tp, cmd, data, flag, p); + if (error >= 0) + return(error); + + switch (cmd) { + case TIOCSBRK: + case TIOCCBRK: + break; + case TIOCSDTR: + (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIS); + break; + case TIOCCDTR: + (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIC); + break; + case TIOCMSET: + (void)dartmctl(sc, port, *(int *) data, DMSET); + break; + case TIOCMBIS: + (void)dartmctl(sc, port, *(int *) data, DMBIS); + break; + case TIOCMBIC: + (void)dartmctl(sc, port, *(int *) data, DMBIC); + break; + case TIOCMGET: + *(int *)data = dartmctl(sc, port, 0, DMGET); + break; + case TIOCGFLAGS: + *(int *)data = dart->dart_swflags; + break; + case TIOCSFLAGS: + error = suser(p, 0); + if (error != 0) + return (EPERM); + + dart->dart_swflags = *(int *)data; + dart->dart_swflags &= /* only allow valid flags */ + (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS); + break; + default: + return (ENOTTY); + } + + return (0); +} + +int +dartparam(struct tty *tp, struct termios *t) +{ + int flags; + u_int port, chip; + int speeds; + unsigned char mr1, mr2; + struct dart_info *dart; + struct dartsoftc *sc; + dev_t dev; + bus_addr_t ptaddr; + + dev = tp->t_dev; + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + dart = &sc->sc_dart[port]; + ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; + + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = t->c_cflag; + + flags = tp->t_flags; + + /* Reset to make global changes*/ + /* disable Tx and Rx */ + + if (sc->sc_console == 0 || CONS_PORT != port) { + if (port == A_PORT) + sc->sc_sv_reg->sv_imr &= ~(ITXRDYA | IRXRDYA); + else + sc->sc_sv_reg->sv_imr &= ~(ITXRDYB | IRXRDYB); + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); + + /* hang up on zero baud rate */ + if (tp->t_ispeed == 0) { + dartmctl(sc, port, HUPCL, DMSET); + return (0); + } else { + /* set baudrate */ + speeds = dart_speed(tp->t_ispeed); + if (speeds == NOBAUD) + speeds = sc->sc_sv_reg->sv_csr[port]; + dart_write(sc, ptaddr + DART_CSRA, speeds); + sc->sc_sv_reg->sv_csr[port] = speeds; + } + + /* get saved mode registers and clear set up parameters */ + mr1 = sc->sc_sv_reg->sv_mr1[port]; + mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK); + + mr2 = sc->sc_sv_reg->sv_mr2[port]; + mr2 &= ~SBMASK; + + /* set up character size */ + switch (t->c_cflag & CSIZE) { + case CL8: + mr1 |= CL8; + break; + case CL7: + mr1 |= CL7; + break; + case CL6: + mr1 |= CL6; + break; + case CL5: + mr1 |= CL5; + break; + } + + /* set up stop bits */ + if (tp->t_ospeed == B110) + mr2 |= SB2; + else + mr2 |= SB1; + + /* set up parity */ + if (t->c_cflag & PARENB) { + mr1 |= PAREN; + if (t->c_cflag & PARODD) + mr1 |= ODDPAR; + else + mr1 |= EVENPAR; + } else + mr1 |= PARDIS; + + if (sc->sc_sv_reg->sv_mr1[port] != mr1 || + sc->sc_sv_reg->sv_mr2[port] != mr2) { + /* write mode registers to duart */ + dart_write(sc, ptaddr + DART_CRA, MRRESET); + dart_write(sc, ptaddr + DART_MR1A, mr1); + dart_write(sc, ptaddr + DART_MR2A, mr2); + + /* save changed mode registers */ + sc->sc_sv_reg->sv_mr1[port] = mr1; + sc->sc_sv_reg->sv_mr2[port] = mr2; + } + } + + /* enable transmitter? */ + if (tp->t_state & TS_BUSY) { + sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB; + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); + } + + /* re-enable the receiver */ +#if 0 + DELAY_CR; +#endif + sc->sc_sv_reg->sv_imr |= port == A_PORT ? IRXRDYA : IRXRDYB; + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); + + return (0); +} + +void +dartmodemtrans(struct dartsoftc *sc, unsigned int ip, unsigned int ipcr) +{ + unsigned int dcdstate; + struct tty *tp; + int port; + struct dart_info *dart; + + /* input is inverted at port!!! */ + if (ipcr & IPCRDCDA) { + port = A_PORT; + dcdstate = !(ip & IPDCDA); + } else if (ipcr & IPCRDCDB) { + port = B_PORT; + dcdstate = !(ip & IPDCDB); + } else { +#ifdef DIAGNOSTIC + printf("dartmodemtrans: unknown transition ip=0x%x ipcr=0x%x\n", + ip, ipcr); +#endif + return; + } + + dart = &sc->sc_dart[port]; + tp = dart->tty; + if (tp != NULL) + ttymodem(tp, dcdstate); +} + +int +dartopen(dev_t dev, int flag, int mode, struct proc *p) +{ + int s; + u_int port, chip; + struct dart_info *dart; + struct dartsoftc *sc; + struct tty *tp; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS) + return (ENODEV); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + if (sc == NULL) + return (ENODEV); + dart = &sc->sc_dart[port]; + + s = spltty(); + if (dart->tty != NULL) + tp = dart->tty; + else + tp = dart->tty = ttymalloc(); + + tp->t_oproc = dartstart; + tp->t_param = dartparam; + tp->t_dev = dev; + + if ((tp->t_state & TS_ISOPEN) == 0) { + ttychars(tp); + + if (tp->t_ispeed == 0) { + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = B9600; + if (sc->sc_console && port == CONS_PORT) { + /* console is 8N1 */ + tp->t_cflag = (CREAD | CS8 | HUPCL); + } else { + tp->t_cflag = TTYDEF_CFLAG; + } + } + + if (dart->dart_swflags & TIOCFLAG_CLOCAL) + tp->t_cflag |= CLOCAL; + if (dart->dart_swflags & TIOCFLAG_CRTSCTS) + tp->t_cflag |= CRTSCTS; + if (dart->dart_swflags & TIOCFLAG_MDMBUF) + tp->t_cflag |= MDMBUF; + + dartparam(tp, &tp->t_termios); + ttsetwater(tp); + + (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMSET); + tp->t_state |= TS_CARR_ON; + } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { + splx(s); + return (EBUSY); + } + + /* + * Reset the tty pointer, as there could have been a dialout + * use of the tty with a dialin open waiting. + */ + tp->t_dev = dev; + splx(s); + return ((*linesw[tp->t_line].l_open)(dev, tp)); +} + +int +dartclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + u_int port, chip; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + dart = &sc->sc_dart[port]; + + tp = dart->tty; + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + + return (0); +} + +int +dartread(dev_t dev, struct uio *uio, int flag) +{ + u_int port, chip; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + dart = &sc->sc_dart[port]; + + tp = dart->tty; + if (tp == NULL) + return (ENXIO); + return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + +int +dartwrite(dev_t dev, struct uio *uio, int flag) +{ + u_int port, chip; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + + chip = DART_CHIP(dev); + port = DART_PORT(dev); + sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; + dart = &sc->sc_dart[port]; + + tp = dart->tty; + if (tp == NULL) + return (ENXIO); + return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); +} + +void +dartrint(struct dartsoftc *sc, int port) +{ + struct tty *tp; + unsigned char data, sr; + struct dart_info *dart; + bus_addr_t ptaddr; + + dart = &sc->sc_dart[port]; + ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; + tp = dart->tty; + + /* read status reg */ + while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) { + /* read data and reset receiver */ + data = dart_read(sc, ptaddr + DART_RBA); + + if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 && + (sc->sc_console == 0 || CONS_PORT != port)) { + return; + } + + if (sr & RBRK) { + /* clear break state */ + dart_write(sc, ptaddr + DART_CRA, BRKINTRESET); + DELAY_CR; + dart_write(sc, ptaddr + DART_CRA, ERRRESET); + +#if defined(DDB) + if (db_console != 0 && + sc->sc_console && port == CONS_PORT) + Debugger(); +#endif + } else { + if (sr & (FRERR | PERR | ROVRN)) { /* errors */ + if (sr & ROVRN) + log(LOG_WARNING, "%s port %c: " + "receiver overrun\n", + sc->sc_dev.dv_xname, 'A' + port); + if (sr & FRERR) + log(LOG_WARNING, "%s port %c: " + "framing error\n", + sc->sc_dev.dv_xname, 'A' + port); + if (sr & PERR) + log(LOG_WARNING, "%s port %c: " + "parity error\n", + sc->sc_dev.dv_xname, 'A' + port); + /* clear error state */ + dart_write(sc, ptaddr + DART_CRA, ERRRESET); + } else { + /* no errors */ + (*linesw[tp->t_line].l_rint)(data,tp); + } + } + } +} + +void +dartxint(struct dartsoftc *sc, int port) +{ + struct tty *tp; + struct dart_info *dart; + + dart = &sc->sc_dart[port]; + tp = dart->tty; + + if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0) + goto out; + + if (tp->t_state & TS_BUSY) { + tp->t_state &= ~(TS_BUSY | TS_FLUSH); + dartstart(tp); + if (tp->t_state & TS_BUSY) { + /* do not disable transmitter, yet */ + return; + } + } +out: + + /* disable transmitter */ + sc->sc_sv_reg->sv_imr &= port == A_PORT ? ~ITXRDYA : ~ITXRDYB; + dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); +} + +int +dartintr(void *arg) +{ + struct dartsoftc *sc = arg; + unsigned char isr, imr; + int port; + + /* read interrupt status register and mask with imr */ + isr = dart_read(sc, DART_ISR); + imr = sc->sc_sv_reg->sv_imr; + + if ((isr & imr) == 0) { + /* + * We got an interrupt on a disabled condition (such as TX + * ready change on a disabled port). This should not happen, + * but we have to claim the interrupt anyway. + */ +#ifdef DIAGNOSTIC + printf("%s: spurious interrupt, isr %x imr %x\n", + sc->sc_dev.dv_xname, isr, imr); +#endif + return (1); + } + isr &= imr; + + if (isr & IIPCHG) { + unsigned int ip, ipcr; + + ip = dart_read(sc, DART_IP); + ipcr = dart_read(sc, DART_IPCR); + dartmodemtrans(sc, ip, ipcr); + return (1); + } + + if (isr & (IRXRDYA | ITXRDYA)) + port = 0; +#ifdef DIAGNOSTIC + else if ((isr & (IRXRDYB | ITXRDYB)) == 0) { + printf("%s: spurious interrupt, isr %x\n", + sc->sc_dev.dv_xname, isr); + return (1); /* claim it anyway */ + } +#endif + else + port = 1; + + if (isr & (IRXRDYA | IRXRDYB)) + dartrint(sc, port); + if (isr & (ITXRDYA | ITXRDYB)) + dartxint(sc, port); + if (isr & (port == A_PORT ? IBRKA : IBRKB)) + dart_write(sc, port == A_PORT ? DART_CRA : DART_CRB, + BRKINTRESET); + + return (1); +} + +/* + * Console interface routines. + */ + +#define dart_cnread(reg) \ + *(volatile u_int8_t *)(IIOV(CONSOLE_DART_BASE) + 3 + ((reg) << 2)) +#define dart_cnwrite(reg, val) \ + *(volatile u_int8_t *)(IIOV(CONSOLE_DART_BASE) + 3 + ((reg) << 2)) = (val) + +void +dartcnprobe(struct consdev *cp) +{ + int maj; + + if (cputyp != CPU_165) + return; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == dartopen) + break; + if (maj == nchrdev) + return; + + cp->cn_dev = makedev(maj, CONS_PORT); + cp->cn_pri = CN_LOWPRI; +} + +void +dartcninit(cp) + struct consdev *cp; +{ + dartcn_sv.sv_mr1[CONS_PORT] = PARDIS | RXRTS | CL8; + dartcn_sv.sv_mr2[CONS_PORT] = /* TXCTS | */ SB1; + dartcn_sv.sv_csr[CONS_PORT] = BD9600; + dartcn_sv.sv_cr[CONS_PORT] = TXEN | RXEN; + dartcn_sv.sv_opr = CONS_PORT == A_PORT ? (OPDTRA | OPRTSA) : + (OPDTRB | OPRTSB); + dartcn_sv.sv_imr = IIPCHG; + + dart_cnwrite(DART_CRA, RXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_cnwrite(DART_CRA, TXRESET | TXDIS | RXDIS); + DELAY_CR; + dart_cnwrite(DART_CRA, ERRRESET | TXDIS | RXDIS); + DELAY_CR; + dart_cnwrite(DART_CRA, BRKINTRESET | TXDIS | RXDIS); + DELAY_CR; + dart_cnwrite(DART_CRA, MRRESET | TXDIS | RXDIS); + DELAY_CR; + + dart_cnwrite(DART_MR1A, dartcn_sv.sv_mr1[CONS_PORT]); + dart_cnwrite(DART_MR2A, dartcn_sv.sv_mr2[CONS_PORT]); + dart_cnwrite(DART_CSRA, dartcn_sv.sv_csr[CONS_PORT]); + dart_cnwrite(DART_CRA, dartcn_sv.sv_cr[CONS_PORT]); + + dart_cnwrite(DART_OPRS, dartcn_sv.sv_opr); + + dart_cnwrite(DART_IMR, dartcn_sv.sv_imr); +} + +void +dartcnputc(dev_t dev, int c) +{ + int s; + u_int port; + bus_addr_t ptaddr; + + port = CONS_PORT; + ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; + + s = spltty(); + + /* inhibit interrupts on the chip */ + dart_cnwrite(DART_IMR, dartcn_sv.sv_imr & + (CONS_PORT == A_PORT ? ~ITXRDYA : ~ITXRDYB)); + /* make sure transmitter is enabled */ +#if 0 + DELAY_CR; +#endif + dart_cnwrite(ptaddr + DART_CRA, TXEN); + + while ((dart_cnread(ptaddr + DART_SRA) & TXRDY) == 0) + ; + dart_cnwrite(ptaddr + DART_TBA, c); + + /* wait for transmitter to empty */ + while ((dart_cnread(ptaddr + DART_SRA) & TXEMT) == 0) + ; + + /* restore the previous state */ + dart_cnwrite(DART_IMR, dartcn_sv.sv_imr); +#if 0 + DELAY_CR; +#endif + dart_cnwrite(ptaddr + DART_CRA, dartcn_sv.sv_cr[0]); + + splx(s); +} + +int +dartcngetc(dev_t dev) +{ + unsigned char sr; /* status reg of port a/b */ + u_char c; /* received character */ + int s; + u_int port; + bus_addr_t ptaddr; + + port = CONS_PORT; + ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; + + s = spltty(); + + /* enable receiver */ + dart_cnwrite(ptaddr + DART_CRA, RXEN); + + for (;;) { + /* read status reg */ + sr = dart_cnread(ptaddr + DART_SRA); + + /* receiver interrupt handler*/ + if (sr & RXRDY) { + /* read character from port */ + c = dart_cnread(ptaddr + DART_RBA); + + /* check break condition */ + if (sr & RBRK) { + /* clear break state */ + dart_cnwrite(ptaddr + DART_CRA, BRKINTRESET); + DELAY_CR; + dart_cnwrite(ptaddr + DART_CRA, ERRRESET); + break; + } + + if (sr & (FRERR | PERR | ROVRN)) { + /* clear error state */ + dart_cnwrite(ptaddr + DART_CRA, ERRRESET); + } else { + break; + } + } + } + splx(s); + + return ((int)c); +} diff --git a/sys/arch/mvme68k/dev/dart_lrc.c b/sys/arch/mvme68k/dev/dart_lrc.c new file mode 100644 index 00000000000..576af188e1a --- /dev/null +++ b/sys/arch/mvme68k/dev/dart_lrc.c @@ -0,0 +1,106 @@ +/* $OpenBSD: dart_lrc.c,v 1.1 2009/03/01 21:40:49 miod Exp $ */ +/* + * Copyright (c) 2006, 2009, Miodrag Vallat + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/autoconf.h> +#include <machine/cpu.h> + +#include <mvme68k/dev/lrcreg.h> + +#include <mvme68k/dev/dartreg.h> +#include <mvme68k/dev/dartvar.h> + +int dart_lrc_match(struct device *parent, void *self, void *aux); +void dart_lrc_attach(struct device *parent, struct device *self, void *aux); + +struct cfattach dartlrc_ca = { + sizeof(struct dartsoftc), dart_lrc_match, dart_lrc_attach +}; + +int +dart_lrc_match(struct device *parent, void *cf, void *aux) +{ + struct confargs *ca = aux; +#if 0 + bus_space_handle_t ioh; + int rc; +#endif + + if (cputyp != CPU_165) + return (0); + + /* + * We do not accept empty locators here... + */ + if (ca->ca_paddr != CONSOLE_DART_BASE) + return (0); + +#if 0 /* overkill, this is the console so if we've run so far, it exists */ + if (bus_space_map(ca->ca_iot, ca->ca_paddr, DART_SIZE, 0, &ioh) != 0) + return (0); + rc = badvaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh) + 3, 1); + bus_space_unmap(ca->ca_iot, ca->ca_paddr, DART_SIZE); + + return (rc == 0); +#else + return (1); +#endif +} + +void +dart_lrc_attach(struct device *parent, struct device *self, void *aux) +{ + struct dartsoftc *sc = (struct dartsoftc *)self; + struct confargs *ca = aux; + bus_space_handle_t ioh; + + if (ca->ca_ipl < 0) + ca->ca_ipl = IPL_TTY; + + sc->sc_iot = ca->ca_iot; + if (bus_space_map(sc->sc_iot, ca->ca_paddr, DART_SIZE, 0, &ioh) != 0) { + printf(": can't map registers!\n"); + return; + } + sc->sc_ioh = ioh; + + sc->sc_console = 1; /* there can't be any other */ + printf(": console"); + + /* enable interrupts */ + sc->sc_ih.ih_fn = dartintr; + sc->sc_ih.ih_arg = sc; + sc->sc_ih.ih_wantframe = 0; + sc->sc_ih.ih_ipl = ca->ca_ipl; + + lrcintr_establish(LRCVEC_DART, &sc->sc_ih, self->dv_xname); + + sc->sc_vec = LRC_VECBASE + LRCVEC_DART; + dart_common_attach(sc); +} diff --git a/sys/arch/mvme68k/dev/dartreg.h b/sys/arch/mvme68k/dev/dartreg.h new file mode 100644 index 00000000000..bc364589ae0 --- /dev/null +++ b/sys/arch/mvme68k/dev/dartreg.h @@ -0,0 +1,155 @@ +/* $OpenBSD: dartreg.h,v 1.1 2009/03/01 21:40:49 miod Exp $ */ + +#define CONSOLE_DART_BASE 0xfffd0000 /* on MVME165 */ + +#define MAXPORTS 2 /* max count of PORTS/DUART */ + +#define A_PORT 0 +#define B_PORT 1 + +/* the access to the same command register must be delayed, + because the chip has some hardware problems in this case */ +#define DELAY_CR delay(2) + +/*********************** MC68681 DEFINITIONS ************************/ + +/* mode register 1: MR1x operations */ +#define RXRTS 0x80 /* enable receiver RTS */ +#define PAREN 0x00 /* with parity */ +#define PARDIS 0x10 /* no parity */ +#define EVENPAR 0x00 /* even parity */ +#define ODDPAR 0x04 /* odd parity */ +#define CL5 0x00 /* 5 bits per char */ +#define CL6 0x01 /* 6 bits per char */ +#define CL7 0x02 /* 7 bits per char */ +#define CL8 0x03 /* 8 bits per char */ +#define PARMODEMASK 0x18 /* parity mode mask */ +#define PARTYPEMASK 0x04 /* parity type mask */ +#define CLMASK 0x03 /* character length mask */ + +/* mode register 2: MR2x operations */ +#define TXRTS 0x20 /* enable transmitter RTS */ +#define TXCTS 0x10 /* enable transmitter CTS */ +#define SB2 0x0f /* 2 stop bits */ +#define SB1 0x07 /* 1 stop bit */ +#define SB1L5 0x00 /* 1 stop bit at 5 bits per character */ + +#define SBMASK 0x0f /* stop bit mask */ + +/* clock-select register: CSRx operations */ +#define NOBAUD -1 /* 50 and 200 baud are not possible */ +/* they are not in Baud register set 2 */ +#define BD75 0x00 /* 75 baud */ +#define BD110 0x11 /* 110 baud */ +#define BD134 0x22 /* 134.5 baud */ +#define BD150 0x33 /* 150 baud */ +#define BD300 0x44 /* 300 baud */ +#define BD600 0x55 /* 600 baud */ +#define BD1200 0x66 /* 1200 baud */ +#define BD1800 0xaa /* 1800 baud */ +#define BD2400 0x88 /* 2400 baud */ +#define BD4800 0x99 /* 4800 baud */ +#define BD9600 0xbb /* 9600 baud */ +#define BD19200 0xcc /* 19200 baud */ + +#define DEFBAUD BD9600 /* default value if baudrate is not possible */ + + +/* channel command register: CRx operations */ +#define MRRESET 0x10 /* reset mr pointer to mr1 */ +#define RXRESET 0x20 /* reset receiver */ +#define TXRESET 0x30 /* reset transmitter */ +#define ERRRESET 0x40 /* reset error status */ +#define BRKINTRESET 0x50 /* reset channel's break interrupt */ +#define BRKSTART 0x60 /* start break */ +#define BRKSTOP 0x70 /* stop break */ +#define TXDIS 0x08 /* disable transmitter */ +#define TXEN 0x04 /* enable transmitter */ +#define RXDIS 0x02 /* disable receiver */ +#define RXEN 0x01 /* enable receiver */ + +/* status register: SRx status */ +#define RBRK 0x80 /* received break */ +#define FRERR 0x40 /* frame error */ +#define PERR 0x20 /* parity error */ +#define ROVRN 0x10 /* receiver overrun error */ +#define TXEMT 0x08 /* transmitter empty */ +#define TXRDY 0x04 /* transmitter ready */ +#define FFULL 0x02 /* receiver FIFO full */ +#define RXRDY 0x01 /* receiver ready */ + +/* output port configuration register: OPCR operations */ +#define OPSET 0x00 /* set all op lines to op function */ +#define OPSETTO 0x04 /* use OP3 for timer output */ + +/* output port register: OP operations */ +#define OPDTRB 0x20 /* DTR line output b on the VME188, 181, 141 */ +#define OPDTRA 0x04 /* DTR line output a */ +#define OPRTSB 0x02 /* RTS line output b */ +#define OPRTSA 0x01 /* RTS line output a */ + +/* auxiliary control register: ACR operations */ +#define BDSET1 0x00 /* baudrate generator set 1 */ +#define BDSET2 0x80 /* baudrate generator set 2 */ +#define CCLK1 0x60 /* timer clock: external rate. TA */ +#define CCLK16 0x30 /* counter clock: x1 clk divided by 16 */ + +/* input port change register: IPCR operations */ +#define IPCRDCDB 0x80 /* IP3 change == DCD change on port B */ +#define IPCRDCDA 0x40 /* IP2 change == DCD change on port A */ + +/* Defines for mvme335 */ +#define IPDCDB 0x20 /* DCD line input b */ +#define IPDCDA 0x10 /* DCD line input a */ + +#define IPDSRB 0x08 /* DSR line input b */ +#define IPDSRA 0x04 /* DSR line input a */ +#define IPCTSB 0x02 /* CTS line input b */ +#define IPCTSA 0x01 /* CTS line input a */ + +/* interrupt status and mask register: ISR status and IMR mask */ +#define IIPCHG 0x80 /* input port change */ +#define IBRKB 0x40 /* delta break b */ +#define IRXRDYB 0x20 /* receiver ready b */ +#define ITXRDYB 0x10 /* transmitter ready b */ +#define ITIMER 0x08 /* Enable timer interrupts. */ +#define IBRKA 0x04 /* delta break a */ +#define IRXRDYA 0x02 /* receiver ready a */ +#define ITXRDYA 0x01 /* transmitter ready a */ + +/* + * MC68681 hardware registers. + */ + +#define DART_MR1A 0x00 /* RW: mode register A */ +#define DART_MR2A 0x00 /* RW: mode register A */ +#define DART_SRA 0x01 /* R: status register A */ +#define DART_CSRA 0x01 /* W: clock select register A */ +#define DART_CRA 0x02 /* W: command register A */ +#define DART_RBA 0x03 /* R: receiver buffer A */ +#define DART_TBA 0x03 /* W: transmit buffer A */ +#define DART_IPCR 0x04 /* R: input port change register */ +#define DART_ACR 0x04 /* W: auxiliary control register */ +#define DART_ISR 0x05 /* R: interrupt status register */ +#define DART_IMR 0x05 /* W: interrupt mask register */ +#define DART_CUR 0x06 /* R: count upper register */ +#define DART_CTUR 0x06 /* W: counter/timer upper register */ +#define DART_CLR 0x07 /* R: count lower register */ +#define DART_CTLR 0x07 /* W: counter/timer lower register */ +#define DART_MR1B 0x08 /* RW: mode register B */ +#define DART_MR2B 0x08 /* RW: mode register B */ +#define DART_SRB 0x09 /* R: status register B */ +#define DART_CSRB 0x09 /* W: clock select register B */ +#define DART_CRB 0x0a /* W: command register B */ +#define DART_RBB 0x0b /* R: receiver buffer B */ +#define DART_TBB 0x0b /* W: transmit buffer B */ +#define DART_IVR 0x0c /* RW: interrupt vector register */ +#define DART_IP 0x0d /* R: input port (unlatched) */ +#define DART_OPCR 0x0d /* W: output port configuration register */ +#define DART_CTSTART 0x0e /* R: start counter command */ +#define DART_OPRS 0x0e /* W: output port bit set */ +#define DART_CTSTOP 0x0f /* R: stop counter command */ +#define DART_OPRR 0x0f /* W: output port bit reset */ + +#define DART_A_BASE 0x00 +#define DART_B_BASE 0x08 diff --git a/sys/arch/mvme68k/dev/dartvar.h b/sys/arch/mvme68k/dev/dartvar.h new file mode 100644 index 00000000000..78a28fac00b --- /dev/null +++ b/sys/arch/mvme68k/dev/dartvar.h @@ -0,0 +1,63 @@ +/* $OpenBSD: dartvar.h,v 1.1 2009/03/01 21:40:49 miod Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1993-1991 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 AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM 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. + */ + +#define NDARTPORTS 2 /* Number of ports */ + +struct dart_info { + struct tty *tty; + u_char dart_swflags; +}; + +/* saved registers */ +struct dart_sv_reg { + u_int8_t sv_mr1[NDARTPORTS]; + u_int8_t sv_mr2[NDARTPORTS]; + u_int8_t sv_csr[NDARTPORTS]; + u_int8_t sv_cr[NDARTPORTS]; + u_int8_t sv_opr; + u_int8_t sv_imr; +}; + +struct dartsoftc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + struct intrhand sc_ih; + + int sc_console; + int sc_vec; + + struct dart_sv_reg *sc_sv_reg; + struct dart_sv_reg sc_sv_reg_storage; + struct dart_info sc_dart[NDARTPORTS]; +}; + +void dart_common_attach(struct dartsoftc *); +int dartintr(void *); + +#define DART_SIZE 0x40 diff --git a/sys/arch/mvme68k/dev/lrc.c b/sys/arch/mvme68k/dev/lrc.c new file mode 100644 index 00000000000..05aa7417aea --- /dev/null +++ b/sys/arch/mvme68k/dev/lrc.c @@ -0,0 +1,232 @@ +/* $OpenBSD: lrc.c,v 1.1 2009/03/01 21:40:49 miod Exp $ */ + +/* + * Copyright (c) 2006, Miodrag Vallat. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * LRC Local Resource Controller, found on MVME165 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/kernel.h> + +#include <machine/autoconf.h> +#include <machine/cpu.h> + +#include <mvme68k/dev/lrcreg.h> + +struct lrcreg *sys_lrc; + +struct lrcsoftc { + struct device sc_dev; + struct lrcreg *sc_regs; + vaddr_t sc_vaddr; + paddr_t sc_paddr; + struct intrhand sc_abortih; +}; + +int lrcabort(void *); +void lrcattach(struct device *, struct device *, void *); +int lrcmatch(struct device *, void *, void *); +int lrcprint(void *, const char *); +int lrcscan(struct device *, void *, void *); + +struct cfattach lrc_ca = { + sizeof(struct lrcsoftc), lrcmatch, lrcattach +}; + +struct cfdriver lrc_cd = { + NULL, "lrc", DV_DULL +}; + +int +lrcmatch(struct device *parent, void *cf, void *aux) +{ + if (cputyp != CPU_165 || sys_lrc != NULL) + return (0); + + return (1); +} + +void +lrcattach(struct device *parent, struct device *self, void *aux) +{ + struct confargs *ca = aux; + struct lrcsoftc *sc = (struct lrcsoftc *)self; + + sc->sc_paddr = ca->ca_paddr; + sc->sc_vaddr = IIOV(sc->sc_paddr); + sys_lrc = sc->sc_regs = (struct lrcreg *)sc->sc_vaddr; + + printf("\n"); + + /* sync serial clock with DUART */ + sc->sc_regs->lrc_gcr &= ~GCR_SCFREQ; + /* disable VSB */ + sc->sc_regs->lrc_bcr &= ~(BCR_VA24 | BCR_VSBEN | BCR_ROEN); + /* set up vector base */ + sc->sc_regs->lrc_icr1 = LRC_VECBASE; + /* enable interrupts */ + sc->sc_regs->lrc_icr0 = ICR0_GIE; + + sc->sc_abortih.ih_fn = lrcabort; + sc->sc_abortih.ih_ipl = IPL_HIGH; + sc->sc_abortih.ih_wantframe = 1; + lrcintr_establish(LRCVEC_ABORT, &sc->sc_abortih, self->dv_xname); + + config_search(lrcscan, self, aux); +} + +int +lrcprint(void *aux, const char *pnp) +{ + struct confargs *ca = aux; + + if (ca->ca_offset != -1) + printf(" offset 0x%x", ca->ca_offset); + if (ca->ca_ipl > 0) + printf(" ipl %d", ca->ca_ipl); + return (UNCONF); +} + +int +lrcscan(struct device *parent, void *self, void *aux) +{ + struct cfdata *cf = self; + struct lrcsoftc *sc = (struct lrcsoftc *)parent; + struct confargs *ca = aux; + struct confargs oca; + + bzero(&oca, sizeof oca); + oca.ca_iot = ca->ca_iot; + oca.ca_dmat = ca->ca_dmat; + oca.ca_offset = cf->cf_loc[0]; + oca.ca_ipl = cf->cf_loc[1]; + if (oca.ca_offset != -1 && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { + oca.ca_vaddr = sc->sc_vaddr + oca.ca_offset; + oca.ca_paddr = sc->sc_paddr + oca.ca_offset; + } else { + oca.ca_vaddr = (vaddr_t)-1; + oca.ca_paddr = (paddr_t)-1; + } + oca.ca_bustype = BUS_LRC; + oca.ca_name = cf->cf_driver->cd_name; + + if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) + return (0); + + config_attach(parent, cf, &oca, lrcprint); + + return (1); +} + +/* + * Register an LRC interrupt. + * This will take care of enabling the right interrupt source in the + * interrupt controller. + */ +int +lrcintr_establish(u_int vec, struct intrhand *ih, const char *name) +{ + int rc; + const struct { + u_int8_t icr0_bit; + u_int8_t icr1_bit; + } icr_bits[] = { + { 0x00, 0x00 }, /* timer 0 done differently */ + { 0x00, 0x00 }, /* timer 1 done differently */ + { 0x00, 0x00 }, /* timer 2 done differently */ + { 0xff, 0xff }, + { ICR0_IRQ7G2IE, 0x00 }, + { ICR0_IRQ6G2IE, 0x00 }, + { 0xff, 0xff }, + { ICR0_IRQ3G2IE, 0x00 }, + { ICR0_IRQ7G2IE, 0x00 }, + { ICR0_IRQ4G2IE, 0x00 }, /* ICR0_IRQ6G4IE */ + { 0x00, ICR1_IRQ7G5IE }, + { 0x00, ICR1_IRQ7G6IE }, + { ICR0_IRQ5G2IE, 0x00 }, + { 0xff, 0xff }, + { 0xff, 0xff }, + { 0xff, 0xff } + }; + +#ifdef DIAGNOSTIC + if (vec < 0 || vec >= LRC_NVEC || icr_bits[vec].icr0_bit == 0xff) + panic("lrcintr_establish: illegal vector for %s: 0x%x", + name, vec); +#endif + + rc = intr_establish(LRC_VECBASE + vec, ih, name); + + if (rc == 0) { + sys_lrc->lrc_icr0 |= icr_bits[vec].icr0_bit; + sys_lrc->lrc_icr1 |= icr_bits[vec].icr1_bit; + } + + return (rc); +} + +int +lrcabort(void *frame) +{ + nmihand(frame); + + return (1); +} + +/* + * Figure out the speed of the board by measuring how many operations + * can be issued in a given time, reusing the delay() logic. + */ +int +lrcspeed(struct lrcreg *lrc) +{ + uint cnt; + int speed; + + /* use timer0 and wait for it to wrap after 200msec */ + cnt = 0; + lrc->lrc_t0base = 200000 + 1; + lrc->lrc_tcr0 = TCR_TLD0; /* reset to one */ + lrc->lrc_stat = STAT_TMR0; /* clear latch */ + lrc->lrc_tcr0 = TCR_TEN0; + while ((lrc->lrc_stat & STAT_TMR0) == 0) + cnt++; + + /* + * Empirically determined. However since there are only + * 25MHz and 33MHz boards available, it is easy to draw + * a line - cnt should be close to cpu MHz * 8000. + */ + if (cnt > 30 * 8000) + speed = 33; + else + speed = 25; + + return speed; +} diff --git a/sys/arch/mvme68k/dev/lrcreg.h b/sys/arch/mvme68k/dev/lrcreg.h new file mode 100644 index 00000000000..3ddd40d250e --- /dev/null +++ b/sys/arch/mvme68k/dev/lrcreg.h @@ -0,0 +1,175 @@ +/* $OpenBSD: lrcreg.h,v 1.1 2009/03/01 21:40:49 miod Exp $ */ + +/* + * Copyright (c) 2006, Miodrag Vallat. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * LRC Local Resource Controller, found on MVME165 + */ + +/* + * Register layout. + * Note that this chip is 24-bit internally, so the 8 high-order bits of + * each register are undefined and likely set to ones. + */ +struct lrcreg { + /* timer constants */ + volatile u_int32_t lrc_t0base; + volatile u_int32_t lrc_t1base; + volatile u_int32_t lrc_t2base; + /* timer counts */ + volatile u_int32_t lrc_t0cnt; + volatile u_int32_t lrc_t1cnt; + volatile u_int32_t lrc_t2cnt; + /* timer control words */ + volatile u_int32_t lrc_tcr0; + volatile u_int32_t lrc_tcr1; + volatile u_int32_t lrc_tcr2; + /* general control */ + volatile u_int32_t lrc_gcr; + /* bus control */ + volatile u_int32_t lrc_bcr; + /* interrupt control */ + volatile u_int32_t lrc_icr0; + volatile u_int32_t lrc_icr1; + /* status register */ + volatile u_int32_t lrc_stat; + /* RAM address */ + volatile u_int32_t lrc_ramaddr; + /* bus error status */ + volatile u_int32_t lrc_berrstat; +}; + +/* TCR0 bits */ +#define TCR_TEN0 0x80 /* timer0 enable */ +#define TCR_TLD0 0x40 /* timer0 reload */ +#define TCR_TCYC0 0x20 /* timer0 cycle */ +#define TCR_T0IE 0x10 /* time0 interrupt enable */ +#define TCR_TOS_MASK 0x0c /* timer output select */ +#define TCR_TOS_TMR0 0x00 +#define TCR_TOS_TMR1 0x04 +#define TCR_TOS_TMR2 0x08 +#define TCR_TOEN 0x02 /* timer output enable */ +#define TCR_TOMD 0x01 /* timer output mode: pulse / square wave */ + +/* TCR1 bits */ +#define TCR_TEN1 0x80 /* timer1 enable */ +#define TCR_TLD1 0x40 /* timer1 reload */ +#define TCR_TCYC1 0x20 /* timer1 cycle */ +#define TCR_T1IE 0x10 /* timer1 interrupt enable */ +#define TCR_TIS_MASK 0x0c /* timer input select */ +#define TCR_TIS_TMR0 0x00 +#define TCR_TIS_TMR1 0x04 +#define TCR_TIS_TMR2 0x08 +#define TCR_TIS_NONE 0x0c +#define TCR_TIEN 0x02 /* timer input enable */ +#define TCR_TIMD 0x01 /* timer input mode */ + +/* TCR2 bits */ +#define TCR_TEN2 0x80 /* timer2 enable */ +#define TCR_TLD2 0x40 /* timer2 reload */ +#define TCR_TCYC2 0x20 /* timer2 cycle */ +#define TCR_T2IE 0x10 /* timer2 interrupt enable */ +#define TCR_TWD_MASK 0x0c /* timer watchdog select */ +#define TCR_TWD_TMR0 0x00 +#define TCR_TWD_TMR1 0x04 +#define TCR_TWD_TMR2 0x08 +#define TCR_TWD_NONE 0x0c +#define TCR_TWDEN 0x02 /* timer watchdog enable */ +#define TCR_TTST 0x01 /* timer test (do not use) */ + +/* GCR bits */ +#define GCR_SCFREQ 0x10 /* dart serial clock frequency */ +#define GCR_FAST 0x08 /* EPROM fast acknowledge */ +#define GCR_GPCTL1 0x04 /* write wrong parity */ +#define GCR_GPCTL0 0x02 /* parity error enable */ +#define GCR_RSTO 0x01 /* reset output */ + +/* BCR bits */ +#define BCR_VA24 0x10 /* force VME A24 addressing for low 16MB */ +#define BCR_VSBEN 0x08 /* VSB enable */ +#define BCR_VSBMD 0x04 /* restricted VSB ranges */ +#define BCR_ROEN 0x02 /* VSB read only enable */ +#define BCR_ROMD 0x01 /* VSB read only mode uses VSBRO */ + +/* ICR0 bits */ +#define ICR0_GIE 0x80 /* global interrupt enable */ +#define ICR0_IRQ3G2IE 0x40 /* DART tick timer, level 3 */ +#define ICR0_IRQ4G2IE 0x20 /* VSBIRQ, level 4 */ +#define ICR0_IRQ5G2IE 0x10 /* DART DUART irq */ +#define ICR0_IRQ6G2IE 0x08 /* DART tick timer, level 6 */ +#define ICR0_IRQ6G4IE 0x04 /* VSBIRQ, level 6 */ +#define ICR0_IRQ7G2IE 0x02 /* unused */ +#define ICR0_IRQ7G4IE 0x01 /* PARERR */ + +/* ICR1 bits */ +#define ICR1_VEC_MASK 0xf0 /* interrupt vector significant nibble */ +#define ICR1_IRQ7G6IE 0x02 /* ACFAIL */ +#define ICR1_IRQ7G5IE 0x01 /* ABORT */ + +/* STAT bits */ +#define STAT_WTS 0x020000 /* Watchdog timeout */ +#define STAT_IRQ7G6S 0x010000 /* ACFAIL */ +#define STAT_IRQ7G5S 0x008000 /* ABORT */ +#define STAT_GPSTATL 0x004000 /* SYSFAIL (latched) */ +#define STAT_GPSTATS 0x002000 /* SYSFAIL */ +#define STAT_PORS 0x001000 /* Power On Reset */ +#define STAT_IRQ3G2 0x000800 /* DART tick timer */ +#define STAT_IRQ4G2 0x000400 /* VSBIRQ */ +#define STAT_IRQ5G2 0x000200 /* DART irq */ +#define STAT_IRQ6G2 0x000100 /* DART tick timer */ +#define STAT_IRQ7G2 0x000080 /* unused */ +#define STAT_TMR2 0x000040 /* timer2 timeout */ +#define STAT_TMR1 0x000020 /* timer1 timeout */ +#define STAT_TMR0 0x000010 /* timer0 timeout */ +#define STAT_IRQ6G4 0x000008 /* VSBIRQ */ +#define STAT_IRQ7G4 0x000004 /* PARERR */ +#define STAT_IRQ7G5 0x000002 /* ABORT */ +#define STAT_IRQ7G6 0x000001 /* ACFAIL */ + +/* + * Fixed interrupt vectors + */ + +#define LRC_VECBASE 0x40 +#define LRC_NVEC 0x10 + +#define LRCVEC_TIMER0 0x00 +#define LRCVEC_TIMER1 0x01 +#define LRCVEC_TIMER2 0x02 +#define LRCVEC_IRQ7G2 0x04 /* not used */ +#define LRCVEC_IRQ6G2 0x05 +#define LRCVEC_IRQ3G2 0x07 +#define LRCVEC_PARERR 0x08 +#define LRCVEC_VSBIRQ 0x09 +#define LRCVEC_ABORT 0x0a +#define LRCVEC_ACFAIL 0x0b + +#define LRCVEC_DART 0x0c /* as set up by the BUG; not a fixed value */ + +int lrcintr_establish(u_int, struct intrhand *, const char *); +int lrcspeed(struct lrcreg *); + +extern struct lrcreg *sys_lrc; diff --git a/sys/arch/mvme68k/dev/nvram.c b/sys/arch/mvme68k/dev/nvram.c index 43572b85600..2b843833641 100644 --- a/sys/arch/mvme68k/dev/nvram.c +++ b/sys/arch/mvme68k/dev/nvram.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nvram.c,v 1.18 2007/12/20 05:19:38 miod Exp $ */ +/* $OpenBSD: nvram.c,v 1.19 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -56,7 +56,7 @@ struct nvramsoftc { paddr_t sc_paddr; vaddr_t sc_vaddr; int sc_len; - struct clockreg *sc_regs; + void *sc_clockregs; }; void nvramattach(struct device *, struct device *, void *); @@ -89,22 +89,41 @@ nvramattach(parent, self, args) { struct confargs *ca = args; struct nvramsoftc *sc = (struct nvramsoftc *)self; + vsize_t maplen; sc->sc_paddr = ca->ca_paddr; sc->sc_vaddr = (vaddr_t)ca->ca_vaddr; sc->sc_len = MK48T08_SIZE; +#ifdef MVME147 if (cputyp == CPU_147) sc->sc_len = MK48T02_SIZE; +#endif + /* + * On the MVME165, the MK48T08 is mapped as one byte per longword, + * thus spans four time as much address space. + */ +#ifdef MVME165 + if (cputyp == CPU_165) + maplen = 4 * sc->sc_len; + else +#endif + maplen = sc->sc_len; /*X*/ if (sc->sc_vaddr == -1) -/*X*/ sc->sc_vaddr = mapiodev(sc->sc_paddr, MAX(sc->sc_len, NBPG)); +/*X*/ sc->sc_vaddr = mapiodev(sc->sc_paddr, maplen); /*X*/ if (sc->sc_vaddr == 0) /*X*/ panic("failed to map!"); - sc->sc_regs = (struct clockreg *)(sc->sc_vaddr + sc->sc_len - - sizeof(struct clockreg)); +#ifdef MVME165 + if (cputyp == CPU_165) + sc->sc_clockregs = (void *)(sc->sc_vaddr + maplen - + sizeof(struct clockreg_165)); + else +#endif + sc->sc_clockregs = (void *)(sc->sc_vaddr + sc->sc_len - + sizeof(struct clockreg)); printf(": MK48T0%d len %d\n", sc->sc_len / 1024, sc->sc_len); } @@ -264,7 +283,6 @@ inittodr(base) time_t base; { struct nvramsoftc *sc = (struct nvramsoftc *) nvram_cd.cd_devs[0]; - register struct clockreg *cl = sc->sc_regs; int sec, min, hour, day, mon, year; int badbase = 0, waszero = base == 0; @@ -279,14 +297,34 @@ inittodr(base) base = 21*SECYR + 186*SECDAY + SECDAY/2; badbase = 1; } - cl->cl_csr |= CLK_READ; /* enable read (stop time) */ - sec = cl->cl_sec; - min = cl->cl_min; - hour = cl->cl_hour; - day = cl->cl_mday; - mon = cl->cl_month; - year = cl->cl_year; - cl->cl_csr &= ~CLK_READ; /* time wears on */ + +#ifdef MVME165 + if (cputyp == CPU_165) { + struct clockreg_165 *cl = sc->sc_clockregs; + + cl->cl_csr |= CLK_READ; /* enable read (stop time) */ + sec = cl->cl_sec; + min = cl->cl_min; + hour = cl->cl_hour; + day = cl->cl_mday; + mon = cl->cl_month; + year = cl->cl_year; + cl->cl_csr &= ~CLK_READ; /* time wears on */ + } else +#endif + { + struct clockreg *cl = sc->sc_clockregs; + + cl->cl_csr |= CLK_READ; /* enable read (stop time) */ + sec = cl->cl_sec; + min = cl->cl_min; + hour = cl->cl_hour; + day = cl->cl_mday; + mon = cl->cl_month; + year = cl->cl_year; + cl->cl_csr &= ~CLK_READ; /* time wears on */ + } + if ((time.tv_sec = chiptotime(sec, min, hour, day, mon, year)) == 0) { printf("WARNING: bad date in nvram"); /* @@ -319,21 +357,40 @@ void resettodr() { struct nvramsoftc *sc = (struct nvramsoftc *) nvram_cd.cd_devs[0]; - register struct clockreg *cl = sc->sc_regs; struct chiptime c; - if (!time.tv_sec || cl == NULL) + if (!time.tv_sec || sc->sc_clockregs == NULL) return; timetochip(&c); - cl->cl_csr |= CLK_WRITE; /* enable write */ - cl->cl_sec = c.sec; - cl->cl_min = c.min; - cl->cl_hour = c.hour; - cl->cl_wday = c.wday; - cl->cl_mday = c.day; - cl->cl_month = c.mon; - cl->cl_year = c.year; - cl->cl_csr &= ~CLK_WRITE; /* load them up */ + +#ifdef MVME165 + if (cputyp == CPU_165) { + struct clockreg_165 *cl = sc->sc_clockregs; + + cl->cl_csr |= CLK_WRITE; /* enable write */ + cl->cl_sec = c.sec; + cl->cl_min = c.min; + cl->cl_hour = c.hour; + cl->cl_wday = c.wday; + cl->cl_mday = c.day; + cl->cl_month = c.mon; + cl->cl_year = c.year; + cl->cl_csr &= ~CLK_WRITE; /* load them up */ + } else +#endif + { + struct clockreg *cl = sc->sc_clockregs; + + cl->cl_csr |= CLK_WRITE; /* enable write */ + cl->cl_sec = c.sec; + cl->cl_min = c.min; + cl->cl_hour = c.hour; + cl->cl_wday = c.wday; + cl->cl_mday = c.day; + cl->cl_month = c.mon; + cl->cl_year = c.year; + cl->cl_csr &= ~CLK_WRITE; /* load them up */ + } } /*ARGSUSED*/ @@ -346,6 +403,11 @@ nvramopen(dev, flag, mode, p) if (minor(dev) >= nvram_cd.cd_ndevs || nvram_cd.cd_devs[minor(dev)] == NULL) return (ENODEV); +#ifdef MVME165 + /* for now, do not allow userland to access the nvram on 165. */ + if (cputyp == CPU_165) + return (ENXIO); +#endif return (0); } diff --git a/sys/arch/mvme68k/dev/nvramreg.h b/sys/arch/mvme68k/dev/nvramreg.h index cc573968068..d430a2565f8 100644 --- a/sys/arch/mvme68k/dev/nvramreg.h +++ b/sys/arch/mvme68k/dev/nvramreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nvramreg.h,v 1.4 2003/06/02 23:27:50 millert Exp $ */ +/* $OpenBSD: nvramreg.h,v 1.5 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1992, 1993 @@ -52,13 +52,34 @@ struct clockreg { volatile u_char cl_year; /* year (0..99; BCD) */ }; +/* + * MK48T08 clock registers as found on MVME165 (sparse layout) + */ +struct clockreg_165 { + volatile u_char __cl_pad0[3]; + volatile u_char cl_csr; /* control register */ + volatile u_char __cl_pad1[3]; + volatile u_char cl_sec; /* seconds (0..59; BCD) */ + volatile u_char __cl_pad2[3]; + volatile u_char cl_min; /* minutes (0..59; BCD) */ + volatile u_char __cl_pad3[3]; + volatile u_char cl_hour; /* hour (0..23; BCD) */ + volatile u_char __cl_pad4[3]; + volatile u_char cl_wday; /* weekday (1..7) */ + volatile u_char __cl_pad5[3]; + volatile u_char cl_mday; /* day in month (1..31; BCD) */ + volatile u_char __cl_pad6[3]; + volatile u_char cl_month; /* month (1..12; BCD) */ + volatile u_char __cl_pad7[3]; + volatile u_char cl_year; /* year (0..99; BCD) */ +}; + /* bits in cl_csr */ #define CLK_WRITE 0x80 /* want to write */ #define CLK_READ 0x40 /* want to read (freeze clock) */ /* * Motorola chose the year `1900' as their base count. - * XXX what happens when it wraps? */ #define YEAR0 0 diff --git a/sys/arch/mvme68k/dev/vme.c b/sys/arch/mvme68k/dev/vme.c index ee135608896..0274b47bf9a 100644 --- a/sys/arch/mvme68k/dev/vme.c +++ b/sys/arch/mvme68k/dev/vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.c,v 1.25 2009/02/17 22:28:41 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.26 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -42,16 +42,20 @@ #include <machine/cpu.h> #include <mvme68k/dev/vme.h> -#include "pcc.h" +#include "lrc.h" #include "mc.h" +#include "pcc.h" #include "pcctwo.h" -#if NPCC > 0 -#include <mvme68k/dev/pccreg.h> +#if NLRC > 0 +#include <mvme68k/dev/lrcreg.h> #endif #if NMC > 0 #include <mvme68k/dev/mcreg.h> #endif +#if NPCC > 0 +#include <mvme68k/dev/pccreg.h> +#endif #if NPCCTWO > 0 #include <mvme68k/dev/pcctworeg.h> #endif @@ -197,7 +201,7 @@ vmematch(parent, cf, args) return (1); } -#if defined(MVME162) || defined(MVME167) || defined(MVME177) +#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177) /* * make local addresses 1G-2G correspond to VME addresses 3G-4G, * as D32 @@ -232,7 +236,8 @@ vmepmap(sc, vmeaddr, len, bustype) len = roundup(len, NBPG); switch (vmebustype) { -#if NPCC > 0 +#if NLRC > 0 || NPCC > 0 + case BUS_LRC: case BUS_PCC: switch (bustype) { case BUS_VMES: @@ -412,7 +417,6 @@ vmescan(parent, child, args, bustype) oca.ca_ipl = cf->cf_loc[2]; if (oca.ca_ipl > 0 && oca.ca_vec == -1) oca.ca_vec = intr_findvec(255, 0); - oca.ca_offset = oca.ca_paddr; oca.ca_vaddr = (vaddr_t)-1; /* nothing mapped during probe */ oca.ca_name = cf->cf_driver->cd_name; @@ -431,7 +435,7 @@ vmeattach(parent, self, args) { struct vmesoftc *sc = (struct vmesoftc *)self; struct confargs *ca = args; -#if NPCC > 0 +#if NLRC > 0 || NPCC > 0 struct vme1reg *vme1; #endif #if NMC > 0 || NPCCTWO > 0 @@ -442,7 +446,8 @@ vmeattach(parent, self, args) vmebustype = ca->ca_bustype; switch (ca->ca_bustype) { -#if NPCC > 0 +#if NLRC > 0 || NPCC > 0 + case BUS_LRC: case BUS_PCC: vme1 = (struct vme1reg *)sc->sc_vaddr; if (vme1->vme1_scon & VME1_SCON_SWITCH) @@ -486,7 +491,7 @@ vmeintr_establish(vec, ih, name) const char *name; { struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0]; -#if NPCC > 0 +#if NLRC > 0 || NPCC > 0 struct vme1reg *vme1; #endif #if NMC > 0 || NPCCTWO > 0 @@ -497,7 +502,8 @@ vmeintr_establish(vec, ih, name) x = intr_establish(vec, ih, name); switch (vmebustype) { -#if NPCC > 0 +#if NLRC > 0 || NPCC > 0 + case BUS_LRC: case BUS_PCC: vme1 = (struct vme1reg *)sc->sc_vaddr; vme1->vme1_irqen = vme1->vme1_irqen | @@ -516,7 +522,7 @@ vmeintr_establish(vec, ih, name) return (x); } -#if defined(MVME147) +#if defined(MVME147) || defined(MVME165) void vme1chip_init(sc) struct vmesoftc *sc; @@ -528,7 +534,7 @@ vme1chip_init(sc) #endif -#if defined(MVME162) || defined(MVME167) || defined(MVME177) +#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177) /* * XXX what AM bits should be used for the D32/D16 mappings? @@ -585,7 +591,6 @@ vme2chip_init(sc) (6 << VME2_IRQL4_VME6SHIFT) | (5 << VME2_IRQL4_VME5SHIFT) | (4 << VME2_IRQL4_VME4SHIFT) | (3 << VME2_IRQL4_VME3SHIFT) | (2 << VME2_IRQL4_VME2SHIFT) | (1 << VME2_IRQL4_VME1SHIFT); - printf("%s: vme to cpu irq level 1:1\n",sc->sc_dev.dv_xname); #if NPCCTWO > 0 if (vmebustype == BUS_PCCTWO) { @@ -638,14 +643,9 @@ int vme2abort(frame) void *frame; { - struct vmesoftc *sc = (struct vmesoftc *)vme_cd.cd_devs[0]; - struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr; + if ((sys_vme2->vme2_irqstat & VME2_IRQ_AB) != 0) + sys_vme2->vme2_irqclr = VME2_IRQ_AB; - if ((vme2->vme2_irqstat & VME2_IRQ_AB) == 0) { - printf("%s: abort irq not set\n", sc->sc_dev.dv_xname); - return (0); - } - vme2->vme2_irqclr = VME2_IRQ_AB; nmihand(frame); return (1); } diff --git a/sys/arch/mvme68k/include/autoconf.h b/sys/arch/mvme68k/include/autoconf.h index d895e92e075..cae6657c853 100644 --- a/sys/arch/mvme68k/include/autoconf.h +++ b/sys/arch/mvme68k/include/autoconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.h,v 1.15 2009/02/17 22:28:41 miod Exp $ */ +/* $OpenBSD: autoconf.h,v 1.16 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -44,11 +44,12 @@ struct confargs { #define BUS_MAIN 1 #define BUS_PCC 2 /* VME147 PCC chip */ -#define BUS_MC 3 /* VME162 MC chip */ -#define BUS_PCCTWO 4 /* VME166/167/177 PCC2 chip */ +#define BUS_MC 3 /* VME162/172 MC chip */ +#define BUS_PCCTWO 4 /* VME166/167/176/177 PCC2 chip */ #define BUS_VMES 5 /* 16 bit VME access */ #define BUS_VMEL 6 /* 32 bit VME access */ -#define BUS_IP 7 /* VME162 IP module bus */ +#define BUS_IP 7 /* VME162/172 IP module bus */ +#define BUS_LRC 8 /* VME165 LRC chip */ /* the following are from the prom/bootblocks */ extern paddr_t bootaddr; /* PA of boot device */ diff --git a/sys/arch/mvme68k/include/conf.h b/sys/arch/mvme68k/include/conf.h index 3d8beea3336..1c5ccb78f6b 100644 --- a/sys/arch/mvme68k/include/conf.h +++ b/sys/arch/mvme68k/include/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.3 2004/07/02 17:37:18 miod Exp $ */ +/* $OpenBSD: conf.h,v 1.4 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 2002, Miodrag Vallat. * All rights reserved. @@ -46,8 +46,8 @@ cdev_decl(nvram); #define sramwrite sramrw cdev_decl(sram); -cdev_decl(bugtty); cdev_decl(cl); +cdev_decl(dart); cdev_decl(wl); cdev_decl(zs); diff --git a/sys/arch/mvme68k/include/cpu.h b/sys/arch/mvme68k/include/cpu.h index 8521b55dc2c..8b21890ab44 100644 --- a/sys/arch/mvme68k/include/cpu.h +++ b/sys/arch/mvme68k/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.29 2009/02/21 20:33:23 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.30 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -162,6 +162,11 @@ extern int iiomapsize; #define INTIOTOP_162 (0xfffd0000) /* was 0xfff50000 */ #define INTIOSIZE_162 ((INTIOTOP_162-INTIOBASE_162)/NBPG) +/* physical memory sections for mvme165 */ +#define INTIOBASE_165 (0xfff90000) +#define INTIOTOP_165 (0xffff0000) +#define INTIOSIZE_165 ((INTIOTOP_165-INTIOBASE_165)/NBPG) + /* * Internal IO space (iiomapsize). * @@ -182,6 +187,7 @@ extern int cputyp; #define CPU_166 0x166 #define CPU_167 0x167 #define CPU_172 0x172 +#define CPU_176 0x176 #define CPU_177 0x177 #include <sys/evcount.h> diff --git a/sys/arch/mvme68k/include/intr.h b/sys/arch/mvme68k/include/intr.h index fc343405588..c6f711cb9aa 100644 --- a/sys/arch/mvme68k/include/intr.h +++ b/sys/arch/mvme68k/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.16 2007/12/02 22:31:26 miod Exp $ */ +/* $OpenBSD: intr.h,v 1.17 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (C) 2000 Steve Murphree, Jr. * All rights reserved. @@ -65,8 +65,8 @@ u_int8_t allocate_sir(void (*proc)(void *), void *arg); #define IPL_SOFTCLOCK 1 #define IPL_BIO 2 #define IPL_NET 3 -#define IPL_TTY 3 -#define IPL_VM 3 +#define IPL_TTY 5 +#define IPL_VM 5 #define IPL_CLOCK 5 #define IPL_STATCLOCK 5 #define IPL_HIGH 7 @@ -76,8 +76,8 @@ u_int8_t allocate_sir(void (*proc)(void *), void *arg); #define splsoftnet() splsoft() #define splbio() _splraise(PSL_S | PSL_IPL2) #define splnet() _splraise(PSL_S | PSL_IPL3) -#define spltty() _splraise(PSL_S | PSL_IPL3) -#define splvm() _splraise(PSL_S | PSL_IPL3) +#define spltty() _splraise(PSL_S | PSL_IPL5) +#define splvm() _splraise(PSL_S | PSL_IPL5) #define splclock() _splraise(PSL_S | PSL_IPL5) #define splstatclock() _splraise(PSL_S | PSL_IPL5) #define splhigh() _spl(PSL_S | PSL_IPL7) diff --git a/sys/arch/mvme68k/mvme68k/conf.c b/sys/arch/mvme68k/mvme68k/conf.c index 6f4b004b202..c00219985e6 100644 --- a/sys/arch/mvme68k/mvme68k/conf.c +++ b/sys/arch/mvme68k/mvme68k/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.44 2009/01/25 17:30:49 miod Exp $ */ +/* $OpenBSD: conf.c,v 1.45 2009/03/01 21:40:49 miod Exp $ */ /*- * Copyright (c) 1995 Theo de Raadt @@ -115,9 +115,10 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]); #include "pty.h" cdev_decl(fd); -#include "zs.h" #include "cl.h" +#include "dart.h" #include "wl.h" +#include "zs.h" /* open, close, write, ioctl */ #define cdev_lp_init(c,n) { \ @@ -168,7 +169,7 @@ struct cdevsw cdevsw[] = cdev_mdev_init(NFLASH,flash), /* 11: /dev/flashX */ cdev_tty_init(NZS,zs), /* 12: SCC serial (tty[a-d]) */ cdev_tty_init(NCL,cl), /* 13: CL-CD2400 serial (tty0[0-3]) */ - cdev_notdef(), /* 14 */ + cdev_tty_init(NDART,dart), /* 14: MC68681 serial (ttyd[0-1]) */ cdev_notdef(), /* 15 */ cdev_notdef(), /* 16 */ cdev_disk_init(NCCD,ccd), /* 17: concatenated disk */ @@ -300,17 +301,22 @@ int nchrtoblktbl = sizeof(chrtoblktbl) / sizeof(chrtoblktbl[0]); */ #include <dev/cons.h> -#define zscnpollc nullcnpollc -cons_decl(zs); -#define clcnpollc nullcnpollc +#define clcnpollc nullcnpollc cons_decl(cl); +#define dartcnpollc nullcnpollc +cons_decl(dart); +#define zscnpollc nullcnpollc +cons_decl(zs); struct consdev constab[] = { -#if NZS > 0 - cons_init(zs), -#endif #if NCL > 0 cons_init(cl), #endif +#if NDART > 0 + cons_init(dart), +#endif +#if NZS > 0 + cons_init(zs), +#endif { 0 }, }; diff --git a/sys/arch/mvme68k/mvme68k/genassym.cf b/sys/arch/mvme68k/mvme68k/genassym.cf index 9c5e3bdb44b..29fa2f7e5e4 100644 --- a/sys/arch/mvme68k/mvme68k/genassym.cf +++ b/sys/arch/mvme68k/mvme68k/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.21 2009/02/18 20:48:02 miod Exp $ +# $OpenBSD: genassym.cf,v 1.22 2009/03/01 21:40:49 miod Exp $ # # Copyright (c) 1995 Theo de Raadt @@ -113,16 +113,21 @@ member emem export INTIOBASE_147 export INTIOBASE_162 +export INTIOBASE_165 export INTIOSIZE_147 export INTIOSIZE_162 +export INTIOSIZE_165 export CPU_147 export CPU_162 +export CPU_165 export CPU_166 export CPU_167 export CPU_172 +export CPU_176 export CPU_177 +export BUS_LRC export BUS_MC export BUS_PCC export BUS_PCCTWO diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index 7714801bfdc..2e2f409614e 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.58 2009/02/18 20:48:02 miod Exp $ */ +/* $OpenBSD: locore.s,v 1.59 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -168,6 +168,11 @@ ASENTRY_NOPROFILE(start) beq is162 #endif +#ifdef MVME165 + cmpw #CPU_165, d0 + beq is165 +#endif + #ifdef MVME167 cmpw #CPU_166, d0 beq is167 @@ -176,10 +181,8 @@ ASENTRY_NOPROFILE(start) #endif #ifdef MVME177 -#ifdef notyet cmpw #CPU_176, d0 beq is177 -#endif cmpw #CPU_177, d0 beq is177 #endif @@ -271,6 +274,39 @@ is162: bra is16x #endif +#ifdef MVME165 +is165: + movl #0xfffe0000, a0 | MVME165 CSR + movl a0@, d0 + movl #4*1024*1024, d1 + btst #18, d0 | 4MEG* + jeq 1f | not set, this is a 4MB board. + movl #16*1024*1024, d1 | set, this is a 16MB board. + + RELOC(mmutype, a0) + movl #MMU_68040,a0@ | with a 68040 MMU + + RELOC(cputype, a0) | no, we have 68040 + movl #CPU_68040,a0@ | set to reflect 68040 CPU + + RELOC(fputype, a0) + movl #FPU_68040,a0@ | and a 68040 FPU + + RELOC(clockbus, a0) | timer is on lrc + movl #BUS_LRC, a0@ + + RELOC(vectab, a1) + movl #_C_LABEL(buserr40),a1@(8) + movl #_C_LABEL(addrerr4060),a1@(12) + + RELOC(iiomapsize, a1) + movl #INTIOSIZE_165, a1@ + RELOC(iiomapbase, a1) + movl #INTIOBASE_165, a1@ + + bra Lstart1 +#endif + #ifdef MVME167 is167: RELOC(memsize1x7, a1) | how much memory? @@ -1700,6 +1736,7 @@ Lbootnot040: cmpw #CPU_147,d0 bne not147 movl #0xfffe2000,a0 | MVME147: "struct vme1reg *" +vmechipreset: movw a0@,d0 movl d0,d1 andw #0x0001,d1 | is VME1_SCON_SWITCH set? @@ -1714,6 +1751,15 @@ Lbootnot040: bra 3f not147: + cmpw #CPU_165, d0 + bne not165 + movl #0xfff90020,a0 | disable timer2 (clock) + movl #0, a0@ + movl #0xfffb0000,a0 | MVME165 VMEChip base address + /* similar to MVME147 sequence above */ + bra vmechipreset + +not165: movl #0xfff40000,a0 | MVME16x: "struct vme2reg *" movl a0@(0x60),d0 movl d0,d1 diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index 58d694d2f60..88516facdab 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.111 2008/06/27 17:22:14 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.112 2009/03/01 21:40:49 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -102,6 +102,9 @@ #ifdef MVME147 #include <mvme68k/dev/pccreg.h> #endif +#ifdef MVME165 +#include <mvme68k/dev/lrcreg.h> +#endif #include <dev/cons.h> @@ -374,8 +377,10 @@ identifycpu() #endif #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177) case CPU_162: + case CPU_166: case CPU_167: case CPU_172: + case CPU_176: case CPU_177: bzero(speed, sizeof speed); speed[0] = brdid.speed[0]; @@ -396,6 +401,13 @@ identifycpu() } break; #endif +#ifdef MVME165 + case CPU_165: + snprintf(suffix, sizeof suffix, "MVME%x", brdid.model); + cpuspeed = lrcspeed((struct lrcreg *)IIOV(0xfff90000)); + snprintf(speed, sizeof speed, "%02d", cpuspeed); + break; +#endif } snprintf(cpu_model, sizeof cpu_model, "Motorola %s: %sMHz MC680%c0 CPU", suffix, speed, mc); @@ -875,12 +887,10 @@ void nmihand(frame) void *frame; { + printf("Abort switch pressed\n"); #ifdef DDB - printf("NMI ... going to debugger\n"); - Debugger(); -#else - /* panic?? */ - printf("unexpected level 7 interrupt ignored\n"); + if (db_console) + Debugger(); #endif } |