summaryrefslogtreecommitdiffstats
path: root/sys/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r--sys/arch/sparc/conf/GENERIC17
-rw-r--r--sys/arch/sparc/conf/files.sparc63
-rw-r--r--sys/arch/sparc/dev/amd7930.c5
-rw-r--r--sys/arch/sparc/dev/amd7930var.h1
-rw-r--r--sys/arch/sparc/dev/bt_subr.c1
-rw-r--r--sys/arch/sparc/dev/btreg.h1
-rw-r--r--sys/arch/sparc/dev/btvar.h1
-rw-r--r--sys/arch/sparc/dev/bwtwo.c45
-rw-r--r--sys/arch/sparc/dev/bwtworeg.h1
-rw-r--r--sys/arch/sparc/dev/cgeight.c30
-rw-r--r--sys/arch/sparc/dev/cgeightreg.h55
-rw-r--r--sys/arch/sparc/dev/cgfour.c30
-rw-r--r--sys/arch/sparc/dev/cgfourteen.c877
-rw-r--r--sys/arch/sparc/dev/cgfourteenreg.h123
-rw-r--r--sys/arch/sparc/dev/cgfourteenvar.h94
-rw-r--r--sys/arch/sparc/dev/cgsix.c44
-rw-r--r--sys/arch/sparc/dev/cgsixreg.h1
-rw-r--r--sys/arch/sparc/dev/cgthree.c47
-rw-r--r--sys/arch/sparc/dev/cgthreereg.h1
-rw-r--r--sys/arch/sparc/dev/cgtwo.c28
-rw-r--r--sys/arch/sparc/dev/cons.c29
-rw-r--r--sys/arch/sparc/dev/dma.c230
-rw-r--r--sys/arch/sparc/dev/dmareg.h14
-rw-r--r--sys/arch/sparc/dev/dmavar.h32
-rw-r--r--sys/arch/sparc/dev/esp.c1913
-rw-r--r--sys/arch/sparc/dev/espreg.h148
-rw-r--r--sys/arch/sparc/dev/espvar.h271
-rw-r--r--sys/arch/sparc/dev/event.c171
-rw-r--r--sys/arch/sparc/dev/event_var.h87
-rw-r--r--sys/arch/sparc/dev/fb.c38
-rw-r--r--sys/arch/sparc/dev/fd.c5
-rw-r--r--sys/arch/sparc/dev/i82586.h1
-rw-r--r--sys/arch/sparc/dev/if_en_sbus.c6
-rw-r--r--sys/arch/sparc/dev/if_ie.c48
-rw-r--r--sys/arch/sparc/dev/if_ie.h1
-rw-r--r--sys/arch/sparc/dev/if_le.c378
-rw-r--r--sys/arch/sparc/dev/if_lereg.h1
-rw-r--r--sys/arch/sparc/dev/if_levar.h6
-rw-r--r--sys/arch/sparc/dev/isp_sbus.c331
-rw-r--r--sys/arch/sparc/dev/kbd.c8
-rw-r--r--sys/arch/sparc/dev/lebuffer.c143
-rw-r--r--sys/arch/sparc/dev/lebuffervar.h (renamed from sys/arch/sparc/dev/cgfourreg.h)39
-rw-r--r--sys/arch/sparc/dev/ms.c12
-rw-r--r--sys/arch/sparc/dev/obio.c266
-rw-r--r--sys/arch/sparc/dev/pfour.c2
-rw-r--r--sys/arch/sparc/dev/pfourreg.h1
-rw-r--r--sys/arch/sparc/dev/power.c4
-rw-r--r--sys/arch/sparc/dev/rcons_font.h1
-rw-r--r--sys/arch/sparc/dev/sbus.c36
-rw-r--r--sys/arch/sparc/dev/sbusreg.h1
-rw-r--r--sys/arch/sparc/dev/sbusvar.h1
-rw-r--r--sys/arch/sparc/dev/si.c114
-rw-r--r--sys/arch/sparc/dev/sireg.h1
-rw-r--r--sys/arch/sparc/dev/tcx.c496
-rw-r--r--sys/arch/sparc/dev/tcxreg.h151
-rw-r--r--sys/arch/sparc/dev/vmereg.h75
-rw-r--r--sys/arch/sparc/dev/xd.c60
-rw-r--r--sys/arch/sparc/dev/xdreg.h1
-rw-r--r--sys/arch/sparc/dev/xdvar.h1
-rw-r--r--sys/arch/sparc/dev/xio.h1
-rw-r--r--sys/arch/sparc/dev/xy.c55
-rw-r--r--sys/arch/sparc/dev/xyreg.h1
-rw-r--r--sys/arch/sparc/dev/xyvar.h1
-rw-r--r--sys/arch/sparc/dev/zs.c98
-rw-r--r--sys/arch/sparc/dev/zsvar.h12
-rw-r--r--sys/arch/sparc/fpu/fpu.c5
-rw-r--r--sys/arch/sparc/fpu/fpu_add.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_arith.h1
-rw-r--r--sys/arch/sparc/fpu/fpu_compare.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_div.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_emu.h1
-rw-r--r--sys/arch/sparc/fpu/fpu_explode.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_extern.h1
-rw-r--r--sys/arch/sparc/fpu/fpu_implode.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_mul.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_sqrt.c1
-rw-r--r--sys/arch/sparc/fpu/fpu_subr.c1
-rw-r--r--sys/arch/sparc/include/ansi.h1
-rw-r--r--sys/arch/sparc/include/asm.h7
-rw-r--r--sys/arch/sparc/include/autoconf.h42
-rw-r--r--sys/arch/sparc/include/bsd_audioio.h1
-rw-r--r--sys/arch/sparc/include/bsd_openprom.h1
-rw-r--r--sys/arch/sparc/include/cdefs.h6
-rw-r--r--sys/arch/sparc/include/cgtworeg.h1
-rw-r--r--sys/arch/sparc/include/conf.h13
-rw-r--r--sys/arch/sparc/include/cpu.h15
-rw-r--r--sys/arch/sparc/include/ctlreg.h139
-rw-r--r--sys/arch/sparc/include/db_machdep.h13
-rw-r--r--sys/arch/sparc/include/eeprom.h29
-rw-r--r--sys/arch/sparc/include/endian.h12
-rw-r--r--sys/arch/sparc/include/exec.h1
-rw-r--r--sys/arch/sparc/include/fbio.h11
-rw-r--r--sys/arch/sparc/include/fbvar.h6
-rw-r--r--sys/arch/sparc/include/float.h5
-rw-r--r--sys/arch/sparc/include/frame.h1
-rw-r--r--sys/arch/sparc/include/fsr.h1
-rw-r--r--sys/arch/sparc/include/idprom.h8
-rw-r--r--sys/arch/sparc/include/ieee.h1
-rw-r--r--sys/arch/sparc/include/ieeefp.h2
-rw-r--r--sys/arch/sparc/include/instr.h4
-rw-r--r--sys/arch/sparc/include/kbd.h1
-rw-r--r--sys/arch/sparc/include/kbio.h1
-rw-r--r--sys/arch/sparc/include/limits.h6
-rw-r--r--sys/arch/sparc/include/oldmon.h1
-rw-r--r--sys/arch/sparc/include/openpromio.h1
-rw-r--r--sys/arch/sparc/include/param.h109
-rw-r--r--sys/arch/sparc/include/pcb.h1
-rw-r--r--sys/arch/sparc/include/pmap.h32
-rw-r--r--sys/arch/sparc/include/proc.h7
-rw-r--r--sys/arch/sparc/include/profile.h32
-rw-r--r--sys/arch/sparc/include/psl.h12
-rw-r--r--sys/arch/sparc/include/pte.h33
-rw-r--r--sys/arch/sparc/include/ptrace.h1
-rw-r--r--sys/arch/sparc/include/reg.h1
-rw-r--r--sys/arch/sparc/include/reloc.h1
-rw-r--r--sys/arch/sparc/include/remote-sl.h1
-rw-r--r--sys/arch/sparc/include/setjmp.h1
-rw-r--r--sys/arch/sparc/include/signal.h1
-rw-r--r--sys/arch/sparc/include/stdarg.h8
-rw-r--r--sys/arch/sparc/include/svr4_machdep.h1
-rw-r--r--sys/arch/sparc/include/trap.h1
-rw-r--r--sys/arch/sparc/include/types.h3
-rw-r--r--sys/arch/sparc/include/varargs.h1
-rw-r--r--sys/arch/sparc/include/vmparam.h7
-rw-r--r--sys/arch/sparc/include/vuid_event.h1
-rw-r--r--sys/arch/sparc/sparc/asm.h17
-rw-r--r--sys/arch/sparc/sparc/autoconf.c224
-rw-r--r--sys/arch/sparc/sparc/auxreg.c2
-rw-r--r--sys/arch/sparc/sparc/cache.c730
-rw-r--r--sys/arch/sparc/sparc/cache.h119
-rw-r--r--sys/arch/sparc/sparc/clock.c75
-rw-r--r--sys/arch/sparc/sparc/clockreg.h1
-rw-r--r--sys/arch/sparc/sparc/conf.c10
-rw-r--r--sys/arch/sparc/sparc/cpu.c1229
-rw-r--r--sys/arch/sparc/sparc/db_disasm.c1
-rw-r--r--sys/arch/sparc/sparc/db_interface.c3
-rw-r--r--sys/arch/sparc/sparc/db_trace.c7
-rw-r--r--sys/arch/sparc/sparc/genassym.cf23
-rw-r--r--sys/arch/sparc/sparc/in_cksum.c16
-rw-r--r--sys/arch/sparc/sparc/intersil7170.h90
-rw-r--r--sys/arch/sparc/sparc/intr.c20
-rw-r--r--sys/arch/sparc/sparc/intreg.h17
-rw-r--r--sys/arch/sparc/sparc/iommu.c34
-rw-r--r--sys/arch/sparc/sparc/iommureg.h1
-rw-r--r--sys/arch/sparc/sparc/kgdb_proto.h1
-rw-r--r--sys/arch/sparc/sparc/kgdb_stub.c3
-rw-r--r--sys/arch/sparc/sparc/locore.s376
-rw-r--r--sys/arch/sparc/sparc/locore2.c3
-rw-r--r--sys/arch/sparc/sparc/machdep.c50
-rw-r--r--sys/arch/sparc/sparc/mem.c1
-rw-r--r--sys/arch/sparc/sparc/memreg.c63
-rw-r--r--sys/arch/sparc/sparc/memreg.h1
-rw-r--r--sys/arch/sparc/sparc/openprom.c1
-rw-r--r--sys/arch/sparc/sparc/pmap.c2256
-rw-r--r--sys/arch/sparc/sparc/process_machdep.c1
-rw-r--r--sys/arch/sparc/sparc/rd_root.c1
-rw-r--r--sys/arch/sparc/sparc/sunos_machdep.c28
-rw-r--r--sys/arch/sparc/sparc/svr4_machdep.c50
-rw-r--r--sys/arch/sparc/sparc/sys_machdep.c1
-rw-r--r--sys/arch/sparc/sparc/timerreg.h23
-rw-r--r--sys/arch/sparc/sparc/trap.c145
-rw-r--r--sys/arch/sparc/sparc/vaddrs.h13
-rw-r--r--sys/arch/sparc/sparc/vm_machdep.c43
163 files changed, 7433 insertions, 5602 deletions
diff --git a/sys/arch/sparc/conf/GENERIC b/sys/arch/sparc/conf/GENERIC
index 6b92f12c767..66e4e9956a1 100644
--- a/sys/arch/sparc/conf/GENERIC
+++ b/sys/arch/sparc/conf/GENERIC
@@ -41,6 +41,7 @@ sbus0 at iommu0 # sun4m
audio0 at mainbus0 # sun4c
audio0 at obio0 # sun4m
+audio0 at sbus0 slot ? offset ? # sun4m
auxreg0 at mainbus0 # sun4c
auxreg0 at obio0 # sun4m
@@ -119,9 +120,11 @@ esp* at dma? flags 0xff0f # depending on model
ledma0 at sbus0 slot ? offset ? # sun4m on-board
le0 at ledma0 #
-# Additional SBus LANCE devices - glued on by lebuffer (not yet implemented)
-#lebuffer* at sbus0 slot ? offset ? # sun4m SBus
-#le* at lebuffer? #
+# Additional SBus LANCE devices - glued on by lebuffer
+lebuffer0 at sbus0 slot ? offset ? # sun4m SBus
+lebuffer* at sbus? slot ? offset ? # sun4m SBus
+le0 at lebuffer0 #
+le* at lebuffer? #
# sun4/300 and sun4c Ethernet - an AMD 7990 LANCE
le0 at sbus0 slot ? offset ? # sun4c on-board
@@ -209,9 +212,17 @@ cgsix0 at obio0 addr 0x0b000000 level 4 # sun4/100 P4
cgeight0 at obio0 addr 0xfb300000 level 4 # sun4/300 P4
cgeight0 at obio0 addr 0x0b300000 level 4 # sun4/100 P4
+# Sun "tcx" accelerated color framebuffer.
+tcx0 at sbus? slot ? offset ?
+tcx* at sbus? slot ? offset ?
+
+# Sun "cgfourteen" accelerated 24-bit framebuffer.
+cgfourteen0 at obio0 # sun4m
+
# SCSI bus layer. SCSI devices attach to the SCSI bus, which attaches
# to the underlying hardware controller.
scsibus* at esp?
+#scsibus* at isp?
scsibus* at si?
scsibus* at sw?
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index 15dd29e1559..2615ba65760 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,5 @@
-# $NetBSD: files.sparc,v 1.23 1996/05/21 19:06:26 pk Exp $
+# $OpenBSD: files.sparc,v 1.12 1997/08/08 08:24:35 downsj Exp $
+# $NetBSD: files.sparc,v 1.40 1997/07/07 21:53:43 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
# sparc-specific configuration info
@@ -13,15 +14,19 @@ attach mainbus at root
device obio { [addr = -1], [level = -1] }
attach obio at mainbus
+
+device iommu {}
+attach iommu at mainbus
+file arch/sparc/sparc/iommu.c iommu
+
+device vme {}
+attach vme at iommu
+
device vmel { [addr = -1], [level = -1], [vect = -1] }
-attach vmel at mainbus
+attach vmel at mainbus, vme
device vmes { [addr = -1], [level = -1], [vect = -1] }
-attach vmes at mainbus
-file arch/sparc/dev/obio.c obio | vmel | vmes
-
-device audio
-attach audio at mainbus, obio
-file arch/sparc/dev/amd7930.c audio
+attach vmes at mainbus, vme
+file arch/sparc/dev/obio.c obio | vmel | vmes | vme
device auxreg
attach auxreg at mainbus, obio
@@ -63,10 +68,6 @@ attach fd at fdc
file arch/sparc/dev/fd.c fdc | fd needs-flag
file arch/sparc/sparc/bsd_fdintr.s fdc
-device iommu {}
-attach iommu at mainbus
-file arch/sparc/sparc/iommu.c iommu
-
device sbus { slot = -1, offset = -1 }
attach sbus at mainbus, iommu
file arch/sparc/dev/sbus.c sbus
@@ -92,11 +93,19 @@ attach dma at sbus, obio
device ledma {}
attach ledma at sbus
file arch/sparc/dev/dma.c dma | ledma
+device lebuffer {}
+attach lebuffer at sbus
+file arch/sparc/dev/lebuffer.c lebuffer
-device esp: scsi
+device esp: scsi, ncr53c9x
attach esp at sbus, dma, obio
file arch/sparc/dev/esp.c esp
+device audio
+attach audio at mainbus, obio, sbus
+file arch/sparc/dev/amd7930.c audio
+file arch/sparc/sparc/amd7930intr.s audio
+
# Brooktree DAC attribute
define bt_dac
@@ -124,10 +133,18 @@ device cgeight: bt_dac
attach cgeight at obio
file arch/sparc/dev/cgeight.c cgeight needs-flag
+device tcx: bt_dac
+attach tcx at sbus
+file arch/sparc/dev/tcx.c tcx needs-flag
+
+device cgfourteen
+attach cgfourteen at obio
+file arch/sparc/dev/cgfourteen.c cgfourteen needs-flag
+
file arch/sparc/dev/bt_subr.c bt_dac
# device definition in sys/conf/files
-attach le at sbus, ledma, obio
+attach le at sbus, ledma, lebuffer, obio
file arch/sparc/dev/if_le.c le
device ie: ifnet, ether
@@ -154,10 +171,24 @@ device sw: scsi, ncr5380sbc
attach sw at obio
file arch/sparc/dev/si.c si | sw
+# Efficient Networks, Inc. ATM interface
+# device declaration in sys/conf/files
+#attach en at sbus with en_sbus
+#file arch/sparc/dev/if_en_sbus.c en_sbus
+
+# Qlogic ISP 10x0 (Sbus) family
+# device declaration in sys/conf/files
+#attach isp at sbus with isp_sbus
+#file arch/sparc/dev/isp_sbus.c isp_sbus
+
pseudo-device kbd
+#
+# Generic Sun stuff
+#
+include "../../../dev/sun/files.sun"
+
file arch/sparc/dev/cons.c
-file arch/sparc/dev/event.c
file arch/sparc/dev/fb.c
file arch/sparc/dev/ms.c
file arch/sparc/dev/kbd.c kbd
@@ -175,9 +206,9 @@ file arch/sparc/fpu/fpu_subr.c
# N.B.: optimizer breaks pmap.c and/or cache.c somehow -- have not
# identified the exact problem yet. NOOPT_C suffices for now.
file arch/sparc/sparc/autoconf.c
-file arch/sparc/sparc/amd7930intr.s audio
file arch/sparc/sparc/cache.c
file arch/sparc/sparc/conf.c
+file arch/sparc/sparc/emul.c
file arch/sparc/sparc/in_cksum.c
file arch/sparc/sparc/intr.c
file arch/sparc/sparc/kgdb_stub.c
diff --git a/sys/arch/sparc/dev/amd7930.c b/sys/arch/sparc/dev/amd7930.c
index bb250924af1..998e89f5d1f 100644
--- a/sys/arch/sparc/dev/amd7930.c
+++ b/sys/arch/sparc/dev/amd7930.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: amd7930.c,v 1.8 1997/07/13 21:48:42 angelos Exp $ */
+/* $OpenBSD: amd7930.c,v 1.9 1997/08/08 08:24:37 downsj Exp $ */
/* $NetBSD: amd7930.c,v 1.10 1996/03/31 22:38:29 pk Exp $ */
/*
@@ -304,8 +304,7 @@ amd7930attach(parent, self, args)
pri = ra->ra_intr[0].int_pri;
printf(" pri %d, softpri %d\n", pri, PIL_AUSOFT);
amd = (volatile struct amd7930 *)(ra->ra_vaddr ?
- ra->ra_vaddr : mapiodev(ra->ra_reg, 0, sizeof (*amd),
- ca->ca_bustype));
+ ra->ra_vaddr : mapiodev(ra->ra_reg, 0, sizeof (*amd)));
sc->sc_map.mr_mmr1 = AMD_MMR1_GX | AMD_MMR1_GER |
AMD_MMR1_GR | AMD_MMR1_STG;
diff --git a/sys/arch/sparc/dev/amd7930var.h b/sys/arch/sparc/dev/amd7930var.h
index 2d2e5f28257..8e6cf85e529 100644
--- a/sys/arch/sparc/dev/amd7930var.h
+++ b/sys/arch/sparc/dev/amd7930var.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: amd7930var.h,v 1.3 1997/08/08 08:24:38 downsj Exp $ */
/* $NetBSD: amd7930var.h,v 1.3 1996/02/01 22:32:25 mycroft Exp $ */
/*
diff --git a/sys/arch/sparc/dev/bt_subr.c b/sys/arch/sparc/dev/bt_subr.c
index 2a1df0ad71b..11105ffa29d 100644
--- a/sys/arch/sparc/dev/bt_subr.c
+++ b/sys/arch/sparc/dev/bt_subr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: bt_subr.c,v 1.3 1997/08/08 08:24:39 downsj Exp $ */
/* $NetBSD: bt_subr.c,v 1.5 1996/03/14 19:44:32 christos Exp $ */
/*
diff --git a/sys/arch/sparc/dev/btreg.h b/sys/arch/sparc/dev/btreg.h
index aa3f5fbc0db..e146117c25b 100644
--- a/sys/arch/sparc/dev/btreg.h
+++ b/sys/arch/sparc/dev/btreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: btreg.h,v 1.3 1997/08/08 08:24:40 downsj Exp $ */
/* $NetBSD: btreg.h,v 1.4 1996/02/27 22:09:21 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/btvar.h b/sys/arch/sparc/dev/btvar.h
index 68be1189422..e08df3b8b1c 100644
--- a/sys/arch/sparc/dev/btvar.h
+++ b/sys/arch/sparc/dev/btvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: btvar.h,v 1.2 1997/08/08 08:24:41 downsj Exp $ */
/* $NetBSD: btvar.h,v 1.2 1994/11/20 20:51:56 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/bwtwo.c b/sys/arch/sparc/dev/bwtwo.c
index f629c0cffa4..e8f1177fea5 100644
--- a/sys/arch/sparc/dev/bwtwo.c
+++ b/sys/arch/sparc/dev/bwtwo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: bwtwo.c,v 1.13 1996/08/13 08:05:18 downsj Exp $ */
-/* $NetBSD: bwtwo.c,v 1.26 1996/04/01 17:30:15 christos Exp $ */
+/* $OpenBSD: bwtwo.c,v 1.14 1997/08/08 08:24:43 downsj Exp $ */
+/* $NetBSD: bwtwo.c,v 1.33 1997/05/24 20:16:02 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -105,14 +105,13 @@ struct bwtwo_softc {
/* autoconfiguration driver */
static void bwtwoattach __P((struct device *, struct device *, void *));
static int bwtwomatch __P((struct device *, void *, void *));
-int bwtwoopen __P((dev_t, int, int, struct proc *));
-int bwtwoclose __P((dev_t, int, int, struct proc *));
-int bwtwoioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int bwtwommap __P((dev_t, int, int));
static void bwtwounblank __P((struct device *));
static void bwtwo_set_video __P((struct bwtwo_softc *, int));
static int bwtwo_get_video __P((struct bwtwo_softc *));
+/* cdevsw prototypes */
+cdev_decl(bwtwo);
+
struct cfattach bwtwo_ca = {
sizeof(struct bwtwo_softc), bwtwomatch, bwtwoattach
};
@@ -212,14 +211,13 @@ bwtwoattach(parent, self, args)
* Map the control register.
*/
if (fb->fb_flags & FB_PFOUR) {
- fb->fb_pfour =
- (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
sc->sc_reg = NULL;
} else {
- sc->sc_reg =
- (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- BWREG_REG, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_reg = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg, BWREG_REG,
+ sizeof(struct fbcontrol));
fb->fb_pfour = NULL;
}
@@ -291,13 +289,13 @@ bwtwoattach(parent, self, args)
#if defined(SUN4)
if (CPU_ISSUN4) {
struct eeprom *eep = (struct eeprom *)eeprom_va;
- int constype = (fb->fb_flags & FB_PFOUR) ? EED_CONS_P4 :
- EED_CONS_BW;
+ int constype = (fb->fb_flags & FB_PFOUR) ? EE_CONS_P4OPT :
+ EE_CONS_BW;
/*
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == constype)
+ if (eep == NULL || eep->eeConsole == constype)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
@@ -316,8 +314,7 @@ bwtwoattach(parent, self, args)
if ((fb->fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen (on sun4c), but what the heck */
fb->fb_pixels =
- mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset,
- ramsize, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset, ramsize);
}
/* Insure video is enabled */
@@ -326,7 +323,16 @@ bwtwoattach(parent, self, args)
if (isconsole) {
printf(" (console)\n");
#ifdef RASTERCONSOLE
- fbrcons_init(fb);
+#if defined(SUN4)
+ /*
+ * XXX rcons doesn't seem to work properly on the overlay
+ * XXX plane. This is a temporary kludge until someone
+ * XXX fixes it.
+ */
+ if ((fb->fb_flags & FB_PFOUR) == 0 ||
+ (sc->sc_ovtype == BWO_NONE))
+#endif
+ fbrcons_init(fb);
#endif
} else
printf("\n");
@@ -456,8 +462,7 @@ bwtwommap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, sc->sc_pixeloffset + off,
- sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, sc->sc_pixeloffset + off) | PMAP_NC);
}
static int
diff --git a/sys/arch/sparc/dev/bwtworeg.h b/sys/arch/sparc/dev/bwtworeg.h
index 236f4a44929..f773d3c237e 100644
--- a/sys/arch/sparc/dev/bwtworeg.h
+++ b/sys/arch/sparc/dev/bwtworeg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: bwtworeg.h,v 1.3 1997/08/08 08:24:43 downsj Exp $ */
/* $NetBSD: bwtworeg.h,v 1.3 1996/02/27 00:32:39 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgeight.c b/sys/arch/sparc/dev/cgeight.c
index b720a24744a..48a1675266e 100644
--- a/sys/arch/sparc/dev/cgeight.c
+++ b/sys/arch/sparc/dev/cgeight.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgeight.c,v 1.7 1996/08/13 08:05:20 downsj Exp $ */
-/* $NetBSD: cgeight.c,v 1.7 1996/04/01 17:29:57 christos Exp $ */
+/* $OpenBSD: cgeight.c,v 1.8 1997/08/08 08:24:44 downsj Exp $ */
+/* $NetBSD: cgeight.c,v 1.13 1997/05/24 20:16:04 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -91,14 +91,13 @@ struct cgeight_softc {
/* autoconfiguration driver */
static void cgeightattach(struct device *, struct device *, void *);
static int cgeightmatch(struct device *, void *, void *);
-int cgeightopen __P((dev_t, int, int, struct proc *));
-int cgeightclose __P((dev_t, int, int, struct proc *));
-int cgeightioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgeightmmap __P((dev_t, int, int));
#if defined(SUN4)
static void cgeightunblank __P((struct device *));
#endif
+/* cdevsw prototypes */
+cdev_decl(cgeight);
+
struct cfattach cgeight_ca = {
sizeof(struct cgeight_softc), cgeightmatch, cgeightattach
};
@@ -203,8 +202,8 @@ cgeightattach(parent, self, args)
}
/* Map the pfour register. */
- fb->fb_pfour = (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
@@ -225,7 +224,7 @@ cgeightattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4)
+ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
isconsole = (fbconstty != NULL);
}
@@ -248,13 +247,14 @@ cgeightattach(parent, self, args)
if (isconsole) {
/* XXX this is kind of a waste */
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize, ca->ca_bustype);
+ PFOUR_COLOR_OFF_OVERLAY, ramsize);
}
#endif
/* Map the Brooktree. */
- sc->sc_fbc = (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_fbc = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg,
+ PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -405,7 +405,7 @@ cgeightmmap(dev, off, prot)
panic("cgeightmap");
if ((u_int)off >= NOOVERLAY) {
- off =- NOOVERLAY;
+ off -= NOOVERLAY;
/*
* X11 maps a huge chunk of the frame buffer; far more than
@@ -426,7 +426,7 @@ cgeightmmap(dev, off, prot)
* in enable plane
*/
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
- } else if ((u_int)off < END_COLOR) {
+ } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
/*
* in colour plane
*/
@@ -458,7 +458,7 @@ cgeightmmap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, poff, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
}
#if defined(SUN4)
diff --git a/sys/arch/sparc/dev/cgeightreg.h b/sys/arch/sparc/dev/cgeightreg.h
deleted file mode 100644
index 1fac1d4227c..00000000000
--- a/sys/arch/sparc/dev/cgeightreg.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $NetBSD: cgeightreg.h,v 1.4 1994/11/20 20:52:03 deraadt Exp $ */
-
-/*
- * Copyright (c) 1995 Theo de Raadt
- * 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 Theo de Raadt.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * cgeight display registers. Much like bwtwo registers, except that
- * there is a Brooktree Video DAC in there (so we also use btreg.h).
- */
-
-/* offsets */
-#define CG8REG_CMAP 0x200000
-#define CG8REG_P4REG 0x300000
-#define CG8REG_OVERLAY 0x400000
-#define CG8REG_ENABLE 0x600000
-#define CG8REG_COLOUR 0x800000
-#define CG8REG_END 0xa00000
-
-/* same, but for gdb */
-struct cgeight_all {
- char ba_nothing[0x200000];
- struct bt_regs ba_btreg; /* Brooktree registers */
- char ba_xxx1[0x100000-sizeof(struct bt_regs)];
- char ba_pfourreg[0x100000];
- char ba_overlay[0x200000];
- char ba_enable[0x200000];
- char ba_color[0x200000];
-};
diff --git a/sys/arch/sparc/dev/cgfour.c b/sys/arch/sparc/dev/cgfour.c
index 279d1cb0fea..4284b1c5781 100644
--- a/sys/arch/sparc/dev/cgfour.c
+++ b/sys/arch/sparc/dev/cgfour.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgfour.c,v 1.7 1996/08/13 08:05:21 downsj Exp $ */
-/* $NetBSD: cgfour.c,v 1.7 1996/04/01 17:29:58 christos Exp $ */
+/* $OpenBSD: cgfour.c,v 1.8 1997/08/08 08:24:46 downsj Exp $ */
+/* $NetBSD: cgfour.c,v 1.13 1997/05/24 20:16:06 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -95,14 +95,13 @@ struct cgfour_softc {
/* autoconfiguration driver */
static void cgfourattach __P((struct device *, struct device *, void *));
static int cgfourmatch __P((struct device *, void *, void *));
-int cgfouropen __P((dev_t, int, int, struct proc *));
-int cgfourclose __P((dev_t, int, int, struct proc *));
-int cgfourioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgfourmmap __P((dev_t, int, int));
#if defined(SUN4)
static void cgfourunblank __P((struct device *));
#endif
+/* cdevsw prototypes */
+cdev_decl(cgfour);
+
struct cfattach cgfour_ca = {
sizeof(struct cgfour_softc), cgfourmatch, cgfourattach
};
@@ -207,8 +206,8 @@ cgfourattach(parent, self, args)
}
/* Map the pfour register. */
- fb->fb_pfour = (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
@@ -229,7 +228,7 @@ cgfourattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4)
+ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
isconsole = (fbconstty != NULL);
}
@@ -252,13 +251,14 @@ cgfourattach(parent, self, args)
if (isconsole) {
/* XXX this is kind of a waste */
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize, ca->ca_bustype);
+ PFOUR_COLOR_OFF_OVERLAY, ramsize);
}
#endif
/* Map the Brooktree. */
- sc->sc_fbc = (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_fbc = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg,
+ PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -403,7 +403,7 @@ cgfourmmap(dev, off, prot)
panic("cgfourmap");
if ((u_int)off >= NOOVERLAY) {
- off =- NOOVERLAY;
+ off -= NOOVERLAY;
/*
* X11 maps a huge chunk of the frame buffer; far more than
@@ -424,7 +424,7 @@ cgfourmmap(dev, off, prot)
* in enable plane
*/
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
- } else if ((u_int)off < END_COLOR) {
+ } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
/*
* in colour plane
*/
@@ -432,7 +432,7 @@ cgfourmmap(dev, off, prot)
} else
return (-1);
- return (REG2PHYS(&sc->sc_phys, poff, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
}
#if defined(SUN4)
diff --git a/sys/arch/sparc/dev/cgfourteen.c b/sys/arch/sparc/dev/cgfourteen.c
new file mode 100644
index 00000000000..2786bb6a9ff
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteen.c
@@ -0,0 +1,877 @@
+/* $OpenBSD: cgfourteen.c,v 1.1 1997/08/08 08:24:48 downsj Exp $ */
+/* $NetBSD: cgfourteen.c,v 1.7 1997/05/24 20:16:08 pk Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. All rights reserved.
+ * 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 Harvard University.
+ * 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.
+ * This product includes software developed by Harvard University 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.
+ *
+ * Based on:
+ * NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
+ * NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
+ */
+
+/*
+ * Driver for Campus-II on-board mbus-based video (cgfourteen).
+ * Provides minimum emulation of a Sun cgthree 8-bit framebuffer to
+ * allow X to run.
+ *
+ * Does not handle interrupts, even though they can occur.
+ *
+ * XXX should defer colormap updates to vertical retrace interrupts
+ */
+
+/*
+ * The following is for debugging only; it opens up a security hole
+ * enabled by allowing any user to map the control registers for the
+ * cg14 into their space.
+ */
+#undef CG14_MAP_REGS
+
+/*
+ * The following enables 24-bit operation: when opened, the framebuffer
+ * will switch to 24-bit mode (actually 32-bit mode), and provide a
+ * simple cg8 emulation.
+ *
+ * XXX Note that the code enabled by this define is currently untested/broken.
+ */
+#undef CG14_CG8
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+
+#include <vm/vm.h>
+
+#include <machine/fbio.h>
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+#include <machine/fbvar.h>
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <sparc/dev/cgfourteenreg.h>
+#include <sparc/dev/cgfourteenvar.h>
+
+/* autoconfiguration driver */
+static void cgfourteenattach(struct device *, struct device *, void *);
+static int cgfourteenmatch(struct device *, void *, void *);
+static void cgfourteenunblank(struct device *);
+
+/* cdevsw prototypes */
+cdev_decl(cgfourteen);
+
+struct cfattach cgfourteen_ca = {
+ sizeof(struct cgfourteen_softc), cgfourteenmatch, cgfourteenattach
+};
+
+struct cfdriver cgfourteen_cd = {
+ NULL, "cgfourteen", DV_DULL
+};
+
+/* frame buffer generic driver */
+static struct fbdriver cgfourteenfbdriver = {
+ cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
+ cgfourteenmmap
+};
+
+extern int fbnode;
+extern struct tty *fbconstty;
+
+static void cg14_set_video __P((struct cgfourteen_softc *, int));
+static int cg14_get_video __P((struct cgfourteen_softc *));
+static int cg14_get_cmap __P((struct fbcmap *, union cg14cmap *, int));
+static int cg14_put_cmap __P((struct fbcmap *, union cg14cmap *, int));
+static void cg14_load_hwcmap __P((struct cgfourteen_softc *, int, int));
+static void cg14_init __P((struct cgfourteen_softc *));
+static void cg14_reset __P((struct cgfourteen_softc *));
+static void cg14_loadomap __P((struct cgfourteen_softc *));/* cursor overlay */
+static void cg14_setcursor __P((struct cgfourteen_softc *));/* set position */
+static void cg14_loadcursor __P((struct cgfourteen_softc *));/* set shape */
+
+/*
+ * Match a cgfourteen.
+ */
+int
+cgfourteenmatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+
+ /*
+ * Mask out invalid flags from the user.
+ */
+ cf->cf_flags &= FB_USERMASK;
+
+ /* Check driver name */
+ if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
+ return (0);
+
+ /*
+ * The cgfourteen is a local-bus video adaptor, accessed directly
+ * via the processor, and not through device space or an external
+ * bus. Thus we look _only_ at the obio bus.
+ * Additionally, these things exist only on the Sun4m.
+ */
+ if (CPU_ISSUN4M && ca->ca_bustype == BUS_OBIO)
+ return(1);
+ return (0);
+}
+
+/*
+ * Attach a display. We need to notice if it is the console, too.
+ */
+void
+cgfourteenattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ register struct cgfourteen_softc *sc = (struct cgfourteen_softc *)self;
+ register struct confargs *ca = args;
+ register int node = 0, ramsize;
+ register u_int32_t *lut;
+ int i, isconsole;
+
+ sc->sc_fb.fb_driver = &cgfourteenfbdriver;
+ sc->sc_fb.fb_device = &sc->sc_dev;
+ sc->sc_fb.fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
+
+ /*
+ * We're emulating a cg3/8, so represent ourselves as one
+ */
+#ifdef CG14_CG8
+ sc->sc_fb.fb_type.fb_type = FBTYPE_MEMCOLOR;
+#else
+ sc->sc_fb.fb_type.fb_type = FBTYPE_SUN3COLOR;
+#endif
+
+ node = ca->ca_ra.ra_node;
+#ifdef CG14_CG8
+ sc->sc_fb.fb_type.fb_depth = 32;
+#else
+ sc->sc_fb.fb_type.fb_depth = 8;
+#endif
+ fb_setsize(&sc->sc_fb, sc->sc_fb.fb_type.fb_depth,
+ 1152, 900, node, ca->ca_bustype);
+
+ ramsize = roundup(sc->sc_fb.fb_type.fb_height * sc->sc_fb.fb_linebytes,
+ NBPG);
+
+ sc->sc_fb.fb_type.fb_cmsize = CG14_CLUT_SIZE;
+ sc->sc_fb.fb_type.fb_size = ramsize;
+
+ /*
+ * Now map in the 8 useful pages of registers
+ */
+ if (ca->ca_ra.ra_len < 0x10000) {
+#ifdef DIAGNOSTIC
+ printf("warning: can't find all cgfourteen registers...\n");
+#endif
+ ca->ca_ra.ra_len = 0x10000;
+ }
+ sc->sc_ctl = (struct cg14ctl *) mapiodev(ca->ca_ra.ra_reg, 0,
+ ca->ca_ra.ra_len);
+
+ sc->sc_hwc = (struct cg14curs *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CURS);
+ sc->sc_dac = (struct cg14dac *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_DAC);
+ sc->sc_xlut = (struct cg14xlut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_XLUT);
+ sc->sc_clut1 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT1);
+ sc->sc_clut2 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT2);
+ sc->sc_clut3 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT3);
+ sc->sc_clutincr = (u_int *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUTINCR);
+
+ /*
+ * Stash the physical address of the framebuffer for use by mmap
+ */
+ if (ca->ca_ra.ra_nreg < 2)
+ panic("cgfourteen with only one register set; can't find"
+ " framebuffer");
+ sc->sc_phys = ca->ca_ra.ra_reg[1];
+
+#if defined(DEBUG) && defined(CG14_MAP_REGS)
+ /* Store the physical address of the control registers */
+ sc->sc_regphys = ca->ca_ra.ra_reg[0];
+#endif
+
+ /*
+ * Let the user know that we're here
+ */
+#ifdef CG14_CG8
+ printf(": cgeight emulated at %dx%dx24bpp",
+ sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
+#else
+ printf(": cgthree emulated at %dx%dx8bpp",
+ sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
+#endif
+ /*
+ * Enable the video, but don't change the pixel depth.
+ */
+ cg14_set_video(sc, 1);
+
+ /*
+ * Grab the initial colormap
+ */
+ lut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++)
+ sc->sc_cmap.cm_chip[i] = lut[i];
+
+ /* See if we're the console */
+ isconsole = node == fbnode && fbconstty != NULL;
+
+ /*
+ * We don't use the raster console since the cg14 is fast enough
+ * already.
+ */
+#ifdef notdef
+ /*
+ * When the ROM has mapped in a cgfourteen display, the address
+ * maps only the video RAM, so in any case we have to map the
+ * registers ourselves. We only need the video RAM if we are
+ * going to print characters via rconsole.
+ */
+ if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
+ /* this probably cannot happen, but what the heck */
+ sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
+ ramsize);
+ }
+#endif /* notdef */
+
+
+ if (isconsole) {
+ printf(" (console)\n");
+#ifdef notdef
+#ifdef RASTERCONSOLE
+ fbrcons_init(&sc->sc_fb);
+#endif
+#endif /* notdef */
+ } else
+ printf("\n");
+
+ /* Attach to /dev/fb */
+ if (node == fbnode)
+ fb_attach(&sc->sc_fb, isconsole);
+}
+
+/*
+ * Keep track of the number of opens made. In the 24-bit driver, we need to
+ * switch to 24-bit mode on the first open, and switch back to 8-bit on
+ * the last close. This kind of nonsense is needed to give screenblank
+ * a fighting chance of working.
+ */
+static int cg14_opens = 0;
+
+int
+cgfourteenopen(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ int unit = minor(dev);
+ int s, oldopens;
+
+ if (unit >= cgfourteen_cd.cd_ndevs ||
+ cgfourteen_cd.cd_devs[unit] == NULL)
+ return (ENXIO);
+
+ s = splhigh();
+ oldopens = cg14_opens++;
+ splx(s);
+
+ /* Setup the cg14 as we want it, and save the original PROM state */
+ if (oldopens == 0) /* first open only, to make screenblank work */
+ cg14_init(sc);
+
+ return (0);
+}
+
+int
+cgfourteenclose(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ int s, opens;
+
+ s = splhigh();
+ opens = --cg14_opens;
+ if (cg14_opens < 0)
+ opens = cg14_opens = 0;
+ splx(s);
+
+ /*
+ * Restore video state to make the PROM happy, on last close.
+ */
+ if (opens == 0)
+ cg14_reset(sc);
+
+ return (0);
+}
+
+int
+cgfourteenioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ register caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ register struct fbgattr *fba;
+ union cg14cursor_cmap tcm;
+ int v, error;
+ u_int count;
+
+ switch (cmd) {
+
+ case FBIOGTYPE:
+ *(struct fbtype *)data = sc->sc_fb.fb_type;
+ break;
+
+ case FBIOGATTR:
+ fba = (struct fbgattr *)data;
+ fba->real_type = FBTYPE_MDICOLOR;
+ fba->owner = 0; /* XXX ??? */
+ fba->fbtype = sc->sc_fb.fb_type;
+ fba->sattr.flags = 0;
+ fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
+ fba->sattr.dev_specific[0] = -1;
+ fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
+ fba->emu_types[1] = -1;
+ break;
+
+ case FBIOGETCMAP:
+ return (cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
+ CG14_CLUT_SIZE));
+
+ case FBIOPUTCMAP:
+ /* copy to software map */
+#define p ((struct fbcmap *)data)
+#ifdef CG14_CG8
+ p->index &= 0xffffff;
+#endif
+ error = cg14_put_cmap(p, &sc->sc_cmap, CG14_CLUT_SIZE);
+ if (error)
+ return (error);
+ /* now blast them into the chip */
+ /* XXX should use retrace interrupt */
+ cg14_load_hwcmap(sc, p->index, p->count);
+#undef p
+ break;
+
+ case FBIOGVIDEO:
+ *(int *)data = cg14_get_video(sc);
+ break;
+
+ case FBIOSVIDEO:
+ cg14_set_video(sc, *(int *)data);
+ break;
+
+/* these are for both FBIOSCURSOR and FBIOGCURSOR */
+#define p ((struct fbcursor *)data)
+#define cc (&sc->sc_cursor)
+ case FBIOGCURSOR:
+ /* do not quite want everything here... */
+ p->set = FB_CUR_SETALL; /* close enough, anyway */
+ p->enable = cc->cc_enable;
+ p->pos = cc->cc_pos;
+ p->hot = cc->cc_hot;
+ p->size = cc->cc_size;
+
+ /* begin ugh ... can we lose some of this crap?? */
+ if (p->image != NULL) {
+ count = cc->cc_size.y * 32 / NBBY;
+ error = copyout((caddr_t)cc->cc_cplane,
+ (caddr_t)p->image, count);
+ if (error)
+ return (error);
+ error = copyout((caddr_t)cc->cc_eplane,
+ (caddr_t)p->mask, count);
+ if (error)
+ return (error);
+ }
+ if (p->cmap.red != NULL) {
+ error = cg14_get_cmap(&p->cmap,
+ (union cg14cmap *)&cc->cc_color, 2);
+ if (error)
+ return (error);
+ } else {
+ p->cmap.index = 0;
+ p->cmap.count = 2;
+ }
+ /* end ugh */
+ break;
+
+ case FBIOSCURSOR:
+ /*
+ * For setcmap and setshape, verify parameters, so that
+ * we do not get halfway through an update and then crap
+ * out with the software state screwed up.
+ */
+ v = p->set;
+ if (v & FB_CUR_SETCMAP) {
+ /*
+ * This use of a temporary copy of the cursor
+ * colormap is not terribly efficient, but these
+ * copies are small (8 bytes)...
+ */
+ tcm = cc->cc_color;
+ error = cg14_put_cmap(&p->cmap, (union cg14cmap *)&tcm,
+ 2);
+ if (error)
+ return (error);
+ }
+ if (v & FB_CUR_SETSHAPE) {
+ if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
+ return (EINVAL);
+ count = p->size.y * 32 / NBBY;
+ if (!useracc(p->image, count, B_READ) ||
+ !useracc(p->mask, count, B_READ))
+ return (EFAULT);
+ }
+
+ /* parameters are OK; do it */
+ if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
+ if (v & FB_CUR_SETCUR)
+ cc->cc_enable = p->enable;
+ if (v & FB_CUR_SETPOS)
+ cc->cc_pos = p->pos;
+ if (v & FB_CUR_SETHOT)
+ cc->cc_hot = p->hot;
+ cg14_setcursor(sc);
+ }
+ if (v & FB_CUR_SETCMAP) {
+ cc->cc_color = tcm;
+ cg14_loadomap(sc); /* XXX defer to vertical retrace */
+ }
+ if (v & FB_CUR_SETSHAPE) {
+ cc->cc_size = p->size;
+ count = p->size.y * 32 / NBBY;
+ bzero((caddr_t)cc->cc_eplane, sizeof cc->cc_eplane);
+ bzero((caddr_t)cc->cc_cplane, sizeof cc->cc_cplane);
+ bcopy(p->mask, (caddr_t)cc->cc_eplane, count);
+ bcopy(p->image, (caddr_t)cc->cc_cplane, count);
+ cg14_loadcursor(sc);
+ }
+ break;
+
+#undef cc
+#undef p
+ case FBIOGCURPOS:
+ *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
+ break;
+
+ case FBIOSCURPOS:
+ sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
+ cg14_setcursor(sc);
+ break;
+
+ case FBIOGCURMAX:
+ /* max cursor size is 32x32 */
+ ((struct fbcurpos *)data)->x = 32;
+ ((struct fbcurpos *)data)->y = 32;
+ break;
+
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+/*
+ * Undo the effect of an FBIOSVIDEO that turns the video off.
+ */
+static void
+cgfourteenunblank(dev)
+ struct device *dev;
+{
+
+ cg14_set_video((struct cgfourteen_softc *)dev, 1);
+}
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ *
+ * The cg14 frame buffer can be mapped in either 8-bit or 32-bit mode
+ * starting at the address stored in the PROM. In 8-bit mode, the X
+ * channel is not present, and can be ignored. In 32-bit mode, mapping
+ * at 0K delivers a 32-bpp buffer where the upper 8 bits select the X
+ * channel information. We hardwire the Xlut to all zeroes to insure
+ * that, regardless of this value, direct 24-bit color access will be
+ * used.
+ *
+ * Alternatively, mapping the frame buffer at an offset of 16M seems to
+ * tell the chip to ignore the X channel. XXX where does it get the X value
+ * to use?
+ */
+int
+cgfourteenmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+
+#define CG3START (128*1024 + 128*1024)
+#define CG8START (256*1024)
+#define NOOVERLAY (0x04000000)
+
+ if (off & PGOFSET)
+ panic("cgfourteenmmap");
+
+#if defined(DEBUG) && defined(CG14_MAP_REGS) /* XXX: security hole */
+ /*
+ * Map the control registers into user space. Should only be
+ * used for debugging!
+ */
+ if ((u_int)off >= 0x10000000 && (u_int)off < 0x10000000 + 16*4096) {
+ off -= 0x10000000;
+ return (REG2PHYS(&sc->sc_regphys, off, 0) | PMAP_NC);
+ }
+#endif
+
+ if ((u_int)off >= NOOVERLAY)
+ off -= NOOVERLAY;
+#ifdef CG14_CG8
+ else if ((u_int)off >= CG8START) {
+ off -= CG8START;
+ }
+#else
+ else if ((u_int)off >= CG3START)
+ off -= CG3START;
+#endif
+ else
+ off = 0;
+
+ if ((unsigned)off >= sc->sc_fb.fb_type.fb_size *
+ sc->sc_fb.fb_type.fb_depth/8) {
+#ifdef DEBUG
+ printf("\nmmap request out of bounds: request 0x%x, "
+ "bound 0x%x\n", (unsigned) off,
+ (unsigned)sc->sc_fb.fb_type.fb_size);
+#endif
+ return (-1);
+ }
+
+ /*
+ * Use PMAP_NC to disable the cache, since otherwise refresh is
+ * very confused.
+ */
+ return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
+}
+
+/*
+ * Miscellaneous helper functions
+ */
+
+/* Initialize the framebuffer, storing away useful state for later reset */
+static void
+cg14_init(sc)
+ struct cgfourteen_softc *sc;
+{
+ register u_int32_t *clut;
+ register u_int8_t *xlut;
+ register int i;
+
+ /*
+ * We stash away the following to restore on close:
+ *
+ * color look-up table 1 (sc->sc_saveclut)
+ * x look-up table (sc->sc_savexlut)
+ * control register (sc->sc_savectl)
+ * cursor control register (sc->sc_savehwc)
+ */
+ sc->sc_savectl = sc->sc_ctl->ctl_mctl;
+ sc->sc_savehwc = sc->sc_hwc->curs_ctl;
+
+ clut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ xlut = (u_int8_t *) sc->sc_xlut->xlut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++) {
+ sc->sc_saveclut.cm_chip[i] = clut[i];
+ sc->sc_savexlut[i] = xlut[i];
+ }
+
+#ifdef CG14_CG8
+ /*
+ * Enable the video, and put in 24 bit mode.
+ */
+ sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 |
+ CG14_MCTL_POWERCTL;
+
+ /*
+ * Zero the xlut to enable direct-color mode
+ */
+ bzero(sc->sc_xlut, CG14_CLUT_SIZE);
+#else
+ /*
+ * Enable the video and put it in 8 bit mode
+ */
+ sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_8 |
+ CG14_MCTL_POWERCTL;
+#endif
+}
+
+static void
+cg14_reset(sc) /* Restore the state saved on cg14_init */
+ struct cgfourteen_softc *sc;
+{
+ register u_int32_t *clut;
+ register u_int8_t *xlut;
+ register int i;
+
+ /*
+ * We restore the following, saved in cg14_init:
+ *
+ * color look-up table 1 (sc->sc_saveclut)
+ * x look-up table (sc->sc_savexlut)
+ * control register (sc->sc_savectl)
+ * cursor control register (sc->sc_savehwc)
+ *
+ * Note that we don't touch the video enable bits in the
+ * control register; otherwise, screenblank wouldn't work.
+ */
+ sc->sc_ctl->ctl_mctl = (sc->sc_ctl->ctl_mctl & (CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL)) |
+ (sc->sc_savectl & ~(CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL));
+ sc->sc_hwc->curs_ctl = sc->sc_savehwc;
+
+ clut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ xlut = (u_int8_t *) sc->sc_xlut->xlut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++) {
+ clut[i] = sc->sc_saveclut.cm_chip[i];
+ xlut[i] = sc->sc_savexlut[i];
+ }
+}
+
+/* Enable/disable video display; power down monitor if DPMS-capable */
+static void
+cg14_set_video(sc, enable)
+ struct cgfourteen_softc *sc;
+ int enable;
+{
+ /*
+ * We can only use DPMS to power down the display if the chip revision
+ * is greater than 0.
+ */
+ if (enable) {
+ if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
+ sc->sc_ctl->ctl_mctl |= (CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL);
+ else
+ sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEVID;
+ } else {
+ if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
+ sc->sc_ctl->ctl_mctl &= ~(CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL);
+ else
+ sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEVID;
+ }
+}
+
+/* Get status of video display */
+static int
+cg14_get_video(sc)
+ struct cgfourteen_softc *sc;
+{
+ return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0);
+}
+
+/* Read the software shadow colormap */
+static int
+cg14_get_cmap(p, cm, cmsize)
+ register struct fbcmap *p;
+ union cg14cmap *cm;
+ int cmsize;
+{
+ register u_int i, start, count;
+ register u_char *cp;
+
+ start = p->index;
+ count = p->count;
+ if (start >= cmsize || start + count > cmsize)
+#ifdef DEBUG
+ {
+ printf("putcmaperror: start %d cmsize %d count %d\n",
+ start,cmsize,count);
+#endif
+ return (EINVAL);
+#ifdef DEBUG
+ }
+#endif
+
+ if (!useracc(p->red, count, B_WRITE) ||
+ !useracc(p->green, count, B_WRITE) ||
+ !useracc(p->blue, count, B_WRITE))
+ return (EFAULT);
+ for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
+ p->red[i] = cp[3];
+ p->green[i] = cp[2];
+ p->blue[i] = cp[1];
+ }
+ return (0);
+}
+
+/* Write the software shadow colormap */
+static int
+cg14_put_cmap(p, cm, cmsize)
+ register struct fbcmap *p;
+ union cg14cmap *cm;
+ int cmsize;
+{
+ register u_int i, start, count;
+ register u_char *cp;
+
+ start = p->index;
+ count = p->count;
+ if (start >= cmsize || start + count > cmsize)
+#ifdef DEBUG
+ {
+ printf("putcmaperror: start %d cmsize %d count %d\n",
+ start,cmsize,count);
+#endif
+ return (EINVAL);
+#ifdef DEBUG
+ }
+#endif
+
+ if (!useracc(p->red, count, B_READ) ||
+ !useracc(p->green, count, B_READ) ||
+ !useracc(p->blue, count, B_READ))
+ return (EFAULT);
+ for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
+ cp[3] = p->red[i];
+ cp[2] = p->green[i];
+ cp[1] = p->blue[i];
+ cp[0] = 0; /* no alpha channel */
+ }
+ return (0);
+}
+
+static void
+cg14_load_hwcmap(sc, start, ncolors)
+ register struct cgfourteen_softc *sc;
+ register int start, ncolors;
+{
+ /* XXX switch to auto-increment, and on retrace intr */
+
+ /* Setup pointers to source and dest */
+ register u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
+ volatile register u_int32_t *lutp = &sc->sc_clut1->clut_lut[start];
+
+ /* Copy by words */
+ while (--ncolors >= 0)
+ *lutp++ = *colp++;
+}
+
+/*
+ * Load the cursor (overlay `foreground' and `background') colors.
+ */
+static void
+cg14_setcursor(sc)
+ register struct cgfourteen_softc *sc;
+{
+ /* we need to subtract the hot-spot value here */
+#define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
+
+ sc->sc_hwc->curs_ctl = (sc->sc_cursor.cc_enable ? CG14_CURS_ENABLE : 0);
+ sc->sc_hwc->curs_x = COORD(x);
+ sc->sc_hwc->curs_y = COORD(y);
+
+#undef COORD
+}
+
+static void
+cg14_loadcursor(sc)
+ register struct cgfourteen_softc *sc;
+{
+ register volatile struct cg14curs *hwc;
+ register u_int edgemask, m;
+ register int i;
+
+ /*
+ * Keep the top size.x bits. Here we *throw out* the top
+ * size.x bits from an all-one-bits word, introducing zeros in
+ * the top size.x bits, then invert all the bits to get what
+ * we really wanted as our mask. But this fails if size.x is
+ * 32---a sparc uses only the low 5 bits of the shift count---
+ * so we have to special case that.
+ */
+ edgemask = ~0;
+ if (sc->sc_cursor.cc_size.x < 32)
+ edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
+ hwc = sc->sc_hwc;
+ for (i = 0; i < 32; i++) {
+ m = sc->sc_cursor.cc_eplane[i] & edgemask;
+ hwc->curs_plane0[i] = m;
+ hwc->curs_plane1[i] = m & sc->sc_cursor.cc_cplane[i];
+ }
+}
+
+static void
+cg14_loadomap(sc)
+ register struct cgfourteen_softc *sc;
+{
+ /* set background color */
+ sc->sc_hwc->curs_color1 = sc->sc_cursor.cc_color.cm_chip[0];
+ /* set foreground color */
+ sc->sc_hwc->curs_color2 = sc->sc_cursor.cc_color.cm_chip[1];
+}
diff --git a/sys/arch/sparc/dev/cgfourteenreg.h b/sys/arch/sparc/dev/cgfourteenreg.h
new file mode 100644
index 00000000000..c0fdb1b5c0a
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteenreg.h
@@ -0,0 +1,123 @@
+/* $OpenBSD: cgfourteenreg.h,v 1.1 1997/08/08 08:24:49 downsj Exp $ */
+/* $NetBSD: cgfourteenreg.h,v 1.1 1996/09/30 22:41:02 abrown Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. 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 Harvard University 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.
+ */
+
+/*
+ * Register/dac/clut/cursor definitions for cgfourteen frame buffer
+ */
+
+/* Locations of control registers in cg14 register set */
+#define CG14_OFFSET_CURS 0x1000
+#define CG14_OFFSET_DAC 0x2000
+#define CG14_OFFSET_XLUT 0x3000
+#define CG14_OFFSET_CLUT1 0x4000
+#define CG14_OFFSET_CLUT2 0x5000
+#define CG14_OFFSET_CLUT3 0x6000
+#define CG14_OFFSET_CLUTINCR 0xf000
+
+/* Main control register set */
+struct cg14ctl {
+ volatile u_int8_t ctl_mctl; /* main control register */
+#define CG14_MCTL_ENABLEINTR 0x80 /* interrupts */
+#define CG14_MCTL_ENABLEVID 0x40 /* enable video */
+#define CG14_MCTL_PIXMODE_MASK 0x30
+#define CG14_MCTL_PIXMODE_8 0x00 /* data is 16 8-bit pixels */
+#define CG14_MCTL_PIXMODE_16 0x20 /* data is 8 16-bit pixels */
+#define CG14_MCTL_PIXMODE_32 0x30 /* data is 4 32-bit pixels */
+#define CG14_MCTL_PIXMODE_SHIFT 4
+#define CG14_MCTL_TMR 0x0c
+#define CG14_MCTL_ENABLETMR 0x02
+#define CG14_MCTL_rev0RESET 0x01
+#define CG14_MCTL_POWERCTL 0x01
+
+ volatile u_int8_t ctl_ppr; /* packed pixel register */
+ volatile u_int8_t ctl_tmsr0; /* test status reg. 0 */
+ volatile u_int8_t ctl_tmsr1; /* test status reg. 1 */
+ volatile u_int8_t ctl_msr; /* master status register */
+ volatile u_int8_t ctl_fsr; /* fault status register */
+ volatile u_int8_t ctl_rsr; /* revision status register */
+#define CG14_RSR_REVMASK 0xf0 /* mask to get revision */
+#define CG14_RSR_IMPLMASK 0x0f /* mask to get impl. code */
+ volatile u_int8_t ctl_ccr; /* clock control register */
+ /* XXX etc. */
+};
+
+/* Hardware cursor map */
+#define CG14_CURS_SIZE 32
+struct cg14curs {
+ volatile u_int32_t curs_plane0[CG14_CURS_SIZE]; /* plane 0 */
+ volatile u_int32_t curs_plane1[CG14_CURS_SIZE];
+ volatile u_int8_t curs_ctl; /* control register */
+#define CG14_CURS_ENABLE 0x4
+#define CG14_CURS_DOUBLEBUFFER 0x2 /* use X-channel for curs */
+ volatile u_int8_t pad0[3];
+ volatile u_int16_t curs_x; /* x position */
+ volatile u_int16_t curs_y; /* y position */
+ volatile u_int32_t curs_color1; /* color register 1 */
+ volatile u_int32_t curs_color2; /* color register 2 */
+ volatile u_int32_t pad[444]; /* pad to 2KB boundary */
+ volatile u_int32_t curs_plane0incr[CG14_CURS_SIZE]; /* autoincr */
+ volatile u_int32_t curs_plane1incr[CG14_CURS_SIZE]; /* autoincr */
+};
+
+/* DAC */
+struct cg14dac {
+ volatile u_int8_t dac_addr; /* address register */
+ volatile u_int8_t pad0[255];
+ volatile u_int8_t dac_gammalut; /* gamma LUT */
+ volatile u_int8_t pad1[255];
+ volatile u_int8_t dac_regsel; /* register select */
+ volatile u_int8_t pad2[255];
+ volatile u_int8_t dac_mode; /* mode register */
+};
+
+#define CG14_CLUT_SIZE 256
+
+/* XLUT registers */
+struct cg14xlut {
+ volatile u_int8_t xlut_lut[CG14_CLUT_SIZE]; /* the LUT */
+ volatile u_int8_t xlut_lutd[CG14_CLUT_SIZE]; /* ??? */
+ volatile u_int8_t pad0[0x600];
+ volatile u_int8_t xlut_lutinc[CG14_CLUT_SIZE]; /* autoincrLUT*/
+ volatile u_int8_t xlut_lutincd[CG14_CLUT_SIZE];
+};
+
+/* Color Look-Up Table (CLUT) */
+struct cg14clut {
+ volatile u_int32_t clut_lut[CG14_CLUT_SIZE]; /* the LUT */
+ volatile u_int32_t clut_lutd[CG14_CLUT_SIZE]; /* ??? */
+ volatile u_int32_t clut_lutinc[CG14_CLUT_SIZE]; /* autoincr */
+ volatile u_int32_t clut_lutincd[CG14_CLUT_SIZE];
+};
diff --git a/sys/arch/sparc/dev/cgfourteenvar.h b/sys/arch/sparc/dev/cgfourteenvar.h
new file mode 100644
index 00000000000..654945e01bb
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteenvar.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: cgfourteenvar.h,v 1.1 1997/08/08 08:24:50 downsj Exp $ */
+/* $NetBSD: cgfourteenvar.h,v 1.1 1996/09/30 22:41:03 abrown Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. 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 Harvard University 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.
+ */
+
+/*
+ * Layout of cg14 hardware colormap
+ */
+union cg14cmap {
+ u_char cm_map[256][4]; /* 256 R/G/B/A entries (B is high)*/
+ u_int32_t cm_chip[256]; /* the way the chip gets loaded */
+};
+
+/*
+ * cg14 hardware cursor colormap
+ */
+union cg14cursor_cmap { /* colormap, like bt_cmap, but tiny */
+ u_char cm_map[2][4]; /* 2 R/G/B/A entries */
+ u_int32_t cm_chip[2]; /* 2 chip equivalents */
+};
+
+/*
+ * cg14 hardware cursor status
+ */
+struct cg14_cursor { /* cg14 hardware cursor status */
+ short cc_enable; /* cursor is enabled */
+ struct fbcurpos cc_pos; /* position */
+ struct fbcurpos cc_hot; /* hot-spot */
+ struct fbcurpos cc_size; /* size of mask & image fields */
+ u_int cc_eplane[32]; /* enable plane */
+ u_int cc_cplane[32]; /* color plane */
+ union cg14cursor_cmap cc_color; /* cursor colormap */
+};
+
+/*
+ * per-cg14 variables/state
+ */
+struct cgfourteen_softc {
+ struct device sc_dev; /* base device */
+ struct fbdevice sc_fb; /* frame buffer device */
+
+ struct rom_reg sc_phys; /* phys address of frame buffer */
+#if defined(DEBUG) && defined(CG14_MAP_REGS)
+ struct rom_reg sc_regphys; /* phys addr of fb regs; for debug */
+#endif
+ union cg14cmap sc_cmap; /* current colormap */
+
+ struct cg14_cursor sc_cursor; /* Hardware cursor state */
+
+ union cg14cmap sc_saveclut; /* a place to stash PROM state */
+ u_int8_t sc_savexlut[256];
+ u_int8_t sc_savectl;
+ u_int8_t sc_savehwc;
+
+ struct cg14ctl *sc_ctl; /* various registers */
+ struct cg14curs *sc_hwc;
+ struct cg14dac *sc_dac;
+ struct cg14xlut *sc_xlut;
+ struct cg14clut *sc_clut1;
+ struct cg14clut *sc_clut2;
+ struct cg14clut *sc_clut3;
+ u_int *sc_clutincr;
+};
diff --git a/sys/arch/sparc/dev/cgsix.c b/sys/arch/sparc/dev/cgsix.c
index dd967ebf558..f7cf868f8bb 100644
--- a/sys/arch/sparc/dev/cgsix.c
+++ b/sys/arch/sparc/dev/cgsix.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgsix.c,v 1.7 1996/08/13 08:05:22 downsj Exp $ */
-/* $NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp $ */
+/* $OpenBSD: cgsix.c,v 1.8 1997/08/08 08:24:51 downsj Exp $ */
+/* $NetBSD: cgsix.c,v 1.32 1997/07/29 09:58:04 fair Exp $ */
/*
* Copyright (c) 1993
@@ -122,12 +122,11 @@ struct cgsix_softc {
/* autoconfiguration driver */
static void cgsixattach __P((struct device *, struct device *, void *));
static int cgsixmatch __P((struct device *, void *, void *));
-int cgsixopen __P((dev_t, int, int, struct proc *));
-int cgsixclose __P((dev_t, int, int, struct proc *));
-int cgsixioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgsixmmap __P((dev_t, int, int));
static void cg6_unblank __P((struct device *));
+/* cdevsw prototypes */
+cdev_decl(cgsix);
+
struct cfattach cgsix_ca = {
sizeof(struct cgsix_softc), cgsixmatch, cgsixattach
};
@@ -186,7 +185,8 @@ cgsixmatch(parent, vcf, aux)
* differently on the cgsix than other pfour framebuffers.
*/
bus_untmp();
- tmp = bus_tmp(ra->ra_paddr + CGSIX_FHC_OFFSET, ca->ca_bustype);
+ tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CGSIX_FHC_OFFSET,
+ NBPG);
if (probeget(tmp, 4) == -1)
return (0);
@@ -231,17 +231,13 @@ cgsixattach(parent, self, args)
sc->sc_physadr = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
sc->sc_bt = bt = (volatile struct bt_regs *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_bt_un.un_btregs),
- sizeof *sc->sc_bt, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_bt_un.un_btregs),sizeof *sc->sc_bt);
sc->sc_fhc = (volatile int *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_fhc_un.un_fhc),
- sizeof *sc->sc_fhc, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_fhc_un.un_fhc), sizeof *sc->sc_fhc);
sc->sc_thc = (volatile struct cg6_thc *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_thc_un.un_thc),
- sizeof *sc->sc_thc, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_thc_un.un_thc), sizeof *sc->sc_thc);
sc->sc_tec = (volatile struct cg6_tec_xxx *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_tec_un.un_tec),
- sizeof *sc->sc_tec, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_tec_un.un_tec), sizeof *sc->sc_tec);
switch (ca->ca_bustype) {
case BUS_OBIO:
@@ -292,13 +288,13 @@ cgsixattach(parent, self, args)
#if defined(SUN4)
if (CPU_ISSUN4) {
struct eeprom *eep = (struct eeprom *)eeprom_va;
- int constype = (fb->fb_flags & FB_PFOUR) ? EED_CONS_P4 :
- EED_CONS_COLOR;
+ int constype = (fb->fb_flags & FB_PFOUR) ? EE_CONS_P4OPT :
+ EE_CONS_COLOR;
/*
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == constype)
+ if (eep == NULL || eep->eeConsole == constype)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
@@ -329,8 +325,7 @@ cgsixattach(parent, self, args)
printf(" (console)\n");
#ifdef RASTERCONSOLE
sc->sc_fb.fb_pixels = (caddr_t)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_ram[0]),
- ramsize, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_ram[0]), ramsize);
fbrcons_init(&sc->sc_fb);
#endif
} else
@@ -535,7 +530,7 @@ cgsixioctl(dev, cmd, data, flags, p)
default:
#ifdef DEBUG
- log(LOG_NOTICE, "cgsixioctl(%lx) (%s[%d])\n", cmd,
+ log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
p->p_comm, p->p_pid);
#endif
return (ENOTTY);
@@ -752,13 +747,14 @@ cgsixmmap(dev, off, prot)
u = off - mo->mo_uaddr;
sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
if (u < sz)
- return (REG2PHYS(&sc->sc_physadr, u + mo->mo_physoff,
- sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_physadr, u + mo->mo_physoff) |
+ PMAP_NC);
}
#ifdef DEBUG
{
register struct proc *p = curproc; /* XXX */
- log(LOG_NOTICE, "cgsixmmap(%x) (%s[%d])\n", off, p->p_comm, p->p_pid);
+ log(LOG_NOTICE, "cgsixmmap(0x%x) (%s[%d])\n",
+ off, p->p_comm, p->p_pid);
}
#endif
return (-1); /* not a user-map offset */
diff --git a/sys/arch/sparc/dev/cgsixreg.h b/sys/arch/sparc/dev/cgsixreg.h
index d9b90977c85..a8a63d0a082 100644
--- a/sys/arch/sparc/dev/cgsixreg.h
+++ b/sys/arch/sparc/dev/cgsixreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: cgsixreg.h,v 1.3 1997/08/08 08:24:52 downsj Exp $ */
/* $NetBSD: cgsixreg.h,v 1.4 1996/02/27 22:09:31 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgthree.c b/sys/arch/sparc/dev/cgthree.c
index 1599048c61d..b978af5fde4 100644
--- a/sys/arch/sparc/dev/cgthree.c
+++ b/sys/arch/sparc/dev/cgthree.c
@@ -1,4 +1,5 @@
-/* $NetBSD: cgthree.c,v 1.27 1996/04/01 17:30:03 christos Exp $ */
+/* $OpenBSD: cgthree.c,v 1.6 1997/08/08 08:24:53 downsj Exp $ */
+/* $NetBSD: cgthree.c,v 1.33 1997/05/24 20:16:11 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -90,12 +91,11 @@ struct cgthree_softc {
/* autoconfiguration driver */
static void cgthreeattach(struct device *, struct device *, void *);
static int cgthreematch(struct device *, void *, void *);
-int cgthreeopen __P((dev_t, int, int, struct proc *));
-int cgthreeclose __P((dev_t, int, int, struct proc *));
-int cgthreeioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgthreemmap __P((dev_t, int, int));
static void cgthreeunblank(struct device *);
+/* cdevsw prototypes */
+cdev_decl(cgthree);
+
struct cfattach cgthree_ca = {
sizeof(struct cgthree_softc), cgthreematch, cgthreeattach
};
@@ -116,6 +116,20 @@ static void cgthreeloadcmap __P((struct cgthree_softc *, int, int));
static void cgthree_set_video __P((struct cgthree_softc *, int));
static int cgthree_get_video __P((struct cgthree_softc *));
+/* Video control parameters */
+struct cg3_videoctrl {
+ unsigned char sense; /* Monitor sense value */
+ unsigned char vctrl[12];
+} cg3_videoctrl[] = {
+/* Missing entries: sense 0x10, 0x30, 0x50 */
+ { 0x40, /* this happens to be my 19'' 1152x900 gray-scale monitor */
+ {0xbb, 0x2b, 0x3, 0xb, 0xb3, 0x3, 0xaf, 0x2b, 0x2, 0xa, 0xff, 0x1}
+ },
+ { 0x00, /* default? must be last */
+ {0xbb, 0x2b, 0x3, 0xb, 0xb3, 0x3, 0xaf, 0x2b, 0x2, 0xa, 0xff, 0x1}
+ }
+};
+
/*
* Match a cgthree.
*/
@@ -206,11 +220,28 @@ cgthreeattach(parent, self, args)
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen, but what the heck */
sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
- ramsize, ca->ca_bustype);
+ ramsize);
}
sc->sc_fbc = (volatile struct fbcontrol *)
mapiodev(ca->ca_ra.ra_reg, CG3REG_REG,
- sizeof(struct fbcontrol), ca->ca_bustype);
+ sizeof(struct fbcontrol));
+
+ /* Transfer video magic to board, if it's not running */
+ if ((sc->sc_fbc->fbc_ctrl & FBC_TIMING) == 0)
+ for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]);
+ i++) {
+ volatile struct fbcontrol *fbc = sc->sc_fbc;
+ if ((fbc->fbc_status & FBS_MSENSE) ==
+ cg3_videoctrl[i].sense) {
+ int j;
+ printf(" setting video ctrl");
+ for (j = 0; j < 12; j++)
+ fbc->fbc_vcontrol[j] =
+ cg3_videoctrl[i].vctrl[j];
+ fbc->fbc_ctrl |= FBC_TIMING;
+ break;
+ }
+ }
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -408,5 +439,5 @@ cgthreemmap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, CG3REG_MEM+off, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, CG3REG_MEM+off) | PMAP_NC);
}
diff --git a/sys/arch/sparc/dev/cgthreereg.h b/sys/arch/sparc/dev/cgthreereg.h
index 073cc52e66c..89811921252 100644
--- a/sys/arch/sparc/dev/cgthreereg.h
+++ b/sys/arch/sparc/dev/cgthreereg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: cgthreereg.h,v 1.3 1997/08/08 08:24:54 downsj Exp $ */
/* $NetBSD: cgthreereg.h,v 1.5 1996/02/27 00:14:17 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgtwo.c b/sys/arch/sparc/dev/cgtwo.c
index 8c5dcc8f11a..e682f6b8a26 100644
--- a/sys/arch/sparc/dev/cgtwo.c
+++ b/sys/arch/sparc/dev/cgtwo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgtwo.c,v 1.10 1996/08/13 08:05:23 downsj Exp $ */
-/* $NetBSD: cgtwo.c,v 1.16 1996/05/18 12:19:14 mrg Exp $ */
+/* $OpenBSD: cgtwo.c,v 1.11 1997/08/08 08:24:55 downsj Exp $ */
+/* $NetBSD: cgtwo.c,v 1.22 1997/05/24 20:16:12 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -92,14 +92,13 @@ struct cgtwo_softc {
/* autoconfiguration driver */
static void cgtwoattach __P((struct device *, struct device *, void *));
static int cgtwomatch __P((struct device *, void *, void *));
-int cgtwoopen __P((dev_t, int, int, struct proc *));
-int cgtwoclose __P((dev_t, int, int, struct proc *));
-int cgtwoioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgtwommap __P((dev_t, int, int));
static void cgtwounblank __P((struct device *));
int cgtwogetcmap __P((struct cgtwo_softc *, struct fbcmap *));
int cgtwoputcmap __P((struct cgtwo_softc *, struct fbcmap *));
+/* cdevsw prototypes */
+cdev_decl(cgtwo);
+
struct cfattach cgtwo_ca = {
sizeof(struct cgtwo_softc), cgtwomatch, cgtwoattach
};
@@ -148,7 +147,7 @@ cgtwomatch(parent, vcf, aux)
/* XXX - Must do our own mapping at CG2_CTLREG_OFF */
bus_untmp();
- tmp = (caddr_t)bus_tmp(ra->ra_paddr + CG2_CTLREG_OFF, ca->ca_bustype);
+ tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CG2_CTLREG_OFF, NBPG);
if (probeget(tmp, 2) != -1)
return 1;
#endif
@@ -207,20 +206,21 @@ cgtwoattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_COLOR)
+ if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
}
#endif
sc->sc_phys = ca->ca_ra.ra_reg[0];
+ /* Apparently, the pixels are 32-bit data space */
+ sc->sc_phys.rr_iospace = PMAP_VME32;
sc->sc_bustype = ca->ca_bustype;
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen, but what the heck */
- sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG2_PIXMAP_OFF,
- CG2_PIXMAP_SIZE,
- PMAP_VME32/*ca->ca_bustype*/);
+ sc->sc_fb.fb_pixels = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
+ CG2_PIXMAP_SIZE);
}
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
@@ -229,12 +229,12 @@ cgtwoattach(parent, self, args)
sc->sc_reg = (volatile struct cg2statusreg *)
mapiodev(ca->ca_ra.ra_reg,
CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
- sizeof(struct cg2statusreg), ca->ca_bustype);
+ sizeof(struct cg2statusreg));
sc->sc_cmap = (volatile u_short *)
mapiodev(ca->ca_ra.ra_reg,
CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap[0]),
- 3 * CG2_CMSIZE, ca->ca_bustype);
+ 3 * CG2_CMSIZE);
if (isconsole) {
printf(" (console)\n");
@@ -432,5 +432,5 @@ cgtwommap(dev, off, prot)
if ((unsigned)off >= sc->sc_fb.fb_type.fb_size)
return (-1);
- return (REG2PHYS(&sc->sc_phys, off, PMAP_VME32/*sc->sc_bustype*/) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
}
diff --git a/sys/arch/sparc/dev/cons.c b/sys/arch/sparc/dev/cons.c
index 11a1606bae8..fba5c2e4eb1 100644
--- a/sys/arch/sparc/dev/cons.c
+++ b/sys/arch/sparc/dev/cons.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cons.c,v 1.5 1996/08/13 08:05:24 downsj Exp $ */
-/* $NetBSD: cons.c,v 1.23.4.1 1996/06/02 09:07:53 mrg Exp $ */
+/* $OpenBSD: cons.c,v 1.6 1997/08/08 08:24:56 downsj Exp $ */
+/* $NetBSD: cons.c,v 1.30 1997/07/07 23:30:23 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -70,6 +70,11 @@
#include <machine/autoconf.h>
#include <machine/conf.h>
+#ifdef RASTERCONSOLE
+#include <machine/fbio.h>
+#include <machine/fbvar.h>
+#endif
+
#include "zs.h"
struct tty *constty = 0; /* virtual console output device */
@@ -286,20 +291,30 @@ cnopen(dev, flag, mode, p)
/* output queue doesn't need quoting */
clalloc(&tp->t_outq, 1024, 0);
tty_attach(tp);
+
/*
* get the console struct winsize.
*/
+#ifdef RASTERCONSOLE
+ if (fbconstty) {
+ rows = fbrcons_rows();
+ cols = fbrcons_cols();
+ }
+#endif
+
if (CPU_ISSUN4COR4M) {
int i;
char *prop;
- if ((prop = getpropstring(optionsnode, "screen-#rows"))) {
+ if (rows == 0 &&
+ (prop = getpropstring(optionsnode, "screen-#rows"))) {
i = 0;
while (*prop != '\0')
i = i * 10 + *prop++ - '0';
rows = (unsigned short)i;
}
- if ((prop = getpropstring(optionsnode, "screen-#columns"))) {
+ if (cols == 0 &&
+ (prop = getpropstring(optionsnode, "screen-#columns"))) {
i = 0;
while (*prop != '\0')
i = i * 10 + *prop++ - '0';
@@ -310,8 +325,10 @@ cnopen(dev, flag, mode, p)
struct eeprom *ep = (struct eeprom *)eeprom_va;
if (ep) {
- rows = (u_short)ep->ee_diag.eed_rowsize;
- cols = (u_short)ep->ee_diag.eed_colsize;
+ if (rows == 0)
+ rows = (u_short)ep->eeTtyRows;
+ if (cols == 0)
+ cols = (u_short)ep->eeTtyCols;
}
}
firstopen = 0;
diff --git a/sys/arch/sparc/dev/dma.c b/sys/arch/sparc/dev/dma.c
index 4c961cac690..c01200a20c1 100644
--- a/sys/arch/sparc/dev/dma.c
+++ b/sys/arch/sparc/dev/dma.c
@@ -1,4 +1,5 @@
-/* $NetBSD: dma.c,v 1.28.2.2 1996/07/02 23:46:29 jtc Exp $ */
+/* $OpenBSD: dma.c,v 1.8 1997/08/08 08:24:57 downsj Exp $ */
+/* $NetBSD: dma.c,v 1.45 1997/07/29 09:58:06 fair Exp $ */
/*
* Copyright (c) 1994 Paul Kranenburg. All rights reserved.
@@ -45,19 +46,25 @@
#include <sparc/autoconf.h>
#include <sparc/cpu.h>
+#include <sparc/sparc/cpuvar.h>
+
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
#include <sparc/dev/espvar.h>
int dmaprint __P((void *, const char *));
void dmaattach __P((struct device *, struct device *, void *));
int dmamatch __P((struct device *, void *, void *));
-void dma_reset __P((struct dma_softc *));
+void dma_reset __P((struct dma_softc *, int));
+void espdma_reset __P((struct dma_softc *));
+void ledma_reset __P((struct dma_softc *));
void dma_enintr __P((struct dma_softc *));
int dma_isintr __P((struct dma_softc *));
int espdmaintr __P((struct dma_softc *));
@@ -100,7 +107,7 @@ dmamatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -131,8 +138,7 @@ dmaattach(parent, self, aux)
if (ca->ca_ra.ra_vaddr == NULL || ca->ca_ra.ra_nvaddrs == 0)
ca->ca_ra.ra_vaddr =
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len,
- ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
sc->sc_regs = (struct dma_regs *) ca->ca_ra.ra_vaddr;
@@ -156,35 +162,24 @@ dmaattach(parent, self, aux)
}
delay(20000); /* manual says we need 20ms delay */
}
-
+
/*
- * Get transfer burst size from PROM and plug it into the controller
- * registers. This is needed on the Sun4m; do others need it too?
- * XXX
+ * Get transfer burst size from PROM and plug it into the
+ * controller registers. This is needed on the Sun4m; do
+ * others need it too?
*/
if (CPU_ISSUN4M) {
+ int sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
+
sc->sc_burst = getpropint(ca->ca_ra.ra_node,"burst-sizes", -1);
- if (sc->sc_burst == -1) {
- /* check parent SBus for burst sizes */
- if (((struct sbus_softc *)parent)->sc_burst == 0)
- sc->sc_burst = SBUS_BURST_32 - 1; /* 1->16 */
- else
- sc->sc_burst =
- ((struct sbus_softc *)parent)->sc_burst;
- }
- sc->sc_regs->csr &= ~D_BURST_SIZE; /* must clear first */
- if (sc->sc_burst & SBUS_BURST_32) {
- sc->sc_regs->csr |= D_BURST_32;
- } else if (sc->sc_burst & SBUS_BURST_16) {
- sc->sc_regs->csr |= D_BURST_16;
- } else if (strcmp(ca->ca_ra.ra_name,"espdma") == 0) {
- /* only espdma supports non-burst */
- sc->sc_regs->csr |= D_BURST_0;
-#ifdef DIAGNOSTIC
- } else {
- printf(" <unknown burst size 0x%x>", sc->sc_burst);
-#endif
- }
+ if (sc->sc_burst == -1)
+ /* take SBus burst sizes */
+ sc->sc_burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ sc->sc_burst &= sbusburst;
}
printf(": rev ");
@@ -193,6 +188,9 @@ dmaattach(parent, self, aux)
case DMAREV_0:
printf("0");
break;
+ case DMAREV_ESC:
+ printf("esc");
+ break;
case DMAREV_1:
printf("1");
break;
@@ -203,19 +201,20 @@ dmaattach(parent, self, aux)
printf("2");
break;
default:
- printf("unknown");
+ printf("unknown (0x%x)", sc->sc_rev);
}
printf("\n");
/* indirect functions */
if (sc->sc_dev.dv_cfdata->cf_attach == &dma_ca) {
+ sc->reset = espdma_reset;
sc->intr = espdmaintr;
} else {
+ sc->reset = ledma_reset;
sc->intr = ledmaintr;
}
sc->enintr = dma_enintr;
sc->isintr = dma_isintr;
- sc->reset = dma_reset;
sc->setup = dma_setup;
sc->go = dma_go;
@@ -272,24 +271,94 @@ espsearch:
}
}
+#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
+ int count = 500000; \
+ while ((COND) && --count > 0) DELAY(1); \
+ if (count == 0) { \
+ printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \
+ (SC)->sc_regs->csr); \
+ if (DONTPANIC) \
+ printf(MSG); \
+ else \
+ panic(MSG); \
+ } \
+} while (0)
+
+#define DMA_DRAIN(sc, dontpanic) do { \
+ /* \
+ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
+ * and "drain" bits while it is still thinking about a \
+ * request. \
+ * other revs: D_R_PEND bit reads as 0 \
+ */ \
+ DMAWAIT(sc, sc->sc_regs->csr & D_R_PEND, "R_PEND", dontpanic); \
+ /* \
+ * Select drain bit based on revision \
+ * also clears errors and D_TC flag \
+ */ \
+ if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
+ DMACSR(sc) |= D_DRAIN; \
+ else \
+ DMACSR(sc) |= D_INVALIDATE; \
+ /* \
+ * Wait for draining to finish \
+ * rev0 & rev1 call this PACKCNT \
+ */ \
+ DMAWAIT(sc, sc->sc_regs->csr & D_DRAINING, "DRAINING", dontpanic);\
+} while(0)
+
void
-dma_reset(sc)
+dma_reset(sc, isledma)
struct dma_softc *sc;
+ int isledma;
{
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* Drain (DMA rev 1) */
+ DMA_DRAIN(sc, 1);
DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
- DMAWAIT1(sc); /* let things drain */
DMACSR(sc) |= D_RESET; /* reset DMA */
DELAY(200); /* what should this be ? */
- DMAWAIT1(sc);
+ /*DMAWAIT1(sc); why was this here? */
DMACSR(sc) &= ~D_RESET; /* de-assert reset line */
DMACSR(sc) |= D_INT_EN; /* enable interrupts */
- if (sc->sc_rev > DMAREV_1)
+ if (sc->sc_rev > DMAREV_1 && isledma == 0)
DMACSR(sc) |= D_FASTER;
+
+ switch (sc->sc_rev) {
+ case DMAREV_2:
+ sc->sc_regs->csr &= ~D_BURST_SIZE; /* must clear first */
+ if (sc->sc_burst & SBUS_BURST_32) {
+ DMACSR(sc) |= D_BURST_32;
+ } else if (sc->sc_burst & SBUS_BURST_16) {
+ DMACSR(sc) |= D_BURST_16;
+ } else {
+ DMACSR(sc) |= D_BURST_0;
+ }
+ break;
+ case DMAREV_ESC:
+ DMACSR(sc) |= D_AUTODRAIN; /* Auto-drain */
+ if (sc->sc_burst & SBUS_BURST_32) {
+ DMACSR(sc) &= ~0x800;
+ } else
+ DMACSR(sc) |= 0x800;
+ break;
+ default:
+ }
+
sc->sc_active = 0; /* and of course we aren't */
}
+void
+espdma_reset(sc)
+ struct dma_softc *sc;
+{
+ dma_reset(sc, 0);
+}
+
+void
+ledma_reset(sc)
+ struct dma_softc *sc;
+{
+ dma_reset(sc, 1);
+}
void
dma_enintr(sc)
@@ -321,12 +390,7 @@ dma_setup(sc, addr, len, datain, dmasize)
{
u_long csr;
- /* clear errors and D_TC flag */
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* ? */
- DMAWAIT1(sc);
- DMACSR(sc) |= D_INVALIDATE;
- DMAWAIT1(sc);
+ DMA_DRAIN(sc, 0);
#if 0
DMACSR(sc) &= ~D_INT_EN;
@@ -334,7 +398,7 @@ dma_setup(sc, addr, len, datain, dmasize)
sc->sc_dmaaddr = addr;
sc->sc_dmalen = len;
- ESP_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
+ NCR_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
*sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0));
/*
@@ -345,7 +409,7 @@ dma_setup(sc, addr, len, datain, dmasize)
*dmasize = sc->sc_dmasize =
min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
- ESP_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
+ NCR_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
/* Program the DMA address */
if (CPU_ISSUN4M && sc->sc_dmasize) {
@@ -361,6 +425,14 @@ dma_setup(sc, addr, len, datain, dmasize)
} else
DMADDR(sc) = *sc->sc_dmaaddr;
+ if (sc->sc_rev == DMAREV_ESC) {
+ /* DMA ESC chip bug work-around */
+ register long bcnt = sc->sc_dmasize;
+ register long eaddr = bcnt + (long)*sc->sc_dmaaddr;
+ if ((eaddr & PGOFSET) != 0)
+ bcnt = roundup(bcnt, NBPG);
+ DMACNT(sc) = bcnt;
+ }
/* Setup DMA control register */
csr = DMACSR(sc);
if (datain)
@@ -394,11 +466,12 @@ int
espdmaintr(sc)
struct dma_softc *sc;
{
+ struct ncr53c9x_softc *nsc = &sc->sc_esp->sc_ncr53c9x;
int trans, resid;
u_long csr;
csr = DMACSR(sc);
- ESP_DMA(("%s: intr: addr %p, csr %b\n", sc->sc_dev.dv_xname,
+ NCR_DMA(("%s: intr: addr %p, csr %b\n", sc->sc_dev.dv_xname,
DMADDR(sc), csr, DMACSRBITS));
if (csr & D_ERR_PEND) {
@@ -406,19 +479,14 @@ espdmaintr(sc)
DMACSR(sc) |= D_INVALIDATE;
printf("%s: error: csr=%b\n", sc->sc_dev.dv_xname,
csr, DMACSRBITS);
- return 0;
+ return -1;
}
/* This is an "assertion" :) */
if (sc->sc_active == 0)
panic("dmaintr: DMA wasn't active");
- /* clear errors and D_TC flag */
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* ? */
- DMAWAIT1(sc);
- DMACSR(sc) |= D_INVALIDATE;
- DMAWAIT1(sc);
+ DMA_DRAIN(sc, 0);
/* DMA has stopped */
DMACSR(sc) &= ~D_EN_DMA;
@@ -426,11 +494,11 @@ espdmaintr(sc)
if (sc->sc_dmasize == 0) {
/* A "Transfer Pad" operation completed */
- ESP_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
- ESP_READ_REG(sc->sc_esp, ESP_TCL) |
- (ESP_READ_REG(sc->sc_esp, ESP_TCM) << 8),
- ESP_READ_REG(sc->sc_esp, ESP_TCL),
- ESP_READ_REG(sc->sc_esp, ESP_TCM)));
+ NCR_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
+ NCR_READ_REG(nsc, NCR_TCL) |
+ (NCR_READ_REG(nsc, NCR_TCM) << 8),
+ NCR_READ_REG(nsc, NCR_TCL),
+ NCR_READ_REG(nsc, NCR_TCM)));
return 0;
}
@@ -442,44 +510,50 @@ espdmaintr(sc)
* bytes are clocked into the FIFO.
*/
if (!(csr & D_WRITE) &&
- (resid = (ESP_READ_REG(sc->sc_esp, ESP_FFLAG) & ESPFIFO_FF)) != 0) {
- ESP_DMA(("dmaintr: empty esp FIFO of %d ", resid));
- ESPCMD(sc->sc_esp, ESPCMD_FLUSH);
+ (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+ NCR_DMA(("dmaintr: empty esp FIFO of %d ", resid));
}
- if ((sc->sc_esp->sc_espstat & ESPSTAT_TC) == 0) {
+ if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
/*
* `Terminal count' is off, so read the residue
* out of the ESP counter registers.
*/
- resid += ( ESP_READ_REG(sc->sc_esp, ESP_TCL) |
- (ESP_READ_REG(sc->sc_esp, ESP_TCM) << 8) |
- ((sc->sc_esp->sc_cfg2 & ESPCFG2_FE)
- ? (ESP_READ_REG(sc->sc_esp, ESP_TCH) << 16)
+ resid += (NCR_READ_REG(nsc, NCR_TCL) |
+ (NCR_READ_REG(nsc, NCR_TCM) << 8) |
+ ((nsc->sc_cfg2 & NCRCFG2_FE)
+ ? (NCR_READ_REG(nsc, NCR_TCH) << 16)
: 0));
if (resid == 0 && sc->sc_dmasize == 65536 &&
- (sc->sc_esp->sc_cfg2 & ESPCFG2_FE) == 0)
+ (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
/* A transfer of 64K is encoded as `TCL=TCM=0' */
resid = 65536;
}
trans = sc->sc_dmasize - resid;
if (trans < 0) { /* transferred < 0 ? */
+#if 0
+ /*
+ * This situation can happen in perfectly normal operation
+ * if the ESP is reselected while using DMA to select
+ * another target. As such, don't print the warning.
+ */
printf("%s: xfer (%d) > req (%d)\n",
sc->sc_dev.dv_xname, trans, sc->sc_dmasize);
+#endif
trans = sc->sc_dmasize;
}
- ESP_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
- ESP_READ_REG(sc->sc_esp, ESP_TCL),
- ESP_READ_REG(sc->sc_esp, ESP_TCM),
- (sc->sc_esp->sc_cfg2 & ESPCFG2_FE)
- ? ESP_READ_REG(sc->sc_esp, ESP_TCH) : 0,
+ NCR_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
+ NCR_READ_REG(nsc, NCR_TCL),
+ NCR_READ_REG(nsc, NCR_TCM),
+ (nsc->sc_cfg2 & NCRCFG2_FE)
+ ? NCR_READ_REG(nsc, NCR_TCH) : 0,
trans, resid));
if (csr & D_WRITE)
- cache_flush(*sc->sc_dmaaddr, trans);
+ cpuinfo.cache_flush(*sc->sc_dmaaddr, trans);
if (CPU_ISSUN4M && sc->sc_dvmakaddr)
dvma_mapout((vm_offset_t)sc->sc_dvmakaddr,
@@ -490,7 +564,7 @@ espdmaintr(sc)
#if 0 /* this is not normal operation just yet */
if (*sc->sc_dmalen == 0 ||
- sc->sc_esp->sc_phase != sc->sc_esp->sc_prevphase)
+ nsc->sc_phase != nsc->sc_prevphase)
return 0;
/* and again */
@@ -515,11 +589,11 @@ ledmaintr(sc)
csr = DMACSR(sc);
if (csr & D_ERR_PEND) {
- printf("Lance DMA error, see your doctor!\n");
DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
DMACSR(sc) |= D_INVALIDATE;
printf("%s: error: csr=%b\n", sc->sc_dev.dv_xname,
- (u_int)csr, DMACSRBITS);
+ csr, DMACSRBITS);
+ DMA_RESET(sc);
}
return 1;
}
diff --git a/sys/arch/sparc/dev/dmareg.h b/sys/arch/sparc/dev/dmareg.h
index 3998581845a..c9e575a262f 100644
--- a/sys/arch/sparc/dev/dmareg.h
+++ b/sys/arch/sparc/dev/dmareg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: dmareg.h,v 1.8 1996/04/22 02:34:58 abrown Exp $ */
+/* $OpenBSD: dmareg.h,v 1.4 1997/08/08 08:24:58 downsj Exp $ */
+/* $NetBSD: dmareg.h,v 1.10 1996/11/28 09:37:34 pk Exp $ */
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -38,19 +39,21 @@ struct dma_regs {
#define D_INT_EN 0x00000010 /* interrupt enable */
#define D_INVALIDATE 0x00000020 /* invalidate fifo */
#define D_SLAVE_ERR 0x00000040 /* slave access size error */
-#define D_DRAIN 0x00000040 /* drain fifo if DMAREV_1 */
+#define D_DRAIN 0x00000040 /* rev0,1,esc: drain fifo */
#define D_RESET 0x00000080 /* reset scsi */
#define D_WRITE 0x00000100 /* 1 = dev -> mem */
#define D_EN_DMA 0x00000200 /* enable DMA requests */
-#define D_R_PEND 0x00000400 /* something only on ver < 2 */
+#define D_R_PEND 0x00000400 /* rev0,1: request pending */
+#define D_ESC_BURST 0x00000800 /* DMA ESC: 16 byte bursts */
#define D_EN_CNT 0x00002000 /* enable byte counter */
#define D_TC 0x00004000 /* terminal count */
#define D_DSBL_CSR_DRN 0x00010000 /* disable fifo drain on csr */
#define D_DSBL_SCSI_DRN 0x00020000 /* disable fifo drain on reg */
#define D_BURST_SIZE 0x000c0000 /* sbus read/write burst size */
#define D_BURST_0 0x00080000 /* no bursts (SCSI-only) */
-#define D_BURST_16 0x00040000 /* 16-byte bursts */
-#define D_BURST_32 0x00000000 /* 32-byte bursts */
+#define D_BURST_16 0x00000000 /* 16-byte bursts */
+#define D_BURST_32 0x00040000 /* 32-byte bursts */
+#define D_AUTODRAIN 0x00040000 /* DMA ESC: Auto-drain */
#define D_DIAG 0x00100000 /* disable fifo drain on addr */
#define D_TWO_CYCLE 0x00200000 /* 2 clocks per transfer */
#define D_FASTER 0x00400000 /* 3 clocks per transfer */
@@ -62,6 +65,7 @@ struct dma_regs {
#define D_NA_LOADED 0x08000000 /* next address loaded */
#define D_DEV_ID 0xf0000000 /* device ID */
#define DMAREV_0 0x00000000 /* Sunray DMA */
+#define DMAREV_ESC 0x40000000 /* DMA ESC array */
#define DMAREV_1 0x80000000 /* 'DMA' */
#define DMAREV_PLUS 0x90000000 /* 'DMA+' */
#define DMAREV_2 0xa0000000 /* 'DMA2' */
diff --git a/sys/arch/sparc/dev/dmavar.h b/sys/arch/sparc/dev/dmavar.h
index 6bc42333a98..57fbbcad5e4 100644
--- a/sys/arch/sparc/dev/dmavar.h
+++ b/sys/arch/sparc/dev/dmavar.h
@@ -1,4 +1,5 @@
-/* $NetBSD: dmavar.h,v 1.8 1996/04/22 02:35:00 abrown Exp $ */
+/* $OpenBSD: dmavar.h,v 1.4 1997/08/08 08:24:59 downsj Exp $ */
+/* $NetBSD: dmavar.h,v 1.11 1996/11/27 21:49:53 pk Exp $ */
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -35,7 +36,7 @@ struct dma_softc {
struct le_softc *sc_le; /* my ethernet */
struct dma_regs *sc_regs; /* the registers */
int sc_active; /* DMA active ? */
- int sc_rev; /* revision */
+ u_int sc_rev; /* revision */
int sc_node; /* PROM node ID */
int sc_burst; /* DVMA burst size in effect */
caddr_t sc_dvmakaddr; /* DVMA cookies */
@@ -53,32 +54,7 @@ struct dma_softc {
#define DMACSR(sc) (sc->sc_regs->csr)
#define DMADDR(sc) (sc->sc_regs->addr)
-
-/*
- * We are not allowed to touch the DMA "flush" and "drain" bits
- * while it is still thinking about a request (DMA_RP).
- */
-
-/*
- * TIME WAIT (to debug hanging machine problem)
- */
-
-#define TIME_WAIT(COND, MSG, SC) { int count = 500000; \
- while (--count > 0 && (COND)) DELAY(1); \
- if (count == 0) { \
- printf("CSR = %lx\n",\
- SC->sc_regs->csr);\
- panic(MSG); } \
- }
-
-#define DMAWAIT(sc) TIME_WAIT((sc->sc_regs->csr & D_R_PEND), "DMAWAIT", sc)
-#define DMAWAIT1(sc) TIME_WAIT((sc->sc_regs->csr & D_DRAINING), "DMAWAIT1", sc)
-#define DMAREADY(sc) TIME_WAIT((!(sc->sc_regs->csr & D_DMA_ON)), "DMAREADY", sc)
-
-#define DMA_DRAIN(sc) if (sc->sc_rev < DMAREV_2) { \
- DMACSR(sc) |= D_DRAIN; \
- DMAWAIT1(sc); \
- }
+#define DMACNT(sc) (sc->sc_regs->bcnt)
/* DMA engine functions */
#define DMA_ENINTR(r) (((r)->enintr)(r))
diff --git a/sys/arch/sparc/dev/esp.c b/sys/arch/sparc/dev/esp.c
index 5cb9d216931..48c211f8ea2 100644
--- a/sys/arch/sparc/dev/esp.c
+++ b/sys/arch/sparc/dev/esp.c
@@ -1,4 +1,65 @@
-/* $NetBSD: esp.c,v 1.47.2.1 1996/06/12 20:46:52 pk Exp $ */
+/* $OpenBSD: esp.c,v 1.10 1997/08/08 08:25:00 downsj Exp $ */
+/* $NetBSD: esp.c,v 1.68 1997/07/19 21:57:01 pk Exp $ */
+
+/*
+ * Copyright (c) 1997 Jason R. Thorpe.
+ * 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 for the NetBSD Project
+ * by Jason R. Thorpe.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1996 Charles M. Hannum. 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 Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
/*
* Copyright (c) 1994 Peter Galbavy
@@ -58,35 +119,17 @@
#include <machine/cpu.h>
#include <machine/autoconf.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
#include <sparc/dev/espvar.h>
-int esp_debug = 0; /*ESP_SHOWPHASE|ESP_SHOWMISC|ESP_SHOWTRAC|ESP_SHOWCMDS;*/
-
-/*static*/ void espattach __P((struct device *, struct device *, void *));
-/*static*/ int espmatch __P((struct device *, void *, void *));
-/*static*/ int espprint __P((void *, const char *));
-/*static*/ u_int esp_adapter_info __P((struct esp_softc *));
-/*static*/ void espreadregs __P((struct esp_softc *));
-/*static*/ void espselect __P((struct esp_softc *,
- u_char, u_char, u_char *, u_char));
-/*static*/ void esp_scsi_reset __P((struct esp_softc *));
-/*static*/ void esp_reset __P((struct esp_softc *));
-/*static*/ void esp_init __P((struct esp_softc *, int));
-/*static*/ int esp_scsi_cmd __P((struct scsi_xfer *));
-/*static*/ int esp_poll __P((struct esp_softc *, struct ecb *));
-/*static*/ void esp_sched __P((struct esp_softc *));
-/*static*/ void esp_done __P((struct ecb *));
-/*static*/ void esp_msgin __P((struct esp_softc *));
-/*static*/ void esp_msgout __P((struct esp_softc *));
-/*static*/ int espintr __P((struct esp_softc *));
-/*static*/ void esp_timeout __P((void *arg));
-/*static*/ void esp_abort __P((struct esp_softc *, struct ecb *));
-int esp_stp2cpb __P((struct esp_softc *, int));
-int esp_cpb2stp __P((struct esp_softc *, int));
+void espattach __P((struct device *, struct device *, void *));
+int espmatch __P((struct device *, void *, void *));
/* Linkup to the rest of the kernel */
struct cfattach esp_ca = {
@@ -98,7 +141,7 @@ struct cfdriver esp_cd = {
};
struct scsi_adapter esp_switch = {
- esp_scsi_cmd,
+ ncr53c9x_scsi_cmd,
minphys, /* no max at this level; handled by DMA code */
NULL,
NULL,
@@ -111,22 +154,39 @@ struct scsi_device esp_dev = {
NULL, /* Use default 'done' routine */
};
-int
-espprint(aux, name)
- void *aux;
- const char *name;
-{
- if (name != NULL)
- printf("%s: scsibus ", name);
- return UNCONF;
-}
+/*
+ * Functions and the switch for the MI code.
+ */
+u_char esp_read_reg __P((struct ncr53c9x_softc *, int));
+void esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
+int esp_dma_isintr __P((struct ncr53c9x_softc *));
+void esp_dma_reset __P((struct ncr53c9x_softc *));
+int esp_dma_intr __P((struct ncr53c9x_softc *));
+int esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
+ size_t *, int, size_t *));
+void esp_dma_go __P((struct ncr53c9x_softc *));
+void esp_dma_stop __P((struct ncr53c9x_softc *));
+int esp_dma_isactive __P((struct ncr53c9x_softc *));
+
+struct ncr53c9x_glue esp_glue = {
+ esp_read_reg,
+ esp_write_reg,
+ esp_dma_isintr,
+ esp_dma_reset,
+ esp_dma_intr,
+ esp_dma_setup,
+ esp_dma_go,
+ esp_dma_stop,
+ esp_dma_isactive,
+ NULL, /* gl_clear_latched_intr */
+};
int
espmatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -147,11 +207,17 @@ espattach(parent, self, aux)
void *aux;
{
register struct confargs *ca = aux;
- struct esp_softc *sc = (void *)self;
+ struct esp_softc *esc = (void *)self;
+ struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
struct bootpath *bp;
int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
/*
+ * Set up glue for MI code early; we use some of it here.
+ */
+ sc->sc_glue = &esp_glue;
+
+ /*
* Make sure things are sane. I don't know if this is ever
* necessary, but it seem to be in all of Torek's code.
*/
@@ -160,25 +226,25 @@ espattach(parent, self, aux)
return;
}
- sc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
- printf(" pri %d", sc->sc_pri);
+ esc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
+ printf(" pri %d", esc->sc_pri);
/*
* Map my registers in, if they aren't already in virtual
* address space.
*/
if (ca->ca_ra.ra_vaddr)
- sc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
+ esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
else {
- sc->sc_reg = (volatile u_char *)
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len, ca->ca_bustype);
+ esc->sc_reg = (volatile u_char *)
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
}
/* Other settings */
- sc->sc_node = ca->ca_ra.ra_node;
+ esc->sc_node = ca->ca_ra.ra_node;
if (ca->ca_bustype == BUS_SBUS) {
- sc->sc_id = getpropint(sc->sc_node, "initiator-id", 7);
- sc->sc_freq = getpropint(sc->sc_node, "clock-frequency", -1);
+ sc->sc_id = getpropint(esc->sc_node, "initiator-id", 7);
+ sc->sc_freq = getpropint(esc->sc_node, "clock-frequency", -1);
} else {
sc->sc_id = 7;
sc->sc_freq = 24000000;
@@ -191,8 +257,8 @@ espattach(parent, self, aux)
sc->sc_freq /= 1000000;
if (dmachild) {
- sc->sc_dma = (struct dma_softc *)parent;
- sc->sc_dma->sc_esp = sc;
+ esc->sc_dma = (struct dma_softc *)parent;
+ esc->sc_dma->sc_esp = esc;
} else {
/*
* find the DMA by poking around the dma device structures
@@ -202,56 +268,68 @@ espattach(parent, self, aux)
* dma actually gets configured, it does the opposing test, and
* if the sc->sc_esp field in it's softc is NULL, then tries to
* find the matching esp driver.
- *
*/
- sc->sc_dma = (struct dma_softc *)
+ esc->sc_dma = (struct dma_softc *)
getdevunit("dma", sc->sc_dev.dv_unit);
/*
* and a back pointer to us, for DMA
*/
- if (sc->sc_dma)
- sc->sc_dma->sc_esp = sc;
- else
+ if (esc->sc_dma)
+ esc->sc_dma->sc_esp = esc;
+ else {
+ printf("\n");
panic("espattach: no dma found");
+ }
}
/*
+ * XXX More of this should be in ncr53c9x_attach(), but
+ * XXX should we really poke around the chip that much in
+ * XXX the MI code? Think about this more...
+ */
+
+ /*
* It is necessary to try to load the 2nd config register here,
- * to find out what rev the esp chip is, else the esp_reset
+ * to find out what rev the esp chip is, else the ncr53c9x_reset
* will not set up the defaults correctly.
*/
- sc->sc_cfg1 = sc->sc_id | ESPCFG1_PARENB;
- sc->sc_cfg2 = ESPCFG2_SCSI2 | ESPCFG2_RPE;
- sc->sc_cfg3 = ESPCFG3_CDB;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-
- if ((ESP_READ_REG(sc, ESP_CFG2) & ~ESPCFG2_RSVD) != (ESPCFG2_SCSI2 | ESPCFG2_RPE)) {
- printf(": ESP100");
- sc->sc_rev = ESP100;
+ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
+ sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
+ sc->sc_cfg3 = NCRCFG3_CDB;
+ NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
+
+ if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
+ (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
+ sc->sc_rev = NCR_VARIANT_ESP100;
} else {
- sc->sc_cfg2 = ESPCFG2_SCSI2;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
+ sc->sc_cfg2 = NCRCFG2_SCSI2;
+ NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- sc->sc_cfg3 = (ESPCFG3_CDB | ESPCFG3_FCLK);
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- if (ESP_READ_REG(sc, ESP_CFG3) != (ESPCFG3_CDB | ESPCFG3_FCLK)) {
- printf(": ESP100A");
- sc->sc_rev = ESP100A;
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ if (NCR_READ_REG(sc, NCR_CFG3) !=
+ (NCRCFG3_CDB | NCRCFG3_FCLK)) {
+ sc->sc_rev = NCR_VARIANT_ESP100A;
} else {
- /* ESPCFG2_FE enables > 64K transfers */
- sc->sc_cfg2 |= ESPCFG2_FE;
+ /* NCRCFG2_FE enables > 64K transfers */
+ sc->sc_cfg2 |= NCRCFG2_FE;
sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- printf(": ESP200");
- sc->sc_rev = ESP200;
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ sc->sc_rev = NCR_VARIANT_ESP200;
}
}
/*
+ * XXX minsync and maxxfer _should_ be set up in MI code,
+ * XXX but it appears to have some dependency on what sort
+ * XXX of DMA we're hooked up to, etc.
+ */
+
+ /*
* This is the value used to start sync negotiations
- * Note that the ESP register "SYNCTP" is programmed
+ * Note that the NCR register "SYNCTP" is programmed
* in "clocks per byte", and has a minimum value of 4.
* The SCSI period used in negotiation is one-fourth
* of the time (in nanoseconds) needed to transfer one byte.
@@ -262,78 +340,45 @@ espattach(parent, self, aux)
/*
* Alas, we must now modify the value a bit, because it's
- * only valid when can switch on FASTCLK and FASTSCSI bits
- * in config register 3...
+ * only valid when can switch on FASTCLK and FASTSCSI bits
+ * in config register 3...
*/
switch (sc->sc_rev) {
- case ESP100:
+ case NCR_VARIANT_ESP100:
sc->sc_maxxfer = 64 * 1024;
sc->sc_minsync = 0; /* No synch on old chip? */
break;
- case ESP100A:
+
+ case NCR_VARIANT_ESP100A:
sc->sc_maxxfer = 64 * 1024;
- sc->sc_minsync = esp_cpb2stp(sc, 5); /* Min clocks/byte is 5 */
+ /* Min clocks/byte is 5 */
+ sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
break;
- case ESP200:
+
+ case NCR_VARIANT_ESP200:
sc->sc_maxxfer = 16 * 1024 * 1024;
/* XXX - do actually set FAST* bits */
+ break;
}
- sc->sc_ccf = FREQTOCCF(sc->sc_freq);
-
- /* The value *must not* be == 1. Make it 2 */
- if (sc->sc_ccf == 1)
- sc->sc_ccf = 2;
-
- /*
- * The recommended timeout is 250ms. This register is loaded
- * with a value calculated as follows, from the docs:
- *
- * (timout period) x (CLK frequency)
- * reg = -------------------------------------
- * 8192 x (Clock Conversion Factor)
- *
- * Since CCF has a linear relation to CLK, this generally computes
- * to the constant of 153.
- */
- sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
-
- /* CCF register only has 3 bits; 0 is actually 8 */
- sc->sc_ccf &= 7;
-
- /* Reset state & bus */
- sc->sc_state = 0;
- esp_init(sc, 1);
-
- printf(" %dMhz, target %d\n", sc->sc_freq, sc->sc_id);
-
/* add me to the sbus structures */
- sc->sc_sd.sd_reset = (void *) esp_reset;
+ esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
#if defined(SUN4C) || defined(SUN4M)
if (ca->ca_bustype == BUS_SBUS) {
if (dmachild)
- sbus_establish(&sc->sc_sd, sc->sc_dev.dv_parent);
+ sbus_establish(&esc->sc_sd, sc->sc_dev.dv_parent);
else
- sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ sbus_establish(&esc->sc_sd, &sc->sc_dev);
}
#endif /* SUN4C || SUN4M */
/* and the interuppts */
- sc->sc_ih.ih_fun = (void *) espintr;
- sc->sc_ih.ih_arg = sc;
- intr_establish(sc->sc_pri, &sc->sc_ih);
+ esc->sc_ih.ih_fun = (void *) ncr53c9x_intr;
+ esc->sc_ih.ih_arg = sc;
+ intr_establish(esc->sc_pri, &esc->sc_ih);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
/*
- * fill in the prototype scsi_link.
- */
- sc->sc_link.adapter_softc = sc;
- sc->sc_link.adapter_target = sc->sc_id;
- sc->sc_link.adapter = &esp_switch;
- sc->sc_link.device = &esp_dev;
- sc->sc_link.openings = 2;
-
- /*
* If the boot path is "esp" at the moment and it's me, then
* walk our pointer to the sub-device, ready for the config
* below.
@@ -352,1622 +397,104 @@ espattach(parent, self, aux)
break;
}
- /*
- * Now try to attach all the sub-devices
- */
- config_found(self, &sc->sc_link, espprint);
-
- bootpath_store(1, NULL);
-}
-
-/*
- * This is the generic esp reset function. It does not reset the SCSI bus,
- * only this controllers, but kills any on-going commands, and also stops
- * and resets the DMA.
- *
- * After reset, registers are loaded with the defaults from the attach
- * routine above.
- */
-void
-esp_reset(sc)
- struct esp_softc *sc;
-{
-
- /* reset DMA first */
- DMA_RESET(sc->sc_dma);
+ /* Do the common parts of attachment. */
+ ncr53c9x_attach(sc, &esp_switch, &esp_dev);
- /* reset SCSI chip */
- ESPCMD(sc, ESPCMD_RSTCHIP);
- ESPCMD(sc, ESPCMD_NOP);
- DELAY(500);
+ /* Turn on target selection using the `dma' method */
+ ncr53c9x_dmaselect = 1;
- /* do these backwards, and fall through */
- switch (sc->sc_rev) {
- case ESP200:
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- case ESP100A:
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
- case ESP100:
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- break;
- default:
- printf("%s: unknown revision code, assuming ESP100\n",
- sc->sc_dev.dv_xname);
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- }
+ bootpath_store(1, NULL);
}
/*
- * Reset the SCSI bus, but not the chip
+ * Glue functions.
*/
-void
-esp_scsi_reset(sc)
- struct esp_softc *sc;
-{
- /* stop DMA first, as the chip will return to Bus Free phase */
- DMACSR(sc->sc_dma) &= ~D_EN_DMA;
-
- printf("esp: resetting SCSI bus\n");
- ESPCMD(sc, ESPCMD_RSTSCSI);
-}
-/*
- * Initialize esp state machine
- */
-void
-esp_init(sc, doreset)
- struct esp_softc *sc;
- int doreset;
+u_char
+esp_read_reg(sc, reg)
+ struct ncr53c9x_softc *sc;
+ int reg;
{
- struct ecb *ecb;
- int r;
+ struct esp_softc *esc = (struct esp_softc *)sc;
- ESP_TRACE(("[ESP_INIT(%d)] ", doreset));
-
- if (sc->sc_state == 0) { /* First time through */
- TAILQ_INIT(&sc->ready_list);
- TAILQ_INIT(&sc->nexus_list);
- TAILQ_INIT(&sc->free_list);
- sc->sc_nexus = NULL;
- ecb = sc->sc_ecb;
- bzero(ecb, sizeof(sc->sc_ecb));
- for (r = 0; r < sizeof(sc->sc_ecb) / sizeof(*ecb); r++) {
- TAILQ_INSERT_TAIL(&sc->free_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QFREE);
- ecb++;
- }
- bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
- } else {
- sc->sc_flags |= ESP_ABORTING;
- sc->sc_state = ESP_IDLE;
- ecb = sc->sc_nexus;
- if (ecb != NULL) {
- ecb->xs->error = XS_TIMEOUT;
- esp_done(ecb);
- sc->sc_nexus = NULL;
- }
- while ((ecb = sc->nexus_list.tqh_first) != NULL) {
- ecb->xs->error = XS_TIMEOUT;
- esp_done(ecb);
- }
- }
-
- /*
- * reset the chip to a known state
- */
- esp_reset(sc);
-
- sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
- for (r = 0; r < 8; r++) {
- struct esp_tinfo *tp = &sc->sc_tinfo[r];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
- int fl = sc->sc_dev.dv_cfdata->cf_flags;
-
- tp->flags = ((sc->sc_minsync && !(fl & (1<<(r+8))))
- ? T_NEGOTIATE : 0) |
- ((fl & (1<<r)) ? T_RSELECTOFF : 0) |
- T_NEED_TO_RESET;
- tp->period = sc->sc_minsync;
- tp->offset = 0;
- }
- sc->sc_flags &= ~ESP_ABORTING;
-
- if (doreset) {
- sc->sc_state = ESP_SBR;
- ESPCMD(sc, ESPCMD_RSTSCSI);
- return;
- }
-
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- return;
+ return (esc->sc_reg[reg * 4]);
}
-/*
- * Read the ESP registers, and save their contents for later use.
- * ESP_STAT, ESP_STEP & ESP_INTR are mostly zeroed out when reading
- * ESP_INTR - so make sure it is the last read.
- *
- * I think that (from reading the docs) most bits in these registers
- * only make sense when he DMA CSR has an interrupt showing. Call only
- * if an interrupt is pending.
- */
void
-espreadregs(sc)
- struct esp_softc *sc;
+esp_write_reg(sc, reg, val)
+ struct ncr53c9x_softc *sc;
+ int reg;
+ u_char val;
{
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ u_char v = val;
- sc->sc_espstat = ESP_READ_REG(sc, ESP_STAT);
- /* Only the stepo bits are of interest */
- sc->sc_espstep = ESP_READ_REG(sc, ESP_STEP) & ESPSTEP_MASK;
- sc->sc_espintr = ESP_READ_REG(sc, ESP_INTR);
-
- /*
- * Determine the SCSI bus phase, return either a real SCSI bus phase
- * or some pseudo phase we use to detect certain exceptions.
- */
-
- sc->sc_phase = (sc->sc_espintr & ESPINTR_DIS)
- ? /* Disconnected */ BUSFREE_PHASE
- : sc->sc_espstat & ESPSTAT_PHASE;
-
- ESP_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
+ esc->sc_reg[reg * 4] = v;
}
-/*
- * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
- */
int
-esp_stp2cpb(sc, period)
- struct esp_softc *sc;
- int period;
+esp_dma_isintr(sc)
+ struct ncr53c9x_softc *sc;
{
- int v;
- v = (sc->sc_freq * period) / 250;
- if (esp_cpb2stp(sc, v) < period)
- /* Correct round-down error */
- v++;
- return v;
-}
+ struct esp_softc *esc = (struct esp_softc *)sc;
-/*
- * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
- */
-int
-esp_cpb2stp(sc, cpb)
- struct esp_softc *sc;
- int cpb;
-{
- return ((250 * cpb) / sc->sc_freq);
+ return (DMA_ISINTR(esc->sc_dma));
}
-/*
- * Send a command to a target, set the driver state to ESP_SELECTING
- * and let the caller take care of the rest.
- *
- * Keeping this as a function allows me to say that this may be done
- * by DMA instead of programmed I/O soon.
- */
void
-espselect(sc, target, lun, cmd, clen)
- struct esp_softc *sc;
- u_char target, lun;
- u_char *cmd;
- u_char clen;
+esp_dma_reset(sc)
+ struct ncr53c9x_softc *sc;
{
- struct esp_tinfo *ti = &sc->sc_tinfo[target];
- int i;
-
- ESP_TRACE(("[espselect(t%d,l%d,cmd:%x)] ", target, lun, *(u_char *)cmd));
-
- /* new state ESP_SELECTING */
- sc->sc_state = ESP_SELECTING;
-
- ESPCMD(sc, ESPCMD_FLUSH);
-
- /*
- * The docs say the target register is never reset, and I
- * can't think of a better place to set it
- */
- ESP_WRITE_REG(sc, ESP_SELID, target);
- if (ti->flags & T_SYNCMODE) {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP, esp_stp2cpb(sc, ti->period));
- } else {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
- }
-
- /*
- * Who am I. This is where we tell the target that we are
- * happy for it to disconnect etc.
- */
- ESP_WRITE_REG(sc, ESP_FIFO,
- MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF)?0:1));
-
- if (ti->flags & T_NEGOTIATE) {
- /* Arbitrate, select and stop after IDENTIFY message */
- ESPCMD(sc, ESPCMD_SELATNS);
- return;
- }
-
- /* Now the command into the FIFO */
- for (i = 0; i < clen; i++)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
-
- /* And get the targets attention */
- ESPCMD(sc, ESPCMD_SELATN);
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ DMA_RESET(esc->sc_dma);
}
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
- */
-
-/*
- * Start a SCSI-command
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
int
-esp_scsi_cmd(xs)
- struct scsi_xfer *xs;
+esp_dma_intr(sc)
+ struct ncr53c9x_softc *sc;
{
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- struct ecb *ecb;
- int s, flags;
-
- ESP_TRACE(("[esp_scsi_cmd] "));
- ESP_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
- sc_link->target));
-
- flags = xs->flags;
-
- /* Get a esp command block */
- s = splbio();
- ecb = sc->free_list.tqh_first;
- if (ecb) {
- TAILQ_REMOVE(&sc->free_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNONE);
- }
- splx(s);
-
- if (ecb == NULL) {
- ESP_MISC(("TRY_AGAIN_LATER"));
- return TRY_AGAIN_LATER;
- }
-
- /* Initialize ecb */
- ecb->xs = xs;
- bcopy(xs->cmd, &ecb->cmd, xs->cmdlen);
- ecb->clen = xs->cmdlen;
- ecb->daddr = xs->data;
- ecb->dleft = xs->datalen;
- ecb->stat = 0;
-
- s = splbio();
- TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QREADY);
- timeout(esp_timeout, ecb, (xs->timeout*hz)/1000);
-
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
-
- splx(s);
-
- if (flags & SCSI_POLL) {
- /* Not allowed to use interrupts, use polling instead */
- return esp_poll(sc, ecb);
- }
-
- ESP_MISC(("SUCCESSFULLY_QUEUED"));
- return SUCCESSFULLY_QUEUED;
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ return (DMA_INTR(esc->sc_dma));
}
-/*
- * Used when interrupt driven I/O isn't allowed, e.g. during boot.
- */
int
-esp_poll(sc, ecb)
- struct esp_softc *sc;
- struct ecb *ecb;
+esp_dma_setup(sc, addr, len, datain, dmasize)
+ struct ncr53c9x_softc *sc;
+ caddr_t *addr;
+ size_t *len;
+ int datain;
+ size_t *dmasize;
{
- struct scsi_xfer *xs = ecb->xs;
- int count = xs->timeout * 100;
+ struct esp_softc *esc = (struct esp_softc *)sc;
- ESP_TRACE(("[esp_poll] "));
- while (count) {
- if (DMA_ISINTR(sc->sc_dma)) {
- espintr(sc);
- }
-#if alternatively
- if (ESP_READ_REG(sc, ESP_STAT) & ESPSTAT_INT)
- espintr(sc);
-#endif
- if (xs->flags & ITSDONE)
- break;
- DELAY(10);
- if (sc->sc_state == ESP_IDLE) {
- ESP_TRACE(("[esp_poll: rescheduling] "));
- esp_sched(sc);
- }
- count--;
- }
-
- if (count == 0) {
- ESP_MISC(("esp_poll: timeout"));
- esp_timeout((caddr_t)ecb);
- }
-
- return COMPLETE;
+ return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
}
-
-/*
- * LOW LEVEL SCSI UTILITIES
- */
-
-/*
- * Schedule a scsi operation. This has now been pulled out of the interrupt
- * handler so that we may call it from esp_scsi_cmd and esp_done. This may
- * save us an unecessary interrupt just to get things going. Should only be
- * called when state == ESP_IDLE and at bio pl.
- */
void
-esp_sched(sc)
- struct esp_softc *sc;
+esp_dma_go(sc)
+ struct ncr53c9x_softc *sc;
{
- struct scsi_link *sc_link;
- struct ecb *ecb;
- int t;
-
- ESP_TRACE(("[esp_sched] "));
- if (sc->sc_state != ESP_IDLE)
- panic("esp_sched: not IDLE (state=%d)", sc->sc_state);
-
- if (sc->sc_flags & ESP_ABORTING)
- return;
-
- /*
- * Find first ecb in ready queue that is for a target/lunit
- * combinations that is not busy.
- */
- for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- t = sc_link->target;
- if (!(sc->sc_tinfo[t].lubusy & (1 << sc_link->lun))) {
- struct esp_tinfo *ti = &sc->sc_tinfo[t];
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if ((ecb->flags & ECB_QBITS) != ECB_QREADY)
- panic("esp: busy entry on ready list");
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNONE);
- sc->sc_nexus = ecb;
- sc->sc_flags = 0;
- sc->sc_prevphase = INVALID_PHASE;
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- ti->lubusy |= (1<<sc_link->lun);
-/*XXX*/if (sc->sc_msgpriq) {
- printf("esp: message queue not empty: %x!\n", sc->sc_msgpriq);
-}
-/*XXX*/sc->sc_msgpriq = sc->sc_msgout = 0;
- espselect(sc, t, sc_link->lun,
- (u_char *)&ecb->cmd, ecb->clen);
- break;
- } else
- ESP_MISC(("%d:%d busy\n", t, sc_link->lun));
- }
+ DMA_GO(esc->sc_dma);
}
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
-void
-esp_done(ecb)
- struct ecb *ecb;
-{
- struct scsi_xfer *xs = ecb->xs;
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
-
- ESP_TRACE(("[esp_done(error:%x)] ", xs->error));
-
- untimeout(esp_timeout, ecb);
-
- /*
- * Now, if we've come here with no error code, i.e. we've kept the
- * initial XS_NOERROR, and the status code signals that we should
- * check sense, we'll need to set up a request sense cmd block and
- * push the command back into the ready queue *before* any other
- * commands for this target/lunit, else we lose the sense info.
- * We don't support chk sense conditions for the request sense cmd.
- */
- if (xs->error == XS_NOERROR) {
- if ((ecb->flags & ECB_ABORTED) != 0) {
- xs->error = XS_TIMEOUT;
- } else if ((ecb->flags & ECB_CHKSENSE) != 0) {
- xs->error = XS_SENSE;
- } else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
- struct scsi_sense *ss = (void *)&ecb->cmd;
- ESP_MISC(("requesting sense "));
- /* First, save the return values */
- xs->resid = ecb->dleft;
- xs->status = ecb->stat;
- /* Next, setup a request sense command block */
- bzero(ss, sizeof(*ss));
- ss->opcode = REQUEST_SENSE;
- /*ss->byte2 = sc_link->lun << 5;*/
- ss->length = sizeof(struct scsi_sense_data);
- ecb->clen = sizeof(*ss);
- ecb->daddr = (char *)&xs->sense;
- ecb->dleft = sizeof(struct scsi_sense_data);
- ecb->flags |= ECB_CHKSENSE;
-/*XXX - must take off queue here */
- if (ecb != sc->sc_nexus) {
- panic("%s: esp_sched: floating ecb %p",
- sc->sc_dev.dv_xname, ecb);
- }
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QREADY);
- ti->lubusy &= ~(1<<sc_link->lun);
- ti->senses++;
- timeout(esp_timeout, ecb, (xs->timeout*hz)/1000);
- if (sc->sc_nexus == ecb) {
- sc->sc_nexus = NULL;
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- }
- return;
- } else {
- xs->resid = ecb->dleft;
- }
- }
-
- xs->flags |= ITSDONE;
-
-#ifdef ESP_DEBUG
- if (esp_debug & ESP_SHOWMISC) {
- printf("err=0x%02x ",xs->error);
- if (xs->error == XS_SENSE) {
- printf("sense=%2x; ", xs->sense.error_code);
- }
- }
- if ((xs->resid || xs->error > XS_SENSE) && esp_debug & ESP_SHOWMISC) {
- if (xs->resid)
- printf("esp_done: resid=%d\n", xs->resid);
- if (xs->error)
- printf("esp_done: error=%d\n", xs->error);
- }
-#endif
-
- /*
- * Remove the ECB from whatever queue it's on.
- */
- switch (ecb->flags & ECB_QBITS) {
- case ECB_QNONE:
- if (ecb != sc->sc_nexus) {
- panic("%s: floating ecb", sc->sc_dev.dv_xname);
- }
- sc->sc_nexus = NULL;
- sc->sc_state = ESP_IDLE;
- ti->lubusy &= ~(1<<sc_link->lun);
- esp_sched(sc);
- break;
- case ECB_QREADY:
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- break;
- case ECB_QNEXUS:
- TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
- ti->lubusy &= ~(1<<sc_link->lun);
- break;
- case ECB_QFREE:
- panic("%s: dequeue: busy ecb on free list",
- sc->sc_dev.dv_xname);
- break;
- default:
- panic("%s: dequeue: unknown queue %d",
- sc->sc_dev.dv_xname, ecb->flags & ECB_QBITS);
- }
-
- /* Put it on the free list, and clear flags. */
- TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
- ecb->flags = ECB_QFREE;
-
- ti->cmds++;
- scsi_done(xs);
- return;
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/*
- * Schedule an outgoing message by prioritizing it, and asserting
- * attention on the bus. We can only do this when we are the initiator
- * else there will be an illegal command interrupt.
- */
-#define esp_sched_msgout(m) \
- do { \
- ESP_MISC(("esp_sched_msgout %d ", m)); \
- ESPCMD(sc, ESPCMD_SETATN); \
- sc->sc_msgpriq |= (m); \
- } while (0)
-
-#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 1)
-
-/*
- * Get an incoming message as initiator.
- *
- * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
- * byte in the FIFO
- */
void
-esp_msgin(sc)
- register struct esp_softc *sc;
+esp_dma_stop(sc)
+ struct ncr53c9x_softc *sc;
{
- register int v;
-
- ESP_TRACE(("[esp_msgin(curmsglen:%d)] ", sc->sc_imlen));
-
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) == 0) {
- printf("%s: msgin: no msg byte available\n",
- sc->sc_dev.dv_xname);
- return;
- }
-
- /*
- * Prepare for a new message. A message should (according
- * to the SCSI standard) be transmitted in one single
- * MESSAGE_IN_PHASE. If we have been in some other phase,
- * then this is a new message.
- */
- if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
- }
-
- v = ESP_READ_REG(sc, ESP_FIFO);
- ESP_MISC(("<msgbyte:0x%02x>", v));
-
-#if 0
- if (sc->sc_state == ESP_RESELECTED && sc->sc_imlen == 0) {
- /*
- * Which target is reselecting us? (The ID bit really)
- */
- sc->sc_selid = v;
- sc->sc_selid &= ~(1<<sc->sc_id);
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- return;
- }
-#endif
-
- sc->sc_imess[sc->sc_imlen] = v;
-
- /*
- * If we're going to reject the message, don't bother storing
- * the incoming bytes. But still, we need to ACK them.
- */
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if ((sc->sc_flags & ESP_DROP_MSGI)) {
- ESPCMD(sc, ESPCMD_SETATN);
- ESPCMD(sc, ESPCMD_MSGOK);
- printf("<dropping msg byte %x>",
- sc->sc_imess[sc->sc_imlen]);
- return;
- }
-
- if (sc->sc_imlen >= ESP_MAX_MSG_LEN) {
- esp_sched_msgout(SEND_REJECT);
- sc->sc_flags |= ESP_DROP_MSGI;
- } else {
- sc->sc_imlen++;
- /*
- * This testing is suboptimal, but most
- * messages will be of the one byte variety, so
- * it should not effect performance
- * significantly.
- */
- if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
- sc->sc_imlen == sc->sc_imess[1] + 2)
- goto gotit;
- }
- /* Ack what we have so far */
- ESPCMD(sc, ESPCMD_MSGOK);
- return;
-
-gotit:
- ESP_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
- /*
- * Now we should have a complete message (1 byte, 2 byte
- * and moderately long extended messages). We only handle
- * extended messages which total length is shorter than
- * ESP_MAX_MSG_LEN. Longer messages will be amputated.
- */
- if (sc->sc_state == ESP_HASNEXUS) {
- struct ecb *ecb = sc->sc_nexus;
- struct esp_tinfo *ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-
- switch (sc->sc_imess[0]) {
- case MSG_CMDCOMPLETE:
- ESP_MSGS(("cmdcomplete "));
- if (sc->sc_dleft < 0) {
- struct scsi_link *sc_link = ecb->xs->sc_link;
- printf("esp: %d extra bytes from %d:%d\n",
- -sc->sc_dleft,
- sc_link->target, sc_link->lun);
- sc->sc_dleft = 0;
- }
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- sc->sc_flags |= ESP_BUSFREE_OK;
- break;
-
- case MSG_MESSAGE_REJECT:
- if (esp_debug & ESP_SHOWMSGS)
- printf("%s: our msg rejected by target\n",
- sc->sc_dev.dv_xname);
-#if 1 /* XXX - must remember last message */
-sc_print_addr(ecb->xs->sc_link); printf("MSG_MESSAGE_REJECT>>");
-#endif
- if (sc->sc_flags & ESP_SYNCHNEGO) {
- ti->period = ti->offset = 0;
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ti->flags &= ~T_NEGOTIATE;
- }
- /* Not all targets understand INITIATOR_DETECTED_ERR */
- if (sc->sc_msgout == SEND_INIT_DET_ERR)
- esp_sched_msgout(SEND_ABORT);
- break;
- case MSG_NOOP:
- ESP_MSGS(("noop "));
- break;
- case MSG_DISCONNECT:
- ESP_MSGS(("disconnect "));
- ti->dconns++;
- sc->sc_flags |= ESP_DISCON;
- sc->sc_flags |= ESP_BUSFREE_OK;
- if ((ecb->xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
- break;
- /*FALLTHROUGH*/
- case MSG_SAVEDATAPOINTER:
- ESP_MSGS(("save datapointer "));
- ecb->dleft = sc->sc_dleft;
- ecb->daddr = sc->sc_dp;
- break;
- case MSG_RESTOREPOINTERS:
- ESP_MSGS(("restore datapointer "));
- if (!ecb) {
- esp_sched_msgout(SEND_ABORT);
- printf("%s: no DATAPOINTERs to restore\n",
- sc->sc_dev.dv_xname);
- break;
- }
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- break;
- case MSG_PARITY_ERROR:
- printf("%s:target%d: MSG_PARITY_ERROR\n",
- sc->sc_dev.dv_xname,
- ecb->xs->sc_link->target);
- break;
- case MSG_EXTENDED:
- ESP_MSGS(("extended(%x) ", sc->sc_imess[2]));
- switch (sc->sc_imess[2]) {
- case MSG_EXT_SDTR:
- ESP_MSGS(("SDTR period %d, offset %d ",
- sc->sc_imess[3], sc->sc_imess[4]));
- ti->period = sc->sc_imess[3];
- ti->offset = sc->sc_imess[4];
- if (sc->sc_minsync == 0) {
- /* We won't do synch */
- ti->offset = 0;
- esp_sched_msgout(SEND_SDTR);
- } else if (ti->offset == 0) {
- printf("%s:%d: async\n", "esp",
- ecb->xs->sc_link->target);
- ti->offset = 0;
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- } else if (ti->period > 124) {
- printf("%s:%d: async\n", "esp",
- ecb->xs->sc_link->target);
- ti->offset = 0;
- esp_sched_msgout(SEND_SDTR);
- } else {
- int r = 250/ti->period;
- int s = (100*250)/ti->period - 100*r;
- int p;
- p = esp_stp2cpb(sc, ti->period);
- ti->period = esp_cpb2stp(sc, p);
-#ifdef ESP_DEBUG
- sc_print_addr(ecb->xs->sc_link);
-#endif
- if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
- /* Target initiated negotiation */
- if (ti->flags & T_SYNCMODE) {
- ti->flags &= ~T_SYNCMODE;
-#ifdef ESP_DEBUG
- printf("renegotiated ");
-#endif
- }
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- 0);
- /* Clamp to our maxima */
- if (ti->period < sc->sc_minsync)
- ti->period = sc->sc_minsync;
- if (ti->offset > 15)
- ti->offset = 15;
- esp_sched_msgout(SEND_SDTR);
- } else {
- /* we are sync */
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- p);
- ti->flags |= T_SYNCMODE;
- }
-#ifdef ESP_DEBUG
- printf("max sync rate %d.%02dMb/s\n",
- r, s);
-#endif
- }
- ti->flags &= ~T_NEGOTIATE;
- break;
- default: /* Extended messages we don't handle */
- ESPCMD(sc, ESPCMD_SETATN);
- break;
- }
- break;
- default:
- ESP_MSGS(("ident "));
- /* thanks for that ident... */
- if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
- ESP_MISC(("unknown "));
-printf("%s: unimplemented message: %d\n", sc->sc_dev.dv_xname, sc->sc_imess[0]);
- ESPCMD(sc, ESPCMD_SETATN);
- }
- break;
- }
- } else if (sc->sc_state == ESP_RESELECTED) {
- struct scsi_link *sc_link = NULL;
- struct ecb *ecb;
- struct esp_tinfo *ti;
- u_char lunit;
-
- if (MSG_ISIDENTIFY(sc->sc_imess[0])) { /* Identify? */
- ESP_MISC(("searching "));
- /*
- * Search wait queue for disconnected cmd
- * The list should be short, so I haven't bothered with
- * any more sophisticated structures than a simple
- * singly linked list.
- */
- lunit = sc->sc_imess[0] & 0x07;
- for (ecb = sc->nexus_list.tqh_first; ecb;
- ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- if (sc_link->lun == lunit &&
- sc->sc_selid == (1<<sc_link->target)) {
- TAILQ_REMOVE(&sc->nexus_list, ecb,
- chain);
- ECB_SETQ(ecb, ECB_QNONE);
- break;
- }
- }
-
- if (!ecb) { /* Invalid reselection! */
- esp_sched_msgout(SEND_ABORT);
- printf("esp: invalid reselect (idbit=0x%2x)\n",
- sc->sc_selid);
- } else { /* Reestablish nexus */
- /*
- * Setup driver data structures and
- * do an implicit RESTORE POINTERS
- */
- ti = &sc->sc_tinfo[sc_link->target];
- sc->sc_nexus = ecb;
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- sc->sc_tinfo[sc_link->target].lubusy
- |= (1<<sc_link->lun);
- if (ti->flags & T_SYNCMODE) {
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- esp_stp2cpb(sc, ti->period));
- } else {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
- }
- ESP_MISC(("... found ecb"));
- sc->sc_state = ESP_HASNEXUS;
- }
- } else {
- printf("%s: bogus reselect (no IDENTIFY) %0x2x\n",
- sc->sc_dev.dv_xname, sc->sc_selid);
- esp_sched_msgout(SEND_DEV_RESET);
- }
- } else { /* Neither ESP_HASNEXUS nor ESP_RESELECTED! */
- printf("%s: unexpected message in; will send DEV_RESET\n",
- sc->sc_dev.dv_xname);
- esp_sched_msgout(SEND_DEV_RESET);
- }
-
- /* Ack last message byte */
- ESPCMD(sc, ESPCMD_MSGOK);
-
- /* Done, reset message pointer. */
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
+ DMACSR(esc->sc_dma) &= ~D_EN_DMA;
}
-
-/*
- * Send the highest priority, scheduled message
- */
-void
-esp_msgout(sc)
- register struct esp_softc *sc;
-{
- struct esp_tinfo *ti;
- struct ecb *ecb;
- size_t size;
-
- ESP_TRACE(("[esp_msgout(priq:%x, prevphase:%x)]", sc->sc_msgpriq, sc->sc_prevphase));
-
- if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
- /* Pick up highest priority message */
- sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
- sc->sc_omlen = 1; /* "Default" message len */
- switch (sc->sc_msgout) {
- case SEND_SDTR:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- sc->sc_omess[0] = MSG_EXTENDED;
- sc->sc_omess[1] = 3;
- sc->sc_omess[2] = MSG_EXT_SDTR;
- sc->sc_omess[3] = ti->period;
- sc->sc_omess[4] = ti->offset;
- sc->sc_omlen = 5;
- break;
- case SEND_IDENTIFY:
- if (sc->sc_state != ESP_HASNEXUS) {
- printf("esp at line %d: no nexus", __LINE__);
- }
- ecb = sc->sc_nexus;
- sc->sc_omess[0] = MSG_IDENTIFY(ecb->xs->sc_link->lun,0);
- break;
- case SEND_DEV_RESET:
- sc->sc_omess[0] = MSG_BUS_DEV_RESET;
- sc->sc_flags |= ESP_BUSFREE_OK;
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- ti->flags &= ~T_SYNCMODE;
- ti->flags |= T_NEGOTIATE;
- break;
- case SEND_PARITY_ERROR:
- sc->sc_omess[0] = MSG_PARITY_ERROR;
- break;
- case SEND_ABORT:
- sc->sc_omess[0] = MSG_ABORT;
- sc->sc_flags |= ESP_BUSFREE_OK;
- break;
- case SEND_INIT_DET_ERR:
- sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
- break;
- case SEND_REJECT:
- sc->sc_omess[0] = MSG_MESSAGE_REJECT;
- break;
- default:
- sc->sc_omess[0] = MSG_NOOP;
- break;
- }
- sc->sc_omp = sc->sc_omess;
- }
-
-#if 1
- /* (re)send the message */
- size = min(sc->sc_omlen, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_omp, &sc->sc_omlen, 0, &size);
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
- ESPCMD(sc, (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
-#else
- { int i;
- ESPCMD(sc, ESPCMD_FLUSH);
- for (i = 0; i < sc->sc_omlen; i++)
- ESP_WRITE_REG(sc, FIFO, sc->sc_omess[i]);
- ESPCMD(sc, ESPCMD_TRANS);
-#if test_stuck_on_msgout
-printf("<<XXXmsgoutdoneXXX>>");
-#endif
- }
-#endif
-}
-
-/*
- * This is the most critical part of the driver, and has to know
- * how to deal with *all* error conditions and phases from the SCSI
- * bus. If there are no errors and the DMA was active, then call the
- * DMA pseudo-interrupt handler. If this returns 1, then that was it
- * and we can return from here without further processing.
- *
- * Most of this needs verifying.
- */
int
-espintr(sc)
- register struct esp_softc *sc;
+esp_dma_isactive(sc)
+ struct ncr53c9x_softc *sc;
{
- register struct ecb *ecb;
- register struct scsi_link *sc_link;
- struct esp_tinfo *ti;
- int loop;
- size_t size;
-
- ESP_TRACE(("[espintr]"));
-
- /*
- * I have made some (maybe seriously flawed) assumptions here,
- * but basic testing (uncomment the printf() below), show that
- * certainly something happens when this loop is here.
- *
- * The idea is that many of the SCSI operations take very little
- * time, and going away and getting interrupted is too high an
- * overhead to pay. For example, selecting, sending a message
- * and command and then doing some work can be done in one "pass".
- *
- * The DELAY is not variable because I do not understand that the
- * DELAY loop should be fixed-time regardless of CPU speed, but
- * I am *assuming* that the faster SCSI processors get things done
- * quicker (sending a command byte etc), and so there is no
- * need to be too slow.
- *
- * This is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
- * at 40Mhz. This needs testing.
- */
- for (loop = 0; 1;loop++, DELAY(50/sc->sc_freq)) {
- /* a feeling of deja-vu */
- if (!DMA_ISINTR(sc->sc_dma))
- return (loop != 0);
-#if 0
- if (loop)
- printf("*");
-#endif
-
- /* and what do the registers say... */
- espreadregs(sc);
-
- sc->sc_intrcnt.ev_count++;
-
- /*
- * At the moment, only a SCSI Bus Reset or Illegal
- * Command are classed as errors. A disconnect is a
- * valid condition, and we let the code check is the
- * "ESP_BUSFREE_OK" flag was set before declaring it
- * and error.
- *
- * Also, the status register tells us about "Gross
- * Errors" and "Parity errors". Only the Gross Error
- * is really bad, and the parity errors are dealt
- * with later
- *
- * TODO
- * If there are too many parity error, go to slow
- * cable mode ?
- */
-
- /* SCSI Reset */
- if (sc->sc_espintr & ESPINTR_SBR) {
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state != ESP_SBR) {
- printf("%s: SCSI bus reset\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 0); /* Restart everything */
- return 1;
- }
-#if 0
- /*XXX*/ printf("<expected bus reset: "
- "[intr %x, stat %x, step %d]>\n",
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
-#endif
- if (sc->sc_nexus)
- panic("%s: nexus in reset state",
- sc->sc_dev.dv_xname);
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- return 1;
- }
-
- ecb = sc->sc_nexus;
-
-#define ESPINTR_ERR (ESPINTR_SBR|ESPINTR_ILL)
- if (sc->sc_espintr & ESPINTR_ERR ||
- sc->sc_espstat & ESPSTAT_GE) {
-
- if (sc->sc_espstat & ESPSTAT_GE) {
- /* no target ? */
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state == ESP_HASNEXUS ||
- sc->sc_state == ESP_SELECTING) {
- ecb->xs->error = XS_DRIVER_STUFFUP;
- esp_done(ecb);
- }
- return 1;
- }
-
- if (sc->sc_espintr & ESPINTR_ILL) {
- /* illegal command, out of sync ? */
- printf("%s: illegal command: 0x%x (state %d, phase %x, prevphase %x)\n",
- sc->sc_dev.dv_xname, sc->sc_lastcmd,
- sc->sc_state, sc->sc_phase,
- sc->sc_prevphase);
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- esp_init(sc, 0); /* Restart everything */
- return 1;
- }
- }
-
- /*
- * Call if DMA is active.
- *
- * If DMA_INTR returns true, then maybe go 'round the loop
- * again in case there is no more DMA queued, but a phase
- * change is expected.
- */
- if (DMA_ISACTIVE(sc->sc_dma)) {
- DMA_INTR(sc->sc_dma);
- /* If DMA active here, then go back to work... */
- if (DMA_ISACTIVE(sc->sc_dma))
- return 1;
-
- if (sc->sc_dleft == 0 &&
- (sc->sc_espstat & ESPSTAT_TC) == 0)
- printf("%s: !TC [intr %x, stat %x, step %d]"
- " prevphase %x, resid %x\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase,
- ecb?ecb->dleft:-1);
- }
-
-#if 0 /* Unreliable on some ESP revisions? */
- if ((sc->sc_espstat & ESPSTAT_INT) == 0) {
- printf("%s: spurious interrupt\n", sc->sc_dev.dv_xname);
- return 1;
- }
-#endif
-
- /*
- * check for less serious errors
- */
- if (sc->sc_espstat & ESPSTAT_PE) {
- printf("%s: SCSI bus parity error\n",
- sc->sc_dev.dv_xname);
- if (sc->sc_prevphase == MESSAGE_IN_PHASE)
- esp_sched_msgout(SEND_PARITY_ERROR);
- else
- esp_sched_msgout(SEND_INIT_DET_ERR);
- }
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if (sc->sc_espintr & ESPINTR_DIS) {
- ESP_MISC(("<DISC [intr %x, stat %x, step %d]>",
- sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /*
- * This command must (apparently) be issued within
- * 250mS of a disconnect. So here you are...
- */
- ESPCMD(sc, ESPCMD_ENSEL);
- if (sc->sc_state != ESP_IDLE) {
- if ((sc->sc_flags & ESP_SYNCHNEGO)) {
-#ifdef ESP_DEBUG
- if (ecb)
- sc_print_addr(ecb->xs->sc_link);
- printf("sync nego not completed!\n");
-#endif
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- sc->sc_tinfo[ecb->xs->sc_link->target].offset = 0;
- sc->sc_tinfo[ecb->xs->sc_link->target].flags &= ~T_NEGOTIATE;
- }
- /*XXX*/sc->sc_msgpriq = sc->sc_msgout = 0;
-
- /* it may be OK to disconnect */
- if (!(sc->sc_flags & ESP_BUSFREE_OK)) {
- if (sc->sc_state == ESP_HASNEXUS) {
- sc_print_addr(ecb->xs->sc_link);
- printf("disconnect without"
- "warning\n");
- }
- ecb->xs->error = XS_TIMEOUT;
- } else if (sc->sc_flags & ESP_DISCON) {
- TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNEXUS);
- sc->sc_nexus = NULL;
- sc->sc_flags &= ~ESP_DISCON;
- sc->sc_state = ESP_IDLE;
-#if ESP_DEBUG
-if ((esp_debug & 0x10000) && ecb->dleft == 0) {
- printf("%s: silly disconnect (ecb %p [stat %x])\n",
- sc->sc_dev.dv_xname, ecb, ecb->stat);
-}
-#endif
- esp_sched(sc);
- return 1;
- }
-
- esp_done(ecb);
- return 1;
- }
- printf("%s: DISCONNECT in IDLE state!\n",
- sc->sc_dev.dv_xname);
- }
-
- /* did a message go out OK ? This must be broken */
- if (sc->sc_prevphase == MESSAGE_OUT_PHASE &&
- sc->sc_phase != MESSAGE_OUT_PHASE) {
- /* we have sent it */
- if (sc->sc_msgout == SEND_SDTR &&
- (sc->sc_flags & ESP_SYNCHNEGO) == 0) {
- /* We've just accepted new sync parameters */
- sc->sc_tinfo[ecb->xs->sc_link->target].flags |=
- T_SYNCMODE;
-if (ecb) sc_print_addr(ecb->xs->sc_link);else printf("NO nexus: ");
-printf("target put in SYNC mode\n");
- }
- sc->sc_msgpriq &= ~sc->sc_msgout;
- sc->sc_msgout = 0;
- }
-
- switch (sc->sc_state) {
-
- case ESP_SBR:
- printf("%s: waiting for SCSI Bus Reset to happen\n",
- sc->sc_dev.dv_xname);
- return 1;
-
- case ESP_RESELECTED:
- /*
- * we must be continuing a message ?
- */
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
-printf("<<RESELECT CONT'd>>");
-#if XXXX
- esp_msgin(sc);
- if (sc->sc_state != ESP_HASNEXUS) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
-#endif
- break;
-
- case ESP_IDLE:
-if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
- case ESP_SELECTING:
-
- if (sc->sc_espintr & ESPINTR_RESEL) {
- /*
- * If we're trying to select a
- * target ourselves, push our command
- * back into the ready list.
- */
- if (sc->sc_state == ESP_SELECTING) {
- ESP_MISC(("backoff selector "));
- sc_link = sc->sc_nexus->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
- TAILQ_INSERT_HEAD(&sc->ready_list,
- sc->sc_nexus, chain);
- ECB_SETQ(sc->sc_nexus, ECB_QREADY);
- ti->lubusy &= ~(1<<sc_link->lun);
- ecb = sc->sc_nexus = NULL;
- }
- sc->sc_state = ESP_RESELECTED;
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- /*
- * Things are seriously fucked up.
- * Pull the brakes, i.e. reset
- */
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- printf("%s: RESELECT: %d bytes in FIFO!\n",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) &
- ESPFIFO_FF);
- esp_init(sc, 1);
- return 1;
- }
- sc->sc_selid = ESP_READ_REG(sc, ESP_FIFO);
- sc->sc_selid &= ~(1<<sc->sc_id);
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- esp_msgin(sc); /* Handle identify message */
- if (sc->sc_state != ESP_HASNEXUS) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
- continue; /* ie. next phase expected soon */
- }
-
-#define ESPINTR_DONE (ESPINTR_FC|ESPINTR_BS)
- if ((sc->sc_espintr & ESPINTR_DONE) == ESPINTR_DONE) {
- ecb = sc->sc_nexus;
- if (!ecb)
- panic("esp: not nexus at sc->sc_nexus");
-
- sc_link = ecb->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
-
- switch (sc->sc_espstep) {
- case 0:
- printf("%s: select timeout/no disconnect\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- case 1:
- if ((ti->flags & T_NEGOTIATE) == 0) {
- printf("%s: step 1 & !NEG\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- }
- if (sc->sc_phase != MESSAGE_OUT_PHASE) {
- printf("%s: !MSGOUT\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- }
- /* Start negotiating */
- ti->period = sc->sc_minsync;
- ti->offset = 15;
- sc->sc_msgpriq = SEND_SDTR;
- sc->sc_flags |= ESP_SYNCHNEGO;
- break;
- case 3:
- /*
- * Grr, this is supposed to mean
- * "target left command phase
- * prematurely". It seems to happen
- * regularly when sync mode is on.
- * Look at FIFO to see if command
- * went out.
- * (Timing problems?)
- */
- if ((ESP_READ_REG(sc, ESP_FFLAG)&ESPFIFO_FF) == 0) {
- /* Hope for the best.. */
- break;
- }
- printf("(%s:%d:%d): selection failed;"
- " %d left in FIFO "
- "[intr %x, stat %x, step %d]\n",
- sc->sc_dev.dv_xname,
- sc_link->target,
- sc_link->lun,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- sc->sc_flags |= ESP_ABORTING;
- esp_sched_msgout(SEND_ABORT);
- return 1;
- case 2:
- /* Select stuck at Command Phase */
- ESPCMD(sc, ESPCMD_FLUSH);
- case 4:
- /* So far, everything went fine */
- sc->sc_msgpriq = 0;
- break;
- }
-#if 0
-/* Why set msgpriq? (and not raise ATN) */
- if (ecb->xs->flags & SCSI_RESET)
- sc->sc_msgpriq = SEND_DEV_RESET;
- else if (ti->flags & T_NEGOTIATE)
- sc->sc_msgpriq =
- SEND_IDENTIFY | SEND_SDTR;
- else
- sc->sc_msgpriq = SEND_IDENTIFY;
-#endif
- sc->sc_state = ESP_HASNEXUS;
- /*???sc->sc_flags = 0; */
- sc->sc_prevphase = INVALID_PHASE; /* ?? */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- ti->lubusy |= (1<<sc_link->lun);
- break;
- } else {
- printf("%s: unexpected status after select"
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- esp_abort(sc, ecb);
- }
- if (sc->sc_state == ESP_IDLE) {
- printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
- return 0;
- }
- break;
-
- case ESP_HASNEXUS:
- if (sc->sc_flags & ESP_ICCS) {
- unsigned char msg;
-
- sc->sc_flags &= ~ESP_ICCS;
-
- if (!(sc->sc_espintr & ESPINTR_DONE)) {
- printf("%s: ICCS: "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- printf("%s: ICCS: expected 2, got %d "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- esp_abort(sc, ecb);
- return 1;
- }
- ecb->stat = ESP_READ_REG(sc, ESP_FIFO);
- msg = ESP_READ_REG(sc, ESP_FIFO);
- ESP_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
- if (msg == MSG_CMDCOMPLETE) {
- sc->sc_flags |= ESP_BUSFREE_OK;
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- } else
- printf("%s: STATUS_PHASE: msg %d\n",
- sc->sc_dev.dv_xname, msg);
- ESPCMD(sc, ESPCMD_MSGOK);
- continue; /* ie. wait for disconnect */
- }
- break;
- default:
- panic("%s: invalid state: %d",
- sc->sc_dev.dv_xname,
- sc->sc_state);
- }
-
- /*
- * Driver is now in state ESP_HASNEXUS, i.e. we
- * have a current command working the SCSI bus.
- */
- if (sc->sc_state != ESP_HASNEXUS || ecb == NULL) {
- panic("esp no nexus");
- }
-
- switch (sc->sc_phase) {
- case MESSAGE_OUT_PHASE:
- ESP_PHASE(("MESSAGE_OUT_PHASE "));
- esp_msgout(sc);
- sc->sc_prevphase = MESSAGE_OUT_PHASE;
- break;
- case MESSAGE_IN_PHASE:
- ESP_PHASE(("MESSAGE_IN_PHASE "));
- if (sc->sc_espintr & ESPINTR_BS) {
- ESPCMD(sc, ESPCMD_FLUSH);
- sc->sc_flags |= ESP_WAITI;
- ESPCMD(sc, ESPCMD_TRANS);
- } else if (sc->sc_espintr & ESPINTR_FC) {
- if ((sc->sc_flags & ESP_WAITI) == 0) {
- printf("%s: MSGIN: unexpected FC bit: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_flags &= ~ESP_WAITI;
- esp_msgin(sc);
- } else {
- printf("%s: MSGIN: weird bits: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_prevphase = MESSAGE_IN_PHASE;
- break;
- case COMMAND_PHASE: {
- /* well, this means send the command again */
- u_char *cmd = (u_char *)&ecb->cmd;
- int i;
-
- ESP_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
- ecb->cmd.opcode, ecb->clen));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /* Now the command into the FIFO */
- for (i = 0; i < ecb->clen; i++)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
- ESPCMD(sc, ESPCMD_TRANS);
- sc->sc_prevphase = COMMAND_PHASE;
- }
- break;
- case DATA_OUT_PHASE:
- ESP_PHASE(("DATA_OUT_PHASE [%d] ", sc->sc_dleft));
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 0, &size);
- sc->sc_prevphase = DATA_OUT_PHASE;
- goto setup_xfer;
- case DATA_IN_PHASE:
- ESP_PHASE(("DATA_IN_PHASE "));
- if (sc->sc_rev == ESP100)
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 1, &size);
- sc->sc_prevphase = DATA_IN_PHASE;
- setup_xfer:
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
-
- /*
- * Note that if `size' is 0, we've already transceived
- * all the bytes we want but we're still in DATA PHASE.
- * Apparently, the device needs padding. Also, a
- * transfer size of 0 means "maximum" to the chip
- * DMA logic.
- */
- ESPCMD(sc,
- (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
- return 1;
- case STATUS_PHASE:
- ESP_PHASE(("STATUS_PHASE "));
- sc->sc_flags |= ESP_ICCS;
- ESPCMD(sc, ESPCMD_ICCS);
- sc->sc_prevphase = STATUS_PHASE;
- break;
- case INVALID_PHASE:
- break;
- case BUSFREE_PHASE:
- if (sc->sc_flags & ESP_BUSFREE_OK) {
- /*It's fun the 1st time.. */
- sc->sc_flags &= ~ESP_BUSFREE_OK;
- }
- break;
- default:
- panic("esp: bogus bus phase\n");
- }
- }
- panic("esp: should not get here..");
-}
-
-void
-esp_abort(sc, ecb)
- struct esp_softc *sc;
- struct ecb *ecb;
-{
- if (ecb == sc->sc_nexus) {
- if (sc->sc_state == ESP_HASNEXUS) {
- sc->sc_flags |= ESP_ABORTING;
- esp_sched_msgout(SEND_ABORT);
- }
- } else {
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
- }
-}
-
-void
-esp_timeout(arg)
- void *arg;
-{
- int s = splbio();
- struct ecb *ecb = (struct ecb *)arg;
- struct esp_softc *sc;
- struct scsi_xfer *xs = ecb->xs;
-
- sc = xs->sc_link->adapter_softc;
- sc_print_addr(xs->sc_link);
-again:
- printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
- "<state %d, nexus %p, phase(c %x, p %x), resid %x, msg(q %x,o %x) %s>",
- sc->sc_dev.dv_xname,
- ecb, ecb->flags, ecb->dleft, ecb->stat,
- sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
- sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
- DMA_ISACTIVE(sc->sc_dma) ? "DMA active" : "");
-#if ESP_DEBUG > 0
- printf("TRACE: %s.", ecb->trace);
-#endif
-
- if (ecb->flags & ECB_ABORTED) {
- /* abort timed out */
- printf(" AGAIN\n");
- esp_init(sc, 1);
- } else {
- /* abort the operation that has timed out */
- printf("\n");
- xs->error = XS_TIMEOUT;
- ecb->flags |= ECB_ABORTED;
- esp_abort(sc, ecb);
- /* 2 secs for the abort */
- if ((xs->flags & SCSI_POLL) == 0)
- timeout(esp_timeout, ecb, 2 * hz);
- else {
- int count = 200000;
- while (count) {
- if (DMA_ISINTR(sc->sc_dma)) {
- espintr(sc);
- }
- if (xs->flags & ITSDONE)
- break;
- DELAY(10);
- --count;
- }
- if (count == 0)
- goto again;
- }
- }
- splx(s);
+ return (DMA_ISACTIVE(esc->sc_dma));
}
diff --git a/sys/arch/sparc/dev/espreg.h b/sys/arch/sparc/dev/espreg.h
deleted file mode 100644
index e08eebcad7c..00000000000
--- a/sys/arch/sparc/dev/espreg.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* $NetBSD: espreg.h,v 1.7 1995/12/18 23:58:39 pk Exp $ */
-
-/*
- * Copyright (c) 1994 Peter Galbavy. 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 Peter Galbavy.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Register addresses, relative to some base address
- */
-
-#define ESP_TCL 0x00 /* RW - Transfer Count Low */
-#define ESP_TCM 0x01 /* RW - Transfer Count Mid */
-#define ESP_TCH 0x0e /* RW - Transfer Count High */
- /* NOT on 53C90 */
-
-#define ESP_FIFO 0x02 /* RW - FIFO data */
-
-#define ESP_CMD 0x03 /* RW - Command (2 deep) */
-#define ESPCMD_DMA 0x80 /* DMA Bit */
-#define ESPCMD_NOP 0x00 /* No Operation */
-#define ESPCMD_FLUSH 0x01 /* Flush FIFO */
-#define ESPCMD_RSTCHIP 0x02 /* Reset Chip */
-#define ESPCMD_RSTSCSI 0x03 /* Reset SCSI Bus */
-#define ESPCMD_RESEL 0x40 /* Reselect Sequence */
-#define ESPCMD_SELNATN 0x41 /* Select without ATN */
-#define ESPCMD_SELATN 0x42 /* Select with ATN */
-#define ESPCMD_SELATNS 0x43 /* Select with ATN & Stop */
-#define ESPCMD_ENSEL 0x44 /* Enable (Re)Selection */
-#define ESPCMD_DISSEL 0x45 /* Disable (Re)Selection */
-#define ESPCMD_SELATN3 0x46 /* Select with ATN3 */
-#define ESPCMD_RESEL3 0x47 /* Reselect3 Sequence */
-#define ESPCMD_SNDMSG 0x20 /* Send Message */
-#define ESPCMD_SNDSTAT 0x21 /* Send Status */
-#define ESPCMD_SNDDATA 0x22 /* Send Data */
-#define ESPCMD_DISCSEQ 0x23 /* Disconnect Sequence */
-#define ESPCMD_TERMSEQ 0x24 /* Terminate Sequence */
-#define ESPCMD_TCCS 0x25 /* Target Command Comp Seq */
-#define ESPCMD_DISC 0x27 /* Disconnect */
-#define ESPCMD_RECMSG 0x28 /* Receive Message */
-#define ESPCMD_RECCMD 0x29 /* Receive Command */
-#define ESPCMD_RECDATA 0x2a /* Receive Data */
-#define ESPCMD_RECCSEQ 0x2b /* Receive Command Sequence*/
-#define ESPCMD_ABORT 0x04 /* Target Abort DMA */
-#define ESPCMD_TRANS 0x10 /* Transfer Information */
-#define ESPCMD_ICCS 0x11 /* Initiator Cmd Comp Seq */
-#define ESPCMD_MSGOK 0x12 /* Message Accepted */
-#define ESPCMD_TRPAD 0x18 /* Transfer Pad */
-#define ESPCMD_SETATN 0x1a /* Set ATN */
-#define ESPCMD_RSTATN 0x1b /* Reset ATN */
-
-#define ESP_STAT 0x04 /* RO - Status */
-#define ESPSTAT_INT 0x80 /* Interrupt */
-#define ESPSTAT_GE 0x40 /* Gross Error */
-#define ESPSTAT_PE 0x20 /* Parity Error */
-#define ESPSTAT_TC 0x10 /* Terminal Count */
-#define ESPSTAT_VGC 0x08 /* Valid Group Code */
-#define ESPSTAT_PHASE 0x07 /* Phase bits */
-
-#define ESP_SELID 0x04 /* WO - Select/Reselect Bus ID */
-
-#define ESP_INTR 0x05 /* RO - Interrupt */
-#define ESPINTR_SBR 0x80 /* SCSI Bus Reset */
-#define ESPINTR_ILL 0x40 /* Illegal Command */
-#define ESPINTR_DIS 0x20 /* Disconnect */
-#define ESPINTR_BS 0x10 /* Bus Service */
-#define ESPINTR_FC 0x08 /* Function Complete */
-#define ESPINTR_RESEL 0x04 /* Reselected */
-#define ESPINTR_SELATN 0x02 /* Select with ATN */
-#define ESPINTR_SEL 0x01 /* Selected */
-
-#define ESP_TIMEOUT 0x05 /* WO - Select/Reselect Timeout */
-
-#define ESP_STEP 0x06 /* RO - Sequence Step */
-#define ESPSTEP_MASK 0x07 /* the last 3 bits */
-#define ESPSTEP_DONE 0x04 /* command went out */
-
-#define ESP_SYNCTP 0x06 /* WO - Synch Transfer Period */
- /* Default 5 (53C9X) */
-
-#define ESP_FFLAG 0x07 /* RO - FIFO Flags */
-#define ESPFIFO_SS 0xe0 /* Sequence Step (Dup) */
-#define ESPFIFO_FF 0x1f /* Bytes in FIFO */
-
-#define ESP_SYNCOFF 0x07 /* WO - Synch Offset */
- /* 0 = ASYNC */
- /* 1 - 15 = SYNC bytes */
-
-#define ESP_CFG1 0x08 /* RW - Configuration #1 */
-#define ESPCFG1_SLOW 0x80 /* Slow Cable Mode */
-#define ESPCFG1_SRR 0x40 /* SCSI Reset Rep Int Dis */
-#define ESPCFG1_PTEST 0x20 /* Parity Test Mod */
-#define ESPCFG1_PARENB 0x10 /* Enable Parity Check */
-#define ESPCFG1_CTEST 0x08 /* Enable Chip Test */
-#define ESPCFG1_BUSID 0x07 /* Bus ID */
-
-#define ESP_CCF 0x09 /* WO - Clock Conversion Factor */
- /* 0 = 35.01 - 40Mhz */
- /* NEVER SET TO 1 */
- /* 2 = 10Mhz */
- /* 3 = 10.01 - 15Mhz */
- /* 4 = 15.01 - 20Mhz */
- /* 5 = 20.01 - 25Mhz */
- /* 6 = 25.01 - 30Mhz */
- /* 7 = 30.01 - 35Mhz */
-
-#define ESP_TEST 0x0a /* WO - Test (Chip Test Only) */
-
-#define ESP_CFG2 0x0b /* RW - Configuration #2 */
-#define ESPCFG2_RSVD 0xa0 /* reserved */
-#define ESPCFG2_FE 0x40 /* Features Enable */
-#define ESPCFG2_DREQ 0x10 /* DREQ High Impedance */
-#define ESPCFG2_SCSI2 0x08 /* SCSI-2 Enable */
-#define ESPCFG2_BPA 0x04 /* Target Bad Parity Abort */
-#define ESPCFG2_RPE 0x02 /* Register Parity Error */
-#define ESPCFG2_DPE 0x01 /* DMA Parity Error */
-
-/* Config #3 only on 53C9X */
-#define ESP_CFG3 0x0c /* RW - Configuration #3 */
-#define ESPCFG3_RSVD 0xe0 /* reserved */
-#define ESPCFG3_IDM 0x10 /* ID Message Res Check */
-#define ESPCFG3_QTE 0x08 /* Queue Tag Enable */
-#define ESPCFG3_CDB 0x04 /* CDB 10-bytes OK */
-#define ESPCFG3_FSCSI 0x02 /* Fast SCSI */
-#define ESPCFG3_FCLK 0x01 /* Fast Clock (>25Mhz) */
diff --git a/sys/arch/sparc/dev/espvar.h b/sys/arch/sparc/dev/espvar.h
index 8b0b414a08a..32f81278479 100644
--- a/sys/arch/sparc/dev/espvar.h
+++ b/sys/arch/sparc/dev/espvar.h
@@ -1,7 +1,10 @@
-/* $NetBSD: espvar.h,v 1.13 1996/05/16 20:31:30 pk Exp $ */
+/* $OpenBSD: espvar.h,v 1.5 1997/08/08 08:25:02 downsj Exp $ */
+/* $NetBSD: espvar.h,v 1.19 1997/02/27 01:16:21 thorpej Exp $ */
/*
- * Copyright (c) 1994 Peter Galbavy. All rights reserved.
+ * Copyright (c) 1997 Jason R. Thorpe.
+ * All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +15,8 @@
* 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 Peter Galbavy.
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
@@ -28,273 +32,20 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define ESP_DEBUG 0
-
-#define FREQTOCCF(freq) (((freq + 4) / 5))
-
-/* esp revisions */
-#define ESP100 0x01
-#define ESP100A 0x02
-#define ESP200 0x03
-
-#if 0
-typedef caddr_t physaddr;
-
-struct esp_dma_seg {
- physaddr addr;
- long len;
-};
-#endif
-
-/*
- * ECB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command. Basicly, we refrain from fiddling with
- * the scsi_xfer struct (except do the expected updating of return values).
- * We'll generally update: xs->{flags,resid,error,sense,status} and
- * occasionally xs->retries.
- */
-struct ecb {
- TAILQ_ENTRY(ecb) chain;
- struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
- int flags; /* Status */
-#define ECB_QNONE 0
-#define ECB_QFREE 1
-#define ECB_QREADY 2
-#define ECB_QNEXUS 3
-#define ECB_QBITS 0x07
-#define ECB_CHKSENSE 0x08
-#define ECB_ABORTED 0x10
-#define ECB_SETQ(e, q) do (e)->flags = ((e)->flags&~ECB_QBITS)|(q); while(0)
- struct scsi_generic cmd; /* SCSI command block */
- int clen;
- char *daddr; /* Saved data pointer */
- int dleft; /* Residue */
- u_char stat; /* SCSI status byte */
-#if ESP_DEBUG > 0
- char trace[1000];
-#endif
-};
-#if ESP_DEBUG > 0
-#define ECB_TRACE(ecb, msg, a, b) do { \
- const char *f = "[" msg "]"; \
- int n = strlen((ecb)->trace); \
- if (n < (sizeof((ecb)->trace)-100)) \
- sprintf((ecb)->trace + n, f, a, b); \
-} while(0)
-#else
-#define ECB_TRACE(ecb, msg, a, b)
-#endif
-
-/*
- * Some info about each (possible) target on the SCSI bus. This should
- * probably have been a "per target+lunit" structure, but we'll leave it at
- * this for now. Is there a way to reliably hook it up to sc->fordriver??
- */
-struct esp_tinfo {
- int cmds; /* #commands processed */
- int dconns; /* #disconnects */
- int touts; /* #timeouts */
- int perrs; /* #parity errors */
- int senses; /* #request sense commands sent */
- ushort lubusy; /* What local units/subr. are busy? */
- u_char flags;
-#define T_NEED_TO_RESET 0x01 /* Should send a BUS_DEV_RESET */
-#define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
-#define T_BUSY 0x04 /* Target is busy, i.e. cmd in progress */
-#define T_SYNCMODE 0x08 /* sync mode has been negotiated */
-#define T_SYNCHOFF 0x10 /* .. */
-#define T_RSELECTOFF 0x20 /* .. */
- u_char period; /* Period suggestion */
- u_char offset; /* Offset suggestion */
-} tinfo_t;
-
-/* Register a linenumber (for debugging) */
-#define LOGLINE(p)
-
-#define ESP_SHOWECBS 0x01
-#define ESP_SHOWINTS 0x02
-#define ESP_SHOWCMDS 0x04
-#define ESP_SHOWMISC 0x08
-#define ESP_SHOWTRAC 0x10
-#define ESP_SHOWSTART 0x20
-#define ESP_SHOWPHASE 0x40
-#define ESP_SHOWDMA 0x80
-#define ESP_SHOWCCMDS 0x100
-#define ESP_SHOWMSGS 0x200
-
-#ifdef ESP_DEBUG
-extern int esp_debug;
-#define ESP_ECBS(str) do {if (esp_debug & ESP_SHOWECBS) printf str;} while (0)
-#define ESP_MISC(str) do {if (esp_debug & ESP_SHOWMISC) printf str;} while (0)
-#define ESP_INTS(str) do {if (esp_debug & ESP_SHOWINTS) printf str;} while (0)
-#define ESP_TRACE(str) do {if (esp_debug & ESP_SHOWTRAC) printf str;} while (0)
-#define ESP_CMDS(str) do {if (esp_debug & ESP_SHOWCMDS) printf str;} while (0)
-#define ESP_START(str) do {if (esp_debug & ESP_SHOWSTART) printf str;}while (0)
-#define ESP_PHASE(str) do {if (esp_debug & ESP_SHOWPHASE) printf str;}while (0)
-#define ESP_DMA(str) do {if (esp_debug & ESP_SHOWDMA) printf str;}while (0)
-#define ESP_MSGS(str) do {if (esp_debug & ESP_SHOWMSGS) printf str;}while (0)
-#else
-#define ESP_ECBS(str)
-#define ESP_MISC(str)
-#define ESP_INTS(str)
-#define ESP_TRACE(str)
-#define ESP_CMDS(str)
-#define ESP_START(str)
-#define ESP_PHASE(str)
-#define ESP_DMA(str)
-#endif
-
-#define ESP_MAX_MSG_LEN 8
-
struct esp_softc {
- struct device sc_dev; /* us as a device */
+ struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
+
struct sbusdev sc_sd; /* sbus device */
struct intrhand sc_ih; /* intr handler */
- struct evcnt sc_intrcnt; /* intr count */
- struct scsi_link sc_link; /* scsi lint struct */
+
volatile u_char *sc_reg; /* the registers */
struct dma_softc *sc_dma; /* pointer to my dma */
- /* register defaults */
- u_char sc_cfg1; /* Config 1 */
- u_char sc_cfg2; /* Config 2, not ESP100 */
- u_char sc_cfg3; /* Config 3, only ESP200 */
- u_char sc_ccf; /* Clock Conversion */
- u_char sc_timeout;
-
- /* register copies, see espreadregs() */
- u_char sc_espintr;
- u_char sc_espstat;
- u_char sc_espstep;
- u_char sc_espfflags;
-
- /* Lists of command blocks */
- TAILQ_HEAD(ecb_list, ecb) free_list,
- ready_list,
- nexus_list;
-
- struct ecb *sc_nexus; /* current command */
- struct ecb sc_ecb[8]; /* one per target */
- struct esp_tinfo sc_tinfo[8];
-
- /* Data about the current nexus (updated for every cmd switch) */
- caddr_t sc_dp; /* Current data pointer */
- ssize_t sc_dleft; /* Data left to transfer */
-
- /* Adapter state */
- int sc_phase; /* Copy of what bus phase we are in */
- int sc_prevphase; /* Copy of what bus phase we were in */
- u_char sc_state; /* State applicable to the adapter */
- u_char sc_flags;
- u_char sc_selid;
- u_char sc_lastcmd;
-
- /* Message stuff */
- u_char sc_msgpriq; /* One or more messages to send (encoded) */
- u_char sc_msgout; /* What message is on its way out? */
- u_char sc_omess[ESP_MAX_MSG_LEN];
- caddr_t sc_omp; /* Message pointer (for multibyte messages) */
- size_t sc_omlen;
- u_char sc_imess[ESP_MAX_MSG_LEN + 1];
- caddr_t sc_imp; /* Message pointer (for multibyte messages) */
- size_t sc_imlen;
-
- /* hardware/openprom stuff */
+ /* openprom stuff */
int sc_node; /* PROM node ID */
- int sc_freq; /* Freq in HZ */
int sc_pri; /* SBUS priority */
- int sc_id; /* our scsi id */
- int sc_rev; /* esp revision */
- int sc_minsync; /* minimum sync period / 4 */
- int sc_maxxfer; /* maximum transfer size */
};
-/*
- * Macros to read and write the chip's registers.
- */
-#define ESP_READ_REG(sc, reg) \
- ((sc)->sc_reg[(reg) * 4])
-#define ESP_WRITE_REG(sc, reg, val) \
- do { \
- u_char v = (val); \
- (sc)->sc_reg[(reg) * 4] = v; \
- } while (0)
-
-/* values for sc_state */
-#define ESP_IDLE 0x01 /* waiting for something to do */
-#define ESP_TMP_UNAVAIL 0x02 /* Don't accept SCSI commands */
-#define ESP_SELECTING 0x03 /* SCSI command is arbiting */
-#define ESP_RESELECTED 0x04 /* Has been reselected */
-#define ESP_HASNEXUS 0x05 /* Actively using the SCSI bus */
-#define ESP_CLEANING 0x06
-#define ESP_SBR 0x07 /* Expect a SCSI RST because we commanded it */
-
-/* values for sc_flags */
-#define ESP_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
-#define ESP_DOINGDMA 0x02 /* The FIFO data path is active! */
-#define ESP_BUSFREE_OK 0x04 /* Bus free phase is OK. */
-#define ESP_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
-/*#define ESP_BLOCKED 0x10 * Don't schedule new scsi bus operations */
-#define ESP_DISCON 0x10 /* Target sent DISCONNECT msg */
-#define ESP_ABORTING 0x20 /* Bailing out */
-#define ESP_ICCS 0x40 /* Expect status phase results */
-#define ESP_WAITI 0x80 /* Waiting for non-DMA data to arrive */
-
-/* values for sc_msgout */
-#define SEND_DEV_RESET 0x01
-#define SEND_PARITY_ERROR 0x02
-#define SEND_ABORT 0x04
-#define SEND_REJECT 0x08
-#define SEND_INIT_DET_ERR 0x10
-#define SEND_IDENTIFY 0x20
-#define SEND_SDTR 0x40
-
-/* SCSI Status codes */
-#define ST_GOOD 0x00
-#define ST_CHKCOND 0x02
-#define ST_CONDMET 0x04
-#define ST_BUSY 0x08
-#define ST_INTERMED 0x10
-#define ST_INTERMED_CONDMET 0x14
-#define ST_RESERVATION_CONFLICT 0x18
-#define ST_CMD_TERM 0x22
-#define ST_QUEUE_FULL 0x28
-
-#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
-
-/* phase bits */
-#define IOI 0x01
-#define CDI 0x02
-#define MSGI 0x04
-
-/* Information transfer phases */
-#define DATA_OUT_PHASE (0)
-#define DATA_IN_PHASE (IOI)
-#define COMMAND_PHASE (CDI)
-#define STATUS_PHASE (CDI|IOI)
-#define MESSAGE_OUT_PHASE (MSGI|CDI)
-#define MESSAGE_IN_PHASE (MSGI|CDI|IOI)
-
-#define PHASE_MASK (MSGI|CDI|IOI)
-
-/* Some pseudo phases for getphase()*/
-#define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */
-#define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
-#define PSEUDO_PHASE 0x100 /* "pseudo" bit */
-
-#ifdef ESP_DEBUG
-#define ESPCMD(sc, cmd) do { \
- if (esp_debug & ESP_SHOWCCMDS) \
- printf("<cmd:0x%x>", (unsigned)cmd); \
- sc->sc_lastcmd = cmd; \
- ESP_WRITE_REG(sc, ESP_CMD, cmd); \
-} while (0)
-#else
-#define ESPCMD(sc, cmd) ESP_WRITE_REG(sc, ESP_CMD, cmd)
-#endif
-
#define SAME_ESP(sc, bp, ca) \
((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
(bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
-
diff --git a/sys/arch/sparc/dev/event.c b/sys/arch/sparc/dev/event.c
deleted file mode 100644
index 3e25c91edb4..00000000000
--- a/sys/arch/sparc/dev/event.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $NetBSD: event.c,v 1.3 1994/11/20 20:52:13 deraadt Exp $ */
-
-/*
- * 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
- */
-
-/*
- * 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 <machine/vuid_event.h>
-#include <sparc/dev/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);
-}
diff --git a/sys/arch/sparc/dev/event_var.h b/sys/arch/sparc/dev/event_var.h
deleted file mode 100644
index 8a7b24fec89..00000000000
--- a/sys/arch/sparc/dev/event_var.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* $NetBSD: event_var.h,v 1.2 1994/11/20 20:52:14 deraadt Exp $ */
-
-/*
- * 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
- */
-
-/*
- * 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
diff --git a/sys/arch/sparc/dev/fb.c b/sys/arch/sparc/dev/fb.c
index 37bf3b10be7..5c7e3c70916 100644
--- a/sys/arch/sparc/dev/fb.c
+++ b/sys/arch/sparc/dev/fb.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: fb.c,v 1.9 1996/08/13 08:05:25 downsj Exp $ */
-/* $NetBSD: fb.c,v 1.18 1996/04/01 17:29:54 christos Exp $ */
+/* $OpenBSD: fb.c,v 1.10 1997/08/08 08:25:04 downsj Exp $ */
+/* $NetBSD: fb.c,v 1.23 1997/07/07 23:30:22 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -299,23 +299,23 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype)
break;
}
} else if (eep != NULL) {
- switch (eep->ee_diag.eed_scrsize) {
- case EED_SCR_1152X900:
+ switch (eep->eeScreenSize) {
+ case EE_SCR_1152X900:
fb->fb_type.fb_width = 1152;
fb->fb_type.fb_height = 900;
break;
- case EED_SCR_1024X1024:
+ case EE_SCR_1024X1024:
fb->fb_type.fb_width = 1024;
fb->fb_type.fb_height = 1024;
break;
- case EED_SCR_1600X1280:
+ case EE_SCR_1600X1280:
fb->fb_type.fb_width = 1600;
fb->fb_type.fb_height = 1280;
break;
- case EED_SCR_1440X1440:
+ case EE_SCR_1440X1440:
fb->fb_type.fb_width = 1440;
fb->fb_type.fb_height = 1440;
break;
@@ -354,12 +354,15 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype)
}
}
+
#ifdef RASTERCONSOLE
#include <machine/kbd.h>
-static int a2int __P((char *, int));
static void fb_bell __P((int));
+#if !(defined(RASTERCONS_FULLSCREEN) || defined(RASTERCONS_SMALLFONT))
+static int a2int __P((char *, int));
+
static int
a2int(cp, deflt)
register char *cp;
@@ -373,6 +376,7 @@ a2int(cp, deflt)
i = i * 10 + *cp++ - '0';
return (i);
}
+#endif
static void
fb_bell(on)
@@ -413,8 +417,8 @@ fbrcons_init(fb)
rc->rc_maxcol = 80;
rc->rc_maxrow = 34;
} else {
- rc->rc_maxcol = eep->ee_diag.eed_colsize;
- rc->rc_maxrow = eep->ee_diag.eed_rowsize;
+ rc->rc_maxcol = eep->eeTtyCols;
+ rc->rc_maxrow = eep->eeTtyRows;
}
}
#endif /* SUN4 */
@@ -439,7 +443,19 @@ fbrcons_init(fb)
/* Hook up virtual console */
v_putc = rcons_cnputc;
}
-#endif
+
+int
+fbrcons_rows()
+{
+ return (devfb ? devfb->fb_rcons.rc_maxrow : 0);
+}
+
+int
+fbrcons_cols()
+{
+ return (devfb ? devfb->fb_rcons.rc_maxcol : 0);
+}
+#endif /* RASTERCONSOLE */
#if defined(SUN4)
/*
diff --git a/sys/arch/sparc/dev/fd.c b/sys/arch/sparc/dev/fd.c
index 456ab415b6e..1643db5b031 100644
--- a/sys/arch/sparc/dev/fd.c
+++ b/sys/arch/sparc/dev/fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fd.c,v 1.19 1997/06/25 13:04:20 downsj Exp $ */
+/* $OpenBSD: fd.c,v 1.20 1997/08/08 08:25:06 downsj Exp $ */
/* $NetBSD: fd.c,v 1.51 1997/05/24 20:16:19 pk Exp $ */
/*-
@@ -369,8 +369,7 @@ fdcattach(parent, self, aux)
fdc->sc_reg = (caddr_t)ca->ca_ra.ra_vaddr;
else
fdc->sc_reg = (caddr_t)mapiodev(ca->ca_ra.ra_reg, 0,
- ca->ca_ra.ra_len,
- ca->ca_bustype);
+ ca->ca_ra.ra_len);
fdc->sc_state = DEVIDLE;
fdc->sc_istate = ISTATE_IDLE;
diff --git a/sys/arch/sparc/dev/i82586.h b/sys/arch/sparc/dev/i82586.h
index 02cd09ef98f..4c5ead2fec3 100644
--- a/sys/arch/sparc/dev/i82586.h
+++ b/sys/arch/sparc/dev/i82586.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: i82586.h,v 1.2 1997/08/08 08:25:07 downsj Exp $ */
/* $NetBSD: i82586.h,v 1.3 1995/01/27 09:49:55 pk Exp $ */
/*-
diff --git a/sys/arch/sparc/dev/if_en_sbus.c b/sys/arch/sparc/dev/if_en_sbus.c
index 9ba4cd3ca99..499f80901fc 100644
--- a/sys/arch/sparc/dev/if_en_sbus.c
+++ b/sys/arch/sparc/dev/if_en_sbus.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: if_en_sbus.c,v 1.2 1996/06/21 21:37:37 chuck Exp $ */
+/* $OpenBSD: if_en_sbus.c,v 1.3 1997/08/08 08:25:08 downsj Exp $ */
+/* $NetBSD: if_en_sbus.c,v 1.4 1997/05/24 20:16:22 pk Exp $ */
/*
*
@@ -138,8 +139,7 @@ void *aux;
return;
}
- sc->en_base = (caddr_t) mapiodev(ca->ca_ra.ra_reg, 0, 4*1024*1024,
- ca->ca_bustype);
+ sc->en_base = (caddr_t) mapiodev(ca->ca_ra.ra_reg, 0, 4*1024*1024);
if (ca->ca_ra.ra_nintr == 1) {
sc->ipl = ca->ca_ra.ra_intr[0].int_pri;
diff --git a/sys/arch/sparc/dev/if_ie.c b/sys/arch/sparc/dev/if_ie.c
index 3bd3defb91a..d57746dbadc 100644
--- a/sys/arch/sparc/dev/if_ie.c
+++ b/sys/arch/sparc/dev/if_ie.c
@@ -1,4 +1,5 @@
-/* $NetBSD: if_ie.c,v 1.24 1996/05/07 01:28:28 thorpej Exp $ */
+/* $OpenBSD: if_ie.c,v 1.7 1997/08/08 08:25:09 downsj Exp $ */
+/* $NetBSD: if_ie.c,v 1.33 1997/07/29 17:55:38 fair Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles Hannum.
@@ -413,23 +414,22 @@ iematch(parent, vcf, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name)) /* correct name? */
return (0);
- if (ca->ca_bustype == BUS_SBUS)
- return (0);
-
- if (CPU_ISSUN4) {
- /*
- * XXX need better probe here so we can figure out what we've got
- */
- if (ca->ca_bustype == BUS_OBIO) {
- if (probeget(ra->ra_vaddr, 1) == -1)
- return (0);
- return(1);
- }
- if (probeget(ra->ra_vaddr, 2) == -1)
- return (0);
+ switch (ca->ca_bustype) {
+ case BUS_SBUS:
+ default:
+ return (0);
+ case BUS_OBIO:
+ if (probeget(ra->ra_vaddr, 1) != -1)
+ return (1);
+ break;
+ case BUS_VME16:
+ case BUS_VME32:
+ if (probeget(ra->ra_vaddr, 2) != -1)
+ return (1);
+ break;
}
- return (1);
+ return (0);
}
/*
@@ -530,8 +530,7 @@ ieattach(parent, self, aux)
sc->memcopy = bcopy;
sc->memzero = bzero;
sc->sc_msize = 65536; /* XXX */
- sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ieob),
- ca->ca_bustype);
+ sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ieob));
ieo = (volatile struct ieob *) sc->sc_reg;
/*
@@ -594,8 +593,8 @@ ieattach(parent, self, aux)
sc->memcopy = wcopy;
sc->memzero = wzero;
sc->sc_msize = 65536; /* XXX */
- sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ievme),
- ca->ca_bustype);
+ sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0,
+ sizeof(struct ievme));
iev = (volatile struct ievme *) sc->sc_reg;
/* top 12 bits */
rampaddr = (u_long)ca->ca_ra.ra_paddr & 0xfff00000;
@@ -603,7 +602,7 @@ ieattach(parent, self, aux)
rampaddr = rampaddr | ((iev->status & IEVME_HADDR) << 16);
rampaddr -= (u_long)ca->ca_ra.ra_paddr;
sc->sc_maddr = mapiodev(ca->ca_ra.ra_reg, rampaddr,
- sc->sc_msize, ca->ca_bustype);
+ sc->sc_msize);
sc->sc_iobase = sc->sc_maddr;
iev->pectrl = iev->pectrl | IEVME_PARACK; /* clear to start */
@@ -731,7 +730,7 @@ void *v;
volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg
;
if (iev->status & IEVME_PERR) {
- printf("%s: parity error (ctrl %x @ %02x%04x)\n",
+ printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
sc->sc_dev.dv_xname, iev->pectrl,
iev->pectrl & IEVME_HADDR, iev->peaddr);
iev->pectrl = iev->pectrl | IEVME_PARACK;
@@ -1317,7 +1316,8 @@ ie_readframe(sc, num)
#ifdef IEDEBUG
if (sc->sc_debug & IED_READFRAME)
- printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
+ printf("%s: frame from ether %s type 0x%x\n",
+ sc->sc_dev.dv_xname,
ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
#endif
@@ -1654,7 +1654,7 @@ run_tdr(sc, cmd)
printf("%s: TDR detected a short %d clocks away\n",
sc->sc_dev.dv_xname, result & IE_TDR_TIME);
else
- printf("%s: TDR returned unknown status %x\n",
+ printf("%s: TDR returned unknown status 0x%x\n",
sc->sc_dev.dv_xname, result);
}
diff --git a/sys/arch/sparc/dev/if_ie.h b/sys/arch/sparc/dev/if_ie.h
index 0008a85417d..b9860155b66 100644
--- a/sys/arch/sparc/dev/if_ie.h
+++ b/sys/arch/sparc/dev/if_ie.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: if_ie.h,v 1.2 1997/08/08 08:25:11 downsj Exp $ */
/* $NetBSD: if_ie.h,v 1.4 1994/12/16 22:01:11 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/if_le.c b/sys/arch/sparc/dev/if_le.c
index 4db240f0f62..b0bf63e56e6 100644
--- a/sys/arch/sparc/dev/if_le.c
+++ b/sys/arch/sparc/dev/if_le.c
@@ -1,6 +1,8 @@
-/* $NetBSD: if_le.c,v 1.35.4.1 1996/07/17 01:46:00 jtc Exp $ */
+/* $OpenBSD: if_le.c,v 1.7 1997/08/08 08:25:12 downsj Exp $ */
+/* $NetBSD: if_le.c,v 1.49 1997/07/07 16:28:44 pk Exp $ */
/*-
+ * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1996
* The President and Fellows of Harvard College. All rights reserved.
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@@ -22,6 +24,8 @@
* must display the following acknowledgement:
* This product includes software developed by Aaron Brown and
* Harvard University.
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
* 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
@@ -54,10 +58,18 @@
#include <sys/malloc.h>
#include <net/if.h>
+#if defined(__NetBSD__)
+#include <net/if_ether.h>
+#include <net/if_media.h>
+#endif /* __NetBSD__ */
#ifdef INET
#include <netinet/in.h>
+#if defined(__NetBSD__)
+#include <netinet/if_inarp.h>
+#else
#include <netinet/if_ether.h>
+#endif /* __NetBSD__ */
#endif
#include <machine/autoconf.h>
@@ -66,6 +78,7 @@
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
+#include <sparc/dev/lebuffervar.h>
#include <dev/ic/am7990reg.h>
#include <dev/ic/am7990var.h>
@@ -73,7 +86,11 @@
#include <sparc/dev/if_lereg.h>
#include <sparc/dev/if_levar.h>
+#if defined(__NetBSD__)
+int lematch __P((struct device *, struct cfdata *, void *));
+#else
int lematch __P((struct device *, void *, void *));
+#endif /* __NetBSD__ */
void leattach __P((struct device *, struct device *, void *));
#if defined(SUN4M) /* XXX */
@@ -89,25 +106,41 @@ myleintr(arg)
if (lesc->sc_dma->sc_regs->csr & D_ERR_PEND)
return ledmaintr(lesc->sc_dma);
- /*
- * XXX There is a bug somewhere in the interrupt code that causes stray
- * ethernet interrupts under high network load. This bug has been
- * impossible to locate, so until it is found, we just ignore stray
- * interrupts, as they do not in fact correspond to dropped packets.
- */
-
- /* return */ am7990_intr(arg);
- return 1;
+ return (am7990_intr(arg));
}
#endif
+#if defined(SUN4M)
+#if defined(__NetBSD__)
+/*
+ * Media types supported by the Sun4m.
+ */
+int lemediasun4m[] = {
+ IFM_ETHER|IFM_10_T,
+ IFM_ETHER|IFM_10_5,
+ IFM_ETHER|IFM_AUTO,
+};
+#define NLEMEDIASUN4M (sizeof(lemediasun4m) / sizeof(lemediasun4m[0]))
+#endif /* __NetBSD__ */
+
+void lesetutp __P((struct am7990_softc *));
+void lesetaui __P((struct am7990_softc *));
+
+int lemediachange __P((struct am7990_softc *));
+#if defined(__NetBSD__)
+void lemediastatus __P((struct am7990_softc *, struct ifmediareq *));
+#endif /* __NetBSD__ */
+#endif /* SUN4M */
+
struct cfattach le_ca = {
sizeof(struct le_softc), lematch, leattach
};
hide void lewrcsr __P((struct am7990_softc *, u_int16_t, u_int16_t));
hide u_int16_t lerdcsr __P((struct am7990_softc *, u_int16_t));
+hide void lehwreset __P((struct am7990_softc *));
hide void lehwinit __P((struct am7990_softc *));
+hide void lenocarrier __P((struct am7990_softc *));
hide void
lewrcsr(sc, port, val)
@@ -115,9 +148,21 @@ lewrcsr(sc, port, val)
u_int16_t port, val;
{
register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+#if defined(SUN4M)
+ volatile u_int16_t discard;
+#endif
ler1->ler1_rap = port;
ler1->ler1_rdp = val;
+#if defined(SUN4M)
+ /*
+ * We need to flush the Sbus->Mbus write buffers. This can most
+ * easily be accomplished by reading back the register that we
+ * just wrote (thanks to Chris Torek for this solution).
+ */
+ if (CPU_ISSUN4M)
+ discard = ler1->ler1_rdp;
+#endif
}
hide u_int16_t
@@ -133,6 +178,109 @@ lerdcsr(sc, port)
return (val);
}
+#if defined(SUN4M)
+void
+lesetutp(sc)
+ struct am7990_softc *sc;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ lesc->sc_dma->sc_regs->csr |= DE_AUI_TP;
+ delay(20000); /* must not touch le for 20ms */
+}
+
+void
+lesetaui(sc)
+ struct am7990_softc *sc;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ lesc->sc_dma->sc_regs->csr &= ~DE_AUI_TP;
+ delay(20000); /* must not touch le for 20ms */
+}
+
+int
+lemediachange(sc)
+ struct am7990_softc *sc;
+{
+#if defined(__NetBSD__)
+ struct ifmedia *ifm = &sc->sc_media;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ /*
+ * Switch to the selected media. If autoselect is
+ * set, we don't really have to do anything. We'll
+ * switch to the other media when we detect loss of
+ * carrier.
+ */
+ switch (IFM_SUBTYPE(ifm->ifm_media)) {
+ case IFM_10_T:
+ lesetutp(sc);
+ break;
+
+ case IFM_10_5:
+ lesetaui(sc);
+ break;
+
+ case IFM_AUTO:
+ break;
+
+ default:
+ return (EINVAL);
+ }
+#else
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ if (ifp->if_flags & IFF_LINK0)
+ lesetutp(sc);
+ else if (ifp->if_flags & IFF_LINK1)
+ lesetaui(sc);
+#endif /* __NetBSD__ */
+ return (0);
+}
+
+#if defined(__NetBSD__)
+void
+lemediastatus(sc, ifmr)
+ struct am7990_softc *sc;
+ struct ifmediareq *ifmr;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ if (lesc->sc_dma == NULL)
+ return;
+
+ /*
+ * Notify the world which media we're currently using.
+ */
+ if (lesc->sc_dma->sc_regs->csr & DE_AUI_TP)
+ ifmr->ifm_active = IFM_ETHER|IFM_10_T;
+ else
+ ifmr->ifm_active = IFM_ETHER|IFM_10_5;
+}
+#endif /* __NetBSD__ */
+#endif /* SUN4M */
+
+hide void
+lehwreset(sc)
+ struct am7990_softc *sc;
+{
+#if defined(SUN4M)
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ /*
+ * Reset DMA channel.
+ */
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ DMA_RESET(lesc->sc_dma);
+ lesc->sc_dma->sc_regs->en_bar = lesc->sc_laddr & 0xff000000;
+ DMA_ENINTR(lesc->sc_dma);
+ }
+#endif
+}
+
hide void
lehwinit(sc)
struct am7990_softc *sc;
@@ -140,25 +288,100 @@ lehwinit(sc)
#if defined(SUN4M)
struct le_softc *lesc = (struct le_softc *)sc;
+ /*
+ * Make sure we're using the currently-enabled media type.
+ * XXX Actually, this is probably unnecessary, now.
+ */
if (CPU_ISSUN4M && lesc->sc_dma) {
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
+ case IFM_10_T:
+ lesetutp(sc);
+ break;
+
+ case IFM_10_5:
+ lesetaui(sc);
+ break;
+ }
+#else
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
if (ifp->if_flags & IFF_LINK0)
- lesc->sc_dma->sc_regs->csr |= DE_AUI_TP;
+ lesetutp(sc);
else if (ifp->if_flags & IFF_LINK1)
- lesc->sc_dma->sc_regs->csr &= ~DE_AUI_TP;
-
- delay(20000); /* must not touch le for 20ms */
+ lesetaui(sc);
+#endif /* __NetBSD__ */
}
#endif
}
+hide void
+lenocarrier(sc)
+ struct am7990_softc *sc;
+{
+#if defined(SUN4M)
+ struct le_softc *lesc = (struct le_softc *)sc;
+#if !defined(__NetBSD__)
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif /* __NetBSD__ */
+
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ /*
+ * Check if the user has requested a certain cable type, and
+ * if so, honor that request.
+ */
+ printf("%s: lost carrier on ", sc->sc_dev.dv_xname);
+ if (lesc->sc_dma->sc_regs->csr & DE_AUI_TP) {
+ printf("UTP port");
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_5:
+ case IFM_AUTO:
+ printf(", switching to AUI port");
+ lesetaui(sc);
+ }
+#else
+ if (!(ifp->if_flags & IFF_LINK0)) {
+ printf(", switching to AUI port");
+ lesetaui(sc);
+ }
+#endif /* __NetBSD__ */
+ } else {
+ printf("AUI port");
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_T:
+ case IFM_AUTO:
+ printf(", switching to UTP port");
+ lesetutp(sc);
+ }
+#else
+ if (!(ifp->if_flags & IFF_LINK1)) {
+ printf(", switching to UTP port");
+ lesetutp(sc);
+ }
+#endif /* __NetBSD__ */
+ }
+ printf("\n");
+ } else
+#endif
+ printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
+}
+
int
-lematch(parent, match, aux)
+#if defined(__NetBSD__)
+lematch(parent, cf, aux)
struct device *parent;
- void *match, *aux;
+ struct cfdata *cf;
+ void *aux;
{
- struct cfdata *cf = match;
+#else
+lematch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+#endif /* __NetBSD__ */
struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -180,9 +403,11 @@ leattach(parent, self, aux)
struct confargs *ca = aux;
int pri;
struct bootpath *bp;
- u_long laddr;
#if defined(SUN4C) || defined(SUN4M)
int sbuschild = strncmp(parent->dv_xname, "sbus", 4) == 0;
+ int lebufchild = strncmp(parent->dv_xname, "lebuffer", 8) == 0;
+ int dmachild = strncmp(parent->dv_xname, "ledma", 5) == 0;
+ struct lebuf_softc *lebuf;
#endif
/* XXX the following declarations should be elsewhere */
@@ -195,31 +420,62 @@ leattach(parent, self, aux)
pri = ca->ca_ra.ra_intr[0].int_pri;
printf(" pri %d", pri);
- lesc->sc_r1 = (struct lereg1 *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct lereg1),
- ca->ca_bustype);
- sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
- laddr = (u_long)dvma_malloc(MEMSIZE, &sc->sc_mem, M_NOWAIT);
+ lesc->sc_r1 = (struct lereg1 *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct lereg1));
+
+#if defined(SUN4C) || defined(SUN4M)
+ lebuf = NULL;
+ if (lebufchild) {
+ lebuf = (struct lebuf_softc *)parent;
+ } else if (sbuschild) {
+ struct sbus_softc *sbus = (struct sbus_softc *)parent;
+ struct sbusdev *sd;
+
+ /*
+ * Find last "unallocated" lebuffer and pair it with
+ * this `le' device on the assumption that we're on
+ * a pre-historic ROM that doesn't establish le<=>lebuffer
+ * parent-child relationships.
+ */
+ for (sd = sbus->sc_sbdev; sd != NULL; sd = sd->sd_bchain) {
+ if (strncmp("lebuffer", sd->sd_dev->dv_xname, 8) != 0)
+ continue;
+ if (((struct lebuf_softc *)sd->sd_dev)->attached == 0) {
+ lebuf = (struct lebuf_softc *)sd->sd_dev;
+ break;
+ }
+ }
+ }
+ if (lebuf != NULL) {
+ sc->sc_mem = lebuf->sc_buffer;
+ sc->sc_memsize = lebuf->sc_bufsiz;
+ sc->sc_addr = 0; /* Lance view is offset by buffer location */
+ lebuf->attached = 1;
+
+ /* That old black magic... */
+ sc->sc_conf3 = getpropint(ca->ca_ra.ra_node,
+ "busmaster-regval",
+ LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
+ } else
+#endif
+ {
+ u_long laddr;
+ laddr = (u_long)dvma_malloc(MEMSIZE, &sc->sc_mem, M_NOWAIT);
#if defined (SUN4M)
- if ((laddr & 0xffffff) >= (laddr & 0xffffff) + MEMSIZE)
- panic("if_le: Lance buffer crosses 16MB boundary");
+ if ((laddr & 0xffffff) >= (laddr & 0xffffff) + MEMSIZE)
+ panic("if_le: Lance buffer crosses 16MB boundary");
#endif
- sc->sc_addr = laddr & 0xffffff;
- sc->sc_memsize = MEMSIZE;
-
- myetheraddr(sc->sc_arpcom.ac_enaddr);
-
- sc->sc_copytodesc = am7990_copytobuf_contig;
- sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
- sc->sc_copytobuf = am7990_copytobuf_contig;
- sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
- sc->sc_zerobuf = am7990_zerobuf_contig;
-
- sc->sc_rdcsr = lerdcsr;
- sc->sc_wrcsr = lewrcsr;
- sc->sc_hwinit = lehwinit;
-
- am7990_config(sc);
+ sc->sc_addr = laddr & 0xffffff;
+ sc->sc_memsize = MEMSIZE;
+ sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
+#if defined(SUN4C) || defined(SUN4M)
+ if (dmachild) {
+ lesc->sc_dma = (struct dma_softc *)parent;
+ lesc->sc_dma->sc_le = lesc;
+ lesc->sc_laddr = laddr;
+ }
+#endif
+ }
bp = ca->ca_ra.ra_bp;
switch (ca->ca_bustype) {
@@ -231,12 +487,8 @@ leattach(parent, self, aux)
case BUS_SBUS:
lesc->sc_sd.sd_reset = (void *)am7990_reset;
if (sbuschild) {
- lesc->sc_dma = NULL;
sbus_establish(&lesc->sc_sd, &sc->sc_dev);
} else {
- lesc->sc_dma = (struct dma_softc *)parent;
- lesc->sc_dma->sc_le = lesc;
- lesc->sc_dma->sc_regs->en_bar = laddr & 0xff000000;
/* Assume SBus is grandparent */
sbus_establish(&lesc->sc_sd, parent);
}
@@ -254,16 +506,44 @@ leattach(parent, self, aux)
break;
}
+#if defined(__NetBSD__)
+ myetheraddr(sc->sc_enaddr);
+#else
+ myetheraddr(sc->sc_arpcom.ac_enaddr);
+#endif /* __NetBSD__ */
+
+ sc->sc_copytodesc = am7990_copytobuf_contig;
+ sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
+ sc->sc_copytobuf = am7990_copytobuf_contig;
+ sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
+ sc->sc_zerobuf = am7990_zerobuf_contig;
+
+ sc->sc_rdcsr = lerdcsr;
+ sc->sc_wrcsr = lewrcsr;
+ sc->sc_hwinit = lehwinit;
+ sc->sc_nocarrier = lenocarrier;
+ sc->sc_hwreset = lehwreset;
+
+#if defined(SUN4M) && defined(__NetBSD__)
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ sc->sc_mediachange = lemediachange;
+ sc->sc_mediastatus = lemediastatus;
+ sc->sc_supmedia = lemediasun4m;
+ sc->sc_nsupmedia = NLEMEDIASUN4M;
+ sc->sc_defaultmedia = IFM_ETHER|IFM_AUTO;
+ }
+#endif
+
+ am7990_config(sc);
+
lesc->sc_ih.ih_fun = am7990_intr;
#if defined(SUN4M) /*XXX*/
- if (CPU_ISSUN4M)
+ if (CPU_ISSUN4M && lesc->sc_dma)
lesc->sc_ih.ih_fun = myleintr;
#endif
lesc->sc_ih.ih_arg = sc;
intr_establish(pri, &lesc->sc_ih);
/* now initialize DMA */
- if (lesc->sc_dma) {
- DMA_ENINTR(lesc->sc_dma);
- }
+ lehwreset(sc);
}
diff --git a/sys/arch/sparc/dev/if_lereg.h b/sys/arch/sparc/dev/if_lereg.h
index 5035566a439..429ba05a831 100644
--- a/sys/arch/sparc/dev/if_lereg.h
+++ b/sys/arch/sparc/dev/if_lereg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: if_lereg.h,v 1.3 1997/08/08 08:25:13 downsj Exp $ */
/* $NetBSD: if_lereg.h,v 1.5 1995/12/10 10:15:07 mycroft Exp $ */
/*-
diff --git a/sys/arch/sparc/dev/if_levar.h b/sys/arch/sparc/dev/if_levar.h
index 934d74c932e..2c73d8405d9 100644
--- a/sys/arch/sparc/dev/if_levar.h
+++ b/sys/arch/sparc/dev/if_levar.h
@@ -1,4 +1,5 @@
-/* $NetBSD: if_levar.h,v 1.5 1996/05/07 01:27:32 thorpej Exp $ */
+/* $OpenBSD: if_levar.h,v 1.3 1997/08/08 08:25:14 downsj Exp $ */
+/* $NetBSD: if_levar.h,v 1.7 1997/04/04 20:29:23 pk Exp $ */
/*-
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@@ -43,7 +44,7 @@
* Ethernet software status per interface.
*
* Each interface is referenced by a network interface structure,
- * arpcom.ac_if, which the routing code uses to locate the interface.
+ * ethercom.ec_if, which the routing code uses to locate the interface.
* This structure contains the output queue for the interface, its address, ...
*/
struct le_softc {
@@ -53,4 +54,5 @@ struct le_softc {
struct intrhand sc_ih; /* interrupt vectoring */
struct lereg1 *sc_r1; /* LANCE registers */
struct dma_softc *sc_dma; /* pointer to my dma */
+ u_long sc_laddr; /* LANCE DMA address */
};
diff --git a/sys/arch/sparc/dev/isp_sbus.c b/sys/arch/sparc/dev/isp_sbus.c
new file mode 100644
index 00000000000..24fcb5caec2
--- /dev/null
+++ b/sys/arch/sparc/dev/isp_sbus.c
@@ -0,0 +1,331 @@
+/* $OpenBSD: isp_sbus.c,v 1.1 1997/08/08 08:25:15 downsj Exp $ */
+/* $NetBSD: isp_sbus.c,v 1.6 1997/06/08 06:35:45 thorpej Exp $ */
+
+/*
+ * SBus specific probe and attach routines for Qlogic ISP SCSI adapters.
+ *
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/device.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <machine/autoconf.h>
+#include <sparc/cpu.h>
+#include <sparc/sparc/cpuvar.h>
+#include <sparc/dev/sbusvar.h>
+
+#include <dev/ic/ispreg.h>
+#include <dev/ic/ispvar.h>
+#include <dev/microcode/isp/asm_sbus.h>
+#include <machine/param.h>
+#include <machine/vmparam.h>
+
+
+static u_int16_t isp_sbus_rd_reg __P((struct ispsoftc *, int));
+static void isp_sbus_wr_reg __P((struct ispsoftc *, int, u_int16_t));
+static int isp_sbus_mbxdma __P((struct ispsoftc *));
+static int isp_sbus_dmasetup __P((struct ispsoftc *, struct scsi_xfer *,
+ ispreq_t *, u_int8_t *, u_int8_t));
+static void isp_sbus_dmateardown __P((struct ispsoftc *, struct scsi_xfer *,
+ u_int32_t));
+
+static struct ispmdvec mdvec = {
+ isp_sbus_rd_reg,
+ isp_sbus_wr_reg,
+ isp_sbus_mbxdma,
+ isp_sbus_dmasetup,
+ isp_sbus_dmateardown,
+ NULL,
+ NULL,
+ ISP_RISC_CODE,
+ ISP_CODE_LENGTH,
+ ISP_CODE_ORG,
+ 0
+};
+
+struct isp_sbussoftc {
+ struct ispsoftc sbus_isp;
+ struct intrhand sbus_ih;
+ volatile u_char *sbus_reg;
+ int sbus_node;
+ int sbus_pri;
+ vm_offset_t sbus_kdma_allocs[RQUEST_QUEUE_LEN];
+};
+
+
+static int isp_match __P((struct device *, void *, void *));
+static void isp_sbus_attach __P((struct device *, struct device *, void *));
+struct cfattach isp_sbus_ca = {
+ sizeof (struct isp_sbussoftc), isp_match, isp_sbus_attach
+};
+
+static int
+isp_match(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ register struct romaux *ra = &ca->ca_ra;
+
+ if (strcmp(cf->cf_driver->cd_name, ra->ra_name) &&
+ strcmp("SUNW,isp", ra->ra_name) &&
+ strcmp("QLGC,isp", ra->ra_name)) {
+ return (0);
+ }
+ if (ca->ca_bustype == BUS_SBUS)
+ return (1);
+ ra->ra_len = NBPG;
+ return (probeget(ra->ra_vaddr, 1) != -1);
+}
+
+static void
+isp_sbus_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) self;
+
+ if (ca->ca_ra.ra_nintr != 1) {
+ printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
+ return;
+ }
+
+ sbc->sbus_pri = ca->ca_ra.ra_intr[0].int_pri;
+ printf(" pri %d\n", sbc->sbus_pri);
+
+ if (ca->ca_ra.ra_vaddr) {
+ sbc->sbus_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
+ } else {
+ sbc->sbus_reg = (volatile u_char *)
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
+ }
+ sbc->sbus_node = ca->ca_ra.ra_node;
+
+ sbc->sbus_isp.isp_mdvec = &mdvec;
+ isp_reset(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_RESETSTATE) {
+ return;
+ }
+ isp_init(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_INITSTATE) {
+ isp_uninit(&sbc->sbus_isp);
+ return;
+ }
+ sbc->sbus_ih.ih_fun = (void *) isp_intr;
+ sbc->sbus_ih.ih_arg = sbc;
+ intr_establish(sbc->sbus_pri, &sbc->sbus_ih);
+
+ /*
+ * Do Generic attach now.
+ */
+ isp_attach(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_RUNSTATE) {
+ isp_uninit(&sbc->sbus_isp);
+ }
+}
+
+#define SBUS_BIU_REGS_OFF 0x00
+#define SBUS_MBOX_REGS_OFF 0x80
+#define SBUS_SXP_REGS_OFF 0x200
+#define SBUS_RISC_REGS_OFF 0x400
+
+static u_int16_t
+isp_sbus_rd_reg(isp, regoff)
+ struct ispsoftc *isp;
+ int regoff;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+
+ int offset;
+ if ((regoff & BIU_BLOCK) != 0) {
+ offset = SBUS_BIU_REGS_OFF;
+ } else if ((regoff & MBOX_BLOCK) != 0) {
+ offset = SBUS_MBOX_REGS_OFF;
+ } else if ((regoff & SXP_BLOCK) != 0) {
+ offset = SBUS_SXP_REGS_OFF;
+ } else {
+ offset = SBUS_RISC_REGS_OFF;
+ }
+ regoff &= 0xff;
+ offset += regoff;
+ return (*((u_int16_t *) &sbc->sbus_reg[offset]));
+}
+
+static void
+isp_sbus_wr_reg (isp, regoff, val)
+ struct ispsoftc *isp;
+ int regoff;
+ u_int16_t val;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ int offset;
+
+ if ((regoff & BIU_BLOCK) != 0) {
+ offset = SBUS_BIU_REGS_OFF;
+ } else if ((regoff & MBOX_BLOCK) != 0) {
+ offset = SBUS_MBOX_REGS_OFF;
+ } else if ((regoff & SXP_BLOCK) != 0) {
+ offset = SBUS_SXP_REGS_OFF;
+ } else {
+ offset = SBUS_RISC_REGS_OFF;
+ }
+ regoff &= 0xff;
+ offset += regoff;
+ *((u_int16_t *) &sbc->sbus_reg[offset]) = val;
+}
+
+static int
+isp_sbus_mbxdma(isp)
+ struct ispsoftc *isp;
+{
+ size_t len;
+
+ /*
+ * NOTE: Since most Sun machines aren't I/O coherent,
+ * map the mailboxes through kdvma space to force them
+ * to be uncached.
+ */
+
+ /*
+ * Allocate and map the request queue.
+ */
+ len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
+ isp->isp_rquest = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
+ if (isp->isp_rquest == 0)
+ return (1);
+ isp->isp_rquest_dma = (u_int32_t)kdvma_mapin((caddr_t)isp->isp_rquest,
+ len, 0);
+ if (isp->isp_rquest_dma == 0)
+ return (1);
+
+ /*
+ * Allocate and map the result queue.
+ */
+ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
+ isp->isp_result = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
+ if (isp->isp_result == 0)
+ return (1);
+ isp->isp_result_dma = (u_int32_t)kdvma_mapin((caddr_t)isp->isp_result,
+ len, 0);
+ if (isp->isp_result_dma == 0)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * TODO: If kdvma_mapin fails, try using multiple smaller chunks..
+ */
+
+static int
+isp_sbus_dmasetup(isp, xs, rq, iptrp, optr)
+ struct ispsoftc *isp;
+ struct scsi_xfer *xs;
+ ispreq_t *rq;
+ u_int8_t *iptrp;
+ u_int8_t optr;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ vm_offset_t kdvma;
+ int dosleep = (xs->flags & SCSI_NOSLEEP) != 0;
+
+ if (xs->datalen == 0) {
+ rq->req_seg_count = 1;
+ rq->req_flags |= REQFLAG_DATA_IN;
+ return (0);
+ }
+
+ if (rq->req_handle >= RQUEST_QUEUE_LEN) {
+ panic("%s: bad handle (%d) in isp_sbus_dmasetup\n",
+ isp->isp_name, rq->req_handle);
+ /* NOTREACHED */
+ }
+ if (CPU_ISSUN4M) {
+ kdvma = (vm_offset_t)
+ kdvma_mapin((caddr_t)xs->data, xs->datalen, dosleep);
+ if (kdvma == (vm_offset_t) 0) {
+ return (1);
+ }
+ } else {
+ kdvma = (vm_offset_t) xs->data;
+ }
+
+ if (sbc->sbus_kdma_allocs[rq->req_handle] != (vm_offset_t) 0) {
+ panic("%s: kdma handle already allocated\n", isp->isp_name);
+ /* NOTREACHED */
+ }
+ sbc->sbus_kdma_allocs[rq->req_handle] = kdvma;
+ if (xs->flags & SCSI_DATA_IN) {
+ rq->req_flags |= REQFLAG_DATA_IN;
+ } else {
+ rq->req_flags |= REQFLAG_DATA_OUT;
+ }
+ rq->req_dataseg[0].ds_count = xs->datalen;
+ rq->req_dataseg[0].ds_base = (u_int32_t) kdvma;
+ rq->req_seg_count = 1;
+ return (0);
+}
+
+static void
+isp_sbus_dmateardown(isp, xs, handle)
+ struct ispsoftc *isp;
+ struct scsi_xfer *xs;
+ u_int32_t handle;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ vm_offset_t kdvma;
+
+ if (xs->flags & SCSI_DATA_IN) {
+ cpuinfo.cache_flush(xs->data, xs->datalen - xs->resid);
+ }
+
+ if (handle >= RQUEST_QUEUE_LEN) {
+ panic("%s: bad handle (%d) in isp_sbus_dmateardown\n",
+ isp->isp_name, handle);
+ /* NOTREACHED */
+ }
+ if (sbc->sbus_kdma_allocs[handle] == (vm_offset_t) 0) {
+ panic("%s: kdma handle not already allocated\n", isp->isp_name);
+ /* NOTREACHED */
+ }
+ kdvma = sbc->sbus_kdma_allocs[handle];
+ sbc->sbus_kdma_allocs[handle] = (vm_offset_t) 0;
+ if (CPU_ISSUN4M) {
+ dvma_mapout(kdvma, (vm_offset_t) xs->data, xs->datalen);
+ }
+}
diff --git a/sys/arch/sparc/dev/kbd.c b/sys/arch/sparc/dev/kbd.c
index c4ae36b0aab..9bf291e0a43 100644
--- a/sys/arch/sparc/dev/kbd.c
+++ b/sys/arch/sparc/dev/kbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: kbd.c,v 1.5 1996/08/11 23:34:01 downsj Exp $ */
-/* $NetBSD: kbd.c,v 1.23 1996/04/01 17:34:34 christos Exp $ */
+/* $OpenBSD: kbd.c,v 1.6 1997/08/08 08:25:16 downsj Exp $ */
+/* $NetBSD: kbd.c,v 1.27 1996/10/13 03:00:01 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -66,7 +66,7 @@
#include <machine/conf.h>
#include <machine/vuid_event.h>
-#include <sparc/dev/event_var.h>
+#include <dev/sun/event_var.h>
#include <machine/kbd.h>
#include <machine/kbio.h>
@@ -326,7 +326,6 @@ kbd_reset(ks)
break;
default:
printf("Unknown keyboard type %d\n", ks->kbd_id);
- break;
}
ks->kbd_leds = 0;
@@ -720,6 +719,7 @@ kbdioctl(dev, cmd, data, flag, p)
*(char *)data = k->k_state.kbd_leds;
return (0);
+
case FIONBIO: /* we will remove this someday (soon???) */
return (0);
diff --git a/sys/arch/sparc/dev/lebuffer.c b/sys/arch/sparc/dev/lebuffer.c
new file mode 100644
index 00000000000..b97675194c6
--- /dev/null
+++ b/sys/arch/sparc/dev/lebuffer.c
@@ -0,0 +1,143 @@
+/* $OpenBSD: lebuffer.c,v 1.1 1997/08/08 08:25:16 downsj Exp $ */
+/* $NetBSD: lebuffer.c,v 1.3 1997/05/24 20:16:28 pk Exp $ */
+
+/*
+ * Copyright (c) 1996 Paul Kranenburg. 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 Peter Galbavy.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <sparc/autoconf.h>
+#include <sparc/cpu.h>
+
+#include <sparc/dev/sbusvar.h>
+#include <sparc/dev/lebuffervar.h>
+#include <sparc/dev/dmareg.h>/*XXX*/
+
+int lebufprint __P((void *, const char *));
+void lebufattach __P((struct device *, struct device *, void *));
+
+struct cfattach lebuffer_ca = {
+ sizeof(struct lebuf_softc), matchbyname, lebufattach
+};
+
+struct cfdriver lebuffer_cd = {
+ NULL, "lebuffer", DV_DULL
+};
+
+int
+lebufprint(aux, name)
+ void *aux;
+ const char *name;
+{
+ register struct confargs *ca = aux;
+
+ if (name)
+ printf("[%s at %s]", ca->ca_ra.ra_name, name);
+ printf(" slot 0x%x offset 0x%x", ca->ca_slot, ca->ca_offset);
+ return (UNCONF);
+}
+
+/*
+ * Attach all the sub-devices we can find
+ */
+void
+lebufattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+#if defined(SUN4C) || defined(SUN4M)
+ register struct confargs *ca = aux;
+ struct lebuf_softc *sc = (void *)self;
+ int node;
+ struct confargs oca;
+ char *name;
+ int sbusburst;
+
+ if (ca->ca_ra.ra_vaddr == NULL || ca->ca_ra.ra_nvaddrs == 0)
+ ca->ca_ra.ra_vaddr =
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
+
+ /*
+ * This device's "register space" is just a buffer where the
+ * Lance ring-buffers can be stored. Note the buffer's location
+ * and size, so the `le' driver can pick them up.
+ */
+ sc->sc_buffer = (caddr_t)ca->ca_ra.ra_vaddr;
+ sc->sc_bufsiz = ca->ca_ra.ra_len;
+
+ /*
+ * Get transfer burst size from PROM
+ */
+ sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
+
+ sc->sc_burst = getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);
+ if (sc->sc_burst == -1)
+ /* take SBus burst sizes */
+ sc->sc_burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ sc->sc_burst &= sbusburst;
+
+ printf("\n");
+
+ node = sc->sc_node = ca->ca_ra.ra_node;
+
+ if (ca->ca_bustype == BUS_SBUS)
+ sbus_establish(&sc->sc_sd, &sc->sc_dev);
+
+ /* Propagate bootpath */
+ if (ca->ca_ra.ra_bp != NULL)
+ oca.ca_ra.ra_bp = ca->ca_ra.ra_bp + 1;
+ else
+ oca.ca_ra.ra_bp = NULL;
+
+ /* search through children */
+ for (node = firstchild(node); node; node = nextsibling(node)) {
+ name = getpropstring(node, "name");
+ if (!romprop(&oca.ca_ra, name, node))
+ continue;
+
+ sbus_translate(parent, &oca);
+ oca.ca_bustype = BUS_SBUS;
+ (void) config_found(&sc->sc_dev, (void *)&oca, lebufprint);
+ }
+#endif /* SUN4C || SUN4M */
+}
diff --git a/sys/arch/sparc/dev/cgfourreg.h b/sys/arch/sparc/dev/lebuffervar.h
index 9d53b73de6e..edd47c7b8e9 100644
--- a/sys/arch/sparc/dev/cgfourreg.h
+++ b/sys/arch/sparc/dev/lebuffervar.h
@@ -1,9 +1,8 @@
-/* $NetBSD: cgfourreg.h,v 1.4 1994/11/20 20:52:03 deraadt Exp $ */
+/* $OpenBSD: lebuffervar.h,v 1.1 1997/08/08 08:25:18 downsj Exp $ */
+/* $NetBSD: lebuffervar.h,v 1.2 1997/03/10 22:56:54 pk Exp $ */
/*
- * Copyright (c) 1995 Theo de Raadt
- * All rights reserved.
- *
+ * Copyright (c) 1996 Paul Kranenburg. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,7 +13,7 @@
* 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 Theo de Raadt.
+ * This product includes software developed by Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
@@ -30,25 +29,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * cgfour display registers. Much like bwtwo registers, except that
- * there is a Brooktree Video DAC in there (so we also use btreg.h).
- */
-
-/* offsets */
-#define CG4REG_CMAP 0x200000
-#define CG4REG_OVERLAY 0x400000
-#define CG4REG_ENABLE 0x600000
-#define CG4REG_COLOUR 0x800000
-#define CG4REG_END 0xa00000
-
-/* same, but for gdb */
-struct cgfour_all {
- char ba_nothing[0x200000];
- struct bt_regs ba_btreg; /* Brooktree registers */
- char ba_xxx1[0x100000-sizeof(struct bt_regs)];
- char ba_pfourreg[0x100000];
- char ba_overlay[0x200000];
- char ba_enable[0x200000];
- char ba_color[0x200000];
+struct lebuf_softc {
+ struct device sc_dev; /* us as a device */
+ struct sbusdev sc_sd; /* sbus device */
+ u_int sc_rev; /* revision */
+ int sc_node; /* PROM node ID */
+ int sc_burst; /* DVMA burst size in effect */
+ caddr_t sc_buffer; /* VA of the buffer we provide */
+ int sc_bufsiz; /* Size of buffer */
+ int attached; /* 1: in use by `le' device */
};
diff --git a/sys/arch/sparc/dev/ms.c b/sys/arch/sparc/dev/ms.c
index 4bf14f2c9b2..1049fb12e45 100644
--- a/sys/arch/sparc/dev/ms.c
+++ b/sys/arch/sparc/dev/ms.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ms.c,v 1.5 1996/08/11 23:28:12 downsj Exp $ */
-/* $NetBSD: ms.c,v 1.8 1996/04/01 17:29:52 christos Exp $ */
+/* $OpenBSD: ms.c,v 1.6 1997/08/08 08:25:19 downsj Exp $ */
+/* $NetBSD: ms.c,v 1.10 1996/09/12 01:36:18 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -64,7 +64,7 @@
#include <machine/kbd.h>
#include <machine/conf.h>
-#include <sparc/dev/event_var.h>
+#include <dev/sun/event_var.h>
/*
* Mouse state. A Mouse Systems mouse is a fairly simple device,
@@ -255,6 +255,12 @@ msopen(dev, flags, mode, p)
ms_softc.ms_events.ev_io = p;
ev_init(&ms_softc.ms_events); /* may cause sleep */
+ if (CPU_ISSUN4) {
+ /* We need to set the baud rate on the mouse. */
+ ms_softc.ms_mouse->t_ispeed =
+ ms_softc.ms_mouse->t_ospeed = 1200;
+ }
+
(*ms_softc.ms_open)(ms_softc.ms_mouse);
ms_softc.ms_ready = 1; /* start accepting events */
return (0);
diff --git a/sys/arch/sparc/dev/obio.c b/sys/arch/sparc/dev/obio.c
index 2787aa91c01..845d97dddd3 100644
--- a/sys/arch/sparc/dev/obio.c
+++ b/sys/arch/sparc/dev/obio.c
@@ -1,8 +1,9 @@
-/* $NetBSD: obio.c,v 1.24 1996/05/18 12:22:49 mrg Exp $ */
+/* $OpenBSD: obio.c,v 1.7 1997/08/08 08:25:20 downsj Exp $ */
+/* $NetBSD: obio.c,v 1.37 1997/07/29 09:58:11 fair Exp $ */
/*
* Copyright (c) 1993, 1994 Theo de Raadt
- * Copyright (c) 1995 Paul Kranenburg
+ * Copyright (c) 1995, 1997 Paul Kranenburg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,28 +51,42 @@
#include <machine/ctlreg.h>
#include <sparc/sparc/asm.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#include <sparc/dev/sbusvar.h>
+#include <sparc/dev/vmereg.h>
+
+struct vmebus_softc {
+ struct device sc_dev; /* base device */
+ struct vmebusreg *sc_reg; /* VME control registers */
+ struct vmebusvec *sc_vec; /* VME interrupt vector */
+ struct rom_range *sc_range; /* ROM range property */
+ int sc_nrange;
+};
+struct vmebus_softc *vmebus_sc;/*XXX*/
struct bus_softc {
union {
struct device scu_dev; /* base device */
struct sbus_softc scu_sbus; /* obio is another sbus slot */
+ struct vmebus_softc scu_vme;
} bu;
-#define sc_dev bu.scu_dev
};
+
/* autoconfiguration driver */
static int busmatch __P((struct device *, void *, void *));
static void obioattach __P((struct device *, struct device *, void *));
static void vmesattach __P((struct device *, struct device *, void *));
static void vmelattach __P((struct device *, struct device *, void *));
+static void vmeattach __P((struct device *, struct device *, void *));
int busprint __P((void *, const char *));
+int vmeprint __P((void *, const char *));
static int busattach __P((struct device *, void *, void *, int));
-void * bus_map __P((struct rom_reg *, int, int));
int obio_scan __P((struct device *, void *, void *));
int vmes_scan __P((struct device *, void *, void *));
int vmel_scan __P((struct device *, void *, void *));
+void vmebus_translate __P((struct device *, struct confargs *, int));
int vmeintr __P((void *));
struct cfattach obio_ca = {
@@ -98,6 +113,14 @@ struct cfdriver vmes_cd = {
NULL, "vmes", DV_DULL
};
+struct cfattach vme_ca = {
+ sizeof(struct bus_softc), busmatch, vmeattach
+};
+
+struct cfdriver vme_cd = {
+ NULL, "vme", DV_DULL
+};
+
struct intrhand **vmeints;
@@ -106,7 +129,7 @@ busmatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -140,6 +163,17 @@ busprint(args, obio)
return (UNCONF);
}
+int
+vmeprint(args, name)
+ void *args;
+ const char *name;
+{
+ register struct confargs *ca = args;
+
+ if (name)
+ printf("%s at %s", ca->ca_ra.ra_name, name);
+ return (UNCONF);
+}
void
obioattach(parent, self, args)
@@ -154,13 +188,16 @@ obioattach(parent, self, args)
register char *name;
register const char *sp;
const char *const *ssp;
+ int rlen;
extern int autoconf_nzs;
static const char *const special4m[] = {
/* find these first */
"eeprom",
"counter",
+#if 0 /* Not all sun4m's have an `auxio' */
"auxio",
+#endif
"",
/* place device to ignore here */
"interrupt",
@@ -187,7 +224,7 @@ obioattach(parent, self, args)
* There is only one obio bus (it is in fact one of the Sbus slots)
* How about VME?
*/
- if (sc->sc_dev.dv_unit > 0) {
+ if (self->dv_unit > 0) {
printf(" unsupported\n");
return;
}
@@ -199,8 +236,16 @@ obioattach(parent, self, args)
else
oca.ca_ra.ra_bp = NULL;
- sc->bu.scu_sbus.sc_range = ra->ra_range;
- sc->bu.scu_sbus.sc_nrange = ra->ra_nrange;
+ node = ra->ra_node;
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->bu.scu_sbus.sc_nrange = rlen / sizeof(struct rom_range);
+ sc->bu.scu_sbus.sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->bu.scu_sbus.sc_range == 0)
+ panic("obio: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->bu.scu_sbus.sc_range, rlen);
+ }
/*
* Loop through ROM children, fixing any relative addresses
@@ -218,7 +263,7 @@ obioattach(parent, self, args)
sbus_translate(self, &oca);
oca.ca_bustype = BUS_OBIO;
- (void) config_found(&sc->sc_dev, (void *)&oca, busprint);
+ (void) config_found(self, (void *)&oca, busprint);
}
for (node = node0; node; node = nextsibling(node)) {
@@ -237,7 +282,7 @@ obioattach(parent, self, args)
/* Translate into parent address spaces */
sbus_translate(self, &oca);
oca.ca_bustype = BUS_OBIO;
- (void) config_found(&sc->sc_dev, (void *)&oca, busprint);
+ (void) config_found(self, (void *)&oca, busprint);
}
#endif
}
@@ -247,7 +292,8 @@ vmesattach(parent, self, args)
struct device *parent, *self;
void *args;
{
- if (CPU_ISSUN4M || self->dv_unit > 0) {
+ if (self->dv_unit > 0 ||
+ (CPU_ISSUN4M && strncmp(parent->dv_xname, "vme", 3) != 0)) {
printf(" unsupported\n");
return;
}
@@ -267,7 +313,8 @@ vmelattach(parent, self, args)
struct device *parent, *self;
void *args;
{
- if (CPU_ISSUN4M || self->dv_unit > 0) {
+ if (self->dv_unit > 0 ||
+ (CPU_ISSUN4M && strncmp(parent->dv_xname, "vme", 3) != 0)) {
printf(" unsupported\n");
return;
}
@@ -282,14 +329,116 @@ vmelattach(parent, self, args)
bus_untmp();
}
+void
+vmeattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct vmebus_softc *sc = (struct vmebus_softc *)self;
+ struct confargs *ca = aux;
+ register struct romaux *ra = &ca->ca_ra;
+ int node, rlen;
+ struct confargs oca;
+
+ if (!CPU_ISSUN4M || self->dv_unit > 0) {
+ printf(" unsupported\n");
+ return;
+ }
+
+ node = ra->ra_node;
+
+ sc->sc_reg = (struct vmebusreg *)
+ mapdev(&ra->ra_reg[0], 0, 0, ra->ra_reg[0].rr_len);
+ sc->sc_vec = (struct vmebusvec *)
+ mapdev(&ra->ra_reg[1], 0, 0, ra->ra_reg[1].rr_len);
+
+ /*
+ * Get "range" property, though we don't do anything with it yet.
+ */
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->sc_nrange = rlen / sizeof(struct rom_range);
+ sc->sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_range == 0)
+ panic("vme: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->sc_range, rlen);
+ }
+
+ vmebus_sc = sc;
+ printf(": version 0x%x\n",
+ sc->sc_reg->vmebus_cr & VMEBUS_CR_IMPL);
+
+ if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "vme") == 0)
+ oca.ca_ra.ra_bp = ra->ra_bp + 1;
+ else
+ oca.ca_ra.ra_bp = NULL;
+
+ oca.ca_ra.ra_name = "vmes";
+ oca.ca_bustype = BUS_MAIN;
+ (void)config_found(self, (void *)&oca, vmeprint);
+
+ oca.ca_ra.ra_name = "vmel";
+ oca.ca_bustype = BUS_MAIN;
+ (void)config_found(self, (void *)&oca, vmeprint);
+}
+
+void
+vmebus_translate(dev, ca, bustype)
+ struct device *dev;
+ struct confargs *ca;
+ int bustype;
+{
+ struct vmebus_softc *sc = (struct vmebus_softc *)dev;
+ register int j;
+ int cspace;
+
+ if (sc->sc_nrange == 0)
+ panic("vmebus: no ranges");
+
+ /*
+ * Find VMEbus modifier based on address space.
+ * XXX - should not be encoded in `ra_paddr'
+ */
+ if (((u_long)ca->ca_ra.ra_paddr & 0xffff0000) == 0xffff0000)
+ cspace = VMEMOD_A16_D_S;
+ else if (((u_long)ca->ca_ra.ra_paddr & 0xff000000) == 0xff000000)
+ cspace = VMEMOD_A24_D_S;
+ else
+ cspace = VMEMOD_A32_D_S;
+
+ cspace |= (bustype == BUS_VME32) ? VMEMOD_D32 : 0;
+
+ /* Translate into parent address spaces */
+ for (j = 0; j < sc->sc_nrange; j++) {
+ if (sc->sc_range[j].cspace == cspace) {
+#if notyet
+ (int)ca->ca_ra.ra_paddr +=
+ sc->sc_range[j].poffset;
+#endif
+ (int)ca->ca_ra.ra_iospace =
+ sc->sc_range[j].pspace;
+ break;
+ }
+ }
+}
+
+int bt2pmt[] = {
+ PMAP_OBIO,
+ PMAP_OBIO,
+ PMAP_VME16,
+ PMAP_VME32,
+ PMAP_OBIO
+};
+
int
-busattach(parent, child, args, bustype)
+busattach(parent, vcf, args, bustype)
struct device *parent;
- void *args, *child;
+ void *vcf, *args;
int bustype;
{
-#if defined(SUN4)
- struct cfdata *cf = child;
+#if defined(SUN4) || defined(SUN4M)
+ register struct cfdata *cf = vcf;
register struct confargs *ca = args;
struct confargs oca;
caddr_t tmp;
@@ -309,24 +458,24 @@ busattach(parent, child, args, bustype)
* XXX: We also assume that 4/[23]00 obio addresses
* must be 0xZYYYYYYY, where (Z != 0)
*/
- if (cpumod == SUN4_100 && (cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type == CPUTYP_4_100 &&
+ (cf->cf_loc[0] & 0xf0000000))
return 0;
- if (cpumod != SUN4_100 && !(cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type != CPUTYP_4_100 &&
+ !(cf->cf_loc[0] & 0xf0000000))
return 0;
}
- if (parent->dv_cfdata->cf_driver->cd_indirect) {
- printf(" indirect devices not supported\n");
- return 0;
- }
-
- oca.ca_ra.ra_iospace = -1;
oca.ca_ra.ra_paddr = (void *)cf->cf_loc[0];
oca.ca_ra.ra_len = 0;
oca.ca_ra.ra_nreg = 1;
+ if (CPU_ISSUN4M)
+ vmebus_translate(parent->dv_parent, &oca, bustype);
+ else
+ oca.ca_ra.ra_iospace = bt2pmt[bustype];
+
if (oca.ca_ra.ra_paddr)
- tmp = (caddr_t)bus_tmp(oca.ca_ra.ra_paddr,
- bustype);
+ tmp = (caddr_t)mapdev(oca.ca_ra.ra_reg, TMPMAP_VA, 0, NBPG);
else
tmp = NULL;
oca.ca_ra.ra_vaddr = tmp;
@@ -364,8 +513,7 @@ busattach(parent, child, args, bustype)
*/
if (oca.ca_ra.ra_len)
oca.ca_ra.ra_vaddr =
- bus_map(oca.ca_ra.ra_reg,
- oca.ca_ra.ra_len, oca.ca_bustype);
+ bus_map(oca.ca_ra.ra_reg, oca.ca_ra.ra_len);
config_attach(parent, cf, &oca, busprint);
return 1;
@@ -421,18 +569,19 @@ int
vmeintr(arg)
void *arg;
{
- int level = (int)arg, vec;
+ int pil = (int)arg, level, vec;
struct intrhand *ih;
int i = 0;
-#ifdef DIAGNOSTIC
- if (!CPU_ISSUN4) {
+ level = (pil_to_vme[pil] << 1) | 1;
+
+ if (CPU_ISSUN4) {
+ vec = ldcontrolb((caddr_t)(AC_VMEINTVEC | level));
+ } else if (CPU_ISSUN4M) {
+ vec = vmebus_sc->sc_vec->vmebusvec[level];
+ } else
panic("vme: spurious interrupt");
- }
-#endif
- vec = ldcontrolb((caddr_t)
- (AC_VMEINTVEC | (pil_to_vme[level] << 1) | 1));
if (vec == -1) {
printf("vme: spurious interrupt\n");
return 0;
@@ -451,13 +600,11 @@ vmeintr_establish(vec, level, ih)
{
struct intrhand *ihs;
- if (!CPU_ISSUN4) {
- panic("vmeintr_establish: not supported on cpu-type %d",
- cputyp);
- }
+ if (vmeints == NULL)
+ panic("vmeintr_establish: interrupt vector not allocated");
if (vec == -1)
- panic("vmeintr_establish: uninitialized vec\n");
+ panic("vmeintr_establish: uninitialized vec");
if (vmeints[vec] == NULL)
vmeints[vec] = ih;
@@ -489,28 +636,16 @@ vmeintr_establish(vec, level, ih)
* Else, create a new mapping.
*/
void *
-bus_map(pa, len, bustype)
+bus_map(pa, len)
struct rom_reg *pa;
int len;
- int bustype;
{
- u_long pf = (u_long)(pa->rr_paddr) >> PGSHIFT;
- u_long va, pte;
- int pgtype = -1;
-
- switch (bt2pmt[bustype]) {
- case PMAP_OBIO:
- pgtype = PG_OBIO;
- break;
- case PMAP_VME32:
- pgtype = PG_VME32;
- break;
- case PMAP_VME16:
- pgtype = PG_VME16;
- break;
- }
- if (len <= NBPG) {
+ if (CPU_ISSUN4 && len <= NBPG) {
+ u_long pf = (u_long)(pa->rr_paddr) >> PGSHIFT;
+ int pgtype = PMAP_T2PTE_4(pa->rr_iospace);
+ u_long va, pte;
+
for (va = OLDMON_STARTVADDR; va < OLDMON_ENDVADDR; va += NBPG) {
pte = getpte(va);
if ((pte & PG_V) != 0 && (pte & PG_TYPE) == pgtype &&
@@ -520,21 +655,8 @@ bus_map(pa, len, bustype)
/* note: preserve page offset */
}
}
- return mapiodev(pa, 0, len, bustype);
-}
-
-void *
-bus_tmp(pa, bustype)
- void *pa;
- int bustype;
-{
- vm_offset_t addr = (vm_offset_t)pa & ~PGOFSET;
- int pmtype = bt2pmt[bustype];
- pmap_enter(pmap_kernel(), TMPMAP_VA,
- addr | pmtype | PMAP_NC,
- VM_PROT_READ | VM_PROT_WRITE, 1);
- return ((void *)(TMPMAP_VA | ((u_long) pa & PGOFSET)) );
+ return mapiodev(pa, 0, len);
}
void
diff --git a/sys/arch/sparc/dev/pfour.c b/sys/arch/sparc/dev/pfour.c
index 3ed22d7df5c..c903754515a 100644
--- a/sys/arch/sparc/dev/pfour.c
+++ b/sys/arch/sparc/dev/pfour.c
@@ -1,4 +1,4 @@
-/* $Id: pfour.c,v 1.5 1995/12/15 13:56:26 deraadt Exp $ */
+/* $OpenBSD: pfour.c,v 1.6 1997/08/08 08:25:20 downsj Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
diff --git a/sys/arch/sparc/dev/pfourreg.h b/sys/arch/sparc/dev/pfourreg.h
index 8ec422c2019..a0ef7094c05 100644
--- a/sys/arch/sparc/dev/pfourreg.h
+++ b/sys/arch/sparc/dev/pfourreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: pfourreg.h,v 1.4 1997/08/08 08:25:21 downsj Exp $ */
/* $NetBSD: pfourreg.h,v 1.1 1996/02/27 22:09:36 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/power.c b/sys/arch/sparc/dev/power.c
index d083500333f..0255c25c059 100644
--- a/sys/arch/sparc/dev/power.c
+++ b/sys/arch/sparc/dev/power.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: power.c,v 1.3 1997/06/22 22:45:34 downsj Exp $ */
+/* $OpenBSD: power.c,v 1.4 1997/08/08 08:25:22 downsj Exp $ */
/* $NetBSD: power.c,v 1.2 1996/05/16 15:56:56 abrown Exp $ */
/*
@@ -91,7 +91,7 @@ powerattach(parent, self, aux)
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
- power_reg = mapdev(ra->ra_reg, 0, 0, sizeof(long), ca->ca_bustype);
+ power_reg = mapdev(ra->ra_reg, 0, 0, sizeof(long));
power_attached = 1;
diff --git a/sys/arch/sparc/dev/rcons_font.h b/sys/arch/sparc/dev/rcons_font.h
index 3cbc847ea53..292ce909ba0 100644
--- a/sys/arch/sparc/dev/rcons_font.h
+++ b/sys/arch/sparc/dev/rcons_font.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: rcons_font.h,v 1.4 1997/08/08 08:25:25 downsj Exp $ */
/* $NetBSD: rcons_font.h,v 1.3 1995/11/29 22:03:53 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/sbus.c b/sys/arch/sparc/dev/sbus.c
index 0f7ceff3bbf..aee7de7fbf8 100644
--- a/sys/arch/sparc/dev/sbus.c
+++ b/sys/arch/sparc/dev/sbus.c
@@ -1,4 +1,5 @@
-/* $NetBSD: sbus.c,v 1.10 1996/04/22 02:35:03 abrown Exp $ */
+/* $OpenBSD: sbus.c,v 1.5 1997/08/08 08:25:27 downsj Exp $ */
+/* $NetBSD: sbus.c,v 1.17 1997/06/01 22:10:39 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -49,8 +50,10 @@
*/
#include <sys/param.h>
+#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <vm/vm.h>
#include <machine/autoconf.h>
@@ -96,7 +99,7 @@ sbus_match(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -121,6 +124,7 @@ sbus_attach(parent, self, aux)
register int node;
register char *name;
struct confargs oca;
+ int rlen;
/*
* XXX there is only one Sbus, for now -- do not know how to
@@ -149,8 +153,15 @@ sbus_attach(parent, self, aux)
else
oca.ca_ra.ra_bp = NULL;
- sc->sc_range = ra->ra_range;
- sc->sc_nrange = ra->ra_nrange;
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->sc_nrange = rlen / sizeof(struct rom_range);
+ sc->sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_range == 0)
+ panic("sbus: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->sc_range, rlen);
+ }
/*
* Loop through ROM children, fixing any relative addresses
@@ -183,15 +194,19 @@ sbus_translate(dev, ca)
ca->ca_slot = SBUS_ABS_TO_SLOT(base);
ca->ca_offset = SBUS_ABS_TO_OFFSET(base);
} else {
+ if (!CPU_ISSUN4C)
+ panic("relative sbus addressing not supported");
ca->ca_slot = slot = ca->ca_ra.ra_iospace;
ca->ca_offset = base;
- ca->ca_ra.ra_paddr =
- (void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_paddr = (void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_iospace = PMAP_OBIO;
+
/* Fix any remaining register banks */
for (i = 1; i < ca->ca_ra.ra_nreg; i++) {
base = (int)ca->ca_ra.ra_reg[i].rr_paddr;
ca->ca_ra.ra_reg[i].rr_paddr =
(void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_reg[i].rr_iospace = PMAP_OBIO;
}
}
@@ -237,12 +252,13 @@ sbus_establish(sd, dev)
*/
for (curdev = dev->dv_parent; ; curdev = curdev->dv_parent) {
if (!curdev || !curdev->dv_xname)
- panic("sbus_establish: can't find sbus parent for %s",
- (sd->sd_dev->dv_xname ? sd->sd_dev->dv_xname :
- "<unknown>"));
+ panic("sbus_establish: can't find sbus parent for %s",
+ sd->sd_dev->dv_xname
+ ? sd->sd_dev->dv_xname
+ : "<unknown>" );
if (strncmp(curdev->dv_xname, "sbus", 4) == 0)
- break;
+ break;
}
sc = (struct sbus_softc *) curdev;
diff --git a/sys/arch/sparc/dev/sbusreg.h b/sys/arch/sparc/dev/sbusreg.h
index 74c0b270292..3455f5eb366 100644
--- a/sys/arch/sparc/dev/sbusreg.h
+++ b/sys/arch/sparc/dev/sbusreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sbusreg.h,v 1.2 1997/08/08 08:25:27 downsj Exp $ */
/* $NetBSD: sbusreg.h,v 1.2 1994/11/20 20:52:26 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/sbusvar.h b/sys/arch/sparc/dev/sbusvar.h
index 72fa1025523..21fd61967c2 100644
--- a/sys/arch/sparc/dev/sbusvar.h
+++ b/sys/arch/sparc/dev/sbusvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sbusvar.h,v 1.4 1997/08/08 08:25:28 downsj Exp $ */
/* $NetBSD: sbusvar.h,v 1.4 1996/04/22 02:35:05 abrown Exp $ */
/*
diff --git a/sys/arch/sparc/dev/si.c b/sys/arch/sparc/dev/si.c
index 5aa1f4f4946..a96caafb133 100644
--- a/sys/arch/sparc/dev/si.c
+++ b/sys/arch/sparc/dev/si.c
@@ -1,11 +1,13 @@
-/* $NetBSD: si.c,v 1.24 1996/05/13 01:53:45 thorpej Exp $ */
+/* $OpenBSD: si.c,v 1.10 1997/08/08 08:25:29 downsj Exp $ */
+/* $NetBSD: si.c,v 1.37 1997/07/29 09:58:13 fair Exp $ */
-/*
- * Copyright (c) 1995 Jason R. Thorpe
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Adam Glass
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
* All rights reserved.
*
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Adam Glass, David Jones, Gordon W. Ross, and Jason R. Thorpe.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,23 +16,25 @@
* 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. The name of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
+ * 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by
- * Adam Glass, David Jones, Gordon Ross, and Jason R. Thorpe
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 AUTHORS ``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 AUTHORS 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.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
*/
/*
@@ -108,6 +112,7 @@
#include <machine/pmap.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#ifndef DDB
#define Debugger()
@@ -190,7 +195,7 @@ struct si_softc {
#define SI_DO_RESELECT 0x04 /* Allow disconnect/reselect */
#define SI_OPTIONS_MASK (SI_ENABLE_DMA|SI_DMA_INTR|SI_DO_RESELECT)
#define SI_OPTIONS_BITS "\10\3RESELECT\2DMA_INTR\1DMA"
-int si_options = 0; /* XXX SI_ENABLE_DMA when dma works */
+int si_options = SI_ENABLE_DMA;
int sw_options = SI_ENABLE_DMA;
/* How long to wait for DMA before declaring an error. */
@@ -201,7 +206,6 @@ static void si_attach __P((struct device *, struct device *, void *));
static int si_intr __P((void *));
static void si_reset_adapter __P((struct ncr5380_softc *));
static void si_minphys __P((struct buf *));
-static int si_print __P((void *, const char *));
void si_dma_alloc __P((struct ncr5380_softc *));
void si_dma_free __P((struct ncr5380_softc *));
@@ -259,22 +263,12 @@ struct cfdriver sw_cd = {
};
static int
-si_print(aux, name)
- void *aux;
- const char *name;
-{
- if (name != NULL)
- printf("%s: scsibus ", name);
- return UNCONF;
-}
-
-static int
-si_match(parent, vcf, args)
+si_match(parent, vcf, aux)
struct device *parent;
- void *vcf, *args;
+ void *vcf, *aux;
{
- struct cfdata *cf = vcf;
- struct confargs *ca = args;
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
/* Are we looking for the right thing? */
@@ -296,13 +290,15 @@ si_match(parent, vcf, args)
switch (ca->ca_bustype) {
case BUS_VME16:
/* AFAIK, the `si' can only exist on the vmes. */
- if (strcmp(ra->ra_name, "si") || cpumod == SUN4_100)
+ if (strcmp(ra->ra_name, "si") ||
+ cpuinfo.cpu_type == CPUTYP_4_100)
return (0);
break;
case BUS_OBIO:
/* AFAIK, an `sw' can only exist on the obio. */
- if (strcmp(ra->ra_name, "sw") || cpumod != SUN4_100)
+ if (strcmp(ra->ra_name, "sw") ||
+ cpuinfo.cpu_type != CPUTYP_4_100)
return (0);
break;
@@ -341,17 +337,20 @@ si_attach(parent, self, args)
struct bootpath *bp;
int i;
- /* Pull in the options flags. */
- if (ca->ca_bustype == BUS_OBIO)
- sc->sc_options = sw_options;
+ /*
+ * Pull in the options flags. Allow the user to completely
+ * override the default values.
+ */
+ if ((ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK) != 0)
+ sc->sc_options =
+ (ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK);
else
- sc->sc_options = si_options;
- sc->sc_options |=
- (ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK);
+ sc->sc_options =
+ (ca->ca_bustype == BUS_OBIO) ? sw_options : si_options;
/* Map the controller registers. */
- regs = (struct si_regs *)mapiodev(ra->ra_reg, 0,
- sizeof(struct si_regs), ca->ca_bustype);
+ regs = (struct si_regs *)
+ mapiodev(ra->ra_reg, 0, sizeof(struct si_regs));
/*
* Fill in the prototype scsi_link.
@@ -413,7 +412,7 @@ si_attach(parent, self, args)
}
ncr_sc->sc_flags = 0;
- if (sc->sc_options & SI_DO_RESELECT)
+ if ((sc->sc_options & SI_DO_RESELECT) == 0)
ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
if ((sc->sc_options & SI_DMA_INTR) == 0)
ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
@@ -494,7 +493,7 @@ si_attach(parent, self, args)
bootpath_store(1, bp + 1);
/* Configure sub-devices */
- config_found(self, &(ncr_sc->sc_link), si_print);
+ config_found(self, &(ncr_sc->sc_link), scsiprint);
bootpath_store(1, NULL);
}
@@ -505,7 +504,7 @@ si_minphys(struct buf *bp)
if (bp->b_bcount > MAX_DMA_LEN) {
#ifdef DEBUG
if (si_debug) {
- printf("si_minphys len = %x.\n", MAX_DMA_LEN);
+ printf("si_minphys len = 0x%x.\n", MAX_DMA_LEN);
Debugger();
}
#endif
@@ -658,21 +657,6 @@ si_dma_alloc(ncr_sc)
if (xlen < MIN_DMA_LEN)
panic("si_dma_alloc: xlen=0x%x\n", xlen);
- /*
- * XXX SUN4 doesn't have this limitation?
- * Never attempt single transfers of more than 63k, because
- * our count register may be only 16 bits (an OBIO adapter).
- * This should never happen since already bounded by minphys().
- * XXX - Should just segment these...
- */
- if (xlen > MAX_DMA_LEN) {
- printf("si_dma_alloc: excessive xlen=0x%x\n", xlen);
-#ifdef DEBUG
- Debugger();
-#endif
- ncr_sc->sc_datalen = xlen = MAX_DMA_LEN;
- }
-
/* Find free DMA handle. Guaranteed to find one since we have
as many DMA handles as the driver has processes. */
for (i = 0; i < SCI_OPENINGS; i++) {
@@ -701,7 +685,7 @@ found:
dh->dh_dvma = (long)kdvma_mapin((caddr_t)addr, xlen, 0);
if (dh->dh_dvma == 0) {
/* Can't remap segment */
- printf("si_dma_alloc: can't remap %p/%x, doing PIO\n",
+ printf("si_dma_alloc: can't remap %p/0x%x, doing PIO\n",
dh->dh_addr, dh->dh_maplen);
dh->dh_flags = 0;
return;
diff --git a/sys/arch/sparc/dev/sireg.h b/sys/arch/sparc/dev/sireg.h
index 8f2ab6e40e3..d17fc344b74 100644
--- a/sys/arch/sparc/dev/sireg.h
+++ b/sys/arch/sparc/dev/sireg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sireg.h,v 1.3 1997/08/08 08:25:30 downsj Exp $ */
/* $NetBSD: sireg.h,v 1.3 1996/01/01 22:40:58 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/tcx.c b/sys/arch/sparc/dev/tcx.c
new file mode 100644
index 00000000000..608fb4e64c0
--- /dev/null
+++ b/sys/arch/sparc/dev/tcx.c
@@ -0,0 +1,496 @@
+/* $OpenBSD: tcx.c,v 1.1 1997/08/08 08:25:31 downsj Exp $ */
+/* $NetBSD: tcx.c,v 1.8 1997/07/29 09:58:14 fair Exp $ */
+
+/*
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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.
+ */
+
+/*
+ * color display (TCX) driver.
+ *
+ * Does not handle interrupts, even though they can occur.
+ *
+ * XXX should defer colormap updates to vertical retrace interrupts
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <machine/fbio.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+
+#ifdef DEBUG
+#include <sys/proc.h>
+#include <sys/syslog.h>
+#endif
+
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+#include <machine/fbvar.h>
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <sparc/dev/btreg.h>
+#include <sparc/dev/btvar.h>
+#include <sparc/dev/tcxreg.h>
+#include <sparc/dev/sbusvar.h>
+
+#if 0
+union cursor_cmap { /* colormap, like bt_cmap, but tiny */
+ u_char cm_map[2][3]; /* 2 R/G/B entries */
+ u_int cm_chip[2]; /* 2 chip equivalents */
+};
+
+struct tcx_cursor { /* tcx hardware cursor status */
+ short cc_enable; /* cursor is enabled */
+ struct fbcurpos cc_pos; /* position */
+ struct fbcurpos cc_hot; /* hot-spot */
+ struct fbcurpos cc_size; /* size of mask & image fields */
+ u_int cc_bits[2][32]; /* space for mask & image bits */
+ union cursor_cmap cc_color; /* cursor colormap */
+};
+#endif
+
+/* per-display variables */
+struct tcx_softc {
+ struct device sc_dev; /* base device */
+ struct sbusdev sc_sd; /* sbus device */
+ struct fbdevice sc_fb; /* frame buffer device */
+ struct rom_reg sc_physadr[TCX_NREG]; /* phys addr of h/w */
+ int sc_bustype; /* type of bus we live on */
+ volatile struct bt_regs *sc_bt; /* Brooktree registers */
+ volatile struct tcx_thc *sc_thc; /* THC registers */
+ short sc_blanked; /* true if blanked */
+ union bt_cmap sc_cmap; /* Brooktree color map */
+};
+
+/* autoconfiguration driver */
+static void tcxattach __P((struct device *, struct device *, void *));
+static int tcxmatch __P((struct device *, void *, void *));
+static void tcx_unblank __P((struct device *));
+
+/* cdevsw prototypes */
+cdev_decl(tcx);
+
+struct cfattach tcx_ca = {
+ sizeof(struct tcx_softc), tcxmatch, tcxattach
+};
+
+struct cfdriver tcx_cd = {
+ NULL, "tcx", DV_DULL
+};
+
+/* frame buffer generic driver */
+static struct fbdriver tcx_fbdriver = {
+ tcx_unblank, tcxopen, tcxclose, tcxioctl, tcxmmap
+};
+
+extern int fbnode;
+
+static void tcx_reset __P((struct tcx_softc *));
+static void tcx_loadcmap __P((struct tcx_softc *, int, int));
+
+#define OBPNAME "SUNW,tcx"
+/*
+ * Match a tcx.
+ */
+int
+tcxmatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+
+ if (strcmp(ra->ra_name, OBPNAME))
+ return (0);
+
+ /*
+ * Mask out invalid flags from the user.
+ */
+ cf->cf_flags &= FB_USERMASK;
+
+ if (ca->ca_bustype == BUS_SBUS)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Attach a display.
+ */
+void
+tcxattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ register struct tcx_softc *sc = (struct tcx_softc *)self;
+ register struct confargs *ca = args;
+ register int node = 0, ramsize, i;
+ register volatile struct bt_regs *bt;
+ struct fbdevice *fb = &sc->sc_fb;
+ int isconsole = 0, sbus = 1;
+ extern struct tty *fbconstty;
+
+ fb->fb_driver = &tcx_fbdriver;
+ fb->fb_device = &sc->sc_dev;
+ fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
+
+ /*
+ * XXX - should be set to FBTYPE_TCX.
+ * XXX For CG3 emulation to work in current (96/6) X11 servers,
+ * XXX `fbtype' must point to an "unregocnised" entry.
+ */
+ fb->fb_type.fb_type = FBTYPE_RESERVED3;
+
+ if (ca->ca_ra.ra_nreg != TCX_NREG)
+ panic("tcx: oops");
+
+ /* Copy register address spaces */
+ for (i = 0; i < TCX_NREG; i++)
+ sc->sc_physadr[i] = ca->ca_ra.ra_reg[i];
+
+ /* XXX - fix THC and TEC offsets */
+ sc->sc_physadr[TCX_REG_TEC].rr_paddr += 0x1000;
+ sc->sc_physadr[TCX_REG_THC].rr_paddr += 0x1000;
+
+ sc->sc_bt = bt = (volatile struct bt_regs *)
+ mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt);
+ sc->sc_thc = (volatile struct tcx_thc *)
+ mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC], 0, sizeof *sc->sc_thc);
+
+ switch (ca->ca_bustype) {
+ case BUS_SBUS:
+ node = ca->ca_ra.ra_node;
+ break;
+
+ case BUS_OBIO:
+ default:
+ printf("TCX on bus 0x%x?\n", ca->ca_bustype);
+ return;
+ }
+
+ fb->fb_type.fb_depth = node_has_property(node, "tcx-24-bit")
+ ? 24
+ : (node_has_property(node, "tcx-8-bit")
+ ? 8
+ : 8);
+
+ fb_setsize(fb, fb->fb_type.fb_depth, 1152, 900,
+ node, ca->ca_bustype);
+
+ ramsize = fb->fb_type.fb_height * fb->fb_linebytes;
+ fb->fb_type.fb_cmsize = 256;
+ fb->fb_type.fb_size = ramsize;
+ printf(": %s, %d x %d", OBPNAME,
+ fb->fb_type.fb_width,
+ fb->fb_type.fb_height);
+
+ isconsole = node == fbnode && fbconstty != NULL;
+
+ printf(", id %d, rev %d, sense %d",
+ (sc->sc_thc->thc_config & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
+ (sc->sc_thc->thc_config & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
+ (sc->sc_thc->thc_config & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
+ );
+
+ /* reset cursor & frame buffer controls */
+ tcx_reset(sc);
+
+ /* grab initial (current) color map (DOES THIS WORK?) */
+ bt->bt_addr = 0;
+ for (i = 0; i < 256 * 3; i++)
+ ((char *)&sc->sc_cmap)[i] = bt->bt_cmap >> 24;
+
+ /* enable video */
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+
+ if (isconsole) {
+ printf(" (console)\n");
+ } else
+ printf("\n");
+
+ if (sbus)
+ sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ if (node == fbnode)
+ fb_attach(&sc->sc_fb, isconsole);
+}
+
+int
+tcxopen(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+
+ if (unit >= tcx_cd.cd_ndevs || tcx_cd.cd_devs[unit] == NULL)
+ return (ENXIO);
+ return (0);
+}
+
+int
+tcxclose(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+
+ tcx_reset(sc);
+ return (0);
+}
+
+int
+tcxioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ register caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ register struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+ int error;
+
+ switch (cmd) {
+
+ case FBIOGTYPE:
+ *(struct fbtype *)data = sc->sc_fb.fb_type;
+ break;
+
+ case FBIOGATTR:
+#define fba ((struct fbgattr *)data)
+ fba->real_type = sc->sc_fb.fb_type.fb_type;
+ fba->owner = 0; /* XXX ??? */
+ fba->fbtype = sc->sc_fb.fb_type;
+ fba->sattr.flags = 0;
+ fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
+ fba->sattr.dev_specific[0] = -1;
+ fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
+ fba->emu_types[1] = FBTYPE_SUN3COLOR;
+ fba->emu_types[2] = -1;
+#undef fba
+ break;
+
+ case FBIOGETCMAP:
+ return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
+
+ case FBIOPUTCMAP:
+ /* copy to software map */
+#define p ((struct fbcmap *)data)
+ error = bt_putcmap(p, &sc->sc_cmap, 256);
+ if (error)
+ return (error);
+ /* now blast them into the chip */
+ /* XXX should use retrace interrupt */
+ tcx_loadcmap(sc, p->index, p->count);
+#undef p
+ break;
+
+ case FBIOGVIDEO:
+ *(int *)data = sc->sc_blanked;
+ break;
+
+ case FBIOSVIDEO:
+ if (*(int *)data)
+ tcx_unblank(&sc->sc_dev);
+ else if (!sc->sc_blanked) {
+ sc->sc_blanked = 1;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
+ /* Put monitor in `power-saving mode' */
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
+ }
+ break;
+
+ default:
+#ifdef DEBUG
+ log(LOG_NOTICE, "tcxioctl(0x%lx) (%s[%d])\n", cmd,
+ p->p_comm, p->p_pid);
+#endif
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+/*
+ * Clean up hardware state (e.g., after bootup or after X crashes).
+ */
+static void
+tcx_reset(sc)
+ register struct tcx_softc *sc;
+{
+ register volatile struct bt_regs *bt;
+
+ /* Enable cursor in Brooktree DAC. */
+ bt = sc->sc_bt;
+ bt->bt_addr = 0x06 << 24;
+ bt->bt_ctrl |= 0x03 << 24;
+}
+
+/*
+ * Load a subset of the current (new) colormap into the color DAC.
+ */
+static void
+tcx_loadcmap(sc, start, ncolors)
+ register struct tcx_softc *sc;
+ register int start, ncolors;
+{
+ register volatile struct bt_regs *bt;
+ register u_int *ip, i;
+ register int count;
+
+ ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */
+ count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
+ bt = sc->sc_bt;
+ bt->bt_addr = BT_D4M4(start) << 24;
+ while (--count >= 0) {
+ i = *ip++;
+ /* hardware that makes one want to pound boards with hammers */
+ bt->bt_cmap = i;
+ bt->bt_cmap = i << 8;
+ bt->bt_cmap = i << 16;
+ bt->bt_cmap = i << 24;
+ }
+}
+
+static void
+tcx_unblank(dev)
+ struct device *dev;
+{
+ struct tcx_softc *sc = (struct tcx_softc *)dev;
+
+ if (sc->sc_blanked) {
+ sc->sc_blanked = 0;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+ }
+}
+
+/*
+ * Base addresses at which users can mmap() the various pieces of a tcx.
+ */
+#define TCX_USER_RAM 0x00000000
+#define TCX_USER_RAM24 0x01000000
+#define TCX_USER_RAM_COMPAT 0x04000000 /* cg3 emulation */
+#define TCX_USER_STIP 0x10000000
+#define TCX_USER_BLIT 0x20000000
+#define TCX_USER_RDFB32 0x28000000
+#define TCX_USER_RSTIP 0x30000000
+#define TCX_USER_RBLIT 0x38000000
+#define TCX_USER_TEC 0x70001000
+#define TCX_USER_BTREGS 0x70002000
+#define TCX_USER_THC 0x70004000
+#define TCX_USER_DHC 0x70008000
+#define TCX_USER_ALT 0x7000a000
+#define TCX_USER_UART 0x7000c000
+#define TCX_USER_VRT 0x7000e000
+#define TCX_USER_ROM 0x70010000
+
+struct mmo {
+ u_int mo_uaddr; /* user (virtual) address */
+ u_int mo_size; /* size, or 0 for video ram size */
+ u_int mo_bank; /* register bank number */
+};
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ *
+ * XXX needs testing against `demanding' applications (e.g., aviator)
+ */
+int
+tcxmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ register struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+ register struct mmo *mo;
+ register u_int u, sz;
+ static struct mmo mmo[] = {
+ { TCX_USER_RAM, 0, TCX_REG_DFB8 },
+ { TCX_USER_RAM24, 0, TCX_REG_DFB24 },
+ { TCX_USER_RAM_COMPAT, 0, TCX_REG_DFB8 },
+
+ { TCX_USER_STIP, 1, TCX_REG_STIP },
+ { TCX_USER_BLIT, 1, TCX_REG_BLIT },
+ { TCX_USER_RDFB32, 1, TCX_REG_RDFB32 },
+ { TCX_USER_RSTIP, 1, TCX_REG_RSTIP },
+ { TCX_USER_RBLIT, 1, TCX_REG_RBLIT },
+ { TCX_USER_TEC, 1, TCX_REG_TEC },
+ { TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP },
+ { TCX_USER_THC, sizeof(struct tcx_thc), TCX_REG_THC },
+ { TCX_USER_DHC, 1, TCX_REG_DHC },
+ { TCX_USER_ALT, 1, TCX_REG_ALT },
+ { TCX_USER_ROM, 65536, TCX_REG_ROM },
+ };
+#define NMMO (sizeof mmo / sizeof *mmo)
+
+ if (off & PGOFSET)
+ panic("tcxmmap");
+
+ /*
+ * Entries with size 0 map video RAM (i.e., the size in fb data).
+ *
+ * Since we work in pages, the fact that the map offset table's
+ * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
+ * one byte is as good as one page.
+ */
+ for (mo = mmo; mo < &mmo[NMMO]; mo++) {
+ if ((u_int)off < mo->mo_uaddr)
+ continue;
+ u = off - mo->mo_uaddr;
+ sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
+ if (u < sz)
+ return (REG2PHYS(&sc->sc_physadr[mo->mo_bank], u) |
+ PMAP_NC);
+ }
+#ifdef DEBUG
+ {
+ register struct proc *p = curproc; /* XXX */
+ log(LOG_NOTICE, "tcxmmap(0x%x) (%s[%d])\n", off, p->p_comm, p->p_pid);
+ }
+#endif
+ return (-1); /* not a user-map offset */
+}
diff --git a/sys/arch/sparc/dev/tcxreg.h b/sys/arch/sparc/dev/tcxreg.h
new file mode 100644
index 00000000000..ef48a21955c
--- /dev/null
+++ b/sys/arch/sparc/dev/tcxreg.h
@@ -0,0 +1,151 @@
+/* $OpenBSD: tcxreg.h,v 1.1 1997/08/08 08:25:32 downsj Exp $ */
+/* $NetBSD: tcxreg.h,v 1.1 1996/06/19 13:17:35 pk Exp $ */
+/*
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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.
+ */
+
+/*
+ * A TCX is composed of numerous groups of control registers, all with TLAs:
+ * DHC - ???
+ * TEC - transform engine control?
+ * THC - TEC Hardware Configuration
+ * ROM - a 128Kbyte ROM with who knows what in it.
+ * STIP - ???
+ * RSTIP - Raw ???
+ * BLIT - ???
+ * RBLIT - Raw ???
+ * ALT - ???
+ * colormap - see below
+ * frame buffer memory (video RAM)
+ * possible other stuff
+ *
+ */
+#define TCX_REG_DFB8 0
+#define TCX_REG_DFB24 1
+#define TCX_REG_STIP 2
+#define TCX_REG_BLIT 3
+#define TCX_REG_RDFB32 4
+#define TCX_REG_RSTIP 5
+#define TCX_REG_RBLIT 6
+#define TCX_REG_TEC 7
+#define TCX_REG_CMAP 8
+#define TCX_REG_THC 9
+#define TCX_REG_ROM 10
+#define TCX_REG_DHC 11
+#define TCX_REG_ALT 12
+
+#define TCX_NREG 13
+
+
+/*
+ * The layout of the THC.
+ */
+struct tcx_thc {
+ u_int thc_config;
+ u_int thc_xxx1[31];
+ u_int thc_sensebus;
+ u_int thc_xxx2[3];
+ u_int thc_delay;
+ u_int thc_strapping;
+ u_int thc_xxx3[1];
+ u_int thc_linecount;
+ u_int thc_xxx4[478];
+ u_int thc_hcmisc;
+ u_int thc_xxx5[56];
+ u_int thc_cursoraddr;
+ u_int thc_cursorAdata[32];
+ u_int thc_cursorBdata[32];
+
+};
+/* bits in thc_config ??? */
+#define THC_CFG_FBID 0xf0000000 /* id mask */
+#define THC_CFG_FBID_SHIFT 28
+#define THC_CFG_SENSE 0x07000000 /* sense mask */
+#define THC_CFG_SENSE_SHIFT 24
+#define THC_CFG_REV 0x00f00000 /* revision mask */
+#define THC_CFG_REV_SHIFT 20
+#define THC_CFG_RST 0x00008000 /* reset */
+
+/* bits in thc_hcmisc */
+#define THC_MISC_OPENFLG 0x80000000 /* open flag (what's that?) */
+#define THC_MISC_SWERR_EN 0x20000000 /* enable SW error interrupt */
+#define THC_MISC_VSYNC_LEVEL 0x08000000 /* vsync level when disabled */
+#define THC_MISC_HSYNC_LEVEL 0x04000000 /* hsync level when disabled */
+#define THC_MISC_VSYNC_DISABLE 0x02000000 /* vsync disable */
+#define THC_MISC_HSYNC_DISABLE 0x01000000 /* hsync disable */
+#define THC_MISC_XXX1 0x00ffe000 /* unused */
+#define THC_MISC_RESET 0x00001000 /* ??? */
+#define THC_MISC_XXX2 0x00000800 /* unused */
+#define THC_MISC_VIDEN 0x00000400 /* video enable */
+#define THC_MISC_SYNC 0x00000200 /* not sure what ... */
+#define THC_MISC_VSYNC 0x00000100 /* ... these really are */
+#define THC_MISC_SYNCEN 0x00000080 /* sync enable */
+#define THC_MISC_CURSRES 0x00000040 /* cursor resolution */
+#define THC_MISC_INTEN 0x00000020 /* v.retrace intr enable */
+#define THC_MISC_INTR 0x00000010 /* intr pending / ack bit */
+#define THC_MISC_DACWAIT 0x0000000f /* ??? */
+
+/*
+ * Partial description of TEC.
+ */
+struct tcx_tec {
+ u_int tec_config; /* what's in it? */
+ u_int tec_xxx0[35];
+ u_int tec_delay; /* */
+#define TEC_DELAY_SYNC 0x00000f00
+#define TEC_DELAY_WR_F 0x000000c0
+#define TEC_DELAY_WR_R 0x00000030
+#define TEC_DELAY_SOE_F 0x0000000c
+#define TEC_DELAY_SOE_S 0x00000003
+ u_int tec_strapping; /* */
+#define TEC_STRAP_FIFO_LIMIT 0x00f00000
+#define TEC_STRAP_CACHE_EN 0x00010000
+#define TEC_STRAP_ZERO_OFFSET 0x00008000
+#define TEC_STRAP_REFRSH_DIS 0x00004000
+#define TEC_STRAP_REF_LOAD 0x00001000
+#define TEC_STRAP_REFRSH_PERIOD 0x000003ff
+ u_int tec_hcmisc; /* */
+ u_int tec_linecount; /* */
+ u_int tec_hss; /* */
+ u_int tec_hse; /* */
+ u_int tec_hds; /* */
+ u_int tec_hsedvs; /* */
+ u_int tec_hde; /* */
+ u_int tec_vss; /* */
+ u_int tec_vse; /* */
+ u_int tec_vds; /* */
+ u_int tec_vde; /* */
+};
+
diff --git a/sys/arch/sparc/dev/vmereg.h b/sys/arch/sparc/dev/vmereg.h
new file mode 100644
index 00000000000..5e7eb708ea4
--- /dev/null
+++ b/sys/arch/sparc/dev/vmereg.h
@@ -0,0 +1,75 @@
+/* $OpenBSD: vmereg.h,v 1.1 1997/08/08 08:25:32 downsj Exp $ */
+/* $NetBSD: vmereg.h,v 1.2 1997/06/07 19:10:57 pk Exp $ */
+
+/*
+ * Copyright (c) 1997 Paul Kranenburg
+ *
+ * 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 Paul Kranenburg.
+ * 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.
+ *
+ */
+
+struct vmebusreg {
+ u_int32_t vmebus_cr; /* VMEbus control register */
+ u_int32_t vmebus_afar; /* VMEbus async fault address */
+ u_int32_t vmebus_afsr; /* VMEbus async fault status */
+};
+
+/* Control Register bits */
+#define VMEBUS_CR_C 0x80000000 /* I/O cache enable */
+#define VMEBUS_CR_S 0x40000000 /* VME slave enable */
+#define VMEBUS_CR_L 0x20000000 /* Loopback enable (diagnostic) */
+#define VMEBUS_CR_R 0x10000000 /* VMEbus reset */
+#define VMEBUS_CR_RSVD 0x0ffffff0 /* reserved */
+#define VMEBUS_CR_IMPL 0x0000000f /* VMEbus interface implementation */
+
+/* Asynchronous Fault Status bits */
+#define VMEBUS_AFSR_SZ 0xe0000000 /* Error transaction size */
+#define VMEBUS_AFSR_SZ4 0 /* 4 byte */
+#define VMEBUS_AFSR_SZ1 1 /* 1 byte */
+#define VMEBUS_AFSR_SZ2 2 /* 2 byte */
+#define VMEBUS_AFSR_SZ32 5 /* 32 byte */
+#define VMEBUS_AFSR_TO 0x10000000 /* VME master access time-out */
+#define VMEBUS_AFSR_BERR 0x08000000 /* VME master got BERR */
+#define VMEBUS_AFSR_WB 0x04000000 /* IOC write-back error (if SZ == 32) */
+ /* Non-IOC write error (id SZ != 32) */
+#define VMEBUS_AFSR_ERR 0x02000000 /* Error summary bit */
+#define VMEBUS_AFSR_S 0x01000000 /* MVME error in supervisor space */
+#define VMEBUS_AFSR_ME 0x00800000 /* Multiple error */
+#define VMEBUS_AFSR_RSVD 0x007fffff /* reserved */
+
+struct vmebusvec {
+ volatile u_int8_t vmebusvec[16];
+};
+
+/* VME address modifiers */
+#define VMEMOD_A16_D_S 0x2d /* 16-bit address, data, supervisor */
+#define VMEMOD_A24_D_S 0x3d /* 24-bit address, data, supervisor */
+#define VMEMOD_A32_D_S 0x0d /* 32-bit address, data, supervisor */
+
+#define VMEMOD_D32 0x40 /* 32-bit access */
+
diff --git a/sys/arch/sparc/dev/xd.c b/sys/arch/sparc/dev/xd.c
index 70caf5e3e48..5bf36fe6db2 100644
--- a/sys/arch/sparc/dev/xd.c
+++ b/sys/arch/sparc/dev/xd.c
@@ -1,4 +1,5 @@
-/* $NetBSD: xd.c,v 1.25 1996/04/22 02:42:06 christos Exp $ */
+/* $OpenBSD: xd.c,v 1.10 1997/08/08 08:25:35 downsj Exp $ */
+/* $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $ */
/*
*
@@ -36,7 +37,7 @@
* x d . c x y l o g i c s 7 5 3 / 7 0 5 3 v m e / s m d d r i v e r
*
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $NetBSD: xd.c,v 1.25 1996/04/22 02:42:06 christos Exp $
+ * id: $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $
* started: 27-Feb-95
* references: [1] Xylogics Model 753 User's Manual
* part number: 166-753-001, Revision B, May 21, 1988.
@@ -85,6 +86,7 @@
#include <sparc/dev/xdvar.h>
#include <sparc/dev/xio.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
/*
* macros
@@ -346,11 +348,11 @@ xdgetdisklabel(xd, b)
* soft reset to detect the xdc.
*/
-int xdcmatch(parent, match, aux)
+int xdcmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
struct xdc *xdc;
@@ -359,7 +361,13 @@ int xdcmatch(parent, match, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
- if (CPU_ISSUN4) {
+ switch (ca->ca_bustype) {
+ case BUS_OBIO:
+ case BUS_SBUS:
+ case BUS_VME16:
+ default:
+ return (0);
+ case BUS_VME32:
xdc = (struct xdc *) ra->ra_vaddr;
if (probeget((caddr_t) &xdc->xdc_csr, 1) == -1)
return (0);
@@ -367,8 +375,8 @@ int xdcmatch(parent, match, aux)
XDC_WAIT(xdc, del, XDC_RESETUSEC, XDC_RESET);
if (del <= 0)
return (0);
+ return (1);
}
- return (1);
}
/*
@@ -389,8 +397,7 @@ xdcattach(parent, self, aux)
/* get addressing and intr level stuff from autoconfig and load it
* into our xdc_softc. */
- ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct xdc), ca->ca_bustype);
+ ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct xdc));
xdc->xdc = (struct xdc *) ca->ca_ra.ra_vaddr;
pri = ca->ca_ra.ra_intr[0].int_pri;
@@ -463,7 +470,7 @@ xdcattach(parent, self, aux)
XDC_DONE(xdc, rqno, err);
return;
}
- printf(": Xylogics 753/7053, PROM=%x.%02x.%02x\n",
+ printf(": Xylogics 753/7053, PROM=0x%x.%02x.%02x\n",
ctl->eprom_partno, ctl->eprom_lvl, ctl->eprom_rev);
XDC_DONE(xdc, rqno, err);
@@ -514,12 +521,11 @@ xdcattach(parent, self, aux)
* call xdattach!).
*/
int
-xdmatch(parent, match, aux)
+xdmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
-
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct xdc_attach_args *xa = aux;
/* looking for autoconf wildcard or exact match */
@@ -987,24 +993,28 @@ xdsize(dev)
{
struct xd_softc *xdsc;
- int part, size;
+ int unit, part, size, omask;
- /* valid unit? try an open */
+ /* valid unit? */
+ unit = DISKUNIT(dev);
+ if (unit >= xd_cd.cd_ndevs || (xdsc = xd_cd.cd_devs[unit]) == NULL)
+ return (-1);
- if (xdopen(dev, 0, S_IFBLK, NULL) != 0)
+ part = DISKPART(dev);
+ omask = xdsc->sc_dk.dk_openmask & (1 << part);
+
+ if (omask == 0 && xdopen(dev, 0, S_IFBLK, NULL) != 0)
return (-1);
/* do it */
-
- xdsc = xd_cd.cd_devs[DISKUNIT(dev)];
- part = DISKPART(dev);
if (xdsc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
size = -1; /* only give valid size for swap partitions */
else
- size = xdsc->sc_dk.dk_label->d_partitions[part].p_size;
- if (xdclose(dev, 0, S_IFBLK, NULL) != 0)
- return -1;
- return size;
+ size = xdsc->sc_dk.dk_label->d_partitions[part].p_size *
+ (xdsc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+ if (omask == 0 && xdclose(dev, 0, S_IFBLK, NULL) != 0)
+ return (-1);
+ return (size);
}
/*
* xdstrategy: buffering system interface to xd.
@@ -1221,7 +1231,7 @@ xdc_rqtopb(iorq, iopb, cmd, subfun)
XDPC_RBC | XDPC_ECC2;
ctrl->throttle = XDC_THROTTLE;
#ifdef sparc
- if (CPU_ISSUN4 && cpumod == SUN4_300)
+ if (CPU_ISSUN4 && cpuinfo.cpu_type == CPUTYP_4_300)
ctrl->delay = XDC_DELAY_4_300;
else
ctrl->delay = XDC_DELAY_SPARC;
diff --git a/sys/arch/sparc/dev/xdreg.h b/sys/arch/sparc/dev/xdreg.h
index c723d018d0d..c2e19564ced 100644
--- a/sys/arch/sparc/dev/xdreg.h
+++ b/sys/arch/sparc/dev/xdreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xdreg.h,v 1.3 1997/08/08 08:25:36 downsj Exp $ */
/* $NetBSD: xdreg.h,v 1.3 1996/03/31 22:38:54 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xdvar.h b/sys/arch/sparc/dev/xdvar.h
index 294f3a8c84b..c3e35672ba4 100644
--- a/sys/arch/sparc/dev/xdvar.h
+++ b/sys/arch/sparc/dev/xdvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xdvar.h,v 1.4 1997/08/08 08:25:37 downsj Exp $ */
/* $NetBSD: xdvar.h,v 1.5 1996/03/31 22:38:56 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xio.h b/sys/arch/sparc/dev/xio.h
index 1ad5662b6be..c55c733712e 100644
--- a/sys/arch/sparc/dev/xio.h
+++ b/sys/arch/sparc/dev/xio.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xio.h,v 1.3 1997/08/08 08:25:37 downsj Exp $ */
/* $NetBSD: xio.h,v 1.2 1996/03/31 22:38:58 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xy.c b/sys/arch/sparc/dev/xy.c
index 2841bd9ba84..2dc3413f2fe 100644
--- a/sys/arch/sparc/dev/xy.c
+++ b/sys/arch/sparc/dev/xy.c
@@ -1,4 +1,5 @@
-/* $NetBSD: xy.c,v 1.17 1996/04/22 02:42:04 christos Exp $ */
+/* $OpenBSD: xy.c,v 1.9 1997/08/08 08:25:39 downsj Exp $ */
+/* $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $ */
/*
*
@@ -36,7 +37,7 @@
* x y . c x y l o g i c s 4 5 0 / 4 5 1 s m d d r i v e r
*
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $NetBSD: xy.c,v 1.17 1996/04/22 02:42:04 christos Exp $
+ * id: $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $
* started: 14-Sep-95
* references: [1] Xylogics Model 753 User's Manual
* part number: 166-753-001, Revision B, May 21, 1988.
@@ -287,11 +288,11 @@ xygetdisklabel(xy, b)
* soft reset to detect the xyc.
*/
-int xycmatch(parent, match, aux)
+int xycmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
struct xyc *xyc;
@@ -299,14 +300,20 @@ int xycmatch(parent, match, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
- if (CPU_ISSUN4) {
+ switch (ca->ca_bustype) {
+ case BUS_OBIO:
+ case BUS_SBUS:
+ case BUS_VME32:
+ default:
+ return (0);
+ case BUS_VME16:
xyc = (struct xyc *) ra->ra_vaddr;
if (probeget((caddr_t) &xyc->xyc_rsetup, 1) == -1)
return (0);
if (xyc_unbusy(xyc, XYC_RESETUSEC) == XY_ERR_FAIL)
return(0);
+ return (1);
}
- return (1);
}
/*
@@ -329,8 +336,7 @@ xycattach(parent, self, aux)
/* get addressing and intr level stuff from autoconfig and load it
* into our xyc_softc. */
- ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct xyc), ca->ca_bustype);
+ ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct xyc));
xyc->xyc = (struct xyc *) ca->ca_ra.ra_vaddr;
pri = ca->ca_ra.ra_intr[0].int_pri;
@@ -458,12 +464,11 @@ xycattach(parent, self, aux)
* call xyattach!).
*/
int
-xymatch(parent, match, aux)
+xymatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
-
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct xyc_attach_args *xa = aux;
/* looking for autoconf wildcard or exact match */
@@ -951,24 +956,28 @@ xysize(dev)
{
struct xy_softc *xysc;
- int part, size;
+ int unit, part, size, omask;
- /* valid unit? try an open */
+ /* valid unit? */
+ unit = DISKUNIT(dev);
+ if (unit >= xy_cd.cd_ndevs || (xysc = xy_cd.cd_devs[unit]) == NULL)
+ return (-1);
- if (xyopen(dev, 0, S_IFBLK, NULL) != 0)
+ part = DISKPART(dev);
+ omask = xysc->sc_dk.dk_openmask & (1 << part);
+
+ if (omask == 0 && xyopen(dev, 0, S_IFBLK, NULL) != 0)
return (-1);
/* do it */
-
- xysc = xy_cd.cd_devs[DISKUNIT(dev)];
- part = DISKPART(dev);
if (xysc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
size = -1; /* only give valid size for swap partitions */
else
- size = xysc->sc_dk.dk_label->d_partitions[part].p_size;
- if (xyclose(dev, 0, S_IFBLK, NULL) != 0)
- return -1;
- return size;
+ size = xysc->sc_dk.dk_label->d_partitions[part].p_size *
+ (xysc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+ if (omask == 0 && xyclose(dev, 0, S_IFBLK, NULL) != 0)
+ return (-1);
+ return (size);
}
/*
diff --git a/sys/arch/sparc/dev/xyreg.h b/sys/arch/sparc/dev/xyreg.h
index 2508bb97a8e..2d8c2704685 100644
--- a/sys/arch/sparc/dev/xyreg.h
+++ b/sys/arch/sparc/dev/xyreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xyreg.h,v 1.3 1997/08/08 08:25:40 downsj Exp $ */
/* $NetBSD: xyreg.h,v 1.3 1996/03/31 22:39:02 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xyvar.h b/sys/arch/sparc/dev/xyvar.h
index e7ec8305980..f6f80cee49d 100644
--- a/sys/arch/sparc/dev/xyvar.h
+++ b/sys/arch/sparc/dev/xyvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xyvar.h,v 1.4 1997/08/08 08:25:41 downsj Exp $ */
/* $NetBSD: xyvar.h,v 1.4 1996/03/31 22:39:04 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/zs.c b/sys/arch/sparc/dev/zs.c
index c44f4aefe72..b9cb8b8eb56 100644
--- a/sys/arch/sparc/dev/zs.c
+++ b/sys/arch/sparc/dev/zs.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: zs.c,v 1.14 1997/06/25 13:01:00 downsj Exp $ */
-/* $NetBSD: zs.c,v 1.37.4.1 1996/06/02 09:07:55 mrg Exp $ */
+/* $OpenBSD: zs.c,v 1.15 1997/08/08 08:25:43 downsj Exp $ */
+/* $NetBSD: zs.c,v 1.48 1997/07/29 09:58:18 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -72,21 +72,18 @@
#include <machine/autoconf.h>
#include <machine/conf.h>
#include <machine/cpu.h>
+#include <machine/kbd.h>
#include <sparc/sparc/vaddrs.h>
#include <sparc/sparc/auxreg.h>
-
-
-#include <machine/kbd.h>
#include <dev/ic/z8530reg.h>
-
#include <sparc/dev/zsvar.h>
#ifdef KGDB
#include <machine/remote-sl.h>
#endif
-#define ZSMAJOR 12 /* XXX */
+#define ZSMAJOR 12 /* XXX */
#define ZS_KBD 2 /* XXX */
#define ZS_MOUSE 3 /* XXX */
@@ -113,8 +110,8 @@
struct zs_softc {
struct device sc_dev; /* base device */
volatile struct zsdevice *sc_zs; /* chip registers */
- struct evcnt sc_intrcnt;
- struct zs_chanstate sc_cs[2]; /* channel A/B software state */
+ struct evcnt sc_intrcnt; /* count interrupts */
+ struct zs_chanstate sc_cs[2]; /* chan A/B software state */
};
/* Definition of the driver for autoconfig. */
@@ -154,10 +151,11 @@ static void zs_loadchannelregs __P((volatile struct zschan *, u_char *));
/* Console stuff. */
static struct tty *zs_ctty; /* console `struct tty *' */
static int zs_consin = -1, zs_consout = -1;
+static struct zs_chanstate *zs_conscs = NULL; /*console channel state */
static void zscnputc __P((int)); /* console putc function */
static volatile struct zschan *zs_conschan;
static struct tty *zs_checkcons __P((struct zs_softc *, int,
- struct zs_chanstate *));
+ struct zs_chanstate *));
#ifdef KGDB
/* KGDB stuff. Must reboot to change zs_kgdbunit. */
@@ -176,7 +174,6 @@ static int zssint __P((struct zs_chanstate *, volatile struct zschan *));
void zsabort __P((void));
static void zsoverrun __P((int, long *, char *));
-extern void *findzs __P((int));
static volatile struct zsdevice *zsaddr[NZS]; /* XXX, but saves work */
/*
@@ -272,7 +269,7 @@ zsattach(parent, dev, aux)
if ((addr = zsaddr[zs]) == NULL)
addr = zsaddr[zs] = (volatile struct zsdevice *)findzs(zs);
- if (ca->ca_bustype == BUS_MAIN)
+ if (ca->ca_bustype==BUS_MAIN)
if ((void *)addr != ra->ra_vaddr)
panic("zsattach");
if (ra->ra_nintr != 1) {
@@ -311,11 +308,12 @@ zsattach(parent, dev, aux)
tp->t_dev = makedev(ZSMAJOR, unit);
tp->t_oproc = zsstart;
tp->t_param = zsparam;
+ }
+ cs->cs_ttyp = tp;
#ifdef KGDB
+ if (ctp == NULL)
zs_checkkgdb(unit, cs, tp);
#endif
- }
- cs->cs_ttyp = tp;
if (unit == ZS_KBD) {
/*
* Keyboard: tell /dev/kbd driver how to talk to us.
@@ -329,14 +327,15 @@ zsattach(parent, dev, aux)
if (tp != ctp)
tty_attach(tp);
ringsize = 4096;
+ if (unit == zs_consout)
+ zs_conscs = cs;
}
-
cs->cs_ringmask = ringsize - 1;
cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
M_DEVBUF, M_NOWAIT);
+
unit++;
cs++;
-
cs->cs_unit = unit;
cs->cs_speed = zs_getspeed(&addr->zs_chan[ZS_CHAN_B]);
cs->cs_zc = &addr->zs_chan[ZS_CHAN_B];
@@ -347,11 +346,12 @@ zsattach(parent, dev, aux)
tp->t_dev = makedev(ZSMAJOR, unit);
tp->t_oproc = zsstart;
tp->t_param = zsparam;
+ }
+ cs->cs_ttyp = tp;
#ifdef KGDB
+ if (ctp == NULL)
zs_checkkgdb(unit, cs, tp);
#endif
- }
- cs->cs_ttyp = tp;
if (unit == ZS_MOUSE) {
/*
* Mouse: tell /dev/mouse driver how to talk to us.
@@ -364,6 +364,8 @@ zsattach(parent, dev, aux)
if (tp != ctp)
tty_attach(tp);
ringsize = 4096;
+ if (unit == zs_consout)
+ zs_conscs = cs;
}
cs->cs_ringmask = ringsize - 1;
cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
@@ -439,7 +441,7 @@ zsconsole(tp, unit, out, fnstop)
v_putc = zscnputc;
} else
zs_consin = unit;
- if(fnstop)
+ if (fnstop)
*fnstop = &zsstop;
zs_ctty = tp;
}
@@ -465,6 +467,24 @@ zscnputc(c)
(void) splzs();
while ((zc->zc_csr & ZSRR0_TX_READY) == 0)
ZS_DELAY();
+ /*
+ * If transmitter was busy doing regular tty I/O (ZSWR1_TIE on),
+ * defer our output until the transmit interrupt runs. We still
+ * sync with TX_READY so we can get by with a single-char "queue".
+ */
+ if (zs_conscs != NULL && (zs_conscs->cs_creg[1] & ZSWR1_TIE)) {
+ /*
+ * If previous not yet done, send it now; zsxint()
+ * will field the interrupt for our char, but doesn't
+ * care. We're running at sufficiently high spl for
+ * this to work.
+ */
+ if (zs_conscs->cs_deferred_cc != 0)
+ zc->zc_data = zs_conscs->cs_deferred_cc;
+ zs_conscs->cs_deferred_cc = c;
+ splx(s);
+ return;
+ }
zc->zc_data = c;
ZS_DELAY();
splx(s);
@@ -483,7 +503,7 @@ zs_checkcons(sc, unit, cs)
register struct tty *tp;
char *i, *o;
- if ((tp = zs_ctty) == NULL)
+ if ((tp = zs_ctty) == NULL) /* XXX */
return (0);
i = zs_consin == unit ? "input" : NULL;
o = zs_consout == unit ? "output" : NULL;
@@ -623,7 +643,7 @@ zsopen(dev, flags, mode, p)
return (EBUSY);
}
error = 0;
- while (1) {
+ for (;;) {
register int rr0;
/* loop, turning on the device, until carrier present */
@@ -720,6 +740,7 @@ zsread(dev, uio, flags)
tp = cs->cs_ttyp;
return (linesw[tp->t_line].l_read(tp, uio, flags));
+
}
int
@@ -850,7 +871,7 @@ zshard(intrarg)
raise(0, PIL_TTY);
else
#endif
- ienab_bis(IE_ZSSOFT);
+ ienab_bis(IE_ZSSOFT);
}
return (intflags & ZSHARD_WAS_SERVICED);
}
@@ -860,11 +881,9 @@ zsrint(cs, zc)
register struct zs_chanstate *cs;
register volatile struct zschan *zc;
{
- register u_int c;
+ register u_int c = zc->zc_data;
- c = zc->zc_data;
ZS_DELAY();
-
if (cs->cs_conk) {
register struct conk_state *conk = &zsconk_state;
@@ -922,6 +941,15 @@ zsxint(cs, zc)
{
register int i = cs->cs_tbc;
+ if (cs->cs_deferred_cc != 0) {
+ /* Handle deferred zscnputc() output first */
+ zc->zc_data = cs->cs_deferred_cc;
+ cs->cs_deferred_cc = 0;
+ ZS_DELAY();
+ zc->zc_csr = ZSWR0_CLR_INTR;
+ ZS_DELAY();
+ return (0);
+ }
if (i == 0) {
zc->zc_csr = ZSWR0_RESET_TXINT;
ZS_DELAY();
@@ -1145,7 +1173,7 @@ again:
break;
default:
- log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
+ log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (0x%x)\n",
unit >> 1, (unit & 1) + 'a', c);
break;
}
@@ -1166,9 +1194,9 @@ zsioctl(dev, cmd, data, flag, p)
{
int unit = minor(dev);
struct zs_softc *sc = zs_cd.cd_devs[unit >> 1];
- register struct tty *tp = sc->sc_cs[unit & 1].cs_ttyp;
- register int error, s;
register struct zs_chanstate *cs = &sc->sc_cs[unit & 1];
+ register struct tty *tp = cs->cs_ttyp;
+ register int error, s;
error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
if (error >= 0)
@@ -1262,14 +1290,8 @@ zsioctl(dev, cmd, data, flag, p)
case TIOCCDTR:
zs_modem(cs, 0);
break;
- case TIOCMGET:
- /* XXX: fixme */
- *(int *)data = TIOCM_CAR | TIOCM_CTS | TIOCM_DTR | TIOCM_RTS;
- return (0);
case TIOCMSET:
- /* XXX: fixme */
- zs_modem(cs, *(int *)data & (TIOCM_DTR|TIOCM_RTS));
- return (0);
+ case TIOCMGET:
case TIOCMBIS:
case TIOCMBIC:
default:
@@ -1396,7 +1418,11 @@ zsparam(tp, t)
return (0);
}
tmp = BPS_TO_TCONST(PCLK / 16, tmp);
- if (tmp < 2)
+#ifdef ALLOW_TC_EQUAL_ZERO
+ if (tmp < 0)
+#else
+ if (tmp < 1)
+#endif
return (EINVAL);
cflag = t->c_cflag;
diff --git a/sys/arch/sparc/dev/zsvar.h b/sys/arch/sparc/dev/zsvar.h
index 8f9274573ee..79b8c6cd2c9 100644
--- a/sys/arch/sparc/dev/zsvar.h
+++ b/sys/arch/sparc/dev/zsvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: zsvar.h,v 1.9 1996/08/12 03:14:50 downsj Exp $ */
-/* $NetBSD: zsvar.h,v 1.8 1996/03/31 22:39:08 pk Exp $ */
+/* $OpenBSD: zsvar.h,v 1.10 1997/08/08 08:25:44 downsj Exp $ */
+/* $NetBSD: zsvar.h,v 1.10 1997/04/14 21:26:28 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -91,9 +91,12 @@ struct zsdevice {
#define ZRING_VALUE(x) ((x) >> 8)
#define ZRING_MAKE(t, v) ((t) | (v) << 8)
+/* forard decl */
+struct zs_softc;
+
struct zs_chanstate {
- struct zs_chanstate *cs_next; /* linked list for zshard() */
- struct zs_softc *cs_sc; /* points to my softc */
+ struct zs_chanstate *cs_next; /* linked list for zshard() */
+ struct zs_softc *cs_sc; /* pointer to softc */
volatile struct zschan *cs_zc; /* points to hardware regs */
int cs_unit; /* unit number */
struct tty *cs_ttyp; /* ### */
@@ -123,6 +126,7 @@ struct zs_chanstate {
char cs_kgdb; /* enter debugger on frame char */
char cs_consio; /* port does /dev/console I/O */
char cs_xxx; /* (spare) */
+ char cs_deferred_cc; /* deferred zscnputc() output */
int cs_speed; /* default baud rate (from ROM) */
/*
diff --git a/sys/arch/sparc/fpu/fpu.c b/sys/arch/sparc/fpu/fpu.c
index 6a502402613..742add709d2 100644
--- a/sys/arch/sparc/fpu/fpu.c
+++ b/sys/arch/sparc/fpu/fpu.c
@@ -1,4 +1,5 @@
-/* $NetBSD: fpu.c,v 1.3 1996/03/14 19:41:49 christos Exp $ */
+/* $OpenBSD: fpu.c,v 1.7 1997/08/08 08:25:46 downsj Exp $ */
+/* $NetBSD: fpu.c,v 1.6 1997/07/29 10:09:51 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -143,7 +144,7 @@ fpu_cleanup(p, fs)
goto out;
default:
- printf("fsr=%x\n", fsr);
+ printf("fsr=0x%x\n", fsr);
panic("fpu error");
}
diff --git a/sys/arch/sparc/fpu/fpu_add.c b/sys/arch/sparc/fpu/fpu_add.c
index 1aa9225c01e..28ee40b9370 100644
--- a/sys/arch/sparc/fpu/fpu_add.c
+++ b/sys/arch/sparc/fpu/fpu_add.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_add.c,v 1.3 1997/08/08 08:25:47 downsj Exp $ */
/* $NetBSD: fpu_add.c,v 1.3 1996/03/14 19:41:52 christos Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_arith.h b/sys/arch/sparc/fpu/fpu_arith.h
index 572b16d7233..d222eae3a39 100644
--- a/sys/arch/sparc/fpu/fpu_arith.h
+++ b/sys/arch/sparc/fpu/fpu_arith.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_arith.h,v 1.2 1997/08/08 08:25:48 downsj Exp $ */
/* $NetBSD: fpu_arith.h,v 1.2 1994/11/20 20:52:35 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_compare.c b/sys/arch/sparc/fpu/fpu_compare.c
index 4868b535dfb..642b5497d70 100644
--- a/sys/arch/sparc/fpu/fpu_compare.c
+++ b/sys/arch/sparc/fpu/fpu_compare.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_compare.c,v 1.2 1997/08/08 08:25:49 downsj Exp $ */
/* $NetBSD: fpu_compare.c,v 1.2 1994/11/20 20:52:37 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_div.c b/sys/arch/sparc/fpu/fpu_div.c
index 0ddb592e45a..366844ec578 100644
--- a/sys/arch/sparc/fpu/fpu_div.c
+++ b/sys/arch/sparc/fpu/fpu_div.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_div.c,v 1.2 1997/08/08 08:25:50 downsj Exp $ */
/* $NetBSD: fpu_div.c,v 1.2 1994/11/20 20:52:38 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_emu.h b/sys/arch/sparc/fpu/fpu_emu.h
index 5b2b317c383..78f4dc69292 100644
--- a/sys/arch/sparc/fpu/fpu_emu.h
+++ b/sys/arch/sparc/fpu/fpu_emu.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_emu.h,v 1.2 1997/08/08 08:25:51 downsj Exp $ */
/* $NetBSD: fpu_emu.h,v 1.2 1994/11/20 20:52:39 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_explode.c b/sys/arch/sparc/fpu/fpu_explode.c
index ceaa896c02d..658ecdaf88b 100644
--- a/sys/arch/sparc/fpu/fpu_explode.c
+++ b/sys/arch/sparc/fpu/fpu_explode.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_explode.c,v 1.3 1997/08/08 08:25:52 downsj Exp $ */
/* $NetBSD: fpu_explode.c,v 1.3 1996/03/14 19:41:54 christos Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_extern.h b/sys/arch/sparc/fpu/fpu_extern.h
index 0f2ed79668d..fa7ca68daec 100644
--- a/sys/arch/sparc/fpu/fpu_extern.h
+++ b/sys/arch/sparc/fpu/fpu_extern.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_extern.h,v 1.2 1997/08/08 08:25:53 downsj Exp $ */
/* $NetBSD: fpu_extern.h,v 1.1 1996/03/14 19:41:56 christos Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_implode.c b/sys/arch/sparc/fpu/fpu_implode.c
index 753b0ba9973..5d07ac1e23b 100644
--- a/sys/arch/sparc/fpu/fpu_implode.c
+++ b/sys/arch/sparc/fpu/fpu_implode.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_implode.c,v 1.3 1997/08/08 08:25:56 downsj Exp $ */
/* $NetBSD: fpu_implode.c,v 1.3 1996/03/14 19:41:59 christos Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_mul.c b/sys/arch/sparc/fpu/fpu_mul.c
index e1439b1b354..241b0211b02 100644
--- a/sys/arch/sparc/fpu/fpu_mul.c
+++ b/sys/arch/sparc/fpu/fpu_mul.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_mul.c,v 1.2 1997/08/08 08:25:57 downsj Exp $ */
/* $NetBSD: fpu_mul.c,v 1.2 1994/11/20 20:52:44 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_sqrt.c b/sys/arch/sparc/fpu/fpu_sqrt.c
index 3fb12acd87c..e603226fc35 100644
--- a/sys/arch/sparc/fpu/fpu_sqrt.c
+++ b/sys/arch/sparc/fpu/fpu_sqrt.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_sqrt.c,v 1.2 1997/08/08 08:25:58 downsj Exp $ */
/* $NetBSD: fpu_sqrt.c,v 1.2 1994/11/20 20:52:46 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/fpu/fpu_subr.c b/sys/arch/sparc/fpu/fpu_subr.c
index 45b80c219ba..d1b5e17e53a 100644
--- a/sys/arch/sparc/fpu/fpu_subr.c
+++ b/sys/arch/sparc/fpu/fpu_subr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: fpu_subr.c,v 1.3 1997/08/08 08:25:59 downsj Exp $ */
/* $NetBSD: fpu_subr.c,v 1.3 1996/03/14 19:42:01 christos Exp $ */
/*
diff --git a/sys/arch/sparc/include/ansi.h b/sys/arch/sparc/include/ansi.h
index ecb80ec50d7..fce22059951 100644
--- a/sys/arch/sparc/include/ansi.h
+++ b/sys/arch/sparc/include/ansi.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: ansi.h,v 1.6 1997/08/08 08:26:01 downsj Exp $ */
/* $NetBSD: ansi.h,v 1.6 1996/11/15 22:38:59 jtc Exp $ */
/*-
diff --git a/sys/arch/sparc/include/asm.h b/sys/arch/sparc/include/asm.h
index 4241a44caa5..d1f4082b5f0 100644
--- a/sys/arch/sparc/include/asm.h
+++ b/sys/arch/sparc/include/asm.h
@@ -1,4 +1,5 @@
-/* $NetBSD: asm.h,v 1.3 1994/11/20 20:52:51 deraadt Exp $ */
+/* $OpenBSD: asm.h,v 1.2 1997/08/08 08:26:02 downsj Exp $ */
+/* $NetBSD: asm.h,v 1.5 1997/07/16 15:16:43 christos Exp $ */
/*
* Copyright (c) 1994 Allen Briggs
@@ -83,7 +84,7 @@
#define _ENTRY(name) \
.align 4; .globl name; .proc 1; FTYPE(name); name:
-#ifdef PROF
+#ifdef GPROF
#define _PROF_PROLOGUE \
.data; .align 4; 1: .long 0; \
.text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \
@@ -99,4 +100,6 @@
#define ASMSTR .asciz
+#define RCSID(name) .asciz name
+
#endif /* _ASM_H_ */
diff --git a/sys/arch/sparc/include/autoconf.h b/sys/arch/sparc/include/autoconf.h
index 1caa73db7ab..0e56dee8093 100644
--- a/sys/arch/sparc/include/autoconf.h
+++ b/sys/arch/sparc/include/autoconf.h
@@ -1,4 +1,5 @@
-/* $NetBSD: autoconf.h,v 1.16 1996/04/10 20:33:38 pk Exp $ */
+/* $OpenBSD: autoconf.h,v 1.5 1997/08/08 08:26:03 downsj Exp $ */
+/* $NetBSD: autoconf.h,v 1.20 1997/05/24 20:03:03 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -60,7 +61,6 @@
#define RA_MAXVADDR 8 /* max (virtual) addresses per device */
#define RA_MAXREG 16 /* max # of register banks per device */
#define RA_MAXINTR 8 /* max interrupts per device */
-#define RA_MAXRANGE 10 /* max # of bus translations */
struct romaux {
const char *ra_name; /* name from FORTH PROM */
@@ -85,18 +85,17 @@ struct romaux {
} ra_intr[RA_MAXINTR];
int ra_nintr; /* number of interrupt info elements */
- struct rom_range { /* Only used on v3 PROMs */
- u_int32_t cspace; /* Client space */
- u_int32_t coffset; /* Client offset */
- u_int32_t pspace; /* Parent space */
- u_int32_t poffset; /* Parent offset */
- u_int32_t size; /* Size in bytes of this range */
- } ra_range[RA_MAXRANGE];
- int ra_nrange;
-
struct bootpath *ra_bp; /* used for locating boot device */
};
+struct rom_range { /* Only used on v3 PROMs */
+ u_int32_t cspace; /* Client space */
+ u_int32_t coffset; /* Client offset */
+ u_int32_t pspace; /* Parent space */
+ u_int32_t poffset; /* Parent offset */
+ u_int32_t size; /* Size in bytes of this range */
+};
+
struct confargs {
int ca_bustype;
@@ -110,8 +109,6 @@ struct confargs {
#define BUS_VME32 3
#define BUS_SBUS 4
-extern int bt2pmt[];
-
/*
* mapiodev maps an I/O device to a virtual address, returning the address.
* mapdev does the real work: you can supply a special virtual address and
@@ -119,22 +116,17 @@ extern int bt2pmt[];
* you get it from ../sparc/vaddrs.h.
*/
void *mapdev __P((struct rom_reg *pa, int va,
- int offset, int size, int bustype));
-#define mapiodev(pa, offset, size, bustype) \
- mapdev(pa, 0, offset, size, bustype)
+ int offset, int size));
+#define mapiodev(pa, offset, size) \
+ mapdev(pa, 0, offset, size)
/*
* REG2PHYS is provided for drivers with a `d_mmap' function.
*/
-#define REG2PHYS(rr, offset, bt) \
- (((u_int)(rr)->rr_paddr + (offset)) | \
- ((CPU_ISSUN4M) \
- ? ((rr)->rr_iospace << PMAP_SHFT4M) \
- : bt2pmt[bt]) \
- )
+#define REG2PHYS(rr, offset) \
+ (((u_int)(rr)->rr_paddr + (offset)) | PMAP_IOENC((rr)->rr_iospace) )
/* For VME and sun4/obio busses */
-void *bus_map __P((struct rom_reg *, int, int));
-void *bus_tmp __P((void *, int));
+void *bus_map __P((struct rom_reg *, int));
void bus_untmp __P((void));
/*
@@ -142,6 +134,7 @@ void bus_untmp __P((void));
* getprop() obtains a property as a byte-sequence, and returns its
* length; the others convert or make some other guarantee.
*/
+int getproplen __P((int node, char *name));
int getprop __P((int node, char *name, void *buf, int bufsiz));
char *getpropstring __P((int node, char *name));
int getpropint __P((int node, char *name, int deflt));
@@ -163,6 +156,7 @@ int romprop __P((struct romaux *ra, const char *name, int node));
* a romaux structure suffices, for instance).
*/
struct device;
+struct cfdata;
int matchbyname __P((struct device *, void *cf, void *aux));
/*
diff --git a/sys/arch/sparc/include/bsd_audioio.h b/sys/arch/sparc/include/bsd_audioio.h
index 4d8bc0aeb34..6f496e0674d 100644
--- a/sys/arch/sparc/include/bsd_audioio.h
+++ b/sys/arch/sparc/include/bsd_audioio.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: bsd_audioio.h,v 1.2 1997/08/08 08:26:05 downsj Exp $ */
/* $NetBSD: bsd_audioio.h,v 1.3 1995/03/04 09:58:45 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/bsd_openprom.h b/sys/arch/sparc/include/bsd_openprom.h
index 35a9b3a7c13..4b2862dc186 100644
--- a/sys/arch/sparc/include/bsd_openprom.h
+++ b/sys/arch/sparc/include/bsd_openprom.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: bsd_openprom.h,v 1.5 1997/08/08 08:26:06 downsj Exp $ */
/* $NetBSD: bsd_openprom.h,v 1.11 1996/05/18 12:27:43 mrg Exp $ */
/*
diff --git a/sys/arch/sparc/include/cdefs.h b/sys/arch/sparc/include/cdefs.h
index 36f4990a9cc..54b934c3216 100644
--- a/sys/arch/sparc/include/cdefs.h
+++ b/sys/arch/sparc/include/cdefs.h
@@ -1,4 +1,5 @@
-/* $NetBSD: cdefs.h,v 1.2 1995/03/23 20:10:48 jtc Exp $ */
+/* $OpenBSD: cdefs.h,v 1.4 1997/08/08 08:26:07 downsj Exp $ */
+/* $NetBSD: cdefs.h,v 1.3 1996/12/27 20:51:31 pk Exp $ */
/*
* Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
@@ -30,6 +31,9 @@
__asm__(".stabs msg,30,0,0,0"); \
__asm__(".stabs \"_/**/sym\",1,0,0,0")
#endif
+#else
+#define __indr_reference(sym,alias)
+#define __warn_references(sym,msg)
#endif
#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/sys/arch/sparc/include/cgtworeg.h b/sys/arch/sparc/include/cgtworeg.h
index 6a874e77cfd..4660ba7f2b6 100644
--- a/sys/arch/sparc/include/cgtworeg.h
+++ b/sys/arch/sparc/include/cgtworeg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: cgtworeg.h,v 1.2 1997/08/08 08:26:09 downsj Exp $ */
/* $NetBSD: cgtworeg.h,v 1.3 1995/10/04 00:21:27 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/conf.h b/sys/arch/sparc/include/conf.h
index 20855735e69..cedfec5cc9b 100644
--- a/sys/arch/sparc/include/conf.h
+++ b/sys/arch/sparc/include/conf.h
@@ -1,5 +1,5 @@
-/* $NetBSD: conf.h,v 1.1 1996/03/30 21:17:55 christos Exp $ */
-/* $OpenBSD: conf.h,v 1.4 1997/05/06 19:07:36 kstailey Exp $ */
+/* $OpenBSD: conf.h,v 1.5 1997/08/08 08:26:10 downsj Exp $ */
+/* $NetBSD: conf.h,v 1.8 1996/12/31 07:12:43 mrg Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. All rights reserved.
@@ -62,6 +62,8 @@ cdev_decl(kbd);
cdev_decl(bwtwo);
+cdev_decl(cgtwo);
+
cdev_decl(cgthree);
cdev_decl(cgfour);
@@ -70,6 +72,10 @@ cdev_decl(cgsix);
cdev_decl(cgeight);
+cdev_decl(tcx);
+
+cdev_decl(cgfourteen);
+
cdev_decl(ipl);
#ifdef IPFILTER
#define NIPF 1
@@ -85,3 +91,6 @@ cdev_decl(xy);
bdev_decl(sw);
cdev_decl(sw);
+
+bdev_decl(rd);
+cdev_decl(rd);
diff --git a/sys/arch/sparc/include/cpu.h b/sys/arch/sparc/include/cpu.h
index 88c05b45a98..7f743246e7a 100644
--- a/sys/arch/sparc/include/cpu.h
+++ b/sys/arch/sparc/include/cpu.h
@@ -1,4 +1,5 @@
-/* $NetBSD: cpu.h,v 1.21 1996/03/31 22:17:14 pk Exp $ */
+/* $OpenBSD: cpu.h,v 1.3 1997/08/08 08:26:11 downsj Exp $ */
+/* $NetBSD: cpu.h,v 1.24 1997/03/15 22:25:15 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -44,8 +45,8 @@
* @(#)cpu.h 8.4 (Berkeley) 1/5/94
*/
-#ifndef _CPU_H_
-#define _CPU_H_
+#ifndef _SPARC_CPU_H_
+#define _SPARC_CPU_H_
/*
* CTL_MACHDEP definitions.
@@ -200,7 +201,7 @@ void copywords __P((const void *, void *, size_t));
void qcopy __P((const void *, void *, size_t));
void qzero __P((void *, size_t));
/* locore2.c */
-void remrq __P((struct proc *));
+void remrunqueue __P((struct proc *));
/* trap.c */
void kill_user_windows __P((struct proc *));
int rwindow_save __P((struct proc *));
@@ -229,6 +230,10 @@ void cpu_set_kpc __P((struct proc *, void (*)(struct proc *)));
/* iommu.c */
void iommu_enter __P((u_int, u_int));
void iommu_remove __P((u_int, u_int));
+/* emul.c */
+struct trapframe;
+int fixalign __P((struct proc *, struct trapframe *));
+int emulinstr __P((int, struct trapframe *));
/*
*
@@ -253,4 +258,4 @@ extern void wzero __P((void *, u_int));
extern void wcopy __P((const void *, void *, u_int));
#endif /* _KERNEL */
-#endif /* _CPU_H_ */
+#endif /* _SPARC_CPU_H_ */
diff --git a/sys/arch/sparc/include/ctlreg.h b/sys/arch/sparc/include/ctlreg.h
index 1f5d8519aef..fa79810cba2 100644
--- a/sys/arch/sparc/include/ctlreg.h
+++ b/sys/arch/sparc/include/ctlreg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: ctlreg.h,v 1.12 1996/05/16 15:57:00 abrown Exp $ */
+/* $OpenBSD: ctlreg.h,v 1.4 1997/08/08 08:26:12 downsj Exp $ */
+/* $NetBSD: ctlreg.h,v 1.15 1997/07/20 18:55:03 pk Exp $ */
/*
* Copyright (c) 1996
@@ -91,11 +92,11 @@
#define ASI_ICACHEDATA 0x0d /* [4m] instruction cache data */
#define ASI_DCACHETAG 0x0e /* [4m] data cache tag */
#define ASI_DCACHEDATA 0x0f /* [4m] data cache data */
-#define ASI_IDCACHELFP 0x10 /* [4m] ms2 only: flush i&d cache line (page) */
-#define ASI_IDCACHELFS 0x11 /* [4m] ms2 only: flush i&d cache line (seg) */
-#define ASI_IDCACHELFR 0x12 /* [4m] ms2 only: flush i&d cache line (reg) */
-#define ASI_IDCACHELFC 0x13 /* [4m] ms2 only: flush i&d cache line (ctxt) */
-#define ASI_IDCACHELFU 0x14 /* [4m] ms2 only: flush i&d cache line (user) */
+#define ASI_IDCACHELFP 0x10 /* [4m] flush i&d cache line (page) */
+#define ASI_IDCACHELFS 0x11 /* [4m] flush i&d cache line (seg) */
+#define ASI_IDCACHELFR 0x12 /* [4m] flush i&d cache line (reg) */
+#define ASI_IDCACHELFC 0x13 /* [4m] flush i&d cache line (ctxt) */
+#define ASI_IDCACHELFU 0x14 /* [4m] flush i&d cache line (user) */
#define ASI_BYPASS 0x20 /* [4m] sun ref mmu bypass,
ie. direct phys access */
#define ASI_ICACHECLR 0x36 /* [4m] ms1 only: I-cache flash clear */
@@ -199,37 +200,111 @@
#define SRMMU_SFADDR 0x00000400 /* Synchronous fault address reg */
#define SRMMU_AFSTAT 0x00000500 /* Asynchronous fault status reg (HS) */
#define SRMMU_AFADDR 0x00000600 /* Asynchronous fault address reg (HS)*/
+#define SRMMU_PCFG 0x00000600 /* Processor configuration reg (TURBO)*/
#define SRMMU_TLBCTRL 0x00001000 /* TLB replacement control reg */
-/* [4m] Bits in SRMMU control register */
-#define SRMMU_PCR_ME 0x00000001 /* MMU Enable */
-#define SRMMU_PCR_NF 0x00000002 /* Fault inhibit bit */
-#define SRMMU_PCR_PSO 0x00000080 /* Partial Store Ordering enable */
-#define SRMMU_PCR_CE 0x00000100 /* HS: Cache enable bit (HyperSPARC) */
-#define SRMMU_PCR_DCE 0x00000100 /* SS: Data cache enable bit */
-#define SRMMU_PCR_ICE 0x00000200 /* SS: SuperSPARC instr. cache enable */
-#define SRMMU_PCR_CM 0x00000400 /* HS: Cache mode: 1 == write-back */
-#define SRMMU_PCR_SB 0x00000400 /* SS: Store buffer enable bit */
-#define SRMMU_PCR_MR 0x00000800 /* HS: Memory reflection: 1 == on */
-#define SRMMU_PCR_MB 0x00000800 /* SS: MBus mode: 0=MXCC, 1=no MXCC */
-#define SRMMU_PCR_CS 0x00001000 /* HS: cache size: 1==256k, 0==128k */
-#define SRMMU_PCR_PE 0x00001000 /* SS: Enable memory parity checking */
-#define SRMMU_PCR_C 0x00002000 /* HS: enable cache when MMU off */
-#define SRMMU_PCR_SSBM 0x00002000 /* SS: 1 iff booting */
-#define SRMMU_PCR_HSBM 0x00004000 /* HS: 1 iff booting */
-#define SRMMU_PCR_SSSE 0x00004000 /* SS: Coherent bus snoop enable */
-#define SRMMU_PCR_AC 0x00008000 /* SS: 1=cache non-MMU accesses */
-#define SRMMU_PCR_TC 0x00010000 /* SS: 1=cache table walks */
-#define SRMMU_PCR_MID 0x00078000 /* HS: MBus module ID MID<3:0> */
-#define SRMMU_PCR_WBE 0x00080000 /* HS: Write buffer enable */
-#define SRMMU_PCR_HSSE 0x00100000 /* HS: Coherent bus snoop enable */
-#define SRMMU_PCR_CWR 0x00200000 /* HS: Cache wrap enable */
+
+/*
+ * [4m] Bits in SRMMU control register. One set per module.
+ */
+#define VIKING_PCR_ME 0x00000001 /* MMU Enable */
+#define VIKING_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define VIKING_PCR_PSO 0x00000080 /* Partial Store Ordering enable */
+#define VIKING_PCR_DCE 0x00000100 /* Data cache enable bit */
+#define VIKING_PCR_ICE 0x00000200 /* SuperSPARC instr. cache enable */
+#define VIKING_PCR_SB 0x00000400 /* Store buffer enable bit */
+#define VIKING_PCR_MB 0x00000800 /* MBus mode: 0=MXCC, 1=no MXCC */
+#define VIKING_PCR_PE 0x00001000 /* Enable memory parity checking */
+#define VIKING_PCR_BM 0x00002000 /* 1 iff booting */
+#define VIKING_PCR_SE 0x00004000 /* Coherent bus snoop enable */
+#define VIKING_PCR_AC 0x00008000 /* 1=cache non-MMU accesses */
+#define VIKING_PCR_TC 0x00010000 /* 1=cache table walks */
+
+#define HYPERSPARC_PCR_ME 0x00000001 /* MMU Enable */
+#define HYPERSPARC_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define HYPERSPARC_PCR_CE 0x00000100 /* Cache enable bit */
+#define HYPERSPARC_PCR_CM 0x00000400 /* Cache mode: 1=write-back */
+#define HYPERSPARC_PCR_MR 0x00000800 /* Memory reflection: 1 = on */
+#define HYPERSPARC_PCR_CS 0x00001000 /* cache size: 1=256k, 0=128k */
+#define HYPERSPARC_PCR_C 0x00002000 /* enable cache when MMU off */
+#define HYPERSPARC_PCR_BM 0x00004000 /* 1 iff booting */
+#define HYPERSPARC_PCR_MID 0x00078000 /* MBus module ID MID<3:0> */
+#define HYPERSPARC_PCR_WBE 0x00080000 /* Write buffer enable */
+#define HYPERSPARC_PCR_SE 0x00100000 /* Coherent bus snoop enable */
+#define HYPERSPARC_PCR_CWR 0x00200000 /* Cache wrap enable */
+
+#define CYPRESS_PCR_ME 0x00000001 /* MMU Enable */
+#define CYPRESS_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define CYPRESS_PCR_CE 0x00000100 /* Cache enable bit */
+#define CYPRESS_PCR_CL 0x00000200 /* Cache Lock (604 only) */
+#define CYPRESS_PCR_CM 0x00000400 /* Cache mode: 1=write-back */
+#define CYPRESS_PCR_MR 0x00000800 /* Memory reflection: 1=on (605 only) */
+#define CYPRESS_PCR_C 0x00002000 /* enable cache when MMU off */
+#define CYPRESS_PCR_BM 0x00004000 /* 1 iff booting */
+#define CYPRESS_PCR_MID 0x00078000 /* MBus module ID MID<3:0> (605 only) */
+#define CYPRESS_PCR_MV 0x00080000 /* Multichip Valid */
+#define CYPRESS_PCR_MCM 0x00300000 /* Multichip Mask */
+#define CYPRESS_PCR_MCA 0x00c00000 /* Multichip Address */
+
+#define MS1_PCR_ME 0x00000001 /* MMU Enable */
+#define MS1_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define MS1_PCR_DCE 0x00000100 /* Data cache enable */
+#define MS1_PCR_ICE 0x00000200 /* Instruction cache enable */
+#define MS1_PCR_RC 0x00000c00 /* DRAM Refresh control */
+#define MS1_PCR_PE 0x00001000 /* Enable memory parity checking */
+#define MS1_PCR_BM 0x00004000 /* 1 iff booting */
+#define MS1_PCR_AC 0x00008000 /* 1=cache if ME==0 (and [ID]CE on) */
+#define MS1_PCR_ID 0x00010000 /* 1=disable ITBR */
+#define MS1_PCR_PC 0x00020000 /* Parity control: 0=even,1=odd */
+#define MS1_PCR_MV 0x00100000 /* Memory data View (diag) */
+#define MS1_PCR_DV 0x00200000 /* Data View (diag) */
+#define MS1_PCR_AV 0x00400000 /* Address View (diag) */
+#define MS1_PCR_STW 0x00800000 /* Software Tablewalk enable */
+
+#define SWIFT_PCR_ME 0x00000001 /* MMU Enable */
+#define SWIFT_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define SWIFT_PCR_DCE 0x00000100 /* Data cache enable */
+#define SWIFT_PCR_ICE 0x00000200 /* Instruction cache enable */
+#define SWIFT_PCR_RC 0x00003c00 /* DRAM Refresh control */
+#define SWIFT_PCR_BM 0x00004000 /* 1 iff booting */
+#define SWIFT_PCR_AC 0x00008000 /* 1=cache if ME=0 (and [ID]CE on) */
+#define SWIFT_PCR_PA 0x00010000 /* TCX/SX control */
+#define SWIFT_PCR_PC 0x00020000 /* Parity control: 0=even,1=odd */
+#define SWIFT_PCR_PE 0x00040000 /* Enable memory parity checking */
+#define SWIFT_PCR_PMC 0x00180000 /* Page mode control */
+#define SWIFT_PCR_BF 0x00200000 /* Branch Folding */
+#define SWIFT_PCR_WP 0x00400000 /* Watch point enable */
+#define SWIFT_PCR_STW 0x00800000 /* Software Tablewalk enable */
+
+#define TURBOSPARC_PCR_ME 0x00000001 /* MMU Enable */
+#define TURBOSPARC_PCR_NF 0x00000002 /* Fault inhibit bit */
+#define TURBOSPARC_PCR_ICS 0x00000004 /* I-cache snoop enable */
+#define TURBOSPARC_PCR_PSO 0x00000008 /* Partial Store order (ro!) */
+#define TURBOSPARC_PCR_DCE 0x00000100 /* Data cache enable */
+#define TURBOSPARC_PCR_ICE 0x00000200 /* Instruction cache enable */
+#define TURBOSPARC_PCR_RC 0x00003c00 /* DRAM Refresh control */
+#define TURBOSPARC_PCR_BM 0x00004000 /* 1 iff booting */
+#define TURBOSPARC_PCR_PC 0x00020000 /* Parity ctrl: 0=even,1=odd */
+#define TURBOSPARC_PCR_PE 0x00040000 /* Enable parity checking */
+#define TURBOSPARC_PCR_PMC 0x00180000 /* Page mode control */
+
+/* The Turbosparc's Processor Configuration Register */
+#define TURBOSPARC_PCFG_SCC 0x00000007 /* e-cache config */
+#define TURBOSPARC_PCFG_SE 0x00000008 /* e-cache enable */
+#define TURBOSPARC_PCFG_US2 0x00000010 /* microsparc II compat */
+#define TURBOSPARC_PCFG_WT 0x00000020 /* write-through enable */
+#define TURBOSPARC_PCFG_SBC 0x000000c0 /* SBus Clock */
+#define TURBOSPARC_PCFG_WS 0x03800000 /* DRAM wait states */
+#define TURBOSPARC_PCFG_RAH 0x0c000000 /* DRAM Row Address Hold */
+#define TURBOSPARC_PCFG_AXC 0x30000000 /* AFX Clock */
+#define TURBOSPARC_PCFG_SNP 0x40000000 /* DVMA Snoop enable */
+#define TURBOSPARC_PCFG_IOCLK 0x80000000 /* I/O clock ratio */
+
+
+/* Implementation and Version fields are common to all modules */
#define SRMMU_PCR_VER 0x0f000000 /* Version of MMU implementation */
#define SRMMU_PCR_IMPL 0xf0000000 /* Implementation number of MMU */
-#ifdef notyet
-#define SRMMU_PCR_INITIAL (SRMMU_PCR_ME | SRMMU_PCR_TC)
-#endif
/* [4m] Bits in the Synchronous Fault Status Register */
#define SFSR_EM 0x00020000 /* Error mode watchdog reset occurred */
diff --git a/sys/arch/sparc/include/db_machdep.h b/sys/arch/sparc/include/db_machdep.h
index b6028854359..f47524d9e80 100644
--- a/sys/arch/sparc/include/db_machdep.h
+++ b/sys/arch/sparc/include/db_machdep.h
@@ -1,4 +1,5 @@
-/* $NetBSD: db_machdep.h,v 1.7 1996/03/31 22:21:28 pk Exp $ */
+/* $OpenBSD: db_machdep.h,v 1.4 1997/08/08 08:26:13 downsj Exp $ */
+/* $NetBSD: db_machdep.h,v 1.9 1997/06/26 01:27:00 thorpej Exp $ */
/*
* Mach Operating System
@@ -43,7 +44,7 @@
/* end of mangling */
typedef vm_offset_t db_addr_t; /* address - unsigned */
-typedef int db_expr_t; /* expression - signed */
+typedef long db_expr_t; /* expression - signed */
typedef struct {
struct trapframe ddb_tf;
@@ -55,7 +56,11 @@ db_regs_t ddb_regs; /* register state */
#define DDB_TF (&ddb_regs.ddb_tf)
#define DDB_FR (&ddb_regs.ddb_fr)
+#if defined(lint)
+#define PC_REGS(regs) ((regs)->ddb_tf.tf_pc)
+#else
#define PC_REGS(regs) ((db_addr_t)(regs)->ddb_tf.tf_pc)
+#endif
#define BKPT_INST 0x91d02001 /* breakpoint instruction */
#define BKPT_SIZE (4) /* size of breakpoint inst */
@@ -78,5 +83,9 @@ db_regs_t ddb_regs; /* register state */
void db_machine_init __P((void));
int kdb_trap __P((int, struct trapframe *));
+/*
+ * We use a.out symbols in DDB.
+ */
+#define DB_AOUT_SYMBOLS
#endif /* _SPARC_DB_MACHDEP_H_ */
diff --git a/sys/arch/sparc/include/eeprom.h b/sys/arch/sparc/include/eeprom.h
index 298e0baef11..89603af32bf 100644
--- a/sys/arch/sparc/include/eeprom.h
+++ b/sys/arch/sparc/include/eeprom.h
@@ -1,8 +1,9 @@
-/* $OpenBSD: eeprom.h,v 1.6 1996/08/16 16:28:25 ccappuc Exp $ */
+/* $OpenBSD: eeprom.h,v 1.7 1997/08/08 08:26:14 downsj Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
* All rights reserved.
+ * Portions Copyright (c) 1997, Jason Downs. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -361,4 +362,30 @@ struct eeprom {
#ifdef _KERNEL
extern char *eeprom_va;
int eeprom_uio __P((struct uio *));
+
+/*
+ * Compatibility defines with NetBSD's eeprom.h.
+ *
+ * The goal here is to provide enough compatibility for kernel drivers to
+ * compile without changes; not to make userland utilities compile. Userland
+ * should use the native interface.
+ */
+#define EE_CONS_BW EED_CONS_BW
+#define EE_CONS_TTYA EED_CONS_TTYA
+#define EE_CONS_TTYB EED_CONS_TTYB
+#define EE_CONS_COLOR EED_CONS_COLOR
+#define EE_CONS_P4OPT EED_CONS_P4
+
+#define EE_SCR_1152X900 EED_SCR_1152X900
+#define EE_SCR_1024X1024 EED_SCR_1024X1024
+#define EE_SCR_1600X1280 EED_SCR_1600X1280
+#define EE_SCR_1440X1440 EED_SCR_1440X1440
+#define EE_SCR_640X480 EED_SCR_640X480
+#define EE_SCR_1280X1024 EED_SCR_1280X1024
+
+#define eeConsole ee_diag.eed_console
+#define eeTtyRows ee_diag.eed_rowsize
+#define eeTtyCols ee_diag.eed_colsize
+#define eeScreenSize ee_diag.eed_scrsize
+
#endif /* _KERNEL */
diff --git a/sys/arch/sparc/include/endian.h b/sys/arch/sparc/include/endian.h
index c536790f9ef..302cc658d93 100644
--- a/sys/arch/sparc/include/endian.h
+++ b/sys/arch/sparc/include/endian.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: endian.h,v 1.6 1997/06/25 12:41:42 grr Exp $ */
-/* $NetBSD: endian.h,v 1.3 1996/02/13 17:04:58 christos Exp $ */
+/* $OpenBSD: endian.h,v 1.7 1997/08/08 08:26:15 downsj Exp $ */
+/* $NetBSD: endian.h,v 1.6 1996/10/11 00:43:00 christos Exp $ */
/*
* Copyright (c) 1987, 1991 Regents of the University of California.
@@ -87,10 +87,10 @@ __END_DECLS
#else
-#define NTOHL(x) (x) = ntohl((u_int32_t)x)
-#define NTOHS(x) (x) = ntohs((u_int16_t)x)
-#define HTONL(x) (x) = htonl((u_int32_t)x)
-#define HTONS(x) (x) = htons((u_int16_t)x)
+#define NTOHL(x) (x) = ntohl((in_addr_t)x)
+#define NTOHS(x) (x) = ntohs((in_port_t)x)
+#define HTONL(x) (x) = htonl((in_addr_t)x)
+#define HTONS(x) (x) = htons((in_port_t)x)
#endif
#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/sys/arch/sparc/include/exec.h b/sys/arch/sparc/include/exec.h
index b4c3925fd48..520345dbe10 100644
--- a/sys/arch/sparc/include/exec.h
+++ b/sys/arch/sparc/include/exec.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: exec.h,v 1.7 1997/08/08 08:26:16 downsj Exp $ */
/* $NetBSD: exec.h,v 1.7 1994/11/20 20:53:02 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/fbio.h b/sys/arch/sparc/include/fbio.h
index 2eddc2b5d69..babb49dea1b 100644
--- a/sys/arch/sparc/include/fbio.h
+++ b/sys/arch/sparc/include/fbio.h
@@ -1,4 +1,5 @@
-/* $NetBSD: fbio.h,v 1.4 1996/03/31 22:21:31 pk Exp $ */
+/* $OpenBSD: fbio.h,v 1.3 1997/08/08 08:26:17 downsj Exp $ */
+/* $NetBSD: fbio.h,v 1.5 1996/09/30 23:45:11 abrown Exp $ */
/*
* Copyright (c) 1992 Regents of the University of California.
@@ -66,10 +67,12 @@
#define FBTYPE_RESERVED5 15 /* reserved, do not use */
#define FBTYPE_RESERVED4 16 /* reserved, do not use */
#define FBTYPE_RESERVED3 17 /* reserved, do not use */
-#define FBTYPE_RESERVED2 18 /* reserved, do not use */
-#define FBTYPE_RESERVED1 19 /* reserved, do not use */
+#define FBTYPE_SUNGP3 17 /* cg12 running gpsi microcode */
+#define FBTYPE_SUNGT 18 /* gt graphics accelerator */
+#define FBTYPE_SUNLEO 19 /* zx graphics accelerator */
+#define FBTYPE_MDICOLOR 20 /* cgfourteen framebuffer */
-#define FBTYPE_LASTPLUSONE 20 /* max number of fbs (change as add) */
+#define FBTYPE_LASTPLUSONE 21 /* max number of fbs (change as add) */
/*
* Frame buffer descriptor as returned by FBIOGTYPE.
diff --git a/sys/arch/sparc/include/fbvar.h b/sys/arch/sparc/include/fbvar.h
index d5f3e8855c5..75117be959c 100644
--- a/sys/arch/sparc/include/fbvar.h
+++ b/sys/arch/sparc/include/fbvar.h
@@ -1,4 +1,5 @@
-/* $NetBSD: fbvar.h,v 1.7 1996/02/27 22:09:39 thorpej Exp $ */
+/* $OpenBSD: fbvar.h,v 1.3 1997/08/08 08:26:18 downsj Exp $ */
+/* $NetBSD: fbvar.h,v 1.9 1997/07/07 23:31:30 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -93,7 +94,10 @@ void fb_attach __P((struct fbdevice *, int));
void fb_setsize __P((struct fbdevice *, int, int, int, int, int));
#ifdef RASTERCONSOLE
void fbrcons_init __P((struct fbdevice *));
+int fbrcons_rows __P((void));
+int fbrcons_cols __P((void));
#endif
+
#if defined(SUN4)
int fb_pfour_id __P((void *));
int fb_pfour_get_video __P((struct fbdevice *));
diff --git a/sys/arch/sparc/include/float.h b/sys/arch/sparc/include/float.h
index eadcad4d141..8a724573044 100644
--- a/sys/arch/sparc/include/float.h
+++ b/sys/arch/sparc/include/float.h
@@ -1,4 +1,5 @@
-/* $NetBSD: float.h,v 1.5 1995/06/20 20:45:53 jtc Exp $ */
+/* $OpenBSD: float.h,v 1.3 1997/08/08 08:26:19 downsj Exp $ */
+/* $NetBSD: float.h,v 1.6 1997/07/18 05:11:52 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -50,7 +51,7 @@
#include <sys/cdefs.h>
__BEGIN_DECLS
-int __flt_rounds __P((void));
+int __flt_rounds __P((void));
__END_DECLS
#define FLT_RADIX 2 /* b */
diff --git a/sys/arch/sparc/include/frame.h b/sys/arch/sparc/include/frame.h
index bc72dfff806..8313eacf8b6 100644
--- a/sys/arch/sparc/include/frame.h
+++ b/sys/arch/sparc/include/frame.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: frame.h,v 1.2 1997/08/08 08:26:20 downsj Exp $ */
/* $NetBSD: frame.h,v 1.2 1994/11/20 20:53:07 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/fsr.h b/sys/arch/sparc/include/fsr.h
index a1d43581015..37688a35173 100644
--- a/sys/arch/sparc/include/fsr.h
+++ b/sys/arch/sparc/include/fsr.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: fsr.h,v 1.2 1997/08/08 08:26:21 downsj Exp $ */
/* $NetBSD: fsr.h,v 1.2 1994/11/20 20:53:08 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/idprom.h b/sys/arch/sparc/include/idprom.h
index 6d8bbe23194..1d754cb9d42 100644
--- a/sys/arch/sparc/include/idprom.h
+++ b/sys/arch/sparc/include/idprom.h
@@ -1,4 +1,5 @@
-/* $NetBSD: idprom.h,v 1.4 1995/02/01 12:37:45 pk Exp $ */
+/* $OpenBSD: idprom.h,v 1.2 1997/08/08 08:26:22 downsj Exp $ */
+/* $NetBSD: idprom.h,v 1.5 1997/03/10 22:47:52 pk Exp $ */
/*
* Copyright (c) 1993 Adam Glass
@@ -48,4 +49,9 @@ struct idprom {
char id_undef[16]; /* undefined */
};
+#define ID_SUN4_100 0x22
+#define ID_SUN4_200 0x21
+#define ID_SUN4_300 0x23
+#define ID_SUN4_400 0x24
+
#define IDPROM_VERSION 1
diff --git a/sys/arch/sparc/include/ieee.h b/sys/arch/sparc/include/ieee.h
index 188438c0d95..d8a2509f540 100644
--- a/sys/arch/sparc/include/ieee.h
+++ b/sys/arch/sparc/include/ieee.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: ieee.h,v 1.2 1997/08/08 08:26:24 downsj Exp $ */
/* $NetBSD: ieee.h,v 1.2 1994/11/20 20:53:10 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/ieeefp.h b/sys/arch/sparc/include/ieeefp.h
index a1e67846b83..eabf383ec9d 100644
--- a/sys/arch/sparc/include/ieeefp.h
+++ b/sys/arch/sparc/include/ieeefp.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: ieeefp.h,v 1.3 1997/08/08 08:26:25 downsj Exp $ */
+
/*
* Written by J.T. Conklin, Apr 6, 1995
* Public domain.
diff --git a/sys/arch/sparc/include/instr.h b/sys/arch/sparc/include/instr.h
index 6aa7c24229d..d4b002445f3 100644
--- a/sys/arch/sparc/include/instr.h
+++ b/sys/arch/sparc/include/instr.h
@@ -1,4 +1,5 @@
-/* $NetBSD: instr.h,v 1.2 1994/11/20 20:53:11 deraadt Exp $ */
+/* $OpenBSD: instr.h,v 1.2 1997/08/08 08:26:26 downsj Exp $ */
+/* $NetBSD: instr.h,v 1.3 1997/03/14 23:54:07 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -244,6 +245,7 @@ union instr {
u_int i_rd:5; /* destination register */
u_int i_op3:6; /* second-level decode */
u_int i_rs1:5; /* source register 1 */
+ u_int i_i:1; /* immediate vs asi */
u_int i_asi:8; /* asi */
u_int i_rs2:5; /* source register 2 */
} i_asi;
diff --git a/sys/arch/sparc/include/kbd.h b/sys/arch/sparc/include/kbd.h
index 4cabc471287..74279bcb80d 100644
--- a/sys/arch/sparc/include/kbd.h
+++ b/sys/arch/sparc/include/kbd.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: kbd.h,v 1.3 1997/08/08 08:26:27 downsj Exp $ */
/* $NetBSD: kbd.h,v 1.6 1996/03/31 22:21:35 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/kbio.h b/sys/arch/sparc/include/kbio.h
index 049bfb79fed..ff54ac3c701 100644
--- a/sys/arch/sparc/include/kbio.h
+++ b/sys/arch/sparc/include/kbio.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: kbio.h,v 1.4 1997/08/08 08:26:28 downsj Exp $ */
/* $NetBSD: kbio.h,v 1.4 1995/05/10 16:07:27 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/limits.h b/sys/arch/sparc/include/limits.h
index 172e9a95d3a..d84ff6cff25 100644
--- a/sys/arch/sparc/include/limits.h
+++ b/sys/arch/sparc/include/limits.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: limits.h,v 1.4 1997/08/08 08:26:30 downsj Exp $ */
/* $NetBSD: limits.h,v 1.7 1996/01/05 18:10:57 pk Exp $ */
/*
@@ -35,9 +36,6 @@
* @(#)limits.h 8.3 (Berkeley) 1/4/94
*/
-#ifndef _MACHINE_LIMITS_H_
-#define _MACHINE_LIMITS_H_
-
#define CHAR_BIT 8 /* number of bits in a char */
#define MB_LEN_MAX 1 /* no multibyte characters */
@@ -87,5 +85,3 @@
#define FLT_MAX 3.40282347E+38F
#define FLT_MIN 1.17549435E-38F
#endif
-
-#endif /* _MACHINE_LIMITS_H_ */
diff --git a/sys/arch/sparc/include/oldmon.h b/sys/arch/sparc/include/oldmon.h
index d18a256f05c..ce1ee9dc0b5 100644
--- a/sys/arch/sparc/include/oldmon.h
+++ b/sys/arch/sparc/include/oldmon.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: oldmon.h,v 1.4 1997/08/08 08:26:32 downsj Exp $ */
/* $NetBSD: oldmon.h,v 1.11 1996/03/31 22:21:38 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/openpromio.h b/sys/arch/sparc/include/openpromio.h
index 748f0fa3cd2..fb50a2b8268 100644
--- a/sys/arch/sparc/include/openpromio.h
+++ b/sys/arch/sparc/include/openpromio.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: openpromio.h,v 1.2 1997/08/08 08:26:35 downsj Exp $ */
/* $NetBSD: openpromio.h,v 1.2 1994/11/20 20:53:17 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/param.h b/sys/arch/sparc/include/param.h
index 8754188b97c..34573d970f4 100644
--- a/sys/arch/sparc/include/param.h
+++ b/sys/arch/sparc/include/param.h
@@ -1,4 +1,5 @@
-/* $NetBSD: param.h,v 1.24 1996/05/15 02:13:48 mrg Exp $ */
+/* $OpenBSD: param.h,v 1.6 1997/08/08 08:26:36 downsj Exp $ */
+/* $NetBSD: param.h,v 1.29 1997/03/10 22:50:37 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -64,41 +65,29 @@
* Round p (pointer or byte index) up to a correctly-aligned value for
* the machine's strictest data type. The result is u_int and must be
* cast to any desired pointer type.
+ *
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits).
+ *
*/
-#define ALIGNBYTES 7
-#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+#define ALIGNBYTES 7
+#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+#define ALIGNED_POINTER(p,t) ((((u_long)(p)) & (sizeof(t)-1)) == 0)
#define SUN4_PGSHIFT 13 /* for a sun4 machine */
#define SUN4CM_PGSHIFT 12 /* for a sun4c or sun4m machine */
/*
- * Three possible cases:
- * sun4 only 8192 bytes/page
- * sun4c/sun4m only 4096 bytes/page
- * sun4/sun4c/sun4m either of the above
- *
- * In the later case NBPG, PGOFSET, and PGSHIFT are encoded in variables
- * initialized early in locore.s. Since they are variables, rather than
- * simple constants, the kernel will not perform slighly worse.
+ * The following variables are always defined and initialized (in locore)
+ * so independently compiled modules (e.g. LKMs) can be used irrespective
+ * of the `options SUN4?' combination a particular kernel was configured with.
+ * See also the definitions of NBPG, PGOFSET and PGSHIFT below.
*/
-#if defined(SUN4) && !defined(SUN4C) && !defined(SUN4M)
-#define NBPG 8192 /* bytes/page */
-#define PGOFSET (NBPG-1) /* byte offset into page */
-#define PGSHIFT SUN4_PGSHIFT /* log2(NBPG) */
-#endif
-#if !defined(SUN4) && (defined(SUN4C) || defined(SUN4M))
-#define NBPG 4096 /* bytes/page */
-#define PGOFSET (NBPG-1) /* byte offset into page */
-#define PGSHIFT SUN4CM_PGSHIFT /* log2(NBPG) */
-#endif
-#if defined(SUN4) && (defined(SUN4C) || defined(SUN4M))
#if defined(_KERNEL) && !defined(_LOCORE)
extern int nbpg, pgofset, pgshift;
#endif
-#define NBPG nbpg /* bytes/page */
-#define PGOFSET pgofset /* byte offset into page */
-#define PGSHIFT pgshift /* log2(NBPG) */
-#endif
#define KERNBASE 0xf8000000 /* start of kernel virtual space */
#define KERNTEXTOFF 0xf8004000 /* start of kernel text */
@@ -123,8 +112,8 @@ extern int nbpg, pgofset, pgshift;
* of the hardware page size.
*/
#define MSIZE 128 /* size of an mbuf */
+#define MCLBYTES 2048 /* enough for whole Ethernet packet */
#define MCLSHIFT 11 /* log2(MCLBYTES) */
-#define MCLBYTES (1 << MCLSHIFT) /* enough for whole Ethernet packet */
#define MCLOFSET (MCLBYTES - 1)
#ifndef NMBCLUSTERS
@@ -192,8 +181,10 @@ extern void delay __P((unsigned int));
#define DELAY(n) delay(n)
extern int cputyp;
+#if 0
extern int cpumod;
extern int mmumod;
+#endif
#endif /* _LOCORE */
#endif /* _KERNEL */
@@ -204,31 +195,19 @@ extern int mmumod;
#define CPU_SUN4 0
#define CPU_SUN4C 1
#define CPU_SUN4M 2
-/*
- * Values for cpumod (cpu model) variable. XXX currently valid only for sun4
- * or Sun4M
- */
-#define SUN4_100 0x22
-#define SUN4_200 0x21
-#define SUN4_300 0x23
-#define SUN4_400 0x24
-#define SUN4M_MS 0x04 /* MicroSPARC-II */
-#define SUN4M_SS 0x40 /* Generic SuperSPARC */
-#define SUN4M_HS 0x10 /* Generic ROSS sparc product (HyperSPARC) */
-#define SUN4M_RT620 0x1f /* Ross HyperSPARC RT620 */
-#define SUN4M_STP1020N 0x41 /* TI SuperSPARC STP1020N */
-#define SUN4M_STP1020P 0x40 /* TI SuperSPARC STP1020P */
-#define SUN4M_STP1020A 0x40 /* TI SuperSPARC STP1020A */
-
-/* Values for mmumod (mmu model) variable. Valid only for Sun4M */
-#define SUN4M_MMU_HS 0x1 /* ROSS HyperSparc */
-#define SUN4M_MMU_SS 0x0 /* TI SuperSPARC */
-#define SUN4M_MMU_MS1 0x4 /* MicroSPARC-I (??? XXX) */
-#define SUN4M_MMU_MS 0x0 /* MicroSPARC-II (ugh, conflicts w/SS) */
/*
* Shorthand CPU-type macros. Enumerate all eight cases.
* Let compiler optimize away code conditional on constants.
+ *
+ * On a sun4 machine, the page size is 8192, while on a sun4c and sun4m
+ * it is 4096. Therefore, in the (SUN4 && (SUN4C || SUN4M)) cases below,
+ * NBPG, PGOFSET and PGSHIFT are defined as variables which are initialized
+ * early in locore.s after the machine type has been detected.
+ *
+ * Note that whenever the macros defined below evaluate to expressions
+ * involving variables, the kernel will perform slighly worse due to the
+ * extra memory references they'll generate.
*/
#if defined(SUN4M) && defined(SUN4C) && defined(SUN4)
# define CPU_ISSUN4M (cputyp == CPU_SUN4M)
@@ -236,46 +215,70 @@ extern int mmumod;
# define CPU_ISSUN4 (cputyp == CPU_SUN4)
# define CPU_ISSUN4OR4C (cputyp == CPU_SUN4 || cputyp == CPU_SUN4C)
# define CPU_ISSUN4COR4M (cputyp == CPU_SUN4C || cputyp == CPU_SUN4M)
+# define NBPG nbpg
+# define PGOFSET pgofset
+# define PGSHIFT pgshift
#elif defined(SUN4M) && defined(SUN4C) && !defined(SUN4)
# define CPU_ISSUN4M (cputyp == CPU_SUN4M)
# define CPU_ISSUN4C (cputyp == CPU_SUN4C)
# define CPU_ISSUN4 (0)
# define CPU_ISSUN4OR4C (cputyp == CPU_SUN4C)
# define CPU_ISSUN4COR4M (cputyp == CPU_SUN4C || cputyp == CPU_SUN4M)
+# define NBPG 4096
+# define PGOFSET (NBPG-1)
+# define PGSHIFT SUN4CM_PGSHIFT
#elif defined(SUN4M) && !defined(SUN4C) && defined(SUN4)
# define CPU_ISSUN4M (cputyp == CPU_SUN4M)
# define CPU_ISSUN4C (0)
# define CPU_ISSUN4 (cputyp == CPU_SUN4)
# define CPU_ISSUN4OR4C (cputyp == CPU_SUN4)
# define CPU_ISSUN4COR4M (cputyp == CPU_SUN4M)
+# define NBPG nbpg
+# define PGOFSET pgofset
+# define PGSHIFT pgshift
#elif defined(SUN4M) && !defined(SUN4C) && !defined(SUN4)
# define CPU_ISSUN4M (1)
# define CPU_ISSUN4C (0)
# define CPU_ISSUN4 (0)
# define CPU_ISSUN4OR4C (0)
# define CPU_ISSUN4COR4M (1)
+# define NBPG 4096
+# define PGOFSET (NBPG-1)
+# define PGSHIFT SUN4CM_PGSHIFT
#elif !defined(SUN4M) && defined(SUN4C) && defined(SUN4)
# define CPU_ISSUN4M (0)
# define CPU_ISSUN4C (cputyp == CPU_SUN4C)
# define CPU_ISSUN4 (cputyp == CPU_SUN4)
# define CPU_ISSUN4OR4C (1)
# define CPU_ISSUN4COR4M (cputyp == CPU_SUN4C)
+# define NBPG nbpg
+# define PGOFSET pgofset
+# define PGSHIFT pgshift
#elif !defined(SUN4M) && defined(SUN4C) && !defined(SUN4)
# define CPU_ISSUN4M (0)
# define CPU_ISSUN4C (1)
# define CPU_ISSUN4 (0)
# define CPU_ISSUN4OR4C (1)
# define CPU_ISSUN4COR4M (1)
+# define NBPG 4096
+# define PGOFSET (NBPG-1)
+# define PGSHIFT SUN4CM_PGSHIFT
#elif !defined(SUN4M) && !defined(SUN4C) && defined(SUN4)
# define CPU_ISSUN4M (0)
# define CPU_ISSUN4C (0)
# define CPU_ISSUN4 (1)
# define CPU_ISSUN4OR4C (1)
# define CPU_ISSUN4COR4M (0)
+# define NBPG 8192
+# define PGOFSET (NBPG-1)
+# define PGSHIFT SUN4_PGSHIFT
#elif !defined(SUN4M) && !defined(SUN4C) && !defined(SUN4)
-# define CPU_ISSUN4M (0)
-# define CPU_ISSUN4C (0)
-# define CPU_ISSUN4 (0)
-# define CPU_ISSUN4OR4C (0)
-# define CPU_ISSUN4COR4M (0)
+# define CPU_ISSUN4M (cputyp == CPU_SUN4M)
+# define CPU_ISSUN4C (cputyp == CPU_SUN4C)
+# define CPU_ISSUN4 (cputyp == CPU_SUN4)
+# define CPU_ISSUN4OR4C (cputyp == CPU_SUN4 || cputyp == CPU_SUN4C)
+# define CPU_ISSUN4COR4M (cputyp == CPU_SUN4C || cputyp == CPU_SUN4M)
+# define NBPG nbpg
+# define PGOFSET pgofset
+# define PGSHIFT pgshift
#endif
diff --git a/sys/arch/sparc/include/pcb.h b/sys/arch/sparc/include/pcb.h
index 3692dd17d96..e3450eabe3c 100644
--- a/sys/arch/sparc/include/pcb.h
+++ b/sys/arch/sparc/include/pcb.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: pcb.h,v 1.2 1997/08/08 08:26:37 downsj Exp $ */
/* $NetBSD: pcb.h,v 1.4 1995/03/28 18:19:56 jtc Exp $ */
/*
diff --git a/sys/arch/sparc/include/pmap.h b/sys/arch/sparc/include/pmap.h
index 90e5f8d26ca..8e66fd2e655 100644
--- a/sys/arch/sparc/include/pmap.h
+++ b/sys/arch/sparc/include/pmap.h
@@ -1,4 +1,5 @@
-/* $NetBSD: pmap.h,v 1.22.4.1 1996/06/12 20:29:01 pk Exp $ */
+/* $OpenBSD: pmap.h,v 1.5 1997/08/08 08:26:38 downsj Exp $ */
+/* $NetBSD: pmap.h,v 1.29 1997/07/06 23:57:16 pk Exp $ */
/*
* Copyright (c) 1996
@@ -138,7 +139,7 @@ TAILQ_HEAD(mmuhd,mmuentry);
struct pmap {
union ctxinfo *pm_ctx; /* current context, if any */
int pm_ctxnum; /* current context's number */
-#if NCPUS > 1
+#if 0
simple_lock_data_t pm_lock; /* spinlock */
#endif
int pm_refcount; /* just what it says */
@@ -203,14 +204,27 @@ extern vm_offset_t vm_first_phys, vm_num_phys;
#define PMAP_VME16 2 /* etc */
#define PMAP_VME32 3 /* etc */
#define PMAP_NC 4 /* tells pmap_enter to set PG_NC */
+#define PMAP_TNC_4 7 /* mask to get PG_TYPE & PG_NC */
+
+#define PMAP_T2PTE_4(x) (((x) & PMAP_TNC_4) << PG_TNC_SHIFT)
+#define PMAP_IOENC_4(io) (io)
+
+/*
+ * On a SRMMU machine, the iospace is encoded in bits [3-6] of the
+ * physical address passed to pmap_enter().
+ */
+#define PMAP_TYPE_SRMMU 0x78 /* mask to get 4m page type */
+#define PMAP_PTESHFT_SRMMU 25 /* right shift to put type in pte */
+#define PMAP_SHFT_SRMMU 3 /* left shift to extract iospace */
+#define PMAP_TNC_SRMMU 127 /* mask to get PG_TYPE & PG_NC */
-#define PMAP_TYPE4M 0x78 /* mask to get 4m page type */
-#define PMAP_PTESHFT4M 25 /* right shift to put type in pte */
-#define PMAP_SHFT4M 0x3 /* left shift to extract type */
-#define PMAP_TNC \
- (CPU_ISSUN4M?127:7) /* mask to get PG_TYPE & PG_NC */
/*#define PMAP_IOC 0x00800000 -* IO cacheable, NOT shifted */
+#define PMAP_T2PTE_SRMMU(x) (((x) & PMAP_TYPE_SRMMU) << PMAP_PTESHFT_SRMMU)
+#define PMAP_IOENC_SRMMU(io) ((io) << PMAP_SHFT_SRMMU)
+
+/* Encode IO space for pmap_enter() */
+#define PMAP_IOENC(io) (CPU_ISSUN4M ? PMAP_IOENC_SRMMU(io) : PMAP_IOENC_4(io))
#if xxx
void pmap_bootstrap __P((int nmmu, int nctx, int nregion));
@@ -264,9 +278,9 @@ void pmap_redzone __P((void));
void kvm_uncache __P((caddr_t, int));
struct user;
void switchexit __P((vm_map_t, struct user *, int));
-int mmu_pagein __P((struct pmap *pm, vm_offset_t, int));
+int mmu_pagein __P((struct pmap *pm, int, int));
#ifdef DEBUG
-int mmu_pagein4m __P((struct pmap *pm, vm_offset_t, int));
+int mmu_pagein4m __P((struct pmap *pm, int, int));
#endif
diff --git a/sys/arch/sparc/include/proc.h b/sys/arch/sparc/include/proc.h
index ff2b7b5805d..dc4b3629af1 100644
--- a/sys/arch/sparc/include/proc.h
+++ b/sys/arch/sparc/include/proc.h
@@ -1,4 +1,5 @@
-/* $NetBSD: proc.h,v 1.2 1994/11/20 20:53:23 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.2 1997/08/08 08:26:39 downsj Exp $ */
+/* $NetBSD: proc.h,v 1.3 1996/09/26 18:51:17 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -50,4 +51,8 @@
struct mdproc {
struct trapframe *md_tf; /* trap/syscall registers */
struct fpstate *md_fpstate; /* fpu state, if any; always resident */
+ u_long md_flags;
};
+
+/* md_flags */
+#define MDP_FIXALIGN 0x1 /* Fix unaligned memory accesses */
diff --git a/sys/arch/sparc/include/profile.h b/sys/arch/sparc/include/profile.h
index 0a27b368163..13af168d2f3 100644
--- a/sys/arch/sparc/include/profile.h
+++ b/sys/arch/sparc/include/profile.h
@@ -1,4 +1,5 @@
-/* $NetBSD: profile.h,v 1.6 1996/04/08 20:55:36 pk Exp $ */
+/* $OpenBSD: profile.h,v 1.4 1997/08/08 08:26:40 downsj Exp $ */
+/* $NetBSD: profile.h,v 1.8 1997/02/01 20:56:40 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -47,26 +48,25 @@
#ifdef PIC
/* Inline expansion of PICCY_SET() (see <machine/asm.h>). */
#define MCOUNT \
- asm(".global mcount");\
- asm("mcount:");\
- asm("add %o7, 8, %o1");\
- asm("1: call 2f; nop; 2:");\
- asm("add %o7,__mcount-1b, %o2");\
- asm("ld [%o2], %o2");\
- asm("jmpl %o2, %g0");\
- asm("add %i7, 8, %o0");
+ __asm__(".global mcount");\
+ __asm__("mcount:");\
+ __asm__("add %o7, 8, %o1");\
+ __asm__("1: call 2f; nop; 2:");\
+ __asm__("add %o7,__mcount-1b, %o2");\
+ __asm__("ld [%o2], %o2");\
+ __asm__("jmpl %o2, %g0");\
+ __asm__("add %i7, 8, %o0");
#else
#define MCOUNT \
- asm(".global mcount");\
- asm("mcount:");\
- asm("add %i7, 8, %o0");\
- asm("sethi %hi(__mcount), %o2");\
- asm("jmpl %o2 + %lo(__mcount), %g0");\
- asm("add %o7, 8, %o1");
+ __asm__(".global mcount");\
+ __asm__("mcount:");\
+ __asm__("add %i7, 8, %o0");\
+ __asm__("sethi %hi(__mcount), %o2");\
+ __asm__("jmpl %o2 + %lo(__mcount), %g0");\
+ __asm__("add %o7, 8, %o1");
#endif
#define _MCOUNT_DECL static void _mcount
-_MCOUNT_DECL __P((unsigned long, unsigned long));
#ifdef _KERNEL
/*
diff --git a/sys/arch/sparc/include/psl.h b/sys/arch/sparc/include/psl.h
index a93b2724348..70507bdd7ff 100644
--- a/sys/arch/sparc/include/psl.h
+++ b/sys/arch/sparc/include/psl.h
@@ -1,4 +1,5 @@
-/* $NetBSD: psl.h,v 1.11 1996/03/31 22:20:14 pk Exp $ */
+/* $OpenBSD: psl.h,v 1.3 1997/08/08 08:26:41 downsj Exp $ */
+/* $NetBSD: psl.h,v 1.12 1997/03/10 21:49:11 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -84,6 +85,7 @@ static __inline void setpsr __P((int));
static __inline int spl0 __P((void));
static __inline int splhigh __P((void));
static __inline void splx __P((int));
+static __inline int getmid __P((void));
/*
* GCC pseudo-functions for manipulating PSR (primarily PIL field).
@@ -96,6 +98,14 @@ static __inline int getpsr()
return (psr);
}
+static __inline int getmid()
+{
+ int mid;
+
+ __asm __volatile("rd %%tbr,%0" : "=r" (mid));
+ return ((mid >> 20) & 0x3);
+}
+
static __inline void setpsr(newpsr)
int newpsr;
{
diff --git a/sys/arch/sparc/include/pte.h b/sys/arch/sparc/include/pte.h
index 7418188bb85..3a7fd59a127 100644
--- a/sys/arch/sparc/include/pte.h
+++ b/sys/arch/sparc/include/pte.h
@@ -1,4 +1,5 @@
-/* $NetBSD: pte.h,v 1.17 1996/05/16 15:57:03 abrown Exp $ */
+/* $OpenBSD: pte.h,v 1.3 1997/08/08 08:26:42 downsj Exp $ */
+/* $NetBSD: pte.h,v 1.18 1997/05/15 22:25:45 pk Exp $ */
/*
* Copyright (c) 1996
@@ -176,14 +177,10 @@ typedef u_char smeg_t; /* 8 bits needed per Sun-4 regmap entry */
* physadr = ((pte & PG_PFNUM) << PGSHIFT) | va.va_off;
*/
-#if defined(MMU_3L) && !defined(SUN4)
+#if defined(SUN4_MMU3L) && !defined(SUN4)
#error "configuration error"
#endif
-#if defined(MMU_3L)
-extern int mmu_3l;
-#endif
-
#define NBPRG (1 << 24) /* bytes per region */
#define RGSHIFT 24 /* log2(NBPRG) */
#define RGOFSET (NBPRG - 1) /* mask for region offset */
@@ -224,30 +221,12 @@ extern int nptesg;
#define VA_ROUNDDOWNTOSEG(va) ((int)(va) & ~SGOFSET)
/* virtual segment to virtual address (must sign extend on holy MMUs!) */
-#if defined(SUN4M) && !(defined(SUN4C) || defined(SUN4))
-#define VRTOVA(vr) ((int)(vr) << RGSHIFT)
-#define VSTOVA(vr,vs) (((int)(vr) << RGSHIFT) + ((int)(vs) << SGSHIFT))
-#else
-#if defined(MMU_3L) || defined(SUN4M) /* hairy.. */
-#if !defined(MMU_3L)
-#define _PTE_HAIRY_3L_TEST (cputyp==CPU_SUN4M)
-#elif !defined(SUN4M)
-#define _PTE_HAIRY_3L_TEST (mmu_3l)
-#else
-#define _PTE_HAIRY_3L_TEST (mmu_3l || cputyp==CPU_SUN4M)
-#endif
-#define VRTOVA(vr) (_PTE_HAIRY_3L_TEST \
- ? ((int)(vr) << RGSHIFT) \
+#define VRTOVA(vr) ((CPU_ISSUN4M || HASSUN4_MMU3L) \
+ ? ((int)(vr) << RGSHIFT) \
: (((int)(vr) << (RGSHIFT+2)) >> 2))
-#define VSTOVA(vr,vs) (_PTE_HAIRY_3L_TEST \
+#define VSTOVA(vr,vs) ((CPU_ISSUN4M || HASSUN4_MMU3L) \
? (((int)(vr) << RGSHIFT) + ((int)(vs) << SGSHIFT)) \
: ((((int)(vr) << (RGSHIFT+2)) >> 2) + ((int)(vs) << SGSHIFT)))
-#else
-#define VRTOVA(vr) (((int)(vr) << (RGSHIFT+2)) >> 2)
-#define VSTOVA(vr,vs) ((((int)(vr) << (RGSHIFT+2)) >> 2) + \
- ((int)(vs) << SGSHIFT))
-#endif
-#endif
extern int mmu_has_hole;
#define VA_INHOLE(va) (mmu_has_hole \
diff --git a/sys/arch/sparc/include/ptrace.h b/sys/arch/sparc/include/ptrace.h
index f01223f36bd..9253256060c 100644
--- a/sys/arch/sparc/include/ptrace.h
+++ b/sys/arch/sparc/include/ptrace.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: ptrace.h,v 1.2 1997/08/08 08:26:43 downsj Exp $ */
/* $NetBSD: ptrace.h,v 1.4 1994/11/20 20:53:27 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/reg.h b/sys/arch/sparc/include/reg.h
index 137d9aed411..ac6a9933849 100644
--- a/sys/arch/sparc/include/reg.h
+++ b/sys/arch/sparc/include/reg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: reg.h,v 1.2 1997/08/08 08:26:44 downsj Exp $ */
/* $NetBSD: reg.h,v 1.4 1994/11/20 20:53:28 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/reloc.h b/sys/arch/sparc/include/reloc.h
index 01c0104e932..b49b7c8a17f 100644
--- a/sys/arch/sparc/include/reloc.h
+++ b/sys/arch/sparc/include/reloc.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: reloc.h,v 1.2 1997/08/08 08:26:45 downsj Exp $ */
/* $NetBSD: reloc.h,v 1.2 1994/11/20 20:53:30 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/remote-sl.h b/sys/arch/sparc/include/remote-sl.h
index 3c48e6b451a..76498e57e87 100644
--- a/sys/arch/sparc/include/remote-sl.h
+++ b/sys/arch/sparc/include/remote-sl.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: remote-sl.h,v 1.2 1997/08/08 08:26:47 downsj Exp $ */
/* $NetBSD: remote-sl.h,v 1.2 1994/11/20 20:53:31 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/include/setjmp.h b/sys/arch/sparc/include/setjmp.h
index e224ce1e7c0..b9a28444183 100644
--- a/sys/arch/sparc/include/setjmp.h
+++ b/sys/arch/sparc/include/setjmp.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: setjmp.h,v 1.2 1997/08/08 08:26:47 downsj Exp $ */
/* $NetBSD: setjmp.h,v 1.1 1994/12/20 10:37:10 cgd Exp $ */
/*
diff --git a/sys/arch/sparc/include/signal.h b/sys/arch/sparc/include/signal.h
index e8339c38520..7b575c569ef 100644
--- a/sys/arch/sparc/include/signal.h
+++ b/sys/arch/sparc/include/signal.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: signal.h,v 1.3 1997/08/08 08:26:48 downsj Exp $ */
/* $NetBSD: signal.h,v 1.4 1996/02/01 22:32:35 mycroft Exp $ */
/*
diff --git a/sys/arch/sparc/include/stdarg.h b/sys/arch/sparc/include/stdarg.h
index aa2081597bf..311ec168f3f 100644
--- a/sys/arch/sparc/include/stdarg.h
+++ b/sys/arch/sparc/include/stdarg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: stdarg.h,v 1.9 1995/12/29 18:53:01 mycroft Exp $ */
+/* $OpenBSD: stdarg.h,v 1.4 1997/08/08 08:26:50 downsj Exp $ */
+/* $NetBSD: stdarg.h,v 1.10 1996/12/27 20:55:28 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -49,6 +50,11 @@
#include <machine/ansi.h>
+#ifdef __lint__
+#define __extension__(x) (0)
+#define __builtin_classify_type(t) (0)
+#endif
+
typedef _BSD_VA_LIST_ va_list;
#define __va_size(type) \
diff --git a/sys/arch/sparc/include/svr4_machdep.h b/sys/arch/sparc/include/svr4_machdep.h
index c7a5d303b74..a4984efdc72 100644
--- a/sys/arch/sparc/include/svr4_machdep.h
+++ b/sys/arch/sparc/include/svr4_machdep.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: svr4_machdep.h,v 1.6 1997/08/08 08:26:50 downsj Exp $ */
/* $NetBSD: svr4_machdep.h,v 1.4 1996/03/31 22:21:45 pk Exp $ */
/*
diff --git a/sys/arch/sparc/include/trap.h b/sys/arch/sparc/include/trap.h
index b2cde2ecc25..793e3b2724e 100644
--- a/sys/arch/sparc/include/trap.h
+++ b/sys/arch/sparc/include/trap.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: trap.h,v 1.4 1997/08/08 08:26:51 downsj Exp $ */
/* $NetBSD: trap.h,v 1.9 1996/05/16 15:57:04 abrown Exp $ */
/*
diff --git a/sys/arch/sparc/include/types.h b/sys/arch/sparc/include/types.h
index b9d0a0a6914..fa1d89d60e9 100644
--- a/sys/arch/sparc/include/types.h
+++ b/sys/arch/sparc/include/types.h
@@ -1,4 +1,5 @@
-/* $NetBSD: types.h,v 1.9 1996/03/14 00:48:30 pk Exp $ */
+/* $OpenBSD: types.h,v 1.5 1997/08/08 08:26:52 downsj Exp $ */
+/* $NetBSD: types.h,v 1.11 1996/12/10 23:19:38 pk Exp $ */
/*
* Copyright (c) 1992, 1993
diff --git a/sys/arch/sparc/include/varargs.h b/sys/arch/sparc/include/varargs.h
index 3585b7caa94..68ed7800c9b 100644
--- a/sys/arch/sparc/include/varargs.h
+++ b/sys/arch/sparc/include/varargs.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: varargs.h,v 1.5 1997/08/08 08:26:53 downsj Exp $ */
/* $NetBSD: varargs.h,v 1.10 1995/12/29 18:53:02 mycroft Exp $ */
/*
diff --git a/sys/arch/sparc/include/vmparam.h b/sys/arch/sparc/include/vmparam.h
index fd578b1e95c..3f3ec56b5e0 100644
--- a/sys/arch/sparc/include/vmparam.h
+++ b/sys/arch/sparc/include/vmparam.h
@@ -1,4 +1,5 @@
-/* $NetBSD: vmparam.h,v 1.10 1996/03/14 19:49:20 christos Exp $ */
+/* $OpenBSD: vmparam.h,v 1.5 1997/08/08 08:26:54 downsj Exp $ */
+/* $NetBSD: vmparam.h,v 1.13 1997/07/12 16:20:03 perry Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -115,6 +116,10 @@
* so we loan each swapped in process memory worth 100$, or just admit
* that we don't consider it worthwhile and swap it out to disk which costs
* $30/mb or about $0.75.
+ * Update: memory prices have changed recently (9/96). At the current
+ * value of $6 per megabyte, we lend each swapped in process memory worth
+ * $0.15, or just admit that we don't consider it worthwhile and swap it out
+ * to disk which costs $0.20/MB, or just under half a cent.
*/
#define SAFERSS 4 /* nominal ``small'' resident set size
protected against replacement */
diff --git a/sys/arch/sparc/include/vuid_event.h b/sys/arch/sparc/include/vuid_event.h
index 0bb4e0015cc..7a3a5c14bab 100644
--- a/sys/arch/sparc/include/vuid_event.h
+++ b/sys/arch/sparc/include/vuid_event.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: vuid_event.h,v 1.2 1997/08/08 08:26:55 downsj Exp $ */
/* $NetBSD: vuid_event.h,v 1.2 1994/11/20 20:53:39 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/asm.h b/sys/arch/sparc/sparc/asm.h
index 1807c358050..534853ce491 100644
--- a/sys/arch/sparc/sparc/asm.h
+++ b/sys/arch/sparc/sparc/asm.h
@@ -1,4 +1,5 @@
-/* $NetBSD: asm.h,v 1.3 1994/11/20 20:53:55 deraadt Exp $ */
+/* $OpenBSD: asm.h,v 1.2 1997/08/08 08:26:58 downsj Exp $ */
+/* $NetBSD: asm.h,v 1.4 1996/07/01 18:01:26 abrown Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -102,3 +103,17 @@
__asm __volatile("sta %0,[%1]%2" : : \
"r" ((int)(value)), "r" ((int)(loc)), "n" (asi)); \
})
+
+/* load 64-bit int from alternate address space */
+#define ldda(loc, asi) ({ \
+ register long long _lda_v; \
+ __asm __volatile("ldda [%1]%2,%0" : "=r" (_lda_v) : \
+ "r" ((int)(loc)), "n" (asi)); \
+ _lda_v; \
+})
+
+/* store 64-bit int to alternate address space */
+#define stda(loc, asi, value) ({ \
+ __asm __volatile("stda %0,[%1]%2" : : \
+ "r" ((long long)(value)), "r" ((int)(loc)), "n" (asi)); \
+})
diff --git a/sys/arch/sparc/sparc/autoconf.c b/sys/arch/sparc/sparc/autoconf.c
index e6b7a359b21..d645fdd3385 100644
--- a/sys/arch/sparc/sparc/autoconf.c
+++ b/sys/arch/sparc/sparc/autoconf.c
@@ -1,4 +1,5 @@
-/* $NetBSD: autoconf.c,v 1.58.2.2 1996/07/02 23:49:54 jtc Exp $ */
+/* $OpenBSD: autoconf.c,v 1.22 1997/08/08 08:27:01 downsj Exp $ */
+/* $NetBSD: autoconf.c,v 1.73 1997/07/29 09:41:53 fair Exp $ */
/*
* Copyright (c) 1996
@@ -79,6 +80,7 @@
#include <machine/ctlreg.h>
#include <machine/pmap.h>
#include <sparc/sparc/asm.h>
+#include <sparc/sparc/cpuvar.h>
#include <sparc/sparc/timerreg.h>
#ifdef DDB
@@ -187,9 +189,6 @@ str2hex(str, vp)
#ifdef SUN4
struct promvec promvecdat;
struct om_vector *oldpvec = (struct om_vector *)PROM_BASE;
-
-struct idprom idprom;
-void getidprom __P((struct idprom *, int size));
#endif
/*
@@ -200,7 +199,6 @@ void getidprom __P((struct idprom *, int size));
void
bootstrap()
{
- int nregion = 0, nsegment = 0, ncontext = 0;
extern int msgbufmapped;
#if defined(SUN4)
@@ -242,77 +240,16 @@ bootstrap()
*/
if (oldpvec->romvecVersion >= 2)
*oldpvec->vector_cmd = oldmon_w_cmd;
- getidprom(&idprom, sizeof(idprom));
- switch (cpumod = idprom.id_machine) {
- case SUN4_100:
- nsegment = 256;
- ncontext = 8;
- break;
- case SUN4_200:
- nsegment = 512;
- ncontext = 16;
- break;
- case SUN4_300:
- nsegment = 256;
- ncontext = 16;
- break;
- case SUN4_400:
- nsegment = 1024;
- ncontext = 64;
- nregion = 256;
- mmu_3l = 1;
- break;
- default:
- printf("bootstrap: sun4 machine type %2x unknown!\n",
- idprom.id_machine);
- callrom();
- }
}
#endif /* SUN4 */
-#if defined(SUN4C)
- if (CPU_ISSUN4C) {
- register int node = findroot();
- nsegment = getpropint(node, "mmu-npmg", 128);
- ncontext = getpropint(node, "mmu-nctx", 8);
- }
-#endif /* SUN4C */
+ bzero(&cpuinfo, sizeof(struct cpu_softc));
+ cpuinfo.master = 1;
+ getcpuinfo(&cpuinfo, 0);
-#if defined (SUN4M)
- if (CPU_ISSUN4M) {
- nsegment = 0;
- cpumod = (u_int) getpsr() >> 24;
- mmumod = (u_int) lda(SRMMU_PCR, ASI_SRMMU) >> 28;
- /*
- * We use the max. number of contexts on the micro and
- * hyper SPARCs. The SuperSPARC would let us use up to 65536
- * contexts (by powers of 2), but we keep it at 4096 since
- * the table must be aligned to #context*4. With 4K contexts,
- * we waste at most 16K of memory. Note that the context
- * table is *always* page-aligned, so there can always be
- * 1024 contexts without sacrificing memory space (given
- * that the chip supports 1024 contexts).
- *
- * Currently known limits: MS2=256, HS=4096, SS=65536
- * some old SS's=4096
- *
- * XXX Should this be a tuneable parameter?
- */
- switch (mmumod) {
- case SUN4M_MMU_MS1:
- ncontext = 64;
- break;
- case SUN4M_MMU_MS:
- ncontext = 256;
- break;
- default:
- ncontext = 4096;
- break;
- }
- }
-#endif /* SUN4M */
-
- pmap_bootstrap(ncontext, nregion, nsegment);
+ pmap_bootstrap(cpuinfo.mmu_ncontext,
+ cpuinfo.mmu_nregion,
+ cpuinfo.mmu_nsegment);
msgbufmapped = 1; /* enable message buffer */
#ifdef KGDB
zs_kgdb_init(); /* XXX */
@@ -418,6 +355,15 @@ bootstrap()
timerreg_4m = (struct timer_4m *)ra.ra_vaddrs[ra.ra_nvaddrs-1];
}
#endif /* SUN4M */
+
+ if (CPU_ISSUN4OR4C) {
+ /* Map Interrupt Enable Register */
+ pmap_enter(pmap_kernel(), INTRREG_VA,
+ INT_ENABLE_REG_PHYSADR | PMAP_NC | PMAP_OBIO,
+ VM_PROT_READ | VM_PROT_WRITE, 1);
+ /* Disable all interrupts */
+ *((unsigned char *)INTRREG_VA) = 0;
+ }
}
/*
@@ -617,23 +563,23 @@ bootpath_fake(bp, cp)
int target, lun;
- switch (cpumod) {
- case SUN4_200:
- case SUN4_400:
+ switch (cpuinfo.cpu_type) {
+ case CPUTYP_4_200:
+ case CPUTYP_4_400:
BP_APPEND(bp, "vmes", -1, 0, 0);
BP_APPEND(bp, "si", -1, v0val[0], 0);
break;
- case SUN4_100:
+ case CPUTYP_4_100:
BP_APPEND(bp, "obio", -1, 0, 0);
BP_APPEND(bp, "sw", -1, v0val[0], 0);
break;
- case SUN4_300:
+ case CPUTYP_4_300:
BP_APPEND(bp, "obio", -1, 0, 0);
BP_APPEND(bp, "esp", -1, v0val[0], 0);
break;
default:
- panic("bootpath_fake: unknown cpumod %d",
- cpumod);
+ panic("bootpath_fake: unknown system type %d",
+ cpuinfo.cpu_type);
}
/*
* Deal with target/lun encodings.
@@ -715,6 +661,8 @@ bootpath_fake(bp, cp)
/*
* print out the bootpath
+ * the %x isn't 0x%x because the Sun EPROMs do it this way, and
+ * consistency with the EPROMs is probably better here.
*/
static void
@@ -873,21 +821,23 @@ configure()
* must be 0xZYYYYYYY, where (Z != 0)
* make sure we get the correct memreg cfdriver!
*/
- if (cpumod==SUN4_100 && (cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type == CPUTYP_4_100 &&
+ (cf->cf_loc[0] & 0xf0000000))
continue;
- if (cpumod!=SUN4_100 && !(cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type != CPUTYP_4_100 &&
+ !(cf->cf_loc[0] & 0xf0000000))
continue;
for (p = cf->cf_parents; memregcf==NULL && *p >= 0; p++)
if (cfdata[*p].cf_driver == &obio_cd)
memregcf = cf;
}
- if (memregcf==NULL)
+ if (memregcf == NULL)
panic("configure: no memreg found!");
- rr.rr_iospace = BUS_OBIO;
+ rr.rr_iospace = PMAP_OBIO;
rr.rr_paddr = (void *)memregcf->cf_loc[0];
rr.rr_len = NBPG;
- par_err_reg = (u_int *)bus_map(&rr, NBPG, BUS_OBIO);
+ par_err_reg = (u_int *)bus_map(&rr, NBPG);
if (par_err_reg == NULL)
panic("configure: ROM hasn't mapped memreg!");
}
@@ -911,6 +861,16 @@ configure()
oca.ca_ra.ra_name = cp = "mainbus";
if (config_rootfound(cp, (void *)&oca) == NULL)
panic("mainbus not configured");
+
+ /* Enable device interrupts */
+#if defined(SUN4M)
+ if (CPU_ISSUN4M)
+ ienab_bic(SINTR_MA);
+#endif
+#if defined(SUN4) || defined(SUN4C)
+ if (CPU_ISSUN4OR4C)
+ ienab_bis(IE_ALLIE);
+#endif
(void)spl0();
/*
@@ -1067,17 +1027,6 @@ romprop(rp, cp, node)
#endif
}
-#if defined(SUN4M)
- if (CPU_ISSUN4M) {
- len = getprop(node, "ranges", (void *)&rp->ra_range,
- sizeof rp->ra_range);
- if (len == -1)
- len = 0;
- rp->ra_nrange = len / sizeof(struct rom_range);
- } else
-#endif
- rp->ra_nrange = 0;
-
return (1);
}
@@ -1110,8 +1059,8 @@ mainbus_attach(parent, dev, aux)
{
struct confargs oca;
register const char *const *ssp, *sp = NULL;
-#if defined(SUN4C) || defined(SUN4M)
struct confargs *ca = aux;
+#if defined(SUN4C) || defined(SUN4M)
register int node0, node;
const char *const *openboot_special;
#define L1A_HACK /* XXX hack to allow L1-A during autoconf */
@@ -1176,8 +1125,10 @@ mainbus_attach(parent, dev, aux)
#endif
#if defined(SUN4M)
- if (CPU_ISSUN4M)
- printf(": %s", getpropstring(ca->ca_ra.ra_node, "name"));
+ if (CPU_ISSUN4)
+ printf(": SUN-4/%d series\n", cpuinfo.classlvl);
+ else
+ printf(": %s\n", getpropstring(ca->ca_ra.ra_node, "name"));
#endif
printf("\n");
@@ -1225,26 +1176,29 @@ mainbus_attach(parent, dev, aux)
node = ca->ca_ra.ra_node; /* i.e., the root node */
/* the first early device to be configured is the cpu */
-#if defined(SUN4M)
if (CPU_ISSUN4M) {
/* XXX - what to do on multiprocessor machines? */
register const char *cp;
for (node = firstchild(node); node; node = nextsibling(node)) {
cp = getpropstring(node, "device_type");
- if (strcmp(cp, "cpu") == 0)
- break;
+ if (strcmp(cp, "cpu") == 0) {
+ bzero(&oca, sizeof(oca));
+ oca.ca_ra.ra_node = node;
+ oca.ca_ra.ra_name = "cpu";
+ oca.ca_ra.ra_paddr = 0;
+ oca.ca_ra.ra_nreg = 0;
+ config_found(dev, (void *)&oca, mbprint);
+ }
}
- if (node == 0)
- panic("None of the CPUs found\n");
+ } else if (CPU_ISSUN4C) {
+ bzero(&oca, sizeof(oca));
+ oca.ca_ra.ra_node = node;
+ oca.ca_ra.ra_name = "cpu";
+ oca.ca_ra.ra_paddr = 0;
+ oca.ca_ra.ra_nreg = 0;
+ config_found(dev, (void *)&oca, mbprint);
}
-#endif
-
- oca.ca_ra.ra_node = node;
- oca.ca_ra.ra_name = "cpu";
- oca.ca_ra.ra_paddr = 0;
- oca.ca_ra.ra_nreg = 0;
- config_found(dev, (void *)&oca, mbprint);
node = ca->ca_ra.ra_node; /* re-init root node */
@@ -1303,12 +1257,6 @@ mainbus_attach(parent, dev, aux)
(void) config_found(dev, (void *)&oca, mbprint);
}
}
-#if defined(SUN4M)
- if (CPU_ISSUN4M) {
- /* Enable device interrupts */
- ienab_bic(SINTR_MA);
- }
-#endif
#endif /* SUN4C || SUN4M */
}
@@ -1355,9 +1303,9 @@ findzs(zs)
panic("findzs: unknown zs device %d", zs);
}
- rr.rr_iospace = BUS_OBIO;
+ rr.rr_iospace = PMAP_OBIO;
rr.rr_len = NBPG;
- vaddr = bus_map(&rr, NBPG, BUS_OBIO);
+ vaddr = bus_map(&rr, NBPG);
if (vaddr)
return (vaddr);
}
@@ -1537,7 +1485,7 @@ getprop(node, name, buf, bufsiz)
no = promvec->pv_nodeops;
len = no->no_proplen(node, name);
if (len > bufsiz) {
- printf("node %x property %s length %d > %d\n",
+ printf("node 0x%x property %s length %d > %d\n",
node, name, len, bufsiz);
#ifdef DEBUG
panic("getprop");
@@ -1551,6 +1499,19 @@ getprop(node, name, buf, bufsiz)
}
/*
+ * Internal form of proplen(). Returns the property length.
+ */
+int
+getproplen(node, name)
+ int node;
+ char *name;
+{
+ register struct nodeops *no = promvec->pv_nodeops;
+
+ return (no->no_proplen(node, name));
+}
+
+/*
* Return a string property. There is a (small) limit on the length;
* the string is fetched into a static buffer which is overwritten on
* subsequent calls.
@@ -1609,7 +1570,6 @@ nextsibling(node)
return (promvec->pv_nodeops->no_nextnode(node));
}
-char *strchr __P((const char *, int));
u_int hexatoi __P((const char *));
/* The following recursively searches a PROM tree for a given node */
@@ -1698,7 +1658,7 @@ romgetcursoraddr(rowp, colp)
* and in some newer proms. They are local in version 2.9. The
* correct cutoff point is unknown, as yet; we use 2.9 here.
*/
- if (promvec->pv_romvec_vers < 2 || promvec->pv_printrev < 0x00020007)
+ if (promvec->pv_romvec_vers < 2 || promvec->pv_printrev < 0x00020009)
sprintf(buf,
"' line# >body >user %lx ! ' column# >body >user %lx !",
(u_long)rowp, (u_long)colp);
@@ -1708,8 +1668,6 @@ romgetcursoraddr(rowp, colp)
(u_long)rowp, (u_long)colp);
*rowp = *colp = NULL;
rominterpret(buf);
- if (*rowp == *colp && *rowp != NULL)
- panic("romgetcursor prom version");
return (*rowp == NULL || *colp == NULL);
}
#endif
@@ -2163,25 +2121,6 @@ getdevunit(name, unit)
return dev;
}
-
-/*
- * The $#!@$&%# kernel library doesn't have strchr or atoi. Ugh. We duplicate
- * here.
- */
-
-char *
-strchr(p, ch) /* cribbed from libc */
- register const char *p, ch;
-{
- for (;; ++p) {
- if (*p == ch)
- return((char *)p);
- if (!*p)
- return((char *)NULL);
- }
- /* NOTREACHED */
-}
-
u_int
hexatoi(nptr) /* atoi assuming hex, no 0x */
const char *nptr;
@@ -2190,4 +2129,3 @@ hexatoi(nptr) /* atoi assuming hex, no 0x */
str2hex((char *)nptr, &retval);
return retval;
}
-
diff --git a/sys/arch/sparc/sparc/auxreg.c b/sys/arch/sparc/sparc/auxreg.c
index 2a28ec0d7e5..0aa296a7ce6 100644
--- a/sys/arch/sparc/sparc/auxreg.c
+++ b/sys/arch/sparc/sparc/auxreg.c
@@ -120,7 +120,7 @@ auxregattach(parent, self, aux)
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
- (void)mapdev(ra->ra_reg, AUXREG_VA, 0, sizeof(long), ca->ca_bustype);
+ (void)mapdev(ra->ra_reg, AUXREG_VA, 0, sizeof(long));
if (CPU_ISSUN4M) {
auxio_reg = AUXIO4M_REG;
auxio_regval = *AUXIO4M_REG | AUXIO4M_MB1;
diff --git a/sys/arch/sparc/sparc/cache.c b/sys/arch/sparc/sparc/cache.c
index 1a02e82639b..aa28655e4bc 100644
--- a/sys/arch/sparc/sparc/cache.c
+++ b/sys/arch/sparc/sparc/cache.c
@@ -1,4 +1,5 @@
-/* $NetBSD: cache.c,v 1.8.4.1 1996/06/12 20:40:35 pk Exp $ */
+/* $OpenBSD: cache.c,v 1.4 1997/08/08 08:27:03 downsj Exp $ */
+/* $NetBSD: cache.c,v 1.33 1997/07/29 09:41:56 fair Exp $ */
/*
* Copyright (c) 1996
@@ -66,169 +67,254 @@
#include <sparc/sparc/asm.h>
#include <sparc/sparc/cache.h>
+#include <sparc/sparc/cpuvar.h>
-enum vactype vactype;
struct cachestats cachestats;
-#if defined(SUN4M)
int cache_alias_dist; /* Cache anti-aliasing constants */
int cache_alias_bits;
-#endif
-
-/*
- * A few quick macros to allow for different ASI's between 4M/4/4C machines
- */
-#define flushls_ctx(p) do { \
- CPU_ISSUN4M \
- ? sta(p, ASI_IDCACHELFC, 0) \
- : sta(p, ASI_FLUSHCTX, 0); \
-} while (0)
-#define flushls_reg(p) do { \
- CPU_ISSUN4M \
- ? sta(p, ASI_IDCACHELFR, 0) \
- : sta(p, ASI_FLUSHREG, 0); \
-} while (0)
-#define flushls_seg(p) do { \
- CPU_ISSUN4M \
- ? sta(p, ASI_IDCACHELFS, 0) \
- : sta(p, ASI_FLUSHSEG, 0); \
-} while (0)
-#define flushls_pag(p) do { \
- CPU_ISSUN4M \
- ? sta(p, ASI_IDCACHELFP, 0) \
- : sta(p, ASI_FLUSHPG, 0); \
-} while (0)
-#define flushls_usr(p) do { \
- if (CPU_ISSUN4M) \
- sta(p, ASI_IDCACHELFU, 0); \
-while(0)
-
-/* XXX: (ABB) need more generic Sun4m cache support */
-#if !defined(SUN4) && !defined(SUN4C)
-#define ASI_HWFLUSHSEG 0x05 /* hardware assisted version of FLUSHSEG */
-#define ASI_HWFLUSHPG 0x06 /* hardware assisted version of FLUSHPG */
-#define ASI_HWFLUSHCTX 0x07 /* hardware assisted version of FLUSHCTX */
-#endif
/*
* Enable the cache.
* We need to clear out the valid bits first.
*/
void
-cache_enable()
+sun4_cache_enable()
{
register u_int i, lim, ls, ts;
- ls = cacheinfo.c_linesize;
- ts = cacheinfo.c_totalsize;
-
- if (CPU_ISSUN4M) {
- i = lda(SRMMU_PCR, ASI_SRMMU);
- switch (mmumod) {
- case SUN4M_MMU_HS: /* HyperSPARC */
- /*
- * First we determine what type of cache we have, and
- * setup the anti-aliasing constants appropriately.
- */
- if (i & SRMMU_PCR_CS) {
- cache_alias_bits = CACHE_ALIAS_BITS_HS256k;
- cache_alias_dist = CACHE_ALIAS_DIST_HS256k;
- } else {
- cache_alias_bits = CACHE_ALIAS_BITS_HS128k;
- cache_alias_dist = CACHE_ALIAS_DIST_HS128k;
- }
- /* Now reset cache tag memory */
- for (i = 0, lim = ts; i < lim; i += ls)
- sta(i, ASI_DCACHETAG, 0);
-
- sta(SRMMU_PCR, ASI_SRMMU, /* Enable write-back cache */
- lda(SRMMU_PCR, ASI_SRMMU) | SRMMU_PCR_CE |
- SRMMU_PCR_CM);
- cacheinfo.c_enabled = 1;
- vactype = VAC_NONE;
- /* HyperSPARC uses phys. tagged cache */
-
- /* XXX: should add support */
- if (cacheinfo.c_hwflush)
- panic("cache_enable: can't handle 4M with hw-flush cache");
-
- printf("cache enabled\n");
- break;
-
- case SUN4M_MMU_SS: /* SuperSPARC */
- if ((cpumod & 0xf0) != (SUN4M_SS & 0xf0)) {
- printf(
- "cache NOT enabled for %x/%x cpu/mmu combination\n",
- cpumod, mmumod);
- break; /* ugh, SS and MS have same MMU # */
- }
- cache_alias_bits = CACHE_ALIAS_BITS_SS;
- cache_alias_dist = CACHE_ALIAS_DIST_SS;
-
- /* We "flash-clear" the I/D caches. */
- sta(0x80000000, ASI_ICACHECLR, 0); /* Unlock */
- sta(0, ASI_ICACHECLR, 0); /* clear */
- sta(0x80000000, ASI_DCACHECLR, 0);
- sta(0, ASI_DCACHECLR, 0);
-
- /* Turn on caches via MMU */
- sta(SRMMU_PCR, ASI_SRMMU,
- lda(SRMMU_PCR,ASI_SRMMU) | SRMMU_PCR_DCE |
- SRMMU_PCR_ICE);
- cacheinfo.c_enabled = cacheinfo.dc_enabled = 1;
-
- /* Now try to turn on MultiCache if it exists */
- /* XXX (ABB) THIS IS BROKEN MUST FIX */
- if (0&&(lda(SRMMU_PCR, ASI_SRMMU) & SRMMU_PCR_MB) == 0
- && cacheinfo.ec_totalsize > 0) {
- /* Multicache controller */
- sta(MXCC_ENABLE_ADDR, ASI_CONTROL,
- lda(MXCC_ENABLE_ADDR, ASI_CONTROL) |
- MXCC_ENABLE_BIT);
- cacheinfo.ec_enabled = 1;
- }
- printf("cache enabled\n");
- break;
- case SUN4M_MMU_MS1: /* MicroSPARC */
- /* We "flash-clear" the I/D caches. */
- sta(0, ASI_ICACHECLR, 0); /* clear */
- sta(0, ASI_DCACHECLR, 0);
-
- /* Turn on caches via MMU */
- sta(SRMMU_PCR, ASI_SRMMU,
- lda(SRMMU_PCR,ASI_SRMMU) | SRMMU_PCR_DCE |
- SRMMU_PCR_ICE);
- cacheinfo.c_enabled = cacheinfo.dc_enabled = 1;
-
- printf("cache enabled\n");
- break;
-
- default:
- printf("Unknown MMU architecture...cache disabled.\n");
- /* XXX: not HyperSPARC -- guess for now */
- cache_alias_bits = GUESS_CACHE_ALIAS_BITS;
- cache_alias_dist = GUESS_CACHE_ALIAS_DIST;
- }
+ cache_alias_bits = CPU_ISSUN4
+ ? CACHE_ALIAS_BITS_SUN4
+ : CACHE_ALIAS_BITS_SUN4C;
+ cache_alias_dist = CPU_ISSUN4
+ ? CACHE_ALIAS_DIST_SUN4
+ : CACHE_ALIAS_DIST_SUN4C;
- } else {
+ ls = CACHEINFO.c_linesize;
+ ts = CACHEINFO.c_totalsize;
- for (i = AC_CACHETAGS, lim = i + ts; i < lim; i += ls)
- sta(i, ASI_CONTROL, 0);
+ for (i = AC_CACHETAGS, lim = i + ts; i < lim; i += ls)
+ sta(i, ASI_CONTROL, 0);
- stba(AC_SYSENABLE, ASI_CONTROL,
- lduba(AC_SYSENABLE, ASI_CONTROL) | SYSEN_CACHE);
- cacheinfo.c_enabled = 1;
+ stba(AC_SYSENABLE, ASI_CONTROL,
+ lduba(AC_SYSENABLE, ASI_CONTROL) | SYSEN_CACHE);
+ CACHEINFO.c_enabled = 1;
- printf("cache enabled\n");
+ printf("cache enabled\n");
#ifdef notyet
- if (cpumod == SUN4_400) {
- stba(AC_SYSENABLE, ASI_CONTROL,
- lduba(AC_SYSENABLE, ASI_CONTROL) | SYSEN_IOCACHE);
- printf("iocache enabled\n");
- }
+ if (cpuinfo.flags & SUN4_IOCACHE) {
+ stba(AC_SYSENABLE, ASI_CONTROL,
+ lduba(AC_SYSENABLE, ASI_CONTROL) | SYSEN_IOCACHE);
+ printf("iocache enabled\n");
+ }
#endif
+}
+
+void
+ms1_cache_enable()
+{
+ u_int pcr;
+
+ cache_alias_bits = GUESS_CACHE_ALIAS_BITS;
+ cache_alias_dist = GUESS_CACHE_ALIAS_DIST;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+
+ /* We "flash-clear" the I/D caches. */
+ if ((pcr & MS1_PCR_ICE) == 0)
+ sta(0, ASI_ICACHECLR, 0);
+ if ((pcr & MS1_PCR_DCE) == 0)
+ sta(0, ASI_DCACHECLR, 0);
+
+ /* Turn on caches */
+ sta(SRMMU_PCR, ASI_SRMMU, pcr | MS1_PCR_DCE | MS1_PCR_ICE);
+
+ cpuinfo.flags |= CPUFLG_CACHEPAGETABLES;
+
+ CACHEINFO.c_enabled = CACHEINFO.dc_enabled = 1;
+
+ printf("cache enabled\n");
+}
+
+void
+viking_cache_enable()
+{
+ u_int pcr;
+
+ cache_alias_dist = max(
+ CACHEINFO.ic_totalsize / CACHEINFO.ic_associativity,
+ CACHEINFO.dc_totalsize / CACHEINFO.dc_associativity);
+ cache_alias_bits = (cache_alias_dist - 1) & ~PGOFSET;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+
+ if ((pcr & VIKING_PCR_ICE) == 0) {
+ /* I-cache not on; "flash-clear" it now. */
+ sta(0x80000000, ASI_ICACHECLR, 0); /* Unlock */
+ sta(0, ASI_ICACHECLR, 0); /* clear */
+ }
+ if ((pcr & VIKING_PCR_DCE) == 0) {
+ /* D-cache not on: "flash-clear" it. */
+ sta(0x80000000, ASI_DCACHECLR, 0);
+ sta(0, ASI_DCACHECLR, 0);
}
+
+ /* Turn on caches via MMU */
+ sta(SRMMU_PCR, ASI_SRMMU, pcr | VIKING_PCR_DCE | VIKING_PCR_ICE);
+
+ CACHEINFO.c_enabled = CACHEINFO.dc_enabled = 1;
+
+ /* Now turn on MultiCache if it exists */
+ if (cpuinfo.mxcc && CACHEINFO.ec_totalsize > 0) {
+ /* Multicache controller */
+ stda(MXCC_ENABLE_ADDR, ASI_CONTROL,
+ ldda(MXCC_ENABLE_ADDR, ASI_CONTROL) |
+ (u_int64_t)MXCC_ENABLE_BIT);
+ cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; /* Ok to cache PTEs */
+ CACHEINFO.ec_enabled = 1;
+ }
+ printf("cache enabled\n");
+}
+
+void
+hypersparc_cache_enable()
+{
+ int i, ls, ts;
+ u_int pcr;
+
+ ls = CACHEINFO.c_linesize;
+ ts = CACHEINFO.c_totalsize;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+
+ /*
+ * First we determine what type of cache we have, and
+ * setup the anti-aliasing constants appropriately.
+ */
+ if (pcr & HYPERSPARC_PCR_CS) {
+ cache_alias_bits = CACHE_ALIAS_BITS_HS256k;
+ cache_alias_dist = CACHE_ALIAS_DIST_HS256k;
+ } else {
+ cache_alias_bits = CACHE_ALIAS_BITS_HS128k;
+ cache_alias_dist = CACHE_ALIAS_DIST_HS128k;
+ }
+
+ /* Now reset cache tag memory if cache not yet enabled */
+ if ((pcr & HYPERSPARC_PCR_CE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_DCACHETAG, 0);
+
+ /* Enable write-back cache */
+ pcr |= (HYPERSPARC_PCR_CE | HYPERSPARC_PCR_CM);
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+ CACHEINFO.c_enabled = 1;
+
+ /* XXX: should add support */
+ if (CACHEINFO.c_hwflush)
+ panic("cache_enable: can't handle 4M with hw-flush cache");
+
+ printf("cache enabled\n");
+}
+
+void
+swift_cache_enable()
+{
+ int i, ls, ts;
+ u_int pcr;
+
+ cache_alias_dist = max(
+ CACHEINFO.ic_totalsize / CACHEINFO.ic_associativity,
+ CACHEINFO.dc_totalsize / CACHEINFO.dc_associativity);
+ cache_alias_bits = (cache_alias_dist - 1) & ~PGOFSET;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+ pcr |= (SWIFT_PCR_ICE | SWIFT_PCR_DCE);
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+
+ /* Now reset cache tag memory if cache not yet enabled */
+ ls = CACHEINFO.ic_linesize;
+ ts = CACHEINFO.ic_totalsize;
+ if ((pcr & SWIFT_PCR_ICE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_ICACHETAG, 0);
+
+ ls = CACHEINFO.dc_linesize;
+ ts = CACHEINFO.dc_totalsize;
+ if ((pcr & SWIFT_PCR_DCE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_DCACHETAG, 0);
+
+ /* XXX - assume that an MS2 with ecache is really a turbo in disguise */
+ if (CACHEINFO.ec_totalsize == 0)
+ cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; /* Ok to cache PTEs */
+ CACHEINFO.c_enabled = 1;
+ printf("cache enabled\n");
+}
+
+void
+cypress_cache_enable()
+{
+ int i, ls, ts;
+ u_int pcr;
+
+ cache_alias_dist = CACHEINFO.c_totalsize;
+ cache_alias_bits = (cache_alias_dist - 1) & ~PGOFSET;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+ pcr &= ~(CYPRESS_PCR_CE | CYPRESS_PCR_CM);
+
+ /* Now reset cache tag memory if cache not yet enabled */
+ ls = CACHEINFO.c_linesize;
+ ts = CACHEINFO.c_totalsize;
+ if ((pcr & CYPRESS_PCR_CE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_DCACHETAG, 0);
+
+ pcr |= CYPRESS_PCR_CE;
+ /* If put in write-back mode, turn it on */
+ if (CACHEINFO.c_vactype == VAC_WRITEBACK)
+ pcr |= CYPRESS_PCR_CM;
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+ CACHEINFO.c_enabled = 1;
+ printf("cache enabled\n");
+}
+
+void
+turbosparc_cache_enable()
+{
+ int i, ls, ts;
+ u_int pcr, pcf;
+
+ cache_alias_dist = max(
+ CACHEINFO.ic_totalsize / CACHEINFO.ic_associativity,
+ CACHEINFO.dc_totalsize / CACHEINFO.dc_associativity);
+ cache_alias_bits = (cache_alias_dist - 1) & ~PGOFSET;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+
+ /* Now reset cache tag memory if cache not yet enabled */
+ ls = CACHEINFO.ic_linesize;
+ ts = CACHEINFO.ic_totalsize;
+ if ((pcr & TURBOSPARC_PCR_ICE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_ICACHETAG, 0);
+
+ ls = CACHEINFO.dc_linesize;
+ ts = CACHEINFO.dc_totalsize;
+ if ((pcr & TURBOSPARC_PCR_DCE) == 0)
+ for (i = 0; i < ts; i += ls)
+ sta(i, ASI_DCACHETAG, 0);
+
+ pcr |= (TURBOSPARC_PCR_ICE | TURBOSPARC_PCR_DCE);
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+
+ pcf = lda(SRMMU_PCFG, ASI_SRMMU);
+ if (pcf & TURBOSPARC_PCFG_SNP)
+ printf("DVMA coherent ");
+
+ CACHEINFO.c_enabled = 1;
+ printf("cache enabled\n");
}
/*
@@ -239,27 +325,26 @@ cache_enable()
* hardware flush space, for all cache pages).
*/
void
-cache_flush_context()
+sun4_vcache_flush_context()
{
register char *p;
register int i, ls;
cachestats.cs_ncxflush++;
p = (char *)0; /* addresses 0..cacheinfo.c_totalsize will do fine */
- if (cacheinfo.c_hwflush) {
+ if (CACHEINFO.c_hwflush) {
ls = NBPG;
- i = cacheinfo.c_totalsize >> PGSHIFT;
+ i = CACHEINFO.c_totalsize >> PGSHIFT;
for (; --i >= 0; p += ls)
sta(p, ASI_HWFLUSHCTX, 0);
} else {
- ls = cacheinfo.c_linesize;
- i = cacheinfo.c_totalsize >> cacheinfo.c_l2linesize;
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
for (; --i >= 0; p += ls)
- flushls_ctx(p);
+ sta(p, ASI_FLUSHCTX, 0);
}
}
-#if defined(SUN4) || defined(SUN4M)
/*
* Flush the given virtual region from the cache.
*
@@ -267,11 +352,11 @@ cache_flush_context()
* now the addresses must include the virtual region number, and
* we use the `flush region' space.
*
- * This function is only called on sun4m's or sun4's with 3-level MMUs; there's
+ * This function is only called on sun4's with 3-level MMUs; there's
* no hw-flush space.
*/
void
-cache_flush_region(vreg)
+sun4_vcache_flush_region(vreg)
register int vreg;
{
register int i, ls;
@@ -279,12 +364,11 @@ cache_flush_region(vreg)
cachestats.cs_nrgflush++;
p = (char *)VRTOVA(vreg); /* reg..reg+sz rather than 0..sz */
- ls = cacheinfo.c_linesize;
- i = cacheinfo.c_totalsize >> cacheinfo.c_l2linesize;
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
for (; --i >= 0; p += ls)
- flushls_reg(p);
+ sta(p, ASI_FLUSHREG, 0);
}
-#endif
/*
* Flush the given virtual segment from the cache.
@@ -296,7 +380,7 @@ cache_flush_region(vreg)
* Again, for hardware, we just write each page (in hw-flush space).
*/
void
-cache_flush_segment(vreg, vseg)
+sun4_vcache_flush_segment(vreg, vseg)
register int vreg, vseg;
{
register int i, ls;
@@ -304,16 +388,16 @@ cache_flush_segment(vreg, vseg)
cachestats.cs_nsgflush++;
p = (char *)VSTOVA(vreg, vseg); /* seg..seg+sz rather than 0..sz */
- if (cacheinfo.c_hwflush) {
+ if (CACHEINFO.c_hwflush) {
ls = NBPG;
- i = cacheinfo.c_totalsize >> PGSHIFT;
+ i = CACHEINFO.c_totalsize >> PGSHIFT;
for (; --i >= 0; p += ls)
sta(p, ASI_HWFLUSHSEG, 0);
} else {
- ls = cacheinfo.c_linesize;
- i = cacheinfo.c_totalsize >> cacheinfo.c_l2linesize;
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
for (; --i >= 0; p += ls)
- flushls_seg(p);
+ sta(p, ASI_FLUSHSEG, 0);
}
}
@@ -323,7 +407,7 @@ cache_flush_segment(vreg, vseg)
* Again we write to each cache line.
*/
void
-cache_flush_page(va)
+sun4_vcache_flush_page(va)
int va;
{
register int i, ls;
@@ -331,18 +415,18 @@ cache_flush_page(va)
#ifdef DEBUG
if (va & PGOFSET)
- panic("cache_flush_page: asked to flush misaligned va %x",va);
+ panic("cache_flush_page: asked to flush misaligned va 0x%x",va);
#endif
cachestats.cs_npgflush++;
p = (char *)va;
- if (cacheinfo.c_hwflush)
+ if (CACHEINFO.c_hwflush)
sta(p, ASI_HWFLUSHPG, 0);
else {
- ls = cacheinfo.c_linesize;
- i = NBPG >> cacheinfo.c_l2linesize;
+ ls = CACHEINFO.c_linesize;
+ i = NBPG >> CACHEINFO.c_l2linesize;
for (; --i >= 0; p += ls)
- flushls_pag(p);
+ sta(p, ASI_FLUSHPG, 0);
}
}
@@ -354,37 +438,187 @@ cache_flush_page(va)
* We choose the best of (context,segment,page) here.
*/
-#define CACHE_FLUSH_MAGIC (cacheinfo.c_totalsize / NBPG)
+#define CACHE_FLUSH_MAGIC (CACHEINFO.c_totalsize / NBPG)
void
-cache_flush(base, len)
+sun4_cache_flush(base, len)
caddr_t base;
register u_int len;
{
register int i, ls, baseoff;
register char *p;
-#if defined(SUN4)
- extern int mmu_3l;
-#endif
-#if defined(SUN4M)
+ if (CACHEINFO.c_vactype == VAC_NONE)
+ return;
+
/*
- * Although physically tagged, we still need to flush the
- * data cache after (if we have a write-through cache) or before
- * (in case of write-back caches) DMA operations.
+ * Figure out how much must be flushed.
*
- * SS10s and 20s (supersparcs) use cached DVMA, no need to flush.
+ * If we need to do CACHE_FLUSH_MAGIC pages, we can do a segment
+ * in the same number of loop iterations. We can also do the whole
+ * region. If we need to do between 2 and NSEGRG, do the region.
+ * If we need to do two or more regions, just go ahead and do the
+ * whole context. This might not be ideal (e.g., fsck likes to do
+ * 65536-byte reads, which might not necessarily be aligned).
+ *
+ * We could try to be sneaky here and use the direct mapping
+ * to avoid flushing things `below' the start and `above' the
+ * ending address (rather than rounding to whole pages and
+ * segments), but I did not want to debug that now and it is
+ * not clear it would help much.
+ *
+ * (XXX the magic number 16 is now wrong, must review policy)
*/
- if (CPU_ISSUN4M && mmumod != SUN4M_MMU_SS) {
- /* XXX (ABB) - Need more generic cache interface */
- /* XXX above test conflicts on MicroSPARC (SUN4M_MMU_MS=_SS) */
- sta(0, ASI_DCACHECLR, 0);
+ baseoff = (int)base & PGOFSET;
+ i = (baseoff + len + PGOFSET) >> PGSHIFT;
+
+ cachestats.cs_nraflush++;
+#ifdef notyet
+ cachestats.cs_ra[min(i, MAXCACHERANGE)]++;
+#endif
+
+ if (i < CACHE_FLUSH_MAGIC) {
+ /* cache_flush_page, for i pages */
+ p = (char *)((int)base & ~baseoff);
+ if (CACHEINFO.c_hwflush) {
+ for (; --i >= 0; p += NBPG)
+ sta(p, ASI_HWFLUSHPG, 0);
+ } else {
+ ls = CACHEINFO.c_linesize;
+ i <<= PGSHIFT - CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_FLUSHPG, 0);
+ }
return;
}
+ baseoff = (u_int)base & SGOFSET;
+ i = (baseoff + len + SGOFSET) >> SGSHIFT;
+ if (i == 1)
+ sun4_vcache_flush_segment(VA_VREG(base), VA_VSEG(base));
+ else {
+ if (HASSUN4_MMU3L) {
+ baseoff = (u_int)base & RGOFSET;
+ i = (baseoff + len + RGOFSET) >> RGSHIFT;
+ if (i == 1)
+ sun4_vcache_flush_region(VA_VREG(base));
+ else
+ sun4_vcache_flush_context();
+ } else
+ sun4_vcache_flush_context();
+ }
+}
+
+
+#if defined(SUN4M)
+/*
+ * Flush the current context from the cache.
+ *
+ * This is done by writing to each cache line in the `flush context'
+ * address space (or, for hardware flush, once to each page in the
+ * hardware flush space, for all cache pages).
+ */
+void
+srmmu_vcache_flush_context()
+{
+ register char *p;
+ register int i, ls;
+
+ cachestats.cs_ncxflush++;
+ p = (char *)0; /* addresses 0..cacheinfo.c_totalsize will do fine */
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_IDCACHELFC, 0);
+}
+
+/*
+ * Flush the given virtual region from the cache.
+ *
+ * This is also done by writing to each cache line, except that
+ * now the addresses must include the virtual region number, and
+ * we use the `flush region' space.
+ */
+void
+srmmu_vcache_flush_region(vreg)
+ register int vreg;
+{
+ register int i, ls;
+ register char *p;
+
+ cachestats.cs_nrgflush++;
+ p = (char *)VRTOVA(vreg); /* reg..reg+sz rather than 0..sz */
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_IDCACHELFR, 0);
+}
+
+/*
+ * Flush the given virtual segment from the cache.
+ *
+ * This is also done by writing to each cache line, except that
+ * now the addresses must include the virtual segment number, and
+ * we use the `flush segment' space.
+ *
+ * Again, for hardware, we just write each page (in hw-flush space).
+ */
+void
+srmmu_vcache_flush_segment(vreg, vseg)
+ register int vreg, vseg;
+{
+ register int i, ls;
+ register char *p;
+
+ cachestats.cs_nsgflush++;
+ p = (char *)VSTOVA(vreg, vseg); /* seg..seg+sz rather than 0..sz */
+ ls = CACHEINFO.c_linesize;
+ i = CACHEINFO.c_totalsize >> CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_IDCACHELFS, 0);
+}
+
+/*
+ * Flush the given virtual page from the cache.
+ * (va is the actual address, and must be aligned on a page boundary.)
+ * Again we write to each cache line.
+ */
+void
+srmmu_vcache_flush_page(va)
+ int va;
+{
+ register int i, ls;
+ register char *p;
+
+#ifdef DEBUG
+ if (va & PGOFSET)
+ panic("cache_flush_page: asked to flush misaligned va 0x%x",va);
#endif
- if (vactype == VAC_NONE)
- return;
+ cachestats.cs_npgflush++;
+ p = (char *)va;
+ ls = CACHEINFO.c_linesize;
+ i = NBPG >> CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_IDCACHELFP, 0);
+}
+
+/*
+ * Flush a range of virtual addresses (in the current context).
+ * The first byte is at (base&~PGOFSET) and the last one is just
+ * before byte (base+len).
+ *
+ * We choose the best of (context,segment,page) here.
+ */
+
+#define CACHE_FLUSH_MAGIC (CACHEINFO.c_totalsize / NBPG)
+
+void
+srmmu_cache_flush(base, len)
+ caddr_t base;
+ register u_int len;
+{
+ register int i, ls, baseoff;
+ register char *p;
/*
* Figure out how much must be flushed.
@@ -415,37 +649,121 @@ cache_flush(base, len)
if (i < CACHE_FLUSH_MAGIC) {
/* cache_flush_page, for i pages */
p = (char *)((int)base & ~baseoff);
- if (cacheinfo.c_hwflush) {
- for (; --i >= 0; p += NBPG)
- sta(p, ASI_HWFLUSHPG, 0);
- } else {
- ls = cacheinfo.c_linesize;
- i <<= PGSHIFT - cacheinfo.c_l2linesize;
- for (; --i >= 0; p += ls)
- flushls_pag(p);
- }
+ ls = CACHEINFO.c_linesize;
+ i <<= PGSHIFT - CACHEINFO.c_l2linesize;
+ for (; --i >= 0; p += ls)
+ sta(p, ASI_IDCACHELFP, 0);
return;
}
baseoff = (u_int)base & SGOFSET;
i = (baseoff + len + SGOFSET) >> SGSHIFT;
if (i == 1)
- cache_flush_segment(VA_VREG(base), VA_VSEG(base));
+ srmmu_vcache_flush_segment(VA_VREG(base), VA_VSEG(base));
else {
-#if defined(SUN4) || defined(SUN4M)
baseoff = (u_int)base & RGOFSET;
i = (baseoff + len + RGOFSET) >> RGSHIFT;
- if (i == 1
-#if !defined(SUN4)
- && CPU_ISSUN4M
-#elif !defined(SUN4M)
- && mmu_3l
-#else
- && (CPU_ISSUN4M || mmu_3l)
-#endif
- )
- cache_flush_region(VA_VREG(base));
+ if (i == 1)
+ srmmu_vcache_flush_region(VA_VREG(base));
else
-#endif
- cache_flush_context();
+ srmmu_vcache_flush_context();
}
}
+
+void
+ms1_cache_flush(base, len)
+ caddr_t base;
+ register u_int len;
+{
+ /*
+ * Although physically tagged, we still need to flush the
+ * data cache after (if we have a write-through cache) or before
+ * (in case of write-back caches) DMA operations.
+ */
+
+ /* XXX investigate other methods instead of blowing the entire cache */
+ sta(0, ASI_DCACHECLR, 0);
+}
+
+void
+viking_cache_flush(base, len)
+ caddr_t base;
+ register u_int len;
+{
+ /*
+ * Although physically tagged, we still need to flush the
+ * data cache after (if we have a write-through cache) or before
+ * (in case of write-back caches) DMA operations.
+ */
+
+}
+
+void
+viking_pcache_flush_line(va, pa)
+ int va;
+ int pa;
+{
+ /*
+ * Flush cache line corresponding to virtual address `va'
+ * which is mapped at physical address `pa'.
+ */
+ extern char etext[];
+ static char *base;
+ int i;
+ char *v;
+
+ /*
+ * Construct a virtual address that hits the same cache line
+ * as PA, then read from 2*ASSOCIATIVITY-1 different physical
+ * locations (all different from PA).
+ */
+
+#if 0
+ if (base == 0) {
+ cshift = CACHEINFO.ic_l2linesize;
+ csize = CACHEINFO.ic_nlines << cshift;
+ cmask = csize - 1;
+ base = (char *)roundup((int)etext, csize);
+ }
+
+ v = base + (((va & cmask) >> cshift) << cshift);
+ i = CACHEINFO.dc_associativity * 2 - 1;
+
+ while (i--) {
+ (*(volatile int *)v);
+ v += csize;
+ }
+#else
+#define cshift 5 /* CACHEINFO.ic_l2linesize */
+#define csize (128 << cshift) /* CACHEINFO.ic_nlines << cshift */
+#define cmask (csize - 1)
+#define cass 4 /* CACHEINFO.dc_associativity */
+
+ if (base == 0)
+ base = (char *)roundup((int)etext, csize);
+
+ v = base + (((pa & cmask) >> cshift) << cshift);
+ i = 2 * cass - 1;
+
+ while (i--) {
+ (*(volatile int *)v);
+ v += csize;
+ }
+#undef cass
+#undef cmask
+#undef csize
+#undef cshift
+#endif
+}
+
+void
+srmmu_pcache_flush_line(va, pa)
+ int va;
+ int pa;
+{
+ /*
+ * Flush cache line corresponding to virtual address `va'
+ * which is mapped at physical address `pa'.
+ */
+ sta(va, ASI_IDCACHELFP, 0);
+}
+#endif /* SUN4M */
diff --git a/sys/arch/sparc/sparc/cache.h b/sys/arch/sparc/sparc/cache.h
index 6076ee314b6..1eef90e5d67 100644
--- a/sys/arch/sparc/sparc/cache.h
+++ b/sys/arch/sparc/sparc/cache.h
@@ -1,4 +1,5 @@
-/* $NetBSD: cache.h,v 1.7.4.1 1996/06/12 20:41:22 pk Exp $ */
+/* $OpenBSD: cache.h,v 1.3 1997/08/08 08:27:04 downsj Exp $ */
+/* $NetBSD: cache.h,v 1.16 1997/07/06 21:15:14 pk Exp $ */
/*
* Copyright (c) 1996
@@ -43,6 +44,9 @@
* @(#)cache.h 8.1 (Berkeley) 6/11/93
*/
+#ifndef SPARC_CACHE_H
+#define SPARC_CACHE_H
+
/*
* Sun-4 and Sun-4c virtual address cache.
*
@@ -50,14 +54,8 @@
* and write-back (Sun-4). The write-back caches are much faster
* but require a bit more care.
*
- * VAC_NONE is not actually used now, but if someone builds a physical
- * cache Sun-4 (or, more likely, a virtual index/physical tag cache)
- * everything will work (after pulling out the #ifdef notdef's: grep
- * for VAC_NONE to find them).
*/
-enum vactype { VAC_NONE, VAC_WRITETHROUGH, VAC_WRITEBACK };
-
-extern enum vactype vactype; /* XXX move into cacheinfo struct */
+enum vactype { VAC_UNKNOWN, VAC_NONE, VAC_WRITETHROUGH, VAC_WRITEBACK };
/*
* Cache tags can be written in control space, and must be set to 0
@@ -120,35 +118,29 @@ extern enum vactype vactype; /* XXX move into cacheinfo struct */
#define CACHE_ALIAS_DIST_HS256k 0x40000
#define CACHE_ALIAS_BITS_HS256k 0x3f000
-#define CACHE_ALIAS_DIST_SS 0x0
-#define CACHE_ALIAS_BITS_SS 0x0
-
-#define CACHE_ALIAS_DIST_MS GUESS_CACHE_ALIAS_DIST /* fix! */
-#define CACHE_ALIAS_BITS_MS GUESS_CACHE_ALIAS_BITS /* %%% */
-
/*
* Assuming a tag format where the least significant bits are the byte offset
* into the cache line, and the next-most significant bits are the line id,
* we can calculate the appropriate aliasing constants. We also assume that
* the linesize and total cache size are powers of 2.
*/
-#define GUESS_CACHE_ALIAS_BITS ((cacheinfo.c_totalsize - 1) & ~PGOFSET)
-#define GUESS_CACHE_ALIAS_DIST (cacheinfo.c_totalsize)
+#define GUESS_CACHE_ALIAS_BITS ((cpuinfo.cacheinfo.c_totalsize - 1) & ~PGOFSET)
+#define GUESS_CACHE_ALIAS_DIST (cpuinfo.cacheinfo.c_totalsize)
-extern int cache_alias_dist; /* If `guessed' */
+extern int cache_alias_dist; /* */
extern int cache_alias_bits;
-#define CACHE_ALIAS_DIST (CPU_ISSUN4M \
- ? cache_alias_dist \
- : (CPU_ISSUN4C \
- ? CACHE_ALIAS_DIST_SUN4C \
- : CACHE_ALIAS_DIST_SUN4))
-
-#define CACHE_ALIAS_BITS (CPU_ISSUN4M \
- ? cache_alias_bits \
- : (CPU_ISSUN4C \
- ? CACHE_ALIAS_BITS_SUN4C \
- : CACHE_ALIAS_BITS_SUN4))
+/* Optimize cache alias macros on single architecture kernels */
+#if defined(SUN4) && !defined(SUN4C) && !defined(SUN4M)
+#define CACHE_ALIAS_DIST CACHE_ALIAS_DIST_SUN4
+#define CACHE_ALIAS_BITS CACHE_ALIAS_BITS_SUN4
+#elif !defined(SUN4) && defined(SUN4C) && !defined(SUN4M)
+#define CACHE_ALIAS_DIST CACHE_ALIAS_DIST_SUN4C
+#define CACHE_ALIAS_BITS CACHE_ALIAS_BITS_SUN4C
+#else
+#define CACHE_ALIAS_DIST cache_alias_dist
+#define CACHE_ALIAS_BITS cache_alias_bits
+#endif
/*
* True iff a1 and a2 are `bad' aliases (will cause cache duplication).
@@ -158,12 +150,51 @@ extern int cache_alias_bits;
/*
* Routines for dealing with the cache.
*/
-void cache_enable __P((void)); /* turn it on */
-void cache_flush_context __P((void)); /* flush current context */
-void cache_flush_region __P((int)); /* flush region in cur ctx */
-void cache_flush_segment __P((int, int)); /* flush seg in cur ctx */
-void cache_flush_page __P((int va)); /* flush page in cur ctx */
-void cache_flush __P((caddr_t, u_int)); /* flush region */
+void sun4_cache_enable __P((void)); /* turn it on */
+void ms1_cache_enable __P((void)); /* turn it on */
+void viking_cache_enable __P((void)); /* turn it on */
+void hypersparc_cache_enable __P((void)); /* turn it on */
+void swift_cache_enable __P((void)); /* turn it on */
+void cypress_cache_enable __P((void)); /* turn it on */
+void turbosparc_cache_enable __P((void)); /* turn it on */
+
+void sun4_vcache_flush_context __P((void)); /* flush current context */
+void sun4_vcache_flush_region __P((int)); /* flush region in cur ctx */
+void sun4_vcache_flush_segment __P((int, int));/* flush seg in cur ctx */
+void sun4_vcache_flush_page __P((int va)); /* flush page in cur ctx */
+void sun4_cache_flush __P((caddr_t, u_int));/* flush region */
+
+void srmmu_vcache_flush_context __P((void)); /* flush current context */
+void srmmu_vcache_flush_region __P((int)); /* flush region in cur ctx */
+void srmmu_vcache_flush_segment __P((int, int));/* flush seg in cur ctx */
+void srmmu_vcache_flush_page __P((int va)); /* flush page in cur ctx */
+void srmmu_cache_flush __P((caddr_t, u_int));/* flush region */
+
+void ms1_cache_flush __P((caddr_t, u_int));
+void viking_cache_flush __P((caddr_t, u_int));
+void viking_pcache_flush_line __P((int, int));
+void srmmu_pcache_flush_line __P((int, int));
+
+extern void sparc_noop __P((void));
+
+#define noop_vcache_flush_context \
+ (void (*)__P((void))) sparc_noop
+#define noop_vcache_flush_region \
+ (void (*)__P((int))) sparc_noop
+#define noop_vcache_flush_segment \
+ (void (*)__P((int,int))) sparc_noop
+#define noop_vcache_flush_page \
+ (void (*)__P((int))) sparc_noop
+#define noop_cache_flush \
+ (void (*)__P((caddr_t, u_int))) sparc_noop
+#define noop_pcache_flush_line \
+ (void (*)__P((int, int))) sparc_noop
+
+
+#define cache_flush_page(va) cpuinfo.vcache_flush_page(va)
+#define cache_flush_segment(vr,vs) cpuinfo.vcache_flush_segment(vr,vs)
+#define cache_flush_region(vr) cpuinfo.vcache_flush_region(vr)
+#define cache_flush_context() cpuinfo.vcache_flush_context()
/*
* Cache control information.
@@ -175,22 +206,37 @@ struct cacheinfo {
int c_hwflush; /* true => have hardware flush */
int c_linesize; /* line size, in bytes */
int c_l2linesize; /* log2(linesize) */
- int c_physical; /* true => cache is physical */
+ int c_nlines; /* number of cache lines */
+ int c_physical; /* true => cache has physical
+ address tags */
+ int c_associativity; /* # of "buckets" in cache line */
int c_split; /* true => cache is split */
+
int ic_totalsize; /* instruction cache */
int ic_enabled;
int ic_linesize;
int ic_l2linesize;
+ int ic_nlines;
+ int ic_associativity;
+
int dc_totalsize; /* data cache */
int dc_enabled;
int dc_linesize;
int dc_l2linesize;
+ int dc_nlines;
+ int dc_associativity;
+
int ec_totalsize; /* external cache info */
int ec_enabled;
int ec_linesize;
int ec_l2linesize;
+ int ec_nlines;
+ int ec_associativity;
+
+ enum vactype c_vactype;
};
-extern struct cacheinfo cacheinfo;
+
+#define CACHEINFO cpuinfo.cacheinfo
/*
* Cache control statistics.
@@ -205,3 +251,4 @@ struct cachestats {
int cs_ra[65]; /* pages/range */
#endif
};
+#endif /* SPARC_CACHE_H */
diff --git a/sys/arch/sparc/sparc/clock.c b/sys/arch/sparc/sparc/clock.c
index d8606c7b21d..04027d5d670 100644
--- a/sys/arch/sparc/sparc/clock.c
+++ b/sys/arch/sparc/sparc/clock.c
@@ -1,4 +1,5 @@
-/* $NetBSD: clock.c,v 1.44 1996/05/16 15:57:12 abrown Exp $ */
+/* $OpenBSD: clock.c,v 1.8 1997/08/08 08:27:05 downsj Exp $ */
+/* $NetBSD: clock.c,v 1.52 1997/05/24 20:16:05 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -77,10 +78,10 @@
#include <machine/cpu.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#include <sparc/sparc/clockreg.h>
#include <sparc/sparc/intreg.h>
#include <sparc/sparc/timerreg.h>
-#include <sparc/sparc/cache.h>
/*
* Statistics clock interval and variance, in usec. Variance must be a
@@ -95,7 +96,8 @@ int statvar = 8192;
int statmin; /* statclock interval - 1/2*variance */
int timerok;
-#include <sparc/sparc/intersil7170.h>
+#include <dev/ic/intersil7170.h>
+
extern struct idprom idprom;
#define intersil_command(run, interrupt) \
@@ -120,11 +122,11 @@ static int oldclk = 0;
struct intersil7170 *i7;
static long oclk_get_secs __P((void));
-static void oclk_get_dt __P((struct date_time *));
-static void dt_to_gmt __P((struct date_time *, long *));
-static void oclk_set_dt __P((struct date_time *));
+static void oclk_get_dt __P((struct intersil_dt *));
+static void dt_to_gmt __P((struct intersil_dt *, long *));
+static void oclk_set_dt __P((struct intersil_dt *));
static void oclk_set_secs __P((long));
-static void gmt_to_dt __P((long *, struct date_time *));
+static void gmt_to_dt __P((long *, struct intersil_dt *));
#endif
static int oclockmatch __P((struct device *, void *, void *));
@@ -208,12 +210,14 @@ int timerblurb = 10; /* Guess a value; used before clock is attached */
static int
oclockmatch(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
register struct confargs *ca = aux;
/* Only these sun4s have oclock */
- if (!CPU_ISSUN4 || (cpumod != SUN4_100 && cpumod != SUN4_200))
+ if (!CPU_ISSUN4 ||
+ (cpuinfo.cpu_type != CPUTYP_4_100 &&
+ cpuinfo.cpu_type != CPUTYP_4_200))
return (0);
/* Check configuration name */
@@ -241,8 +245,7 @@ oclockattach(parent, self, aux)
oldclk = 1; /* we've got an oldie! */
- i7 = (struct intersil7170 *)
- mapiodev(ra->ra_reg, 0, sizeof(*i7), ca->ca_bustype);
+ i7 = (struct intersil7170 *) mapiodev(ra->ra_reg, 0, sizeof(*i7));
idp = &idprom;
h = idp->id_machine << 24;
@@ -287,7 +290,7 @@ oclockattach(parent, self, aux)
static int
eeprom_match(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
struct cfdata *cf = vcf;
struct confargs *ca = aux;
@@ -298,7 +301,8 @@ eeprom_match(parent, vcf, aux)
if (cf->cf_unit != 0)
return (0);
- if (cpumod != SUN4_100 && cpumod != SUN4_200)
+ if (cpuinfo.cpu_type != CPUTYP_4_100 &&
+ cpuinfo.cpu_type != CPUTYP_4_200)
return (0);
if (strcmp(eeprom_cd.cd_name, ca->ca_ra.ra_name) != 0)
@@ -327,7 +331,7 @@ eeprom_attach(parent, self, aux)
printf("\n");
- eeprom_va = (char *)mapiodev(ra->ra_reg, 0, EEPROM_SIZE, ca->ca_bustype);
+ eeprom_va = (char *)mapiodev(ra->ra_reg, 0, EEPROM_SIZE);
eeprom_nvram = 0;
#endif /* SUN4 */
@@ -340,13 +344,14 @@ eeprom_attach(parent, self, aux)
static int
clockmatch(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
register struct confargs *ca = aux;
if (CPU_ISSUN4) {
/* Only these sun4s have "clock" (others have "oclock") */
- if (cpumod != SUN4_300 && cpumod != SUN4_400)
+ if (cpuinfo.cpu_type != CPUTYP_4_300 &&
+ cpuinfo.cpu_type != CPUTYP_4_400)
return (0);
if (strcmp(clock_cd.cd_name, ca->ca_ra.ra_name) != 0)
@@ -399,8 +404,7 @@ clockattach(parent, self, aux)
/*
* the MK48T08 is 8K
*/
- cl = (struct clockreg *)mapiodev(ra->ra_reg, 0, 8192,
- ca->ca_bustype);
+ cl = (struct clockreg *)mapiodev(ra->ra_reg, 0, 8192);
pmap_changeprot(pmap_kernel(), (vm_offset_t)cl, VM_PROT_READ, 1);
pmap_changeprot(pmap_kernel(), (vm_offset_t)cl + 4096,
VM_PROT_READ, 1);
@@ -410,8 +414,7 @@ clockattach(parent, self, aux)
* the MK48T02 is 2K
*/
cl = (struct clockreg *)mapiodev(ra->ra_reg, 0,
- sizeof *clockreg,
- ca->ca_bustype);
+ sizeof *clockreg);
pmap_changeprot(pmap_kernel(), (vm_offset_t)cl, VM_PROT_READ, 1);
}
idp = &cl->cl_idprom;
@@ -420,7 +423,8 @@ clockattach(parent, self, aux)
if (CPU_ISSUN4) {
idp = &idprom;
- if (cpumod == SUN4_300 || cpumod == SUN4_400) {
+ if (cpuinfo.cpu_type == CPUTYP_4_300 ||
+ cpuinfo.cpu_type == CPUTYP_4_400) {
eeprom_va = (char *)cl->cl_nvram;
eeprom_nvram = 1;
}
@@ -441,12 +445,13 @@ clockattach(parent, self, aux)
static int
timermatch(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
register struct confargs *ca = aux;
if (CPU_ISSUN4) {
- if (cpumod != SUN4_300 && cpumod != SUN4_400)
+ if (cpuinfo.cpu_type != CPUTYP_4_300 &&
+ cpuinfo.cpu_type != CPUTYP_4_400)
return (0);
if (strcmp("timer", ca->ca_ra.ra_name) != 0)
@@ -483,9 +488,9 @@ timerattach(parent, self, aux)
if (CPU_ISSUN4M) {
(void)mapdev(&ra->ra_reg[ra->ra_nreg-1], TIMERREG_VA, 0,
- sizeof(struct timer_4m), ca->ca_bustype);
+ sizeof(struct timer_4m));
(void)mapdev(&ra->ra_reg[0], COUNTERREG_VA, 0,
- sizeof(struct counter_4m), ca->ca_bustype);
+ sizeof(struct counter_4m));
timerreg_4m = (struct timer_4m *)TIMERREG_VA;
counterreg_4m = (struct counter_4m *)COUNTERREG_VA;
@@ -503,7 +508,7 @@ timerattach(parent, self, aux)
* microtime() faster (in SUN4/SUN4C kernel only).
*/
(void)mapdev(ra->ra_reg, TIMERREG_VA, 0,
- sizeof(struct timerreg_4), ca->ca_bustype);
+ sizeof(struct timerreg_4));
cnt = &timerreg4->t_c14.t_counter;
lim = &timerreg4->t_c14.t_limit;
@@ -641,8 +646,8 @@ cpu_initclocks()
statvar >>= 1;
if (CPU_ISSUN4M) {
- timerreg_4m->t_limit = tmr_ustolim(tick);
- counterreg_4m->t_limit = tmr_ustolim(statint);
+ timerreg_4m->t_limit = tmr_ustolim4m(tick);
+ counterreg_4m->t_limit = tmr_ustolim4m(statint);
}
if (CPU_ISSUN4OR4C) {
@@ -768,7 +773,7 @@ statintr(cap)
newint = statmin + r;
if (CPU_ISSUN4M) {
- counterreg_4m->t_limit = tmr_ustolim(newint);
+ counterreg_4m->t_limit = tmr_ustolim4m(newint);
}
if (CPU_ISSUN4OR4C) {
@@ -990,7 +995,7 @@ resettodr()
static long
oclk_get_secs()
{
- struct date_time dt;
+ struct intersil_dt dt;
long gmt;
oclk_get_dt(&dt);
@@ -1002,7 +1007,7 @@ static void
oclk_set_secs(secs)
long secs;
{
- struct date_time dt;
+ struct intersil_dt dt;
long gmt;
gmt = secs;
@@ -1017,7 +1022,7 @@ oclk_set_secs(secs)
*/
static void
oclk_get_dt(dt)
- struct date_time *dt;
+ struct intersil_dt *dt;
{
int s;
register volatile char *src, *dst;
@@ -1041,7 +1046,7 @@ oclk_get_dt(dt)
static void
oclk_set_dt(dt)
- struct date_time *dt;
+ struct intersil_dt *dt;
{
int s;
register volatile char *src, *dst;
@@ -1085,7 +1090,7 @@ static int month_days[12] = {
static void
gmt_to_dt(tp, dt)
long *tp;
- struct date_time *dt;
+ struct intersil_dt *dt;
{
register int i;
register long days, secs;
@@ -1126,7 +1131,7 @@ gmt_to_dt(tp, dt)
static void
dt_to_gmt(dt, tp)
- struct date_time *dt;
+ struct intersil_dt *dt;
long *tp;
{
register int i;
diff --git a/sys/arch/sparc/sparc/clockreg.h b/sys/arch/sparc/sparc/clockreg.h
index e2222446f1c..a1769a69d6d 100644
--- a/sys/arch/sparc/sparc/clockreg.h
+++ b/sys/arch/sparc/sparc/clockreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: clockreg.h,v 1.2 1997/08/08 08:27:07 downsj Exp $ */
/* $NetBSD: clockreg.h,v 1.5 1994/11/20 20:54:07 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/conf.c b/sys/arch/sparc/sparc/conf.c
index 9147630566e..a62696e300d 100644
--- a/sys/arch/sparc/sparc/conf.c
+++ b/sys/arch/sparc/sparc/conf.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: conf.c,v 1.14 1997/08/08 08:27:08 downsj Exp $ */
/* $NetBSD: conf.c,v 1.40 1996/04/11 19:20:03 thorpej Exp $ */
/*
@@ -71,10 +72,13 @@
#include "zs.h"
#include "fdc.h" /* has NFDC and NFD; see files.sparc */
#include "bwtwo.h"
+#include "cgtwo.h"
#include "cgthree.h"
#include "cgfour.h"
#include "cgsix.h"
#include "cgeight.h"
+#include "tcx.h"
+#include "cgfourteen.h"
#include "xd.h"
#include "xy.h"
@@ -141,7 +145,7 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 28 */
cdev_gen_init(1,kbd), /* 29: /dev/kbd */
cdev_notdef(), /* 30 */
- cdev_notdef(), /* 31: should be /dev/cgtwo */
+ cdev_fb_init(NCGTWO,cgtwo), /* 31: /dev/cgtwo */
cdev_notdef(), /* 32: should be /dev/gpone */
cdev_notdef(), /* 33 */
cdev_notdef(), /* 34 */
@@ -209,7 +213,7 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 96 */
cdev_notdef(), /* 97 */
cdev_notdef(), /* 98 */
- cdev_notdef(), /* 99 */
+ cdev_fb_init(NCGFOURTEEN,cgfourteen), /* 99: /dev/cgfourteen */
cdev_notdef(), /* 100 */
cdev_notdef(), /* 101 */
cdev_notdef(), /* 102 */
@@ -219,7 +223,7 @@ struct cdevsw cdevsw[] =
cdev_disk_init(NRD,rd), /* 106: ram disk driver */
cdev_notdef(), /* 107 */
cdev_notdef(), /* 108 */
- cdev_notdef(), /* 109 */
+ cdev_fb_init(NTCX,tcx), /* 109: /dev/tcx */
cdev_disk_init(NVND,vnd), /* 110: vnode disk driver */
cdev_bpftun_init(NTUN,tun), /* 111: network tunnel */
cdev_lkm_init(NLKM,lkm), /* 112: loadable module driver */
diff --git a/sys/arch/sparc/sparc/cpu.c b/sys/arch/sparc/sparc/cpu.c
index f9c5af8c424..8826a84ae33 100644
--- a/sys/arch/sparc/sparc/cpu.c
+++ b/sys/arch/sparc/sparc/cpu.c
@@ -1,4 +1,5 @@
-/* $NetBSD: cpu.c,v 1.22.4.1 1996/06/12 20:39:45 pk Exp $ */
+/* $OpenBSD: cpu.c,v 1.7 1997/08/08 08:27:10 downsj Exp $ */
+/* $NetBSD: cpu.c,v 1.52 1997/07/29 09:41:58 fair Exp $ */
/*
* Copyright (c) 1996
@@ -64,14 +65,16 @@
#include <machine/trap.h>
#include <machine/pmap.h>
+#include <machine/oldmon.h>
+#include <machine/idprom.h>
+
#include <sparc/sparc/cache.h>
#include <sparc/sparc/asm.h>
-
-/* This is declared here so that you must include a CPU for the cache code. */
-struct cacheinfo cacheinfo;
+#include <sparc/sparc/cpuvar.h>
/* The following are used externally (sysctl_hw). */
-char machine[] = "sparc";
+char machine[] = MACHINE; /* from <machine/param.h> */
+char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
char cpu_model[100];
/* The CPU configuration driver. */
@@ -79,24 +82,24 @@ static void cpu_attach __P((struct device *, struct device *, void *));
int cpu_match __P((struct device *, void *, void *));
struct cfattach cpu_ca = {
- sizeof(struct device), cpu_match, cpu_attach
+ sizeof(struct cpu_softc), cpu_match, cpu_attach
};
struct cfdriver cpu_cd = {
NULL, "cpu", DV_CPU
};
-#if defined(SUN4C) || defined(SUN4M)
-static char *psrtoname __P((int, int, int, char *));
-#endif
static char *fsrtoname __P((int, int, int, char *));
+void cache_print __P((struct cpu_softc *));
+void cpu_spinup __P((struct cpu_softc *));
+void fpu_init __P((struct cpu_softc *));
#define IU_IMPL(psr) ((u_int)(psr) >> 28)
#define IU_VERS(psr) (((psr) >> 24) & 0xf)
-#if defined(SUN4M)
+
#define SRMMU_IMPL(mmusr) ((u_int)(mmusr) >> 28)
#define SRMMU_VERS(mmusr) (((mmusr) >> 24) & 0xf)
-#endif
+
#ifdef notdef
/*
@@ -140,9 +143,9 @@ static char *iu_vendor[16] = {
int
cpu_match(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
return (strcmp(cf->cf_driver->cd_name, ca->ca_ra.ra_name) == 0);
@@ -154,271 +157,965 @@ cpu_match(parent, vcf, aux)
* (slightly funny place to do it, but this is where it is to be found).
*/
static void
-cpu_attach(parent, dev, aux)
+cpu_attach(parent, self, aux)
struct device *parent;
- struct device *dev;
+ struct device *self;
void *aux;
{
- register int node, clk, bug = 0, i;
- register int impl, vers, fver;
+ struct cpu_softc *sc = (struct cpu_softc *)self;
+ register int node;
register char *fpuname;
struct confargs *ca = aux;
- struct fpstate fpstate;
- char *sep;
char fpbuf[40];
-#if defined(SUN4C) || defined(SUN4M)
- register int l;
- char iubuf[40];
+
+ sc->node = node = ca->ca_ra.ra_node;
+
+ /*
+ * First, find out if we're attaching the boot CPU.
+ */
+ if (node == 0)
+ sc->master = 1;
+ else {
+ sc->mid = getpropint(node, "mid", 0);
+ if (sc->mid == 0 || sc->mid == getmid() + 8 /*XXX*/)
+ sc->master = 1;
+ }
+
+ if (sc->master) {
+ /*
+ * Gross, but some things in cpuinfo may already have
+ * been setup by early routines like pmap_bootstrap().
+ */
+ bcopy(&sc->dv, &cpuinfo, sizeof(sc->dv));
+ bcopy(&cpuinfo, sc, sizeof(cpuinfo));
+ }
+
+ getcpuinfo(sc, node);
+
+ fpuname = "no";
+ if (sc->master) {
+ if (sc->hotfix)
+ sc->hotfix(sc);
+
+ fpu_init(sc);
+ if (foundfpu)
+ fpuname = fsrtoname(sc->cpu_impl, sc->cpu_vers,
+ sc->fpuvers, fpbuf);
+ }
+ /* XXX - multi-processor: take care of `cpu_model' and `foundfpu' */
+
+ sprintf(cpu_model, "%s @ %s MHz, %s FPU",
+ sc->cpu_name,
+ clockfreq(sc->hz), fpuname);
+ printf(": %s\n", cpu_model);
+
+ if (sc->cacheinfo.c_totalsize != 0)
+ cache_print(sc);
+
+ if (sc->master) {
+ bcopy(sc, &cpuinfo, sizeof(cpuinfo));
+ /* Enable the cache */
+ sc->cache_enable();
+ return;
+ }
+
+ /* Now start this CPU */
+}
+
+#if 0
+void
+cpu_(sc)
+ struct cpu_softc *sc;
+{
+ if (sc->hotfix)
+ sc->hotfix(sc);
+
+ /* Initialize FPU */
+ fpu_init(sc);
+
+ /* Enable the cache */
+ sc->cache_enable();
+}
#endif
+void
+cpu_spinup(sc)
+ struct cpu_softc *sc;
+{
+#if 0
+ pmap_cpusetup();
+#endif
+}
+
+void
+fpu_init(sc)
+ struct cpu_softc *sc;
+{
+ struct fpstate fpstate;
+
/*
* Get the FSR and clear any exceptions. If we do not unload
* the queue here and it is left over from a previous crash, we
- * will panic in the first loadfpstate(), due to a sequence error,
- * so we need to dump the whole state anyway.
+ * will panic in the first loadfpstate(), due to a sequence
+ * error, so we need to dump the whole state anyway.
*
* If there is no FPU, trap.c will advance over all the stores,
* so we initialize fs_fsr here.
*/
- fpstate.fs_fsr = 7 << FSR_VER_SHIFT; /* 7 is reserved for "none" */
+
+ /* 7 is reserved for "none" */
+ fpstate.fs_fsr = 7 << FSR_VER_SHIFT;
savefpstate(&fpstate);
- fver = (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
- i = getpsr();
- impl = IU_IMPL(i);
- vers = IU_VERS(i);
- if (fver != 7) {
+ sc->fpuvers =
+ (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
+
+ if (sc->fpuvers != 7)
foundfpu = 1;
- fpuname = fsrtoname(impl, vers, fver, fpbuf);
- } else
- fpuname = "no";
-
- /* tell them what we have */
- node = ca->ca_ra.ra_node;
-
-#ifdef SUN4
- if (CPU_ISSUN4) {
- clk = 0;
- vactype = VAC_WRITEBACK;
- switch (cpumod) {
- case SUN4_100:
- sprintf(cpu_model, "SUN-4/100 series (%s FPU)", fpuname);
- vactype = VAC_NONE;
- cacheinfo.c_totalsize = 0;
- cacheinfo.c_hwflush = 0;
- cacheinfo.c_linesize = 0;
- cacheinfo.c_l2linesize = 0;
- break;
- case SUN4_200:
- sprintf(cpu_model, "SUN-4/200 series (%s FPU)", fpuname);
- cacheinfo.c_totalsize = 128*1024;
- cacheinfo.c_hwflush = 0;
- cacheinfo.c_linesize = 16;
- cacheinfo.c_l2linesize = 4;
- break;
- case SUN4_300:
- sprintf(cpu_model, "SUN-4/300 series (%s FPU)", fpuname);
- bug = 1;
- vactype = VAC_WRITETHROUGH;
- cacheinfo.c_totalsize = 128*1024;
- cacheinfo.c_hwflush = 0;
- cacheinfo.c_linesize = 16;
- cacheinfo.c_l2linesize = 4;
- break;
- case SUN4_400:
- sprintf(cpu_model, "SUN-4/400 series (%s FPU)", fpuname);
- cacheinfo.c_totalsize = 128 * 1024;
- cacheinfo.c_hwflush = 0;
- cacheinfo.c_linesize = 32;
- cacheinfo.c_l2linesize = 5;
- break;
+}
+
+void
+cache_print(sc)
+ struct cpu_softc *sc;
+{
+ struct cacheinfo *ci = &sc->cacheinfo;
+ char *sep;
+
+ printf("%s:", sc->dv.dv_xname);
+
+ sep = " ";
+ if (ci->c_split) {
+ printf("%s", (ci->c_physical ? " physical" : ""));
+ if (ci->ic_totalsize > 0) {
+ printf("%s%dK instruction (%d b/l)", sep,
+ ci->ic_totalsize/1024, ci->ic_linesize);
+ sep = ", ";
}
- printf(": %s\n", cpu_model);
+ if (ci->dc_totalsize > 0) {
+ printf("%s%dK data (%d b/l)", sep,
+ ci->dc_totalsize/1024, ci->dc_linesize);
+ sep = ", ";
+ }
+ printf(" ");
+ } else if (ci->c_physical) {
+ /* combined, physical */
+ printf(" physical %dK combined cache (%d bytes/line) ",
+ ci->c_totalsize/1024, ci->c_linesize);
+ } else {
+ /* combined, virtual */
+ printf(" %d byte write-%s, %d bytes/line, %cw flush ",
+ ci->c_totalsize,
+ (ci->c_vactype == VAC_WRITETHROUGH) ? "through" : "back",
+ ci->c_linesize,
+ ci->c_hwflush ? 'h' : 's');
+ }
+
+ if (ci->ec_totalsize > 0) {
+ printf(", %dK external (%d b/l)",
+ ci->ec_totalsize/1024, ci->ec_linesize);
+ }
+}
+
+
+/*------------*/
+
+
+void cpumatch_unknown __P((struct cpu_softc *, struct module_info *, int));
+void cpumatch_sun4 __P((struct cpu_softc *, struct module_info *, int));
+void cpumatch_sun4c __P((struct cpu_softc *, struct module_info *, int));
+void cpumatch_viking __P((struct cpu_softc *, struct module_info *, int));
+void cpumatch_hypersparc __P((struct cpu_softc *, struct module_info *, int));
+void cpumatch_turbosparc __P((struct cpu_softc *, struct module_info *, int));
+
+void getcacheinfo_sun4 __P((struct cpu_softc *, int node));
+void getcacheinfo_sun4c __P((struct cpu_softc *, int node));
+void getcacheinfo_obp __P((struct cpu_softc *, int node));
+
+void sun4_hotfix __P((struct cpu_softc *));
+void viking_hotfix __P((struct cpu_softc *));
+void turbosparc_hotfix __P((struct cpu_softc *));
+
+void ms1_mmu_enable __P((void));
+void viking_mmu_enable __P((void));
+void swift_mmu_enable __P((void));
+void hypersparc_mmu_enable __P((void));
+
+void srmmu_get_fltstatus __P((void));
+void ms1_get_fltstatus __P((void));
+void viking_get_fltstatus __P((void));
+void swift_get_fltstatus __P((void));
+void turbosparc_get_fltstatus __P((void));
+void hypersparc_get_fltstatus __P((void));
+void cypress_get_fltstatus __P((void));
+
+struct module_info module_unknown = {
+ CPUTYP_UNKNOWN,
+ VAC_UNKNOWN,
+ cpumatch_unknown
+};
+
+
+void
+cpumatch_unknown(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+ panic("Unknown CPU type: "
+ "cpu: impl %d, vers %d; mmu: impl %d, vers %d",
+ sc->cpu_impl, sc->cpu_vers,
+ sc->mmu_impl, sc->mmu_vers);
+}
+
+#if defined(SUN4)
+struct module_info module_sun4 = {
+ CPUTYP_UNKNOWN,
+ VAC_WRITETHROUGH,
+ cpumatch_sun4,
+ getcacheinfo_sun4,
+ sun4_hotfix,
+ 0,
+ sun4_cache_enable,
+ 0, /* ncontext set in `match' function */
+ 0, /* get fault regs: unused */
+ sun4_cache_flush,
+ sun4_vcache_flush_page,
+ sun4_vcache_flush_segment,
+ sun4_vcache_flush_region,
+ sun4_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+void
+getcacheinfo_sun4(sc, node)
+ struct cpu_softc *sc;
+ int node;
+{
+ struct cacheinfo *ci = &sc->cacheinfo;
+
+ switch (sc->cpu_type) {
+ case CPUTYP_4_100:
+ ci->c_vactype = VAC_NONE;
+ ci->c_totalsize = 0;
+ ci->c_hwflush = 0;
+ ci->c_linesize = 0;
+ ci->c_l2linesize = 0;
+ ci->c_split = 0;
+ ci->c_nlines = 0;
+
+ /* Override cache flush functions */
+ sc->cache_flush = noop_cache_flush;
+ sc->vcache_flush_page = noop_vcache_flush_page;
+ sc->vcache_flush_segment = noop_vcache_flush_segment;
+ sc->vcache_flush_region = noop_vcache_flush_region;
+ sc->vcache_flush_context = noop_vcache_flush_context;
+ break;
+ case CPUTYP_4_200:
+ ci->c_vactype = VAC_WRITEBACK;
+ ci->c_totalsize = 128*1024;
+ ci->c_hwflush = 0;
+ ci->c_linesize = 16;
+ ci->c_l2linesize = 4;
+ ci->c_split = 0;
+ ci->c_nlines = ci->c_totalsize << ci->c_l2linesize;
+ break;
+ case CPUTYP_4_300:
+ ci->c_vactype = VAC_WRITEBACK;
+ ci->c_totalsize = 128*1024;
+ ci->c_hwflush = 0;
+ ci->c_linesize = 16;
+ ci->c_l2linesize = 4;
+ ci->c_split = 0;
+ ci->c_nlines = ci->c_totalsize << ci->c_l2linesize;
+ sc->flags |= CPUFLG_SUN4CACHEBUG;
+ break;
+ case CPUTYP_4_400:
+ ci->c_vactype = VAC_WRITEBACK;
+ ci->c_totalsize = 128 * 1024;
+ ci->c_hwflush = 0;
+ ci->c_linesize = 32;
+ ci->c_l2linesize = 5;
+ ci->c_split = 0;
+ ci->c_nlines = ci->c_totalsize << ci->c_l2linesize;
+ break;
}
+}
+
+struct idprom idprom;
+void getidprom __P((struct idprom *, int size));
+
+void
+cpumatch_sun4(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+
+ getidprom(&idprom, sizeof(idprom));
+ switch (idprom.id_machine) {
+ /* XXX: don't know about Sun4 types */
+ case ID_SUN4_100:
+ sc->cpu_type = CPUTYP_4_100;
+ sc->classlvl = 100;
+ sc->mmu_ncontext = 8;
+ sc->mmu_nsegment = 256;
+/*XXX*/ sc->hz = 0;
+ break;
+ case ID_SUN4_200:
+ sc->cpu_type = CPUTYP_4_200;
+ sc->classlvl = 200;
+ sc->mmu_nsegment = 512;
+ sc->mmu_ncontext = 16;
+/*XXX*/ sc->hz = 0;
+ break;
+ case ID_SUN4_300:
+ sc->cpu_type = CPUTYP_4_300;
+ sc->classlvl = 300;
+ sc->mmu_nsegment = 256;
+ sc->mmu_ncontext = 16;
+/*XXX*/ sc->hz = 0;
+ break;
+ case ID_SUN4_400:
+ sc->cpu_type = CPUTYP_4_400;
+ sc->classlvl = 400;
+ sc->mmu_nsegment = 1024;
+ sc->mmu_ncontext = 64;
+ sc->mmu_nregion = 256;
+/*XXX*/ sc->hz = 0;
+ sc->sun4_mmu3l = 1;
+ break;
+ }
+
+}
#endif /* SUN4 */
-#if defined(SUN4C) || defined(SUN4M)
- if (CPU_ISSUN4C || CPU_ISSUN4M) {
- clk = getpropint(node, "clock-frequency", 0);
- if (clk == 0) {
- /*
- * Try to find it in the OpenPROM root...
- */
- clk = getpropint(findroot(), "clock-frequency", 0);
- }
- if (CPU_ISSUN4C)
- sprintf(cpu_model, "%s (%s @ %s MHz, %s FPU)",
- getpropstring(node, "name"),
- psrtoname(impl, vers, fver, iubuf),
- clockfreq(clk), fpuname);
- else
- /* On sun4m, the "name" property identifies CPU */
- sprintf(cpu_model, "%s @ %s MHz, %s FPU",
- getpropstring(node, "name"),
- clockfreq(clk), fpuname);
- printf(": %s\n", cpu_model);
+#if defined(SUN4C)
+struct module_info module_sun4c = {
+ CPUTYP_UNKNOWN,
+ VAC_WRITETHROUGH,
+ cpumatch_sun4c,
+ getcacheinfo_sun4c,
+ sun4_hotfix,
+ 0,
+ sun4_cache_enable,
+ 0, /* ncontext set in `match' function */
+ 0,
+ sun4_cache_flush,
+ sun4_vcache_flush_page,
+ sun4_vcache_flush_segment,
+ sun4_vcache_flush_region,
+ sun4_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+void
+cpumatch_sun4c(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+ int rnode;
+
+ rnode = findroot();
+ sc->mmu_npmeg = sc->mmu_nsegment =
+ getpropint(rnode, "mmu-npmg", 128);
+ sc->mmu_ncontext = getpropint(rnode, "mmu-nctx", 8);
+
+ /* Get clock frequency */
+ sc->hz = getpropint(rnode, "clock-frequency", 0);
+}
+
+void
+getcacheinfo_sun4c(sc, node)
+ struct cpu_softc *sc;
+ int node;
+{
+ struct cacheinfo *ci = &sc->cacheinfo;
+ int i, l;
+ if (node == 0)
+ /* Bootstrapping */
+ return;
+
+ /* Sun4c's have only virtually-addressed caches */
+ ci->c_physical = 0;
+ ci->c_totalsize = getpropint(node, "vac-size", 65536);
+ /*
+ * Note: vac-hwflush is spelled with an underscore
+ * on the 4/75s.
+ */
+ ci->c_hwflush =
+ getpropint(node, "vac_hwflush", 0) |
+ getpropint(node, "vac-hwflush", 0);
+
+ ci->c_linesize = l = getpropint(node, "vac-linesize", 16);
+ for (i = 0; (1 << i) < l; i++)
+ /* void */;
+ if ((1 << i) != l)
+ panic("bad cache line size %d", l);
+ ci->c_l2linesize = i;
+ ci->c_associativity = 1;
+ ci->c_nlines = ci->c_totalsize << i;
+
+ ci->c_vactype = VAC_WRITETHROUGH;
+
+ /*
+ * Machines with "buserr-type" 1 have a bug in the cache
+ * chip that affects traps. (I wish I knew more about this
+ * mysterious buserr-type variable....)
+ */
+ if (getpropint(node, "buserr-type", 0) == 1)
+ sc->flags |= CPUFLG_SUN4CACHEBUG;
+}
+#endif /* SUN4C */
+
+void
+sun4_hotfix(sc)
+ struct cpu_softc *sc;
+{
+ if ((sc->flags & CPUFLG_SUN4CACHEBUG) != 0) {
+ kvm_uncache((caddr_t)trapbase, 1);
+ printf("cache chip bug; trap page uncached ");
+ }
+
+}
+
+#if defined(SUN4M)
+void
+getcacheinfo_obp(sc, node)
+ struct cpu_softc *sc;
+ int node;
+{
+ struct cacheinfo *ci = &sc->cacheinfo;
+ int i, l;
+
+ if (node == 0)
+ /* Bootstrapping */
+ return;
+
+ /*
+ * Determine the Sun4m cache organization.
+ */
+ ci->c_physical = node_has_property(node, "cache-physical?");
+
+ if (getpropint(node, "ncaches", 1) == 2)
+ ci->c_split = 1;
+ else
+ ci->c_split = 0;
+
+ /* hwflush is used only by sun4/4c code */
+ ci->c_hwflush = 0;
+
+ if (node_has_property(node, "icache-nlines") &&
+ node_has_property(node, "dcache-nlines") &&
+ ci->c_split) {
+ /* Harvard architecture: get I and D cache sizes */
+ ci->ic_nlines = getpropint(node, "icache-nlines", 0);
+ ci->ic_linesize = l =
+ getpropint(node, "icache-line-size", 0);
+ for (i = 0; (1 << i) < l && l; i++)
+ /* void */;
+ if ((1 << i) != l && l)
+ panic("bad icache line size %d", l);
+ ci->ic_l2linesize = i;
+ ci->ic_associativity =
+ getpropint(node, "icache-associativity", 1);
+ ci->ic_totalsize = l * ci->ic_nlines * ci->ic_associativity;
+
+ ci->dc_nlines = getpropint(node, "dcache-nlines", 0);
+ ci->dc_linesize = l =
+ getpropint(node, "dcache-line-size",0);
+ for (i = 0; (1 << i) < l && l; i++)
+ /* void */;
+ if ((1 << i) != l && l)
+ panic("bad dcache line size %d", l);
+ ci->dc_l2linesize = i;
+ ci->dc_associativity =
+ getpropint(node, "dcache-associativity", 1);
+ ci->dc_totalsize = l * ci->dc_nlines * ci->dc_associativity;
+
+ ci->c_l2linesize = min(ci->ic_l2linesize, ci->dc_l2linesize);
+ ci->c_linesize = min(ci->ic_linesize, ci->dc_linesize);
+ ci->c_totalsize = ci->ic_totalsize + ci->dc_totalsize;
+ } else {
+ /* unified I/D cache */
+ ci->c_nlines = getpropint(node, "cache-nlines", 128);
+ ci->c_linesize = l =
+ getpropint(node, "cache-line-size", 0);
+ for (i = 0; (1 << i) < l && l; i++)
+ /* void */;
+ if ((1 << i) != l && l)
+ panic("bad cache line size %d", l);
+ ci->c_l2linesize = i;
+ ci->c_totalsize = l *
+ ci->c_nlines *
+ getpropint(node, "cache-associativity", 1);
+ }
+
+ if (node_has_property(node, "ecache-nlines")) {
+ /* we have a L2 "e"xternal cache */
+ ci->ec_nlines = getpropint(node, "ecache-nlines", 32768);
+ ci->ec_linesize = l = getpropint(node, "ecache-line-size", 0);
+ for (i = 0; (1 << i) < l && l; i++)
+ /* void */;
+ if ((1 << i) != l && l)
+ panic("bad ecache line size %d", l);
+ ci->ec_l2linesize = i;
+ ci->ec_associativity =
+ getpropint(node, "ecache-associativity", 1);
+ ci->ec_totalsize = l * ci->ec_nlines * ci->ec_associativity;
+ }
+ if (ci->c_totalsize == 0)
+ printf("warning: couldn't identify cache\n");
+}
+
+/*
+ * We use the max. number of contexts on the micro and
+ * hyper SPARCs. The SuperSPARC would let us use up to 65536
+ * contexts (by powers of 2), but we keep it at 4096 since
+ * the table must be aligned to #context*4. With 4K contexts,
+ * we waste at most 16K of memory. Note that the context
+ * table is *always* page-aligned, so there can always be
+ * 1024 contexts without sacrificing memory space (given
+ * that the chip supports 1024 contexts).
+ *
+ * Currently known limits: MS1=64, MS2=256, HS=4096, SS=65536
+ * some old SS's=4096
+ */
+
+/* TI Microsparc I */
+struct module_info module_ms1 = {
+ CPUTYP_MS1,
+ VAC_NONE,
+ 0,
+ getcacheinfo_obp,
+ 0,
+ ms1_mmu_enable,
+ ms1_cache_enable,
+ 64,
+ ms1_get_fltstatus,
+ ms1_cache_flush,
+ noop_vcache_flush_page,
+ noop_vcache_flush_segment,
+ noop_vcache_flush_region,
+ noop_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+void
+ms1_mmu_enable()
+{
+}
+
+/* TI Microsparc II */
+struct module_info module_ms2 = { /* UNTESTED */
+ CPUTYP_MS2,
+ VAC_WRITETHROUGH,
+ 0,
+ getcacheinfo_obp,
+ 0,
+ 0,
+ swift_cache_enable,
+ 256,
+ srmmu_get_fltstatus,
+ srmmu_cache_flush,
+ srmmu_vcache_flush_page,
+ srmmu_vcache_flush_segment,
+ srmmu_vcache_flush_region,
+ srmmu_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+
+struct module_info module_swift = { /* UNTESTED */
+ CPUTYP_MS2,
+ VAC_WRITETHROUGH,
+ 0,
+ getcacheinfo_obp,
+ 0,
+ 0,
+ swift_cache_enable,
+ 256,
+ swift_get_fltstatus,
+ srmmu_cache_flush,
+ srmmu_vcache_flush_page,
+ srmmu_vcache_flush_segment,
+ srmmu_vcache_flush_region,
+ srmmu_vcache_flush_context,
+ srmmu_pcache_flush_line
+};
+
+void
+swift_mmu_enable()
+{
+}
+
+struct module_info module_viking = { /* UNTESTED */
+ CPUTYP_UNKNOWN, /* set in cpumatch() */
+ VAC_NONE,
+ cpumatch_viking,
+ getcacheinfo_obp,
+ viking_hotfix,
+ viking_mmu_enable,
+ viking_cache_enable,
+ 4096,
+ viking_get_fltstatus,
+ /* supersparcs use cached DVMA, no need to flush */
+ noop_cache_flush,
+ noop_vcache_flush_page,
+ noop_vcache_flush_segment,
+ noop_vcache_flush_region,
+ noop_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+void
+cpumatch_viking(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+ if (node == 0)
+ viking_hotfix(sc);
+}
+
+void
+viking_hotfix(sc)
+ struct cpu_softc *sc;
+{
+ /* Test if we're directly on the MBus */
+ if (!(lda(SRMMU_PCR, ASI_SRMMU) & VIKING_PCR_MB)) {
+ sc->mxcc = 1;
+ sc->flags |= CPUFLG_CACHE_MANDATORY;
/*
- * Fill in the cache info. Note, vac-hwflush is spelled
- * with an underscore on 4/75s.
+ * Ok to cache PTEs; set the flag here, so we don't
+ * uncache in pmap_bootstrap().
*/
- /*bzero(&cacheinfo, sizeof(cacheinfo));*/
+ sc->flags |= CPUFLG_CACHEPAGETABLES;
+ } else {
+ sc->cache_flush = viking_cache_flush;
+ sc->pcache_flush_line = viking_pcache_flush_line;
+ }
+
+ /* XXX! */
+ if (sc->mxcc)
+ sc->cpu_type = CPUTYP_SS1_MBUS_MXCC;
+ else
+ sc->cpu_type = CPUTYP_SS1_MBUS_NOMXCC;
+}
+
+void
+viking_mmu_enable()
+{
+ int pcr;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+
+ if (cpuinfo.mxcc)
+ pcr |= VIKING_PCR_TC;
+ else
+ pcr &= ~VIKING_PCR_TC;
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+}
+
+
+/* ROSS Hypersparc */
+struct module_info module_hypersparc = { /* UNTESTED */
+ CPUTYP_UNKNOWN,
+ VAC_NONE,
+ cpumatch_hypersparc,
+ getcacheinfo_obp,
+ 0,
+ hypersparc_mmu_enable,
+ hypersparc_cache_enable,
+ 4096,
+ hypersparc_get_fltstatus,
+ srmmu_cache_flush,
+ srmmu_vcache_flush_page,
+ srmmu_vcache_flush_segment,
+ srmmu_vcache_flush_region,
+ srmmu_vcache_flush_context,
+ noop_pcache_flush_line
+};
+
+void
+cpumatch_hypersparc(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+ sc->cpu_type = CPUTYP_HS_MBUS;/*XXX*/
+}
+
+void
+hypersparc_mmu_enable()
+{
+ int pcr;
+
+ pcr = lda(SRMMU_PCR, ASI_SRMMU);
+ pcr |= HYPERSPARC_PCR_C;
+ pcr &= ~HYPERSPARC_PCR_CE;
+
+ sta(SRMMU_PCR, ASI_SRMMU, pcr);
+}
+
+/* Cypress 605 */
+struct module_info module_cypress = { /* UNTESTED */
+ CPUTYP_CYPRESS,
+ VAC_WRITEBACK,
+ 0,
+ getcacheinfo_obp,
+ 0,
+ 0,
+ cypress_cache_enable,
+ 4096,
+ cypress_get_fltstatus,
+ srmmu_cache_flush,
+ srmmu_vcache_flush_page,
+ srmmu_vcache_flush_segment,
+ srmmu_vcache_flush_region,
+ srmmu_vcache_flush_context,
+ srmmu_pcache_flush_line
+};
+
+/* Fujitsu Turbosparc */
+struct module_info module_turbosparc = { /* UNTESTED */
+ CPUTYP_MS2,
+ VAC_WRITEBACK,
+ cpumatch_turbosparc,
+ getcacheinfo_obp,
+ turbosparc_hotfix,
+ 0,
+ turbosparc_cache_enable,
+ 256,
+ turbosparc_get_fltstatus,
+ srmmu_cache_flush,
+ srmmu_vcache_flush_page,
+ srmmu_vcache_flush_segment,
+ srmmu_vcache_flush_region,
+ srmmu_vcache_flush_context,
+ srmmu_pcache_flush_line
+};
+
+void
+cpumatch_turbosparc(sc, mp, node)
+ struct cpu_softc *sc;
+ struct module_info *mp;
+ int node;
+{
+ int i;
+
+ if (node == 0 || sc->master == 0)
+ return;
+
+ i = getpsr();
+ if (sc->cpu_vers == IU_VERS(i))
+ return;
+
+ /*
+ * A cloaked Turbosparc: clear any items in cpuinfo that
+ * might have been set to uS2 versions during bootstrap.
+ */
+ sc->cpu_name = 0;
+ sc->mmu_ncontext = 0;
+ sc->cpu_type = 0;
+ sc->cacheinfo.c_vactype = 0;
+ sc->hotfix = 0;
+ sc->mmu_enable = 0;
+ sc->cache_enable = 0;
+ sc->get_faultstatus = 0;
+ sc->cache_flush = 0;
+ sc->vcache_flush_page = 0;
+ sc->vcache_flush_segment = 0;
+ sc->vcache_flush_region = 0;
+ sc->vcache_flush_context = 0;
+ sc->pcache_flush_line = 0;
+}
+
+void
+turbosparc_hotfix(sc)
+ struct cpu_softc *sc;
+{
+ int pcf;
+
+ pcf = lda(SRMMU_PCFG, ASI_SRMMU);
+ if (pcf & TURBOSPARC_PCFG_US2) {
+ /* Turn off uS2 emulation bit */
+ pcf &= ~TURBOSPARC_PCFG_US2;
+ sta(SRMMU_PCFG, ASI_SRMMU, pcf);
+ }
+}
+#endif /* SUN4M */
+
+
+#define ANY -1 /* match any version */
+
+struct cpu_conf {
+ int arch;
+ int cpu_impl;
+ int cpu_vers;
+ int mmu_impl;
+ int mmu_vers;
+ char *name;
+ struct module_info *minfo;
+} cpu_conf[] = {
+#if defined(SUN4)
+ { CPU_SUN4, 0, 0, ANY, ANY, "MB86900/1A or L64801", &module_sun4 },
+ { CPU_SUN4, 1, 0, ANY, ANY, "L64811", &module_sun4 },
+ { CPU_SUN4, 1, 1, ANY, ANY, "CY7C601", &module_sun4 },
+#endif
+
+#if defined(SUN4C)
+ { CPU_SUN4C, 0, 0, ANY, ANY, "MB86900/1A or L64801", &module_sun4c },
+ { CPU_SUN4C, 1, 0, ANY, ANY, "L64811", &module_sun4c },
+ { CPU_SUN4C, 1, 1, ANY, ANY, "CY7C601", &module_sun4c },
+ { CPU_SUN4C, 9, 0, ANY, ANY, "W8601/8701 or MB86903", &module_sun4c },
+#endif
+
#if defined(SUN4M)
+ { CPU_SUN4M, 0, 4, 0, 4, "MB86904", &module_swift },
+ { CPU_SUN4M, 0, 5, 0, 5, "MB86907", &module_turbosparc },
+ { CPU_SUN4M, 1, 1, 1, 0, "CY7C601/604", &module_cypress },
+ { CPU_SUN4M, 1, 1, 1, 0xb, "CY7C601/605 (v.b)", &module_cypress },
+ { CPU_SUN4M, 1, 1, 1, 0xc, "CY7C601/605 (v.c)", &module_cypress },
+ { CPU_SUN4M, 1, 1, 1, 0xf, "CY7C601/605 (v.f)", &module_cypress },
+ { CPU_SUN4M, 1, 3, 1, ANY, "CY7C611", &module_cypress },
+ { CPU_SUN4M, 1, 0xf, 1, 1, "RT620/625", &module_hypersparc },
+ { CPU_SUN4M, 4, 0, 0, ANY, "TMS390Z50 v0 or TMS390Z55", &module_viking },
+ { CPU_SUN4M, 4, 1, 0, ANY, "TMS390Z50 v1", &module_viking },
+ { CPU_SUN4M, 4, 1, 4, ANY, "TMS390S10", &module_ms1 },
+ { CPU_SUN4M, 4, 2, 0, ANY, "TI_MS2", &module_ms2 },
+ { CPU_SUN4M, 4, 3, ANY, ANY, "TI_4_3", &module_viking },
+ { CPU_SUN4M, 4, 4, ANY, ANY, "TI_4_4", &module_viking },
+#endif
+
+ { ANY, ANY, ANY, ANY, ANY, "Unknown", &module_unknown }
+};
+
+void
+getcpuinfo(sc, node)
+ struct cpu_softc *sc;
+ int node;
+{
+ struct cpu_conf *mp;
+ int i;
+ int cpu_impl, cpu_vers;
+ int mmu_impl, mmu_vers;
+
+ /*
+ * Set up main criteria for selection from the CPU configuration
+ * table: the CPU implementation/version fields from the PSR
+ * register, and -- on sun4m machines -- the MMU
+ * implementation/version from the SCR register.
+ */
+ if (sc->master) {
+ i = getpsr();
+ if (node == 0 ||
+ (cpu_impl =
+ getpropint(node, "psr-implementation", -1)) == -1)
+ cpu_impl = IU_IMPL(i);
+
+ if (node == 0 ||
+ (cpu_vers = getpropint(node, "psr-version", -1)) == -1)
+ cpu_vers = IU_VERS(i);
+
if (CPU_ISSUN4M) {
- cacheinfo.c_physical = 1;
- vactype = node_has_property(node, "cache-physical?")
- ? VAC_NONE
- : VAC_WRITETHROUGH; /* ??? */
- /*
- * Sun4m physical caches are nice since we never
- * have to flush them. Unfortunately it is a pain
- * to determine what size they are, since they may
- * be split...
- */
- switch (mmumod) {
- case SUN4M_MMU_SS:
- case SUN4M_MMU_MS1:
- cacheinfo.c_split = 1;
- cacheinfo.ic_linesize = l =
- getpropint(node, "icache-line-size", 0);
- for (i = 0; (1 << i) < l && l; i++)
- /* void */;
- if ((1 << i) != l && l)
- panic("bad icache line size %d", l);
- cacheinfo.ic_l2linesize = i;
- cacheinfo.ic_totalsize = l *
- getpropint(node, "icache-nlines", 64) *
- getpropint(node, "icache-associativity", 1);
-
- cacheinfo.dc_linesize = l =
- getpropint(node, "dcache-line-size",0);
- for (i = 0; (1 << i) < l && l; i++)
- /* void */;
- if ((1 << i) != l && l)
- panic("bad dcache line size %d", l);
- cacheinfo.dc_l2linesize = i;
- cacheinfo.dc_totalsize = l *
- getpropint(node, "dcache-nlines", 128) *
- getpropint(node, "dcache-associativity", 1);
-
- cacheinfo.ec_linesize = l =
- getpropint(node, "ecache-line-size", 0);
- for (i = 0; (1 << i) < l && l; i++)
- /* void */;
- if ((1 << i) != l && l)
- panic("bad ecache line size %d", l);
- cacheinfo.ec_l2linesize = i;
- cacheinfo.ec_totalsize = l *
- getpropint(node, "ecache-nlines", 32768) *
- getpropint(node, "ecache-associativity", 1);
+ i = lda(SRMMU_PCR, ASI_SRMMU);
+ if (node == 0 ||
+ (mmu_impl =
+ getpropint(node, "implementation", -1)) == -1)
+ mmu_impl = SRMMU_IMPL(i);
- /*
- * XXX - The following will have to do until
- * we have per-cpu cache handling.
- */
- cacheinfo.c_l2linesize =
- min(cacheinfo.ic_l2linesize,
- cacheinfo.dc_l2linesize);
- cacheinfo.c_linesize =
- min(cacheinfo.ic_linesize,
- cacheinfo.dc_linesize);
- cacheinfo.c_totalsize =
- cacheinfo.ic_totalsize +
- cacheinfo.dc_totalsize;
- break;
- case SUN4M_MMU_HS:
- printf("Warning, guessing on HyperSPARC cache...\n");
- cacheinfo.c_split = 0;
- i = lda(SRMMU_PCR, ASI_SRMMU);
- if (i & SRMMU_PCR_CS)
- cacheinfo.c_totalsize = 256 * 1024;
- else
- cacheinfo.c_totalsize = 128 * 1024;
- /* manual says it has 4096 lines */
- cacheinfo.c_linesize = l =
- cacheinfo.c_totalsize / 4096;
- for (i = 0; (1 << i) < l; i++)
- /* void */;
- if ((1 << i) != l)
- panic("bad cache line size %d", l);
- cacheinfo.c_l2linesize = i;
- break;
- default:
- printf("warning: couldn't identify cache\n");
- cacheinfo.c_totalsize = 0;
- }
- } else
-#endif /* SUN4M */
- {
- cacheinfo.c_physical = 0;
- cacheinfo.c_totalsize =
- getpropint(node, "vac-size", 65536);
- cacheinfo.c_hwflush =
- getpropint(node, "vac_hwflush", 0) |
- getpropint(node, "vac-hwflush", 0);
- cacheinfo.c_linesize = l =
- getpropint(node, "vac-linesize", 16);
- for (i = 0; (1 << i) < l; i++)
- /* void */;
- if ((1 << i) != l)
- panic("bad cache line size %d", l);
- cacheinfo.c_l2linesize = i;
- vactype = VAC_WRITETHROUGH;
+ if (node == 0 ||
+ (mmu_vers = getpropint(node, "version", -1)) == -1)
+ mmu_vers = SRMMU_VERS(i);
+ } else {
+ mmu_impl = ANY;
+ mmu_vers = ANY;
}
-
+ } else {
/*
- * Machines with "buserr-type" 1 have a bug in the cache
- * chip that affects traps. (I wish I knew more about this
- * mysterious buserr-type variable....)
+ * Get CPU version/implementation from ROM. If not
+ * available, assume same as boot CPU.
*/
- bug = (getpropint(node, "buserr-type", 0) == 1);
- }
-#endif /* SUN4C || SUN4M */
+ cpu_impl = getpropint(node, "psr-implementation", -1);
+ if (cpu_impl == -1)
+ cpu_impl = cpuinfo.cpu_impl;
+ cpu_vers = getpropint(node, "psr-version", -1);
+ if (cpu_vers == -1)
+ cpu_vers = cpuinfo.cpu_vers;
- if (bug) {
- kvm_uncache((caddr_t)trapbase, 1);
- printf("%s: cache chip bug; trap page uncached\n",
- dev->dv_xname);
+ /* Get MMU version/implementation from ROM always */
+ mmu_impl = getpropint(node, "implementation", -1);
+ mmu_vers = getpropint(node, "version", -1);
}
- if (cacheinfo.c_totalsize == 0)
- return;
+ for (mp = cpu_conf; ; mp++) {
+ if (mp->arch != cputyp && mp->arch != ANY)
+ continue;
- if (!cacheinfo.c_physical) {
- printf("%s: %d byte write-%s, %d bytes/line, %cw flush ",
- dev->dv_xname, cacheinfo.c_totalsize,
- (vactype == VAC_WRITETHROUGH) ? "through" : "back",
- cacheinfo.c_linesize,
- cacheinfo.c_hwflush ? 'h' : 's');
- cache_enable();
- } else {
- sep = " ";
- if (cacheinfo.c_split) {
- printf("%s: physical", dev->dv_xname);
- if (cacheinfo.ic_totalsize > 0) {
- printf("%s%dK instruction (%d b/l)", sep,
- cacheinfo.ic_totalsize/1024,
- cacheinfo.ic_linesize);
- sep = ", ";
- }
- if (cacheinfo.dc_totalsize > 0) {
- printf("%s%dK data (%d b/l)", sep,
- cacheinfo.dc_totalsize/1024,
- cacheinfo.dc_linesize);
- sep = ", ";
- }
- if (cacheinfo.ec_totalsize > 0) {
- printf("%s%dK external (%d b/l)", sep,
- cacheinfo.ec_totalsize/1024,
- cacheinfo.ec_linesize);
+#define MATCH(x) (mp->x == x || mp->x == ANY)
+ if (!MATCH(cpu_impl) ||
+ !MATCH(cpu_vers) ||
+ !MATCH(mmu_impl) ||
+ !MATCH(mmu_vers))
+ continue;
+#undef MATCH
+
+ /*
+ * Got CPU type.
+ */
+ sc->cpu_impl = cpu_impl;
+ sc->cpu_vers = cpu_vers;
+ sc->mmu_impl = mmu_impl;
+ sc->mmu_vers = mmu_vers;
+
+ if (mp->minfo->cpu_match) {
+ /* Additional fixups */
+ mp->minfo->cpu_match(sc, mp->minfo, node);
+ }
+ if (sc->cpu_name == 0)
+ sc->cpu_name = mp->name;
+
+ if (sc->mmu_ncontext == 0)
+ sc->mmu_ncontext = mp->minfo->ncontext;
+
+ if (sc->cpu_type == 0)
+ sc->cpu_type = mp->minfo->cpu_type;
+
+ if (sc->cacheinfo.c_vactype == VAC_UNKNOWN)
+ sc->cacheinfo.c_vactype = mp->minfo->vactype;
+
+ mp->minfo->getcacheinfo(sc, node);
+
+ if (node && sc->hz == 0 && !CPU_ISSUN4/*XXX*/) {
+ sc->hz = getpropint(node, "clock-frequency", 0);
+ if (sc->hz == 0) {
+ /*
+ * Try to find it in the OpenPROM root...
+ */
+ sc->hz = getpropint(findroot(),
+ "clock-frequency", 0);
}
- printf(" ");
- } else
- printf("%s: physical %dK combined cache (%d bytes/"
- "line) ", dev->dv_xname,
- cacheinfo.c_totalsize/1024,
- cacheinfo.c_linesize);
- cache_enable();
+ }
+
+ /*
+ * Copy CPU/MMU/Cache specific routines into cpu_softc.
+ */
+#define MPCOPY(x) if (sc->x == 0) sc->x = mp->minfo->x;
+ MPCOPY(hotfix);
+ MPCOPY(mmu_enable);
+ MPCOPY(cache_enable);
+ MPCOPY(get_faultstatus);
+ MPCOPY(cache_flush);
+ MPCOPY(vcache_flush_page);
+ MPCOPY(vcache_flush_segment);
+ MPCOPY(vcache_flush_region);
+ MPCOPY(vcache_flush_context);
+ MPCOPY(pcache_flush_line);
+#undef MPCOPY
+ return;
}
+ panic("Out of CPUs");
}
/*
@@ -431,50 +1128,13 @@ cpu_attach(parent, dev, aux)
*
*/
struct info {
- u_char valid;
- u_char iu_impl;
- u_char iu_vers;
- u_char fpu_vers;
+ int valid;
+ int iu_impl;
+ int iu_vers;
+ int fpu_vers;
char *name;
};
-#define ANY 0xff /* match any FPU version (or, later, IU version) */
-
-#if defined(SUN4C) || defined(SUN4M)
-static struct info iu_types[] = {
- { 1, 0x0, 0x4, 4, "MB86904" },
- { 1, 0x0, 0x0, ANY, "MB86900/1A or L64801" },
- { 1, 0x1, 0x0, ANY, "RT601 or L64811 v1" },
- { 1, 0x1, 0x1, ANY, "RT601 or L64811 v2" },
- { 1, 0x1, 0x3, ANY, "RT611" },
- { 1, 0x1, 0xf, ANY, "RT620" },
- { 1, 0x2, 0x0, ANY, "B5010" },
- { 1, 0x4, 0x0, 0, "TMS390Z50 v0 or TMS390Z55" },
- { 1, 0x4, 0x1, 0, "TMS390Z50 v1" },
- { 1, 0x4, 0x1, 4, "TMS390S10" },
- { 1, 0x5, 0x0, ANY, "MN10501" },
- { 1, 0x9, 0x0, ANY, "W8601/8701 or MB86903" },
- { 0 }
-};
-
-static char *
-psrtoname(impl, vers, fver, buf)
- register int impl, vers, fver;
- char *buf;
-{
- register struct info *p;
-
- for (p = iu_types; p->valid; p++)
- if (p->iu_impl == impl && p->iu_vers == vers &&
- (p->fpu_vers == fver || p->fpu_vers == ANY))
- return (p->name);
-
- /* Not found. */
- sprintf(buf, "IU impl 0x%x vers 0x%x", impl, vers);
- return (buf);
-}
-#endif /* SUN4C || SUN4M */
-
/* NB: table order matters here; specific numbers must appear before ANY. */
static struct info fpu_types[] = {
/*
@@ -485,6 +1145,7 @@ static struct info fpu_types[] = {
{ 1, 0x0, ANY, 2, "L64802 or ACT8847" },
{ 1, 0x0, ANY, 3, "WTL3170/2" },
{ 1, 0x0, 4, 4, "on-chip" }, /* Swift */
+ { 1, 0x0, 5, 5, "on-chip" }, /* TurboSparc */
{ 1, 0x0, ANY, 4, "L64804" },
/*
@@ -532,6 +1193,6 @@ fsrtoname(impl, vers, fver, buf)
(p->iu_vers == vers || p->iu_vers == ANY) &&
(p->fpu_vers == fver))
return (p->name);
- sprintf(buf, "version %x", fver);
+ sprintf(buf, "version 0x%x", fver);
return (buf);
}
diff --git a/sys/arch/sparc/sparc/db_disasm.c b/sys/arch/sparc/sparc/db_disasm.c
index 901597194d3..344a557cc7e 100644
--- a/sys/arch/sparc/sparc/db_disasm.c
+++ b/sys/arch/sparc/sparc/db_disasm.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: db_disasm.c,v 1.3 1997/08/08 08:27:11 downsj Exp $ */
/* $NetBSD: db_disasm.c,v 1.9 1996/03/31 23:45:07 pk Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/db_interface.c b/sys/arch/sparc/sparc/db_interface.c
index 013e80a046f..0414ca1af53 100644
--- a/sys/arch/sparc/sparc/db_interface.c
+++ b/sys/arch/sparc/sparc/db_interface.c
@@ -1,4 +1,5 @@
-/* $NetBSD: db_interface.c,v 1.12 1996/05/18 12:27:45 mrg Exp $ */
+/* $OpenBSD: db_interface.c,v 1.5 1997/08/08 08:27:12 downsj Exp $ */
+/* $NetBSD: db_interface.c,v 1.15 1997/02/05 00:01:50 pk Exp $ */
/*
* Mach Operating System
diff --git a/sys/arch/sparc/sparc/db_trace.c b/sys/arch/sparc/sparc/db_trace.c
index 8da02ce3082..3fc0c8e56eb 100644
--- a/sys/arch/sparc/sparc/db_trace.c
+++ b/sys/arch/sparc/sparc/db_trace.c
@@ -1,4 +1,5 @@
-/* $NetBSD: db_trace.c,v 1.8 1996/04/04 23:25:35 pk Exp $ */
+/* $OpenBSD: db_trace.c,v 1.3 1997/08/08 08:27:13 downsj Exp $ */
+/* $NetBSD: db_trace.c,v 1.9 1997/07/29 09:42:00 fair Exp $ */
/*
* Mach Operating System
@@ -90,8 +91,8 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
* actual arguments somewhat...
*/
for (i=0; i < 5; i++)
- db_printf("%x, ", frame->fr_arg[i]);
- db_printf("%x) at ", frame->fr_arg[i]);
+ db_printf("0x%x, ", frame->fr_arg[i]);
+ db_printf("0x%x) at ", frame->fr_arg[i]);
db_printsym(pc, DB_STGY_PROC);
db_printf("\n");
diff --git a/sys/arch/sparc/sparc/genassym.cf b/sys/arch/sparc/sparc/genassym.cf
index 338ff4b89b0..68951337bdb 100644
--- a/sys/arch/sparc/sparc/genassym.cf
+++ b/sys/arch/sparc/sparc/genassym.cf
@@ -1,5 +1,8 @@
-# $OpenBSD: genassym.cf,v 1.1 1997/06/25 14:47:12 downsj Exp $
+# $OpenBSD: genassym.cf,v 1.2 1997/08/08 08:27:14 downsj Exp $
+# $NetBSD: genassym.cf,v 1.2 1997/06/28 19:59:04 pk Exp $
+
#
+# Copyright (c) 1997 Christos Zoulas. All rights reserved.
# Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved.
#
@@ -62,10 +65,13 @@ include <machine/cpu.h>
include <machine/oldmon.h>
include <machine/bsd_openprom.h>
+include <sparc/sparc/cpuvar.h>
+
ifdef notyet
include <sparc/dev/zsreg.h>
include <sparc/dev/zsvar.h>
endif
+
include <dev/ic/am7930reg.h>
include <sparc/dev/amd7930var.h>
@@ -86,22 +92,25 @@ define P_VMSPACE offsetof(struct proc, p_vmspace)
define SRUN SRUN
# VM structure fields
-define VM_PMAP offsetof(struct vmspace, vm_pmap)
-define VM_PMAP_CTX offsetof(struct vmspace, vm_pmap.pm_ctx)
-define VM_PMAP_CTXNUM offsetof(struct vmspace, vm_pmap.pm_ctxnum)
+define VM_PMAP offsetof(struct vmspace, vm_map.pmap)
+define PMAP_CTX offsetof(struct pmap, pm_ctx)
+define PMAP_CTXNUM offsetof(struct pmap, pm_ctxnum)
# interrupt/fault metering
define V_SWTCH offsetof(struct vmmeter, v_swtch)
define V_INTR offsetof(struct vmmeter, v_intr)
define V_FAULTS offsetof(struct vmmeter, v_faults)
+# CPU info structure
+define CPUINFO_FAULTSTATUS offsetof(struct cpu_softc, get_faultstatus)
+
# PTE bits and related information
define PG_W PG_W
define PG_VSHIFT PG_VSHIFT
define PG_PROTSHIFT PG_PROTSHIFT
define PG_PROTUREAD PG_PROTUREAD
define PG_PROTUWRITE PG_PROTUWRITE
-ifdef SUN4M
+if defined(SUN4M)
define SRMMU_TETYPE SRMMU_TETYPE
define SRMMU_TEPTE SRMMU_TEPTE
define SRMMU_PROT_MASK SRMMU_PROT_MASK
@@ -138,13 +147,13 @@ define PCB_UW offsetof(struct pcb, pcb_uw)
define PCB_WIM offsetof(struct pcb, pcb_wim)
# interrupt enable register PTE
-define IE_REG_PTE_PG PG_V | PG_W | PG_S | PG_NC | PG_OBIO
+define IE_REG_PTE_PG (PG_V | PG_W | PG_S | PG_NC | PG_OBIO)
ifdef notyet
# ZSCC interrupt fields
define ZSC_A offsetof(struct zs_softc, sc_a)
define ZSC_B offsetof(struct zs_softc, sc_b)
-# define ZL_WREG offsetof(struct zs_line, zl_wreg)
+define ZL_WREG offsetof(struct zs_line, zl_wreg)
define ZL_TBC offsetof(struct zs_line, zl_tbc)
define ZL_TBA offsetof(struct zs_line, zl_tba)
define ZL_RBPUT offsetof(struct zs_line, zl_rbput)
diff --git a/sys/arch/sparc/sparc/in_cksum.c b/sys/arch/sparc/sparc/in_cksum.c
index 991dd17cc18..a6e0a86371a 100644
--- a/sys/arch/sparc/sparc/in_cksum.c
+++ b/sys/arch/sparc/sparc/in_cksum.c
@@ -1,9 +1,9 @@
-/* $NetBSD: in_cksum.c,v 1.3 1995/04/26 13:30:03 pk Exp $ */
+/* $OpenBSD: in_cksum.c,v 1.8 1997/08/08 08:27:15 downsj Exp $ */
+/* $NetBSD: in_cksum.c,v 1.7 1996/10/05 23:44:34 mrg Exp $ */
/*
* Copyright (c) 1995 Zubin Dittia.
- * Copyright (c) 1995 Theo de Raadt.
- * Copyright (c) 1995 Matthew Green.
+ * Copyright (c) 1995 Matthew R. Green.
* Copyright (c) 1994 Charles Hannum.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -46,7 +46,6 @@
#include <sys/param.h>
#include <sys/mbuf.h>
-
#include <netinet/in.h>
/*
@@ -74,8 +73,8 @@
* Another possible optimization is to replace a pair of 32-bit loads
* with a single 64-bit load (ldd) instruction, but I found that although
* this improves performance somewhat on Sun4c machines, it actually
- * reduces performance considerably on Sun4m machines (because of their
- * superscaler architecture). So I chose to leave it out.
+ * reduces performance considerably on Sun4m machines (I don't know why).
+ * So I chose to leave it out.
*
* Zubin Dittia (zubin@dworkin.wustl.edu)
*/
@@ -150,7 +149,8 @@ in_cksum(m, len)
* allow the compiler to pick which specific machine registers to
* use, instead of hard-coding this in the asm code above.
*/
- register u_int tmp1, tmp2;
+ /* XXX - initialized because of gcc's `-Wuninitialized' ! */
+ register u_int tmp1 = 0, tmp2 = 0;
for (; m && len; m = m->m_next) {
if (m->m_len == 0)
@@ -160,7 +160,7 @@ in_cksum(m, len)
if (len < mlen)
mlen = len;
len -= mlen;
-
+
/*
* Ensure that we're aligned on a word boundary here so
* that we can do 32 bit operations below.
diff --git a/sys/arch/sparc/sparc/intersil7170.h b/sys/arch/sparc/sparc/intersil7170.h
deleted file mode 100644
index b91f526e62e..00000000000
--- a/sys/arch/sparc/sparc/intersil7170.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $NetBSD: intersil7170.h,v 1.3 1996/05/02 18:17:40 pk Exp $ */
-
-/*
- * 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 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.
- */
-
-/*
- * Driver support for the intersil7170 used in sun[34]s to provide
- * real time clock and time-of-day support.
- *
- * Derived from: datasheet "ICM7170 a uP-Compatible Real-Time Clock"
- * document #301680-005, Dec 85
- */
-
-struct date_time { /* from p. 7 of 10 */
- volatile unsigned char dt_csec;
- volatile unsigned char dt_hour;
- volatile unsigned char dt_min;
- volatile unsigned char dt_sec;
- volatile unsigned char dt_month;
- volatile unsigned char dt_day;
- volatile unsigned char dt_year;
- volatile unsigned char dt_dow;
-};
-
-struct intersil7170 {
- struct date_time counters;
- struct date_time clk_ram; /* should be ok as both are word aligned */
- volatile unsigned char clk_intr_reg;
- volatile unsigned char clk_cmd_reg;
-};
-
-/* bit assignments for command register, p. 6 of 10, write-only */
-#define INTERSIL_CMD_FREQ_32K 0x0
-#define INTERSIL_CMD_FREQ_1M 0x1
-#define INTERSIL_CMD_FREQ_2M 0x2
-#define INTERSIL_CMD_FREQ_4M 0x3
-
-#define INTERSIL_CMD_12HR_MODE 0x0
-#define INTERSIL_CMD_24HR_MODE 0x4
-
-#define INTERSIL_CMD_STOP 0x0
-#define INTERSIL_CMD_RUN 0x8
-
-#define INTERSIL_CMD_IDISABLE 0x0
-#define INTERSIL_CMD_IENABLE 0x10
-
-#define INTERSIL_CMD_TEST_MODE 0x20
-#define INTERSIL_CMD_NORMAL_MODE 0x0
-
-/* bit assignments for interrupt register r/w, p 7 of 10*/
-
-#define INTERSIL_INTER_ALARM 0x1 /* r/w */
-#define INTERSIL_INTER_CSECONDS 0x2 /* r/w */
-#define INTERSIL_INTER_DSECONDS 0x4 /* r/w */
-#define INTERSIL_INTER_SECONDS 0x8 /* r/w */
-#define INTERSIL_INTER_MINUTES 0x10 /* r/w */
-#define INTERSIL_INTER_HOURS 0x20 /* r/w */
-#define INTERSIL_INTER_DAYS 0x40 /* r/w */
-#define INTERSIL_INTER_PENDING 0x80 /* read-only */
-
-#define INTERSIL_INTER_BITS "\20\10PENDING\7DAYS\6HRS\5MIN\4SCDS\3DSEC\2CSEC\1ALARM"
-
diff --git a/sys/arch/sparc/sparc/intr.c b/sys/arch/sparc/sparc/intr.c
index e4ca57141b4..7ca610c248e 100644
--- a/sys/arch/sparc/sparc/intr.c
+++ b/sys/arch/sparc/sparc/intr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.13 1996/03/31 23:35:20 pk Exp $ */
+/* $NetBSD: intr.c,v 1.20 1997/07/29 09:42:03 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -44,8 +44,6 @@
* @(#)intr.c 8.3 (Berkeley) 11/11/93
*/
-#include "ppp.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -68,9 +66,6 @@
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#endif
-#ifdef NETATALK
-#include <netatalk/at_extern.h>
-#endif
#ifdef NS
#include <netns/ns_var.h>
#endif
@@ -78,6 +73,9 @@
#include <netiso/iso.h>
#include <netiso/clnp.h>
#endif
+#ifdef NETATALK
+#include <netatalk/at_extern.h>
+#endif
#include "ppp.h"
#if NPPP > 0
#include <net/ppp_defs.h>
@@ -98,7 +96,7 @@ strayintr(fp)
static int straytime, nstray;
int timesince;
- printf("stray interrupt ipl %x pc=%x npc=%x psr=%b\n",
+ printf("stray interrupt ipl 0x%x pc=0x%x npc=0x%x psr=%b\n",
fp->ipl, fp->pc, fp->npc, fp->psr, PSR_BITS);
timesince = time.tv_sec - straytime;
if (timesince <= 10) {
@@ -160,6 +158,10 @@ soft01intr(fp)
if (n & (1 << NETISR_ISO))
clnlintr();
#endif
+#ifdef NATM
+ if (n & (1 << NETISR_NATM))
+ natmintr();
+#endif
#if NPPP > 0
if (n & (1 << NETISR_PPP))
pppintr();
@@ -236,7 +238,7 @@ intr_establish(level, ih)
if (tv->tv_instr[0] != I_MOVi(I_L3, level) ||
tv->tv_instr[1] != I_BA(0, displ) ||
tv->tv_instr[2] != I_RDPSR(I_L0))
- panic("intr_establish(%d, %p)\n%x %x %x != %x %x %x",
+ panic("intr_establish(%d, %p)\n0x%x 0x%x 0x%x != 0x%x 0x%x 0x%x",
level, ih,
tv->tv_instr[0], tv->tv_instr[1], tv->tv_instr[2],
I_MOVi(I_L3, level), I_BA(0, displ), I_RDPSR(I_L0));
@@ -285,7 +287,7 @@ intr_fasttrap(level, vec)
if (tv->tv_instr[0] != I_MOVi(I_L3, level) ||
tv->tv_instr[1] != I_BA(0, displ) ||
tv->tv_instr[2] != I_RDPSR(I_L0))
- panic("intr_fasttrap(%d, %p)\n%x %x %x != %x %x %x",
+ panic("intr_fasttrap(%d, %p)\n0x%x 0x%x 0x%x != 0x%x 0x%x 0x%x",
level, vec,
tv->tv_instr[0], tv->tv_instr[1], tv->tv_instr[2],
I_MOVi(I_L3, level), I_BA(0, displ), I_RDPSR(I_L0));
diff --git a/sys/arch/sparc/sparc/intreg.h b/sys/arch/sparc/sparc/intreg.h
index 5abbb8342f1..e74859f6327 100644
--- a/sys/arch/sparc/sparc/intreg.h
+++ b/sys/arch/sparc/sparc/intreg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: intreg.h,v 1.5 1996/03/31 23:03:39 pk Exp $ */
+/* $OpenBSD: intreg.h,v 1.3 1997/08/08 08:27:19 downsj Exp $ */
+/* $NetBSD: intreg.h,v 1.6 1997/07/22 20:19:10 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -121,18 +122,20 @@ void ienab_bic __P((int bic)); /* clear given bits */
#define SINTR_ME 0x40000000 /* Module Error (async) */
#define SINTR_I 0x20000000 /* MSI (MBus-SBus) */
#define SINTR_M 0x10000000 /* ECC Memory controller */
-#define SINTR_RSVD2 0x0f800000
+#define SINTR_V 0x08000000 /* VME Async error */
+#define SINTR_RSVD2 0x07800000
#define SINTR_F 0x00400000 /* Floppy */
-#define SINTR_RSVD3 0x00200000
-#define SINTR_V 0x00100000 /* Video (Supersparc only) */
+#define SINTR_MI 0x00200000 /* Module interrupt */
+#define SINTR_VI 0x00100000 /* Video (Supersparc only) */
#define SINTR_T 0x00080000 /* Level 10 counter */
#define SINTR_SC 0x00040000 /* SCSI */
-#define SINTR_RSVD4 0x00020000
+#define SINTR_A 0x00020000 /* Audio/ISDN */
#define SINTR_E 0x00010000 /* Ethernet */
#define SINTR_S 0x00008000 /* Serial port */
#define SINTR_K 0x00004000 /* Keyboard/mouse */
#define SINTR_SBUSMASK 0x00003f80 /* SBus */
-#define SINTR_SBUS(n) (((n) << 7) & 0x00003f80)
-#define SINTR_RSVD5 0x0000007f
+#define SINTR_SBUS(n) (1 << (7+(n)-1))
+#define SINTR_VMEMASK 0x0000007f /* VME */
+#define SINTR_VME(n) (1 << ((n)-1))
#endif
diff --git a/sys/arch/sparc/sparc/iommu.c b/sys/arch/sparc/sparc/iommu.c
index 765bca78d17..91d125afae4 100644
--- a/sys/arch/sparc/sparc/iommu.c
+++ b/sys/arch/sparc/sparc/iommu.c
@@ -1,4 +1,5 @@
-/* $NetBSD: iommu.c,v 1.4 1996/05/21 07:25:07 pk Exp $ */
+/* $OpenBSD: iommu.c,v 1.3 1997/08/08 08:27:20 downsj Exp $ */
+/* $NetBSD: iommu.c,v 1.13 1997/07/29 09:42:04 fair Exp $ */
/*
* Copyright (c) 1996
@@ -45,6 +46,7 @@
#include <machine/ctlreg.h>
#include <sparc/sparc/asm.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#include <sparc/sparc/iommureg.h>
struct iommu_softc {
@@ -96,7 +98,7 @@ iommu_match(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -121,12 +123,12 @@ iommu_attach(parent, self, aux)
register int node;
register char *name;
register u_int pbase, pa;
- register int i, mmupcrsav, s, wierdviking = 0;
+ register int i, mmupcrsave, s;
register iopte_t *tpte_p;
extern u_int *kernel_iopte_table;
extern u_int kernel_iopte_table_pa;
-/*XXX-GCC!*/mmupcrsav=0;
+/*XXX-GCC!*/mmupcrsave=0;
iommu_sc = sc;
/*
* XXX there is only one iommu, for now -- do not know how to
@@ -151,10 +153,12 @@ iommu_attach(parent, self, aux)
* other fields for?
*/
sc->sc_reg = (struct iommureg *)
- mapdev(ra->ra_reg, 0, 0, ra->ra_len, ra->ra_iospace);
+ mapiodev(ra->ra_reg, 0, ra->ra_len);
#endif
sc->sc_hasiocache = node_has_property(node, "cache-coherence?");
+ if (CACHEINFO.c_enabled == 0) /* XXX - is this correct? */
+ sc->sc_hasiocache = 0;
has_iocache = sc->sc_hasiocache; /* Set global flag */
sc->sc_pagesize = getpropint(node, "page-size", NBPG),
@@ -191,10 +195,10 @@ iommu_attach(parent, self, aux)
*
* XXX: PGOFSET, NBPG assume same page size as SRMMU
*/
- if ((getpsr() & 0x40000000) && (!(lda(SRMMU_PCR,ASI_SRMMU) & 0x800))) {
- wierdviking = 1;
- sta(SRMMU_PCR, ASI_SRMMU, /* set MMU AC bit */
- ((mmupcrsav = lda(SRMMU_PCR,ASI_SRMMU)) | SRMMU_PCR_AC));
+ if (cpuinfo.cpu_vers == 4 && cpuinfo.mxcc) {
+ /* set MMU AC bit */
+ sta(SRMMU_PCR, ASI_SRMMU,
+ ((mmupcrsave = lda(SRMMU_PCR, ASI_SRMMU)) | VIKING_PCR_AC));
}
for (tpte_p = &sc->sc_ptes[((0 - DVMA4M_BASE)/NBPG) - 1],
@@ -207,8 +211,9 @@ iommu_attach(parent, self, aux)
(tpte_p - &sc->sc_ptes[0])*NBPG + DVMA4M_BASE);
*tpte_p = lda(pa, ASI_BYPASS);
}
- if (wierdviking) { /* restore mmu after bug-avoidance */
- sta(SRMMU_PCR, ASI_SRMMU, mmupcrsav);
+ if (cpuinfo.cpu_vers == 4 && cpuinfo.mxcc) {
+ /* restore mmu after bug-avoidance */
+ sta(SRMMU_PCR, ASI_SRMMU, mmupcrsave);
}
/*
@@ -232,7 +237,7 @@ iommu_attach(parent, self, aux)
IOMMU_FLUSHALL(sc);
splx(s);
- printf(": version %x/%x, page-size %d, range %dMB\n",
+ printf(": version 0x%x/0x%x, page-size %d, range %dMB\n",
(sc->sc_reg->io_cr & IOMMU_CTL_VER) >> 24,
(sc->sc_reg->io_cr & IOMMU_CTL_IMPL) >> 28,
sc->sc_pagesize,
@@ -299,7 +304,6 @@ iommu_remove(va, len)
#endif
#endif
sc->sc_ptes[atop(va - sc->sc_dvmabase)] = 0;
- sta(sc->sc_ptes + atop(va - sc->sc_dvmabase), ASI_BYPASS, 0);
IOMMU_FLUSHPAGE(sc, va);
len -= sc->sc_pagesize;
va += sc->sc_pagesize;
@@ -313,8 +317,8 @@ iommu_error()
struct iommu_softc *sc = X;
struct iommureg *iop = sc->sc_reg;
- printf("iommu: afsr %x, afar %x\n", iop->io_afsr, iop->io_afar);
- printf("iommu: mfsr %x, mfar %x\n", iop->io_mfsr, iop->io_mfar);
+ printf("iommu: afsr 0x%x, afar 0x%x\n", iop->io_afsr, iop->io_afar);
+ printf("iommu: mfsr 0x%x, mfar 0x%x\n", iop->io_mfsr, iop->io_mfar);
}
int
iommu_alloc(va, len)
diff --git a/sys/arch/sparc/sparc/iommureg.h b/sys/arch/sparc/sparc/iommureg.h
index 24c5ac9f8cf..021e32f09e0 100644
--- a/sys/arch/sparc/sparc/iommureg.h
+++ b/sys/arch/sparc/sparc/iommureg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: iommureg.h,v 1.2 1997/08/08 08:27:22 downsj Exp $ */
/* $NetBSD: iommureg.h,v 1.2 1996/05/16 15:57:18 abrown Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/kgdb_proto.h b/sys/arch/sparc/sparc/kgdb_proto.h
index 8d1869a3a47..bc2c777ddea 100644
--- a/sys/arch/sparc/sparc/kgdb_proto.h
+++ b/sys/arch/sparc/sparc/kgdb_proto.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: kgdb_proto.h,v 1.3 1997/08/08 08:27:23 downsj Exp $ */
/* $NetBSD: kgdb_proto.h,v 1.4 1996/05/16 15:57:19 abrown Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/kgdb_stub.c b/sys/arch/sparc/sparc/kgdb_stub.c
index 3ba0c5e9975..15f3f2b9d35 100644
--- a/sys/arch/sparc/sparc/kgdb_stub.c
+++ b/sys/arch/sparc/sparc/kgdb_stub.c
@@ -1,4 +1,5 @@
-/* $NetBSD: kgdb_stub.c,v 1.8 1996/05/16 15:57:20 abrown Exp $ */
+/* $OpenBSD: kgdb_stub.c,v 1.3 1997/08/08 08:27:24 downsj Exp $ */
+/* $NetBSD: kgdb_stub.c,v 1.10 1996/10/13 03:00:36 christos Exp $ */
/*
* Copyright (c) 1992, 1993
diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s
index 4826e06aa56..8878d8048bc 100644
--- a/sys/arch/sparc/sparc/locore.s
+++ b/sys/arch/sparc/sparc/locore.s
@@ -1,3 +1,6 @@
+/* $OpenBSD: locore.s,v 1.17 1997/08/08 08:27:27 downsj Exp $ */
+/* $NetBSD: locore.s,v 1.72 1997/07/07 20:06:42 pk Exp $ */
+
/*
* Copyright (c) 1996 Paul Kranenburg
* Copyright (c) 1996
@@ -64,7 +67,6 @@
#include <compat/svr4/svr4_syscall.h>
#endif
-
/*
* GNU assembler does not understand `.empty' directive; Sun assembler
* gripes about labels without it. To allow cross-compilation using
@@ -270,19 +272,6 @@ sun4_notsup:
_msgbuf = KERNBASE
/*
- * We need to map the interrupt enable register very early on in the
- * boot process, so that we can handle NMIs (parity errors) halfway
- * sensibly during boot. We use virtual address f8002000 (`page 2')
- * for this, wasting a page of physical memory.
- *
- * This doesn't work for the Sun4M, which can have 5 or more pages of
- * registers, a system register and one for each processor. Thus we use
- * a reserved piece of the virtual address space, set up in bootstrap().
- */
-
-IE_reg_addr = INTRREG_VA ! KERNBASE + 8192 - points to IEreg
-
-/*
* Each trap has room for four instructions, of which one perforce must
* be a branch. On entry the hardware has copied pc and npc to %l1 and
* %l2 respectively. We use two more to read the psr into %l0, and to
@@ -1156,7 +1145,7 @@ trapbase_sun4m:
* need to .skip 4096 to pad to page size iff. the number of trap tables
* defined above is odd.
*/
-#if defined(SUN4) + defined(SUN4C) + defined(SUN4M) - 2 == 0
+#if (defined(SUN4) + defined(SUN4C) + defined(SUN4M)) % 2 == 1
.skip 4096
#endif
@@ -1294,47 +1283,44 @@ Lpanic_red:
#endif /* 4m */
#if defined(SUN4M) && !(defined(SUN4C) || defined(SUN4))
-#define PTE_OF_ADDR PTE_OF_ADDR4M
-#define CMP_PTE_USER_WRITE(pte,tmp) CMP_PTE_USER_WRITE4M(pte)
-#define CMP_PTE_USER_READ(pte,tmp) CMP_PTE_USER_READ4M(pte)
+
+#define PTE_OF_ADDR(addr, pte, bad, page_offset, label) \
+ PTE_OF_ADDR4M(addr, pte, bad, page_offset)
+#define CMP_PTE_USER_WRITE(pte, tmp, label) CMP_PTE_USER_WRITE4M(pte)
+#define CMP_PTE_USER_READ(pte, tmp, label) CMP_PTE_USER_READ4M(pte)
+
#elif (defined(SUN4C) || defined(SUN4)) && !defined(SUN4M)
-#define PTE_OF_ADDR PTE_OF_ADDR4_4C
-#define CMP_PTE_USER_WRITE(pte,tmp) CMP_PTE_USER_WRITE4_4C(pte)
-#define CMP_PTE_USER_READ(pte,tmp) CMP_PTE_USER_READ4_4C(pte)
+
+#define PTE_OF_ADDR(addr, pte, bad, page_offset,label) \
+ PTE_OF_ADDR4_4C(addr, pte, bad, page_offset)
+#define CMP_PTE_USER_WRITE(pte, tmp, label) CMP_PTE_USER_WRITE4_4C(pte)
+#define CMP_PTE_USER_READ(pte, tmp, label) CMP_PTE_USER_READ4_4C(pte)
+
#else /* both defined, ugh */
-#define PTE_OF_ADDR(addr, pte, bad, page_offset) \
- sethi %hi(_cputyp), pte; \
- ld [pte + %lo(_cputyp)], pte; \
- cmp pte, CPU_SUN4M; \
- bne 2f; nop; \
+
+#define PTE_OF_ADDR(addr, pte, bad, page_offset, label) \
+label: b,a 2f; \
PTE_OF_ADDR4M(addr, pte, bad, page_offset); \
b,a 3f; \
2: \
PTE_OF_ADDR4_4C(addr, pte, bad, page_offset); \
3:
-#define CMP_PTE_USER_READ(pte, tmp) \
- sethi %hi(_cputyp), tmp; \
- ld [tmp + %lo(_cputyp)], tmp; \
- cmp tmp, CPU_SUN4M; \
- bne 1f; nop; \
+#define CMP_PTE_USER_READ(pte, tmp, label) \
+label: b,a 1f; \
CMP_PTE_USER_READ4M(pte); \
b,a 2f; \
1: \
CMP_PTE_USER_READ4_4C(pte); \
2:
-#define CMP_PTE_USER_WRITE(pte, tmp) \
- sethi %hi(_cputyp), tmp; \
- ld [tmp + %lo(_cputyp)], tmp; \
- cmp tmp, CPU_SUN4M; \
- bne 1f; nop; \
+#define CMP_PTE_USER_WRITE(pte, tmp, label) \
+label: b,a 1f; \
CMP_PTE_USER_WRITE4M(pte); \
b,a 2f; \
1: \
CMP_PTE_USER_WRITE4_4C(pte); \
2:
-
#endif
@@ -1605,8 +1591,8 @@ ctw_user:
sethi %hi(_pgofset), %g6 ! trash %g6=curpcb
ld [%g6 + %lo(_pgofset)], %g6
- PTE_OF_ADDR(%sp, %g7, ctw_invalid, %g6)
- CMP_PTE_USER_WRITE(%g7, %g5) ! likewise if not writable
+ PTE_OF_ADDR(%sp, %g7, ctw_invalid, %g6, NOP_ON_4M_1)
+ CMP_PTE_USER_WRITE(%g7, %g5, NOP_ON_4M_2) ! likewise if not writable
bne ctw_invalid
EMPTY
/* Note side-effect of SLT_IF_1PAGE_RW: decrements %g6 by 62 */
@@ -1615,8 +1601,8 @@ ctw_user:
std %l0, [%sp]
add %sp, 7*8, %g5 ! check last addr too
add %g6, 62, %g6 ! restore %g6 to `pgofset'
- PTE_OF_ADDR(%g5, %g7, ctw_invalid, %g6)
- CMP_PTE_USER_WRITE(%g7, %g6)
+ PTE_OF_ADDR(%g5, %g7, ctw_invalid, %g6, NOP_ON_4M_3)
+ CMP_PTE_USER_WRITE(%g7, %g6, NOP_ON_4M_4)
be,a ctw_merge ! all ok: store <l0,l1> and merge
std %l0, [%sp]
@@ -1828,10 +1814,10 @@ memfault_sun4c:
* This code is essentially the same as that at `nmi' below,
* but the register usage is different and we cannot merge.
*/
- sethi %hi(IE_reg_addr), %l5 ! ienab_bic(IE_ALLIE);
- ldub [%l5 + %lo(IE_reg_addr)], %o0
+ sethi %hi(INTRREG_VA), %l5 ! ienab_bic(IE_ALLIE);
+ ldub [%l5 + %lo(INTRREG_VA)], %o0
andn %o0, IE_ALLIE, %o0
- stb %o0, [%l5 + %lo(IE_reg_addr)]
+ stb %o0, [%l5 + %lo(INTRREG_VA)]
/*
* Now reenable traps and call C code.
@@ -1848,9 +1834,9 @@ memfault_sun4c:
ldd [%sp + CCFSZ + 32], %g4
ldd [%sp + CCFSZ + 40], %g6
/* now safe to set IE_ALLIE again */
- ldub [%l5 + %lo(IE_reg_addr)], %o1
+ ldub [%l5 + %lo(INTRREG_VA)], %o1
or %o1, IE_ALLIE, %o1
- stb %o1, [%l5 + %lo(IE_reg_addr)]
+ stb %o1, [%l5 + %lo(INTRREG_VA)]
b return_from_trap
wr %l4, 0, %y ! restore y
@@ -1880,29 +1866,15 @@ memfault_sun4m:
st %g1, [%sp + CCFSZ + 20] ! save g1
rd %y, %l4 ! save y
- set SRMMU_SFADDR, %o0
std %g2, [%sp + CCFSZ + 24] ! save g2, g3
- lda [%o0] ASI_SRMMU, %o2 ! sync virt addr; must be read first
- set SRMMU_SFSTAT, %o0
- lda [%o0] ASI_SRMMU, %o1 ! get sync fault status register
- std %g4, [%sp + CCFSZ + 32] ! (sneak g4,g5 in here)
+ std %g4, [%sp + CCFSZ + 32] ! save g4, g5
- /* Now test for a HyperSPARC. If we have one, get the async status */
- sethi %hi(_mmumod), %o3 ! get MMU model
- ld [%o3 + %lo(_mmumod)], %o3
- cmp %o3, SUN4M_MMU_HS ! is it hypersparc?
- std %g6, [%sp + CCFSZ + 40] ! sneak in g6, g7
- be 1f ! yup, skip ahead
+ ! get fault status/address
+ set CPUINFO_VA+CPUINFO_FAULTSTATUS, %o0
+ ld [%o0], %o0
+ jmpl %o0, %o7
+ std %g6, [%sp + CCFSZ + 40] ! sneak in g6, g7
- clr %o3 ! clear %o3 and %o4, not hypersparc
- b 2f
- clr %o4
-1:
- set SRMMU_AFSTAT, %o3 ! must read status before fault on HS
- lda [%o3] ASI_SRMMU, %o3 ! get async fault status
- set SRMMU_AFADDR, %o4
- lda [%o4] ASI_SRMMU, %o4 ! get async fault address
-2:
wr %l0, PSR_ET, %psr ! reenable traps
/* Finish stackframe, call C trap handler */
@@ -2329,10 +2301,10 @@ return_from_syscall:
*/
.comm _intrhand, 15 * 8 ! intrhand[0..14]; 0 => error
softintr_sun44c:
- sethi %hi(IE_reg_addr), %l6
- ldub [%l6 + %lo(IE_reg_addr)], %l5
+ sethi %hi(INTRREG_VA), %l6
+ ldub [%l6 + %lo(INTRREG_VA)], %l5
andn %l5, %l4, %l5
- stb %l5, [%l6 + %lo(IE_reg_addr)]
+ stb %l5, [%l6 + %lo(INTRREG_VA)]
softintr_common:
INTR_SETUP(-CCFSZ-80)
@@ -2498,10 +2470,10 @@ nmi_sun4:
* Level 15 interrupts are nonmaskable, so with traps off,
* disable all interrupts to prevent recursion.
*/
- sethi %hi(IE_reg_addr), %o0
- ldub [%o0 + %lo(IE_reg_addr)], %o1
+ sethi %hi(INTRREG_VA), %o0
+ ldub [%o0 + %lo(INTRREG_VA)], %o1
andn %o0, IE_ALLIE, %o1
- stb %o1, [%o0 + %lo(IE_reg_addr)]
+ stb %o1, [%o0 + %lo(INTRREG_VA)]
wr %l0, PSR_ET, %psr ! okay, turn traps on again
std %g2, [%sp + CCFSZ + 0] ! save g2, g3
@@ -2524,10 +2496,10 @@ nmi_sun4c:
* Level 15 interrupts are nonmaskable, so with traps off,
* disable all interrupts to prevent recursion.
*/
- sethi %hi(IE_reg_addr), %o0
- ldub [%o0 + %lo(IE_reg_addr)], %o1
+ sethi %hi(INTRREG_VA), %o0
+ ldub [%o0 + %lo(INTRREG_VA)], %o1
andn %o0, IE_ALLIE, %o1
- stb %o1, [%o0 + %lo(IE_reg_addr)]
+ stb %o1, [%o0 + %lo(INTRREG_VA)]
wr %l0, PSR_ET, %psr ! okay, turn traps on again
std %g2, [%sp + CCFSZ + 0] ! save g2, g3
@@ -2564,10 +2536,10 @@ nmi_common:
mov %l7, %g7
! set IE_ALLIE again (safe, we disabled traps again above)
- sethi %hi(IE_reg_addr), %o0
- ldub [%o0 + %lo(IE_reg_addr)], %o1
+ sethi %hi(INTRREG_VA), %o0
+ ldub [%o0 + %lo(INTRREG_VA)], %o1
or %o1, IE_ALLIE, %o1
- stb %o1, [%o0 + %lo(IE_reg_addr)]
+ stb %o1, [%o0 + %lo(INTRREG_VA)]
b return_from_trap
wr %l4, 0, %y ! restore y
@@ -2595,28 +2567,11 @@ nmi_sun4m:
rd %y, %l4 ! save y
! now read sync error registers
- set SRMMU_SFADDR, %o0
- lda [%o0] ASI_SRMMU, %o2 ! sync virt addr
- set SRMMU_SFSTAT, %o0
- lda [%o0] ASI_SRMMU, %o1 ! sync err reg
- std %g4, [%sp + CCFSZ + 8] ! save g4,g5
-
- /* Now test for a HyperSPARC. If we have one, get the async status */
-
- sethi %hi(_mmumod), %o3 ! get MMU model
- ld [%o3 + %lo(_mmumod)], %o3
- cmp %o3, SUN4M_MMU_HS ! is it hypersparc?
- be 1f ! yup, skip ahead
+ set CPUINFO_VA+CPUINFO_FAULTSTATUS, %o0
+ ld [%o0], %o0
+ jmpl %o0, %o7
+ std %g4, [%sp + CCFSZ + 8] ! save g4,g5
- clr %o3 ! clear %o3 and %o4, not hypersparc
- b 2f
- clr %o4
-1:
- set SRMMU_AFSTAT, %o3 ! read status first on hypersparc
- lda [%o3] ASI_SRMMU, %o3 ! get async fault status
- set SRMMU_AFADDR, %o4
- lda [%o4] ASI_SRMMU, %o4 ! get async fault address
-2:
/* Finish stackframe, call C trap handler */
mov %g1, %l5 ! save g1,g6,g7
mov %g6, %l6
@@ -2822,8 +2777,8 @@ winuf_user:
sethi %hi(_pgofset), %l4
ld [%l4 + %lo(_pgofset)], %l4
- PTE_OF_ADDR(%sp, %l7, winuf_invalid, %l4)
- CMP_PTE_USER_READ(%l7, %l5) ! if first page not readable,
+ PTE_OF_ADDR(%sp, %l7, winuf_invalid, %l4, NOP_ON_4M_5)
+ CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_6) ! if first page not readable,
bne winuf_invalid ! it is invalid
EMPTY
SLT_IF_1PAGE_RW(%sp, %l7, %l4) ! first page is readable
@@ -2831,8 +2786,8 @@ winuf_user:
restore %g0, 1, %l1 ! and goto ok, & set %l1 to 1
add %sp, 7*8, %l5
add %l4, 62, %l4
- PTE_OF_ADDR(%l5, %l7, winuf_invalid, %l4)
- CMP_PTE_USER_READ(%l7, %l5) ! check second page too
+ PTE_OF_ADDR(%l5, %l7, winuf_invalid, %l4, NOP_ON_4M_7)
+ CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_8) ! check second page too
be,a winuf_ok ! enter window X and goto ok
restore %g0, 1, %l1 ! (and then set %l1 to 1)
@@ -3046,8 +3001,8 @@ rft_user:
sethi %hi(_pgofset), %l3
ld [%l3 + %lo(_pgofset)], %l3
- PTE_OF_ADDR(%fp, %l7, rft_invalid, %l3)
- CMP_PTE_USER_READ(%l7, %l5) ! try first page
+ PTE_OF_ADDR(%fp, %l7, rft_invalid, %l3, NOP_ON_4M_9)
+ CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_10) ! try first page
bne rft_invalid ! no good
EMPTY
SLT_IF_1PAGE_RW(%fp, %l7, %l3)
@@ -3055,8 +3010,8 @@ rft_user:
wr %g0, 0, %wim
add %fp, 7*8, %l5
add %l3, 62, %l3
- PTE_OF_ADDR(%l5, %l7, rft_invalid, %l3)
- CMP_PTE_USER_READ(%l7, %l5) ! check 2nd page too
+ PTE_OF_ADDR(%l5, %l7, rft_invalid, %l3, NOP_ON_4M_11)
+ CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_12) ! check 2nd page too
be,a rft_user_ok
wr %g0, 0, %wim
@@ -3446,6 +3401,7 @@ start_havetype:
blu 0b ! no, loop
add %l3, %l0, %l0 ! (and lowva += segsz)
+#if 0 /* moved to autoconf */
/*
* Now map the interrupt enable register and clear any interrupts,
* enabling NMIs. Note that we will not take NMIs until we change
@@ -3462,6 +3418,7 @@ start_havetype:
mov IE_ALLIE, %l1
nop; nop ! paranoia
stb %l1, [%l0]
+#endif
b startmap_done
nop
1:
@@ -3493,6 +3450,7 @@ no_3mmu:
remap_done:
+#if 0 /* moved to autoconf */
/*
* Now map the interrupt enable register and clear any interrupts,
* enabling NMIs. Note that we will not take NMIs until we change
@@ -3509,6 +3467,7 @@ remap_done:
mov IE_ALLIE, %l1
nop; nop ! paranoia
stb %l1, [%l0]
+#endif
b,a startmap_done
2:
#endif /* SUN4 */
@@ -3682,6 +3641,50 @@ noplab: nop
1:
#endif
+#if ((defined(SUN4) || defined(SUN4C)) && defined(SUN4M))
+
+ /*
+ * Patch instructions at specified labels that start
+ * per-architecture code-paths.
+ */
+Lgandul: nop
+
+#define MUNGE(label) \
+ sethi %hi(label), %o0; \
+ st %l0, [%o0 + %lo(label)]
+
+ sethi %hi(Lgandul), %o0
+ ld [%o0 + %lo(Lgandul)], %l0 ! %l0 = NOP
+
+ cmp %g4, CPU_SUN4M
+ bne,a 1f
+ nop
+
+ ! this should be automated!
+ MUNGE(NOP_ON_4M_1)
+ MUNGE(NOP_ON_4M_2)
+ MUNGE(NOP_ON_4M_3)
+ MUNGE(NOP_ON_4M_4)
+ MUNGE(NOP_ON_4M_5)
+ MUNGE(NOP_ON_4M_6)
+ MUNGE(NOP_ON_4M_7)
+ MUNGE(NOP_ON_4M_8)
+ MUNGE(NOP_ON_4M_9)
+ MUNGE(NOP_ON_4M_10)
+ MUNGE(NOP_ON_4M_11)
+ MUNGE(NOP_ON_4M_12)
+ MUNGE(NOP_ON_4M_13)
+ MUNGE(NOP_ON_4M_14)
+ b,a 2f
+
+1:
+ MUNGE(NOP_ON_4_4C_1)
+
+2:
+
+#undef MUNGE
+#endif
+
/*
* Step 4: change the trap base register, now that our trap handlers
* will function (they need the tables we just set up).
@@ -3705,6 +3708,7 @@ noplab: nop
clr %o0 ! our frame arg is ignored
/*NOTREACHED*/
+
/*
* The following code is copied to the top of the user stack when each
* process is exec'ed, and signals are `trampolined' off it.
@@ -3976,6 +3980,13 @@ _svr4_esigcode:
#define ALTENTRY(x) .globl _/**/x; _/**/x:
/*
+ * General-purpose NULL routine.
+ */
+ENTRY(sparc_noop)
+ retl
+ nop
+
+/*
* getfp() - get stack frame pointer
*/
ENTRY(getfp)
@@ -4576,15 +4587,17 @@ Lsw_load:
* zero so it is safe to have interrupts going here.)
*/
ld [%g3 + P_VMSPACE], %o3 ! vm = p->p_vmspace;
- ld [%o3 + VM_PMAP_CTX], %o0! if (vm->vm_pmap.pm_ctx != NULL)
+ ld [%o3 + VM_PMAP], %o3 ! pm = vm->vm_map.vm_pmap;
+ ld [%o3 + PMAP_CTX], %o0 ! if (pm->pm_ctx != NULL)
tst %o0
bnz,a Lsw_havectx ! goto havecontext;
- ld [%o3 + VM_PMAP_CTXNUM], %o0 ! load context number
+ ld [%o3 + PMAP_CTXNUM], %o0 ! load context number
/* p does not have a context: call ctx_alloc to get one */
save %sp, -CCFSZ, %sp
- call _ctx_alloc ! ctx_alloc(&vm->vm_pmap);
- add %i3, VM_PMAP, %o0
+ call _ctx_alloc ! ctx_alloc(pm);
+ mov %i3, %o0
+
ret
restore
@@ -4626,7 +4639,7 @@ Lsw_sameproc:
* Only used just before a crash dump.
*/
ENTRY(snapshot)
- st %o6, [%o0 + PCB_SP] ! save sp
+ std %o6, [%o0 + PCB_SP] ! save sp
rd %psr, %o1 ! save psr
st %o1, [%o0 + PCB_PSR]
@@ -5408,20 +5421,14 @@ ENTRY(loadfpstate)
#if defined(SUN4M) && (defined(SUN4) || defined(SUN4C))
ENTRY(ienab_bis)
- sethi %hi(_cputyp), %o1
- ld [%o1 + %lo(_cputyp)], %o1
- cmp %o1, CPU_SUN4M
- be,a _ienab_bis_4m
- nop
- b,a _ienab_bis_4c
+NOP_ON_4M_13:
+ b,a _ienab_bis_4_4c
+ b,a _ienab_bis_4m
ENTRY(ienab_bic)
- sethi %hi(_cputyp), %o1
- ld [%o1 + %lo(_cputyp)], %o1
- cmp %o1, CPU_SUN4M
- be,a _ienab_bic_4m
- nop
- b,a _ienab_bic_4c
+NOP_ON_4M_14:
+ b,a _ienab_bic_4_4c
+ b,a _ienab_bic_4m
#endif
#if defined(SUN4) || defined(SUN4C)
@@ -5430,7 +5437,7 @@ ENTRY(ienab_bic)
* and one of the interrupts is nonmaskable, we must disable traps.
*/
#if defined(SUN4M)
-ENTRY(ienab_bis_4c)
+ENTRY(ienab_bis_4_4c)
#else
ENTRY(ienab_bis)
#endif
@@ -5438,17 +5445,17 @@ ENTRY(ienab_bis)
rd %psr, %o2
wr %o2, PSR_ET, %psr ! disable traps
nop; nop ! 3-instr delay until ET turns off
- sethi %hi(IE_reg_addr), %o3
- ldub [%o3 + %lo(IE_reg_addr)], %o4
- or %o4, %o0, %o4 ! *IE_reg_addr |= bis;
- stb %o4, [%o3 + %lo(IE_reg_addr)]
+ sethi %hi(INTRREG_VA), %o3
+ ldub [%o3 + %lo(INTRREG_VA)], %o4
+ or %o4, %o0, %o4 ! *INTRREG_VA |= bis;
+ stb %o4, [%o3 + %lo(INTRREG_VA)]
wr %o2, 0, %psr ! reenable traps
nop
retl
nop
#if defined(SUN4M)
-ENTRY(ienab_bic_4c)
+ENTRY(ienab_bic_4_4c)
#else
ENTRY(ienab_bic)
#endif
@@ -5456,10 +5463,10 @@ ENTRY(ienab_bic)
rd %psr, %o2
wr %o2, PSR_ET, %psr ! disable traps
nop; nop
- sethi %hi(IE_reg_addr), %o3
- ldub [%o3 + %lo(IE_reg_addr)], %o4
- andn %o4, %o0, %o4 ! *IE_reg_addr &=~ bic;
- stb %o4, [%o3 + %lo(IE_reg_addr)]
+ sethi %hi(INTRREG_VA), %o3
+ ldub [%o3 + %lo(INTRREG_VA)], %o4
+ andn %o4, %o0, %o4 ! *INTRREG_VA &=~ bic;
+ stb %o4, [%o3 + %lo(INTRREG_VA)]
wr %o2, 0, %psr ! reenable traps
nop
retl
@@ -5504,6 +5511,84 @@ ENTRY(raise)
retl
st %o2, [%o1]
+
+/*
+ * Read Fault Status registers.
+ * On entry: %l1 == PC, %l3 == fault type
+ * On exit: %o1 == sync fault status, %o2 == sync fault address
+ * %o3 == async fault status, %o4 == async fault address
+ */
+ALTENTRY(srmmu_get_fltstatus)
+ set SRMMU_SFADDR, %o2
+ lda [%o2] ASI_SRMMU, %o2 ! sync virt addr; must be read first
+ set SRMMU_SFSTAT, %o1
+ lda [%o1] ASI_SRMMU, %o1 ! get sync fault status register
+
+ clr %o3 ! clear %o3 and %o4
+ retl
+ clr %o4
+
+ALTENTRY(viking_get_fltstatus)
+ cmp %l3, T_TEXTFAULT
+ be,a 1f
+ mov %l1, %o2 ! use PC if type == T_TEXTFAULT
+
+ set SRMMU_SFADDR, %o2
+ lda [%o2] ASI_SRMMU, %o2 ! sync virt addr; must be read first
+1:
+ set SRMMU_SFSTAT, %o1
+ lda [%o1] ASI_SRMMU, %o1 ! get sync fault status register
+
+ clr %o3 ! clear %o3 and %o4
+ retl
+ clr %o4
+
+ALTENTRY(ms1_get_fltstatus)
+ALTENTRY(swift_get_fltstatus)
+ALTENTRY(turbosparc_get_fltstatus)
+ cmp %l3, T_TEXTFAULT
+ be,a 1f
+ mov %l1, %o2 ! use PC if type == T_TEXTFAULT
+
+ set SRMMU_SFADDR, %o2
+ lda [%o2] ASI_SRMMU, %o2 ! sync virt addr; must be read first
+1:
+ set SRMMU_SFSTAT, %o1
+ lda [%o1] ASI_SRMMU, %o1 ! get sync fault status register
+
+ clr %o3 ! clear %o3 and %o4
+ retl
+ clr %o4
+
+ALTENTRY(cypress_get_fltstatus)
+ cmp %l3, T_TEXTFAULT
+ be,a 1f
+ mov %l1, %o2 ! use PC if type == T_TEXTFAULT
+
+ set SRMMU_SFADDR, %o2
+ lda [%o2] ASI_SRMMU, %o2 ! sync virt addr; must be read first
+1:
+ set SRMMU_SFSTAT, %o1
+ lda [%o1] ASI_SRMMU, %o1 ! get sync fault status register
+
+ set SRMMU_AFSTAT, %o3 ! must read status before fault on HS
+ lda [%o3] ASI_SRMMU, %o3 ! get async fault status
+ set SRMMU_AFADDR, %o4
+ retl
+ lda [%o4] ASI_SRMMU, %o4 ! get async fault address
+
+ALTENTRY(hypersparc_get_fltstatus)
+ set SRMMU_SFADDR, %o2
+ lda [%o2] ASI_SRMMU, %o2 ! sync virt addr; must be read first
+ set SRMMU_SFSTAT, %o1
+ lda [%o1] ASI_SRMMU, %o1 ! get sync fault status register
+
+ set SRMMU_AFSTAT, %o3 ! must read status before fault on HS
+ lda [%o3] ASI_SRMMU, %o3 ! get async fault status
+ set SRMMU_AFADDR, %o4
+ retl
+ lda [%o4] ASI_SRMMU, %o4 ! get async fault address
+
#endif /* SUN4M */
/*
@@ -5644,26 +5729,23 @@ ENTRY(lo_microtime)
ENTRY(microtime)
#endif
sethi %hi(_time), %g2
- sethi %hi(TIMERREG_VA), %g3
-/* blech, sun4m has microsecond counter at a different location */
-#if (defined(SUN4) || defined(SUN4C)) && !defined(SUN4M)
-#define r_aardvark %lo(TIMERREG_VA)
-#elif !(defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
-#define r_aardvark %lo(TIMERREG_VA) + 4
+#if defined(SUN4M) && !(defined(SUN4C) || defined(SUN4))
+ sethi %hi(TIMERREG_VA+4), %g3
+ or %g3, %lo(TIMERREG_VA+4), %g3
+#elif (defined(SUN4C) || defined(SUN4)) && !defined(SUN4M)
+ sethi %hi(TIMERREG_VA), %g3
+ or %g3, %lo(TIMERREG_VA), %g3
#else
- sethi %hi(_cputyp), %g4
- ld [%g4 + %lo(_cputyp)], %g4
+ sethi %hi(TIMERREG_VA), %g3
or %g3, %lo(TIMERREG_VA), %g3
- cmp %g4, CPU_SUN4M
- be,a 1f
+NOP_ON_4_4C_1:
add %g3, 4, %g3
-1:
-#define r_aardvark 0
#endif
+
2:
ldd [%g2+%lo(_time)], %o2 ! time.tv_sec & time.tv_usec
- ld [%g3+r_aardvark], %o4 ! usec counter
+ ld [%g3], %o4 ! usec counter
ldd [%g2+%lo(_time)], %g4 ! see if time values changed
cmp %g4, %o2
bne 2b ! if time.tv_sec changed
diff --git a/sys/arch/sparc/sparc/locore2.c b/sys/arch/sparc/sparc/locore2.c
index 7e28fb8f265..75299008f41 100644
--- a/sys/arch/sparc/sparc/locore2.c
+++ b/sys/arch/sparc/sparc/locore2.c
@@ -1,4 +1,5 @@
-/* $NetBSD: locore2.c,v 1.6 1996/03/14 21:09:15 christos Exp $ */
+/* $OpenBSD: locore2.c,v 1.4 1997/08/08 08:27:29 downsj Exp $ */
+/* $NetBSD: locore2.c,v 1.7 1996/11/06 20:19:53 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c
index cb2d1b8f5e8..02fb423eec4 100644
--- a/sys/arch/sparc/sparc/machdep.c
+++ b/sys/arch/sparc/sparc/machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: machdep.c,v 1.26 1997/07/01 21:32:02 grr Exp $ */
-/* $NetBSD: machdep.c,v 1.64 1996/05/19 04:12:56 mrg Exp $ */
+/* $OpenBSD: machdep.c,v 1.27 1997/08/08 08:27:30 downsj Exp $ */
+/* $NetBSD: machdep.c,v 1.83 1997/07/29 10:04:44 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -280,6 +280,14 @@ cpu_startup()
configure();
/*
+ * Re-zero proc0's user area, to nullify the effect of the
+ * stack running into it during auto-configuration.
+ * XXX - should fix stack usage.
+ * XXX - there's a race here, as interrupts are enabled
+ */
+ bzero(proc0paddr, sizeof(struct user));
+
+ /*
* fix message buffer mapping, note phys addr of msgbuf is 0
*/
@@ -384,6 +392,9 @@ setregs(p, pack, stack, retval)
register struct fpstate *fs;
register int psr;
+ /* Don't allow misaligned code by default */
+ p->p_md.md_flags &= ~MDP_FIXALIGN;
+
/*
* The syscall will ``return'' to npc or %g7 or %g2; set them all.
* Set the rest of the registers to 0 except for %o6 (stack pointer,
@@ -662,13 +673,11 @@ boot(howto)
fb_unblank();
boothowto = howto;
if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
-#if 1
extern struct proc proc0;
- /* protect against curproc->p_stats.foo refs in sync() XXX */
+ /* XXX protect against curproc->p_stats.foo refs in sync() */
if (curproc == NULL)
curproc = &proc0;
-#endif
waittime = 0;
vfs_shutdown();
@@ -732,7 +741,7 @@ dumpconf()
/* No usable dump device */
return;
- nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
+ nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
dumpblks = ctod(physmem) + ctod(pmap_dumpsize());
if (dumpblks > (nblks - ctod(1)))
@@ -746,7 +755,7 @@ dumpconf()
/* Put the dump at the end of the partition */
dumplo = nblks - dumpblks;
- /*
+ /*
* savecore(8) expects dumpsize to be the number of pages
* of actual core dumped (i.e. excluding the MMU stuff).
*/
@@ -799,7 +808,7 @@ dumpsys()
if (dumplo <= 0)
return;
printf("\ndumping to dev(%d,%d), at offset %ld blocks\n",
- major(dumpdev), minor(dumpdev), dumplo);
+ major(dumpdev), minor(dumpdev), dumplo);
psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
printf("dump ");
@@ -891,7 +900,7 @@ stackdump()
printf("Frame pointer is at %p\n", fp);
printf("Call traceback:\n");
while (fp && ((u_long)fp >> PGSHIFT) == ((u_long)sfp >> PGSHIFT)) {
- printf(" pc = %x args = (%x, %x, %x, %x, %x, %x, %x) fp = %p\n",
+ printf(" pc = 0x%x args = (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp = %p\n",
fp->fr_pc, fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2],
fp->fr_arg[3], fp->fr_arg[4], fp->fr_arg[5], fp->fr_arg[6],
fp->fr_fp);
@@ -899,27 +908,18 @@ stackdump()
}
}
-int bt2pmt[] = {
- PMAP_OBIO,
- PMAP_OBIO,
- PMAP_VME16,
- PMAP_VME32,
- PMAP_OBIO
-};
-
/*
* Map an I/O device given physical address and size in bytes, e.g.,
*
* mydev = (struct mydev *)mapdev(myioaddr, 0,
- * 0, sizeof(struct mydev), pmtype);
+ * 0, sizeof(struct mydev));
*
* See also machine/autoconf.h.
*/
void *
-mapdev(phys, virt, offset, size, bustype)
+mapdev(phys, virt, offset, size)
register struct rom_reg *phys;
register int offset, virt, size;
- register int bustype;
{
register vm_offset_t v;
register vm_offset_t pa;
@@ -945,9 +945,7 @@ mapdev(phys, virt, offset, size, bustype)
/* note: preserve page offset */
pa = trunc_page(phys->rr_paddr + offset);
- pmtype = (CPU_ISSUN4M)
- ? (phys->rr_iospace << PMAP_SHFT4M)
- : bt2pmt[bustype];
+ pmtype = PMAP_IOENC(phys->rr_iospace);
do {
pmap_enter(pmap_kernel(), v, pa | pmtype | PMAP_NC,
@@ -993,12 +991,12 @@ oldmon_w_trace(va)
#define round_up(x) (( (x) + (NBPG-1) ) & (~(NBPG-1)) )
- printf("\nstack trace with sp = %lx\n", va);
+ printf("\nstack trace with sp = 0x%lx\n", va);
stop = round_up(va);
- printf("stop at %lx\n", stop);
+ printf("stop at 0x%lx\n", stop);
fp = (struct frame *) va;
while (round_up((u_long) fp) == stop) {
- printf(" %x(%x, %x, %x, %x, %x, %x, %x) fp %p\n", fp->fr_pc,
+ printf(" 0x%x(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) fp %p\n", fp->fr_pc,
fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3],
fp->fr_arg[4], fp->fr_arg[5], fp->fr_arg[6], fp->fr_fp);
fp = fp->fr_fp;
diff --git a/sys/arch/sparc/sparc/mem.c b/sys/arch/sparc/sparc/mem.c
index ff531dca56f..cd594c505a2 100644
--- a/sys/arch/sparc/sparc/mem.c
+++ b/sys/arch/sparc/sparc/mem.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: mem.c,v 1.3 1997/08/08 08:27:31 downsj Exp $ */
/* $NetBSD: mem.c,v 1.13 1996/03/30 21:12:16 christos Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/memreg.c b/sys/arch/sparc/sparc/memreg.c
index a2b5bf67ddc..26974d3dcb7 100644
--- a/sys/arch/sparc/sparc/memreg.c
+++ b/sys/arch/sparc/sparc/memreg.c
@@ -1,4 +1,5 @@
-/* $NetBSD: memreg.c,v 1.13 1996/03/31 22:52:08 pk Exp $ */
+/* $OpenBSD: memreg.c,v 1.5 1997/08/08 08:27:32 downsj Exp $ */
+/* $NetBSD: memreg.c,v 1.21 1997/07/29 09:42:08 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -56,6 +57,7 @@
#include <sparc/sparc/memreg.h>
#include <sparc/sparc/vaddrs.h>
#include <sparc/sparc/asm.h>
+#include <sparc/sparc/cpuvar.h>
#include <machine/reg.h> /* for trapframe */
#include <machine/trap.h> /* for trap types */
@@ -82,9 +84,9 @@ static void hardmemerr4m __P((int, u_int, u_int));
static int
memregmatch(parent, vcf, aux)
struct device *parent;
- void *aux, *vcf;
+ void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf;
register struct confargs *ca = aux;
if (CPU_ISSUN4) {
@@ -111,8 +113,7 @@ memregattach(parent, self, aux)
ra->ra_vaddr = (caddr_t)par_err_reg;
} else {
par_err_reg = ra->ra_vaddr ? (volatile u_int *)ra->ra_vaddr :
- (volatile u_int *)mapiodev(ra->ra_reg, 0, sizeof(int),
- ca->ca_bustype);
+ (volatile u_int *)mapiodev(ra->ra_reg, 0, sizeof(int));
}
printf("\n");
}
@@ -129,13 +130,13 @@ memerr(issync, ser, sva, aer, ava)
int issync;
u_int ser, sva, aer, ava;
{
-
/* XXX Ugh! Clean up this switch and all the ifdefs! */
switch (cputyp) {
#if defined(SUN4)
case CPU_SUN4:
if (par_err_reg) {
- printf("mem err: ser=%b sva=%x\n", ser, SER_BITS, sva);
+ printf("mem err: ser=%b sva=0x%x\n",
+ ser, SER_BITS, sva);
printf("parity error register = %b\n",
*par_err_reg, PER_BITS);
} else {
@@ -152,12 +153,12 @@ memerr(issync, ser, sva, aer, ava)
#if defined(SUN4C)
case CPU_SUN4C:
- printf("%ssync mem err: ser=%b sva=%x aer=%b ava=%x\n",
- issync ? "" : "a", ser, SER_BITS,
- sva, aer & 0xff, AER_BITS, ava);
+ printf("%ssync mem arr: ser=%b sva=0x%x ",
+ issync ? "" : "a", ser, SER_BITS, sva);
+ printf("aer=%b ava=0x%x\n", aer & 0xff, AER_BITS, ava);
if (par_err_reg)
printf("parity error register = %b\n",
- *par_err_reg, PER_BITS);
+ *par_err_reg, PER_BITS);
#ifdef DEBUG
callrom();
#else
@@ -196,22 +197,24 @@ hardmemerr4m(issync, fsr, faddr)
case 1:
if ((fsr & SFSR_FT) == SFSR_FT_NONE)
return;
- panic("mem err: sfsr=%b sfaddr=%x", fsr, SFSR_BITS, faddr);
+ printf("mem err: sfsr=%b sfaddr=0x%x\n", fsr, SFSR_BITS, faddr);
break;
case 0:
if (!(fsr & AFSR_AFO))
return;
- panic("async (HS) mem err: afsr=%b afaddr=%x physaddr=%x%x",
+ printf("async (HS) mem err: afsr=%b afaddr=0x%x physaddr=0x%x%x\n",
fsr, AFSR_BITS, faddr,
(fsr & AFSR_AFA) >> AFSR_AFA_RSHIFT, faddr);
break;
default: /* unknown; print both decodings*/
- panic("Unknown mem err: if sync, fsr=%b fva=%x; if async, fsr"
- "=%b fa=%x pa=%x%x", fsr, SFSR_BITS, faddr, fsr,
- AFSR_BITS, faddr, (fsr & AFSR_AFA) >> AFSR_AFA_RSHIFT,
- faddr);
+ printf("unknown mem err: if sync, fsr=%b fva=0x%x; ",
+ fsr, SFSR_BITS, faddr);
+ printf("if async, fsr=%b fa=0x%x pa=0x%x%x", fsr,
+ AFSR_BITS, faddr, (fsr & AFSR_AFA) >> AFSR_AFA_RSHIFT,
+ faddr);
break;
}
+ panic("hard memory error");
}
/*
@@ -248,9 +251,12 @@ memerr4m(type, sfsr, sfva, afsr, afva, tf)
addrold = afva;
addroldtop = afsr & AFSR_AFA;
- } else if (type == T_STOREBUFFAULT) {
- /* We try to reenable the store buffers to force a retry */
+ } else if (type == T_STOREBUFFAULT && cpuinfo.cpu_vers == 4) {
+ /*
+ * On Supersparc, we try to reenable the store buffers
+ * to force a retry.
+ */
printf("store buffer copy-back failure at 0x%x. Retrying...\n",
sfva);
@@ -261,8 +267,9 @@ memerr4m(type, sfsr, sfva, afsr, afva, tf)
oldtype = T_STOREBUFFAULT;
addrold = sfva;
- sta(SRMMU_PCR, ASI_SRMMU, lda(SRMMU_PCR, ASI_SRMMU) |
- SRMMU_PCR_SB); /* reenable store buffer */
+ /* reenable store buffer */
+ sta(SRMMU_PCR, ASI_SRMMU,
+ lda(SRMMU_PCR, ASI_SRMMU) | VIKING_PCR_SB);
} else if (type == T_DATAFAULT && !(sfsr & SFSR_FAV)) { /* bizarre */
/* XXX: Should handle better. See SuperSPARC manual pg. 9-35 */
@@ -276,9 +283,10 @@ memerr4m(type, sfsr, sfva, afsr, afva, tf)
oldtype = T_DATAFAULT;
} else if (type == 0) { /* NMI */
- printf("ERROR: got NMI with sfsr=0x%b, sfva=0x%x, afsr=0x%b, "
- "afaddr=0x%x. Retrying...\n",
- sfsr,SFSR_BITS,sfva,afsr, AFSR_BITS,afva);
+ printf("ERROR: got NMI with sfsr=0x%b, sfva=0x%x, ",
+ sfsr, SFSR_BITS, sfva);
+ printf("afsr=0x%b, afaddr=0x%x. Retrying...\n",
+ afsr, AFSR_BITS, afva);
if (oldtype == 0 || addrold == sfva)
hardmemerr4m(1, sfsr, sfva); /* XXX: async? */
/* NOTREACHED */
@@ -286,9 +294,10 @@ memerr4m(type, sfsr, sfva, afsr, afva, tf)
oldtype = 0;
addrold = sfva;
} else /* something we don't know about?!? */ {
- panic("memerr4m: unknown fatal memory error. type=%d, sfsr=%b,"
- " sfva=%x, afsr=%b, afaddr=%x",
- type, sfsr, SFSR_BITS, sfva, afsr, AFSR_BITS, afva);
+ printf("unknown fatal memory error, type=%d, sfsr=%b, sfva=0x%x",
+ type, sfsr, SFSR_BITS, sfva);
+ printf(", afsr=%b, afaddr=0x%x\n", afsr, AFSR_BITS, afva);
+ panic("memerr4m");
}
return;
diff --git a/sys/arch/sparc/sparc/memreg.h b/sys/arch/sparc/sparc/memreg.h
index be25a8f76c0..f27a5197621 100644
--- a/sys/arch/sparc/sparc/memreg.h
+++ b/sys/arch/sparc/sparc/memreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: memreg.h,v 1.3 1997/08/08 08:27:33 downsj Exp $ */
/* $NetBSD: memreg.h,v 1.4 1996/03/31 22:52:13 pk Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/openprom.c b/sys/arch/sparc/sparc/openprom.c
index 15c9ac1293f..ed362afe3cd 100644
--- a/sys/arch/sparc/sparc/openprom.c
+++ b/sys/arch/sparc/sparc/openprom.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: openprom.c,v 1.3 1997/08/08 08:27:34 downsj Exp $ */
/* $NetBSD: openprom.c,v 1.8 1996/03/31 23:45:34 pk Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/pmap.c b/sys/arch/sparc/sparc/pmap.c
index 9aca4e3a4b5..789619a78bc 100644
--- a/sys/arch/sparc/sparc/pmap.c
+++ b/sys/arch/sparc/sparc/pmap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pmap.c,v 1.16 1997/07/07 07:45:32 grr Exp $ */
-/* $NetBSD: pmap.c,v 1.60.4.1 1996/06/12 20:36:30 pk Exp $ */
+/* $OpenBSD: pmap.c,v 1.17 1997/08/08 08:27:36 downsj Exp $ */
+/* $NetBSD: pmap.c,v 1.91 1997/07/29 09:42:11 fair Exp $ */
/*
* Copyright (c) 1996
@@ -63,14 +63,15 @@
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/malloc.h>
-#include <sys/kcore.h>
+#include <sys/exec.h>
#include <sys/core.h>
-#include <sys/exec_aout.h>
+#include <sys/kcore.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
+#include <vm/lock.h>
#include <machine/autoconf.h>
#include <machine/bsd_openprom.h>
@@ -82,6 +83,7 @@
#include <sparc/sparc/asm.h>
#include <sparc/sparc/cache.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#ifdef DEBUG
#define PTE_BITS "\20\40V\37W\36S\35NC\33IO\32U\31M"
@@ -132,6 +134,9 @@ struct pmap_stats {
int ps_useless_changewire; /* useless wiring changes */
int ps_npg_prot_all; /* # of active pages protected */
int ps_npg_prot_actual; /* # pages actually affected */
+ int ps_npmeg_free; /* # of free pmegs */
+ int ps_npmeg_locked; /* # of pmegs on locked list */
+ int ps_npmeg_lru; /* # of pmegs on lru list */
} pmap_stats;
#ifdef DEBUG
@@ -140,6 +145,7 @@ struct pmap_stats {
#define PDB_REMOVE 0x0004
#define PDB_CHANGEPROT 0x0008
#define PDB_ENTER 0x0010
+#define PDB_FOLLOW 0x0020
#define PDB_MMU_ALLOC 0x0100
#define PDB_MMU_STEAL 0x0200
@@ -148,6 +154,8 @@ struct pmap_stats {
#define PDB_MMUREG_ALLOC 0x1000
#define PDB_MMUREG_STEAL 0x2000
#define PDB_CACHESTUFF 0x4000
+#define PDB_SWITCHMAP 0x8000
+#define PDB_SANITYCHK 0x10000
int pmapdebug = 0;
#endif
@@ -175,10 +183,10 @@ vm_offset_t vm_first_phys, vm_num_phys;
* THIS SHOULD BE PART OF THE CORE MAP
*/
struct pvlist {
- struct pvlist *pv_next; /* next pvlist, if any */
- struct pmap *pv_pmap; /* pmap of this va */
- vm_offset_t pv_va; /* virtual address */
- int pv_flags; /* flags (below) */
+ struct pvlist *pv_next; /* next pvlist, if any */
+ struct pmap *pv_pmap; /* pmap of this va */
+ vm_offset_t pv_va; /* virtual address */
+ int pv_flags; /* flags (below) */
};
/*
@@ -249,6 +257,13 @@ struct pvlist *pv_table; /* array of entries, one per physical page */
* If a virtual segment is valid, its entries will be in both parallel lists.
* If it is not valid, then its entry in the kernel tables will be zero, and
* its entry in the MMU tables will either be nonexistent or zero as well.
+ *
+ * The Reference MMU generally uses a Translation Look-aside Buffer (TLB)
+ * to cache the result of recently executed page table walks. When
+ * manipulating page tables, we need to ensure consistency of the
+ * in-memory and TLB copies of the page table entries. This is handled
+ * by flushing (and invalidating) a TLB entry when appropriate before
+ * altering an in-memory page table entry.
*/
struct mmuentry {
TAILQ_ENTRY(mmuentry) me_list; /* usage list link */
@@ -264,10 +279,8 @@ struct mmuentry *mmuregions; /* allocated in pmap_bootstrap */
struct mmuhd segm_freelist, segm_lru, segm_locked;
struct mmuhd region_freelist, region_lru, region_locked;
-int seginval; /* the invalid segment number */
-#ifdef MMU_3L
-int reginval; /* the invalid region number */
-#endif
+int seginval; /* [4/4c] the invalid segment number */
+int reginval; /* [4/3mmu] the invalid region number */
/*
* (sun4/4c)
@@ -290,36 +303,39 @@ union ctxinfo {
union ctxinfo *c_nextfree; /* free list (if free) */
struct pmap *c_pmap; /* pmap (if busy) */
};
+
+#define ncontext (cpuinfo.mmu_ncontext)
+#define ctx_kick (cpuinfo.ctx_kick)
+#define ctx_kickdir (cpuinfo.ctx_kickdir)
+#define ctx_freelist (cpuinfo.ctx_freelist)
+
+#if 0
union ctxinfo *ctxinfo; /* allocated at in pmap_bootstrap */
-int ncontext;
union ctxinfo *ctx_freelist; /* context free list */
int ctx_kick; /* allocation rover when none free */
int ctx_kickdir; /* ctx_kick roves both directions */
-char *ctxbusyvector; /* [4m] tells what contexts are busy */
-int *ctx_phys_tbl; /* [4m] SRMMU-edible context table */
+char *ctxbusyvector; /* [4m] tells what contexts are busy (XXX)*/
+#endif
caddr_t vpage[2]; /* two reserved MD virtual pages */
caddr_t vmmap; /* one reserved MI vpage for /dev/mem */
caddr_t vdumppages; /* 32KB worth of reserved dump pages */
-#ifdef MMU_3L
-smeg_t tregion;
-#endif
+smeg_t tregion; /* [4/3mmu] Region for temporary mappings */
+
struct pmap kernel_pmap_store; /* the kernel's pmap */
struct regmap kernel_regmap_store[NKREG]; /* the kernel's regmap */
struct segmap kernel_segmap_store[NKREG*NSEGRG];/* the kernel's segmaps */
-#ifdef SUN4M
+#if defined(SUN4M)
u_int *kernel_regtable_store; /* 1k of storage to map the kernel */
u_int *kernel_segtable_store; /* 2k of storage to map the kernel */
u_int *kernel_pagtable_store; /* 128k of storage to map the kernel */
u_int *kernel_iopte_table; /* 64k of storage for iommu */
u_int kernel_iopte_table_pa;
-
-static int cant_cache_pagetables = 0; /* 1 if page tables are uncachable */
#endif
#define MA_SIZE 32 /* size of memory descriptor arrays */
@@ -330,18 +346,10 @@ int cpmemarr; /* pmap_next_page() state */
/*static*/ vm_offset_t avail_end; /* last free physical page */
/*static*/ vm_offset_t avail_next; /* pmap_next_page() state:
next free physical page */
+/*static*/ vm_offset_t unavail_start; /* first stolen free physical page */
+/*static*/ vm_offset_t unavail_end; /* last stolen free physical page */
/*static*/ vm_offset_t virtual_avail; /* first free virtual page number */
/*static*/ vm_offset_t virtual_end; /* last free virtual page number */
-#ifdef SUN4M
-#if 0 /* not needed anymore */
-static void * pmap_bootstrap_malloc __P((unsigned long, int, int));
-
-caddr_t minipool_start;
-caddr_t minipool_current;
-#define MINIPOOL_SIZE 8192 /* number of bytes to reserve for early malloc */
- /* (must be multiple of pagesize) */
-#endif
-#endif
int mmu_has_hole;
@@ -373,12 +381,17 @@ static u_long segfixmask = 0xffffffff; /* all bits valid to start */
/*
* pseudo-functions for mnemonic value
*/
+#define getcontext4() lduba(AC_CONTEXT, ASI_CONTROL)
+#define getcontext4m() lda(SRMMU_CXR, ASI_SRMMU)
#define getcontext() (CPU_ISSUN4M \
- ? lda(SRMMU_CXR, ASI_SRMMU) \
- : lduba(AC_CONTEXT, ASI_CONTROL))
+ ? getcontext4m() \
+ : getcontext4() )
+
+#define setcontext4(c) stba(AC_CONTEXT, ASI_CONTROL, c)
+#define setcontext4m(c) sta(SRMMU_CXR, ASI_SRMMU, c)
#define setcontext(c) (CPU_ISSUN4M \
- ? sta(SRMMU_CXR, ASI_SRMMU, c) \
- : stba(AC_CONTEXT, ASI_CONTROL, c))
+ ? setcontext4m(c) \
+ : setcontext4(c) )
#define getsegmap(va) (CPU_ISSUN4C \
? lduba(va, ASI_SEGMAP) \
@@ -394,6 +407,7 @@ static u_long segfixmask = 0xffffffff; /* all bits valid to start */
#if defined(SUN4M)
#define getpte4m(va) lda((va & 0xFFFFF000) | ASI_SRMMUFP_L3, \
ASI_SRMMUFP)
+void setpgt4m __P((int *ptep, int pte));
void setpte4m __P((vm_offset_t va, int pte));
void setptesw4m __P((struct pmap *pm, vm_offset_t va, int pte));
u_int getptesw4m __P((struct pmap *pm, vm_offset_t va));
@@ -418,11 +432,10 @@ u_int getptesw4m __P((struct pmap *pm, vm_offset_t va));
*/
#if defined(SUN4M)
-static void mmu_setup4m_L1 __P((int, caddr_t, struct pmap *, caddr_t *));
-static void mmu_setup4m_L2 __P((int, caddr_t, struct regmap *, caddr_t *,
- struct segmap *));
-static int mmu_setup4m_L3 __P((int, caddr_t));
-/*static*/ void mmu_reservemon4m __P((struct pmap *, caddr_t *));
+static void mmu_setup4m_L1 __P((int, struct pmap *));
+static void mmu_setup4m_L2 __P((int, struct regmap *));
+static void mmu_setup4m_L3 __P((int, struct segmap *));
+/*static*/ void mmu_reservemon4m __P((struct pmap *));
/*static*/ void pmap_rmk4m __P((struct pmap *, vm_offset_t, vm_offset_t,
int, int));
@@ -585,6 +598,16 @@ getptesw4m(pm, va) /* Assumes L3 mapping! */
return (sm->sg_pte[VA_SUN4M_VPG(va)]); /* return pte */
}
+__inline void
+setpgt4m(ptep, pte)
+ int *ptep;
+ int pte;
+{
+ *ptep = pte;
+ if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0)
+ cpuinfo.pcache_flush_line((int)ptep, VA2PA((caddr_t)ptep));
+}
+
/*
* Set the page table entry for va to pte. Only affects software MMU page-
* tables (the in-core pagetables read by the MMU). Ignores TLB, and
@@ -604,15 +627,15 @@ setptesw4m(pm, va, pte)
#ifdef DEBUG
if (pm->pm_regmap == NULL || rm == NULL)
- panic("setpte4m: no regmap entry");
+ panic("setptesw4m: no regmap entry");
#endif
sm = &rm->rg_segmap[VA_VSEG(va)];
#ifdef DEBUG
if (rm->rg_segmap == NULL || sm == NULL || sm->sg_pte == NULL)
- panic("setpte4m: no segmap for va %p", (caddr_t)va);
+ panic("setptesw4m: no segmap for va %p", (caddr_t)va);
#endif
- sm->sg_pte[VA_SUN4M_VPG(va)] = pte; /* set new pte */
+ setpgt4m(sm->sg_pte + VA_SUN4M_VPG(va), pte);
}
/* Set the page table entry for va to pte. Flushes cache. */
@@ -626,19 +649,20 @@ setpte4m(va, pte)
register struct segmap *sm;
register union ctxinfo *c;
- if (vactype != VAC_NONE)
- cache_flush_page(va);
+ cache_flush_page(va);
/*
* Now walk tables to find pte. We use ctxinfo to locate the pmap
* from the current context
*/
+#if 0
#ifdef DEBUG
- if (ctxbusyvector[getcontext()] == 0)
+ if (ctxbusyvector[getcontext4m()] == 0)
panic("setpte4m: no pmap for current context (%d)",
- getcontext());
+ getcontext4m());
#endif
- c = &ctxinfo[getcontext()];
+#endif
+ c = &cpuinfo.ctxinfo[getcontext4m()];
pm = c->c_pmap;
/* Note: inline version of setptesw4m() */
@@ -654,17 +678,21 @@ setpte4m(va, pte)
panic("setpte4m: no segmap for va %p", (caddr_t)va);
#endif
tlb_flush_page(va);
- sm->sg_pte[VA_SUN4M_VPG(va)] = pte; /* set new pte */
+ setpgt4m(sm->sg_pte + VA_SUN4M_VPG(va), pte);
}
+
#endif /* 4m only */
/*----------------------------------------------------------------*/
-#if defined(MMU_3L)
-#define CTX_USABLE(pm,rp) (CPU_ISSUN4M \
- ? ((pm)->pm_ctx != NULL ) \
- : ((pm)->pm_ctx != NULL && \
- (!mmu_3l || (rp)->rg_smeg != reginval)))
+/*
+ * The following three macros are to be used in sun4/sun4c code only.
+ */
+#if defined(SUN4_MMU3L)
+#define CTX_USABLE(pm,rp) ( \
+ ((pm)->pm_ctx != NULL && \
+ (!HASSUN4_MMU3L || (rp)->rg_smeg != reginval)) \
+)
#else
#define CTX_USABLE(pm,rp) ((pm)->pm_ctx != NULL )
#endif
@@ -688,6 +716,7 @@ setpte4m(va, pte)
} \
} while (0)
+
static void sortm __P((struct memarr *, int));
void ctx_alloc __P((struct pmap *));
void ctx_free __P((struct pmap *));
@@ -789,7 +818,8 @@ pmap_next_page(paddr)
if (++cpmemarr == npmemarr)
return FALSE;
avail_next = pmemarr[cpmemarr].addr;
- }
+ } else if (avail_next == unavail_start)
+ avail_next = unavail_end;
#ifdef DIAGNOSTIC
/* Any available memory remaining? */
@@ -872,16 +902,16 @@ void
mmu_reservemon4_4c(nrp, nsp)
register int *nrp, *nsp;
{
- register vm_offset_t va = 0, eva = 0;
+ register u_int va = 0, eva = 0;
register int mmuseg, i, nr, ns, vr, lastvr;
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
register int mmureg;
#endif
register struct regmap *rp;
#if defined(SUN4M)
if (CPU_ISSUN4M) {
- panic("mmu_reservemon called on Sun4M machine");
+ panic("mmu_reservemon4_4c called on Sun4M machine");
return;
}
#endif
@@ -905,8 +935,8 @@ mmu_reservemon4_4c(nrp, nsp)
vr = VA_VREG(va);
rp = &pmap_kernel()->pm_regmap[vr];
-#ifdef MMU_3L
- if (mmu_3l && vr != lastvr) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && vr != lastvr) {
lastvr = vr;
mmureg = getregmap(va);
if (mmureg < nr)
@@ -922,9 +952,8 @@ mmu_reservemon4_4c(nrp, nsp)
mmuseg = getsegmap(va);
if (mmuseg < ns)
ns = mmuseg;
-#ifdef MMU_3L
- if (!mmu_3l)
-#endif
+
+ if (!HASSUN4_MMU3L)
for (i = ncontext; --i > 0;)
(*promvec->pv_setctxt)(i, (caddr_t)va, mmuseg);
@@ -963,24 +992,20 @@ mmu_reservemon4_4c(nrp, nsp)
/*
* mmu_reservemon4m(): Copies the existing (ROM) page tables to kernel space,
* converting any L1/L2 PTEs to L3 PTEs. Does *not* copy the L1 entry mapping
- * the kernel at 0xf8000000 (KERNBASE) since we don't want to map 16M of
+ * the kernel at KERNBASE (0xf8000000) since we don't want to map 16M of
* physical memory for the kernel. Thus the kernel must be installed later!
* Also installs ROM mappings into the kernel pmap.
* NOTE: This also revokes all user-mode access to the mapped regions.
- * NOTE ALSO: Must set up kernel pmap as all invalid before this is called.
*/
void
-mmu_reservemon4m(kpmap, kmemtop)
+mmu_reservemon4m(kpmap)
struct pmap *kpmap;
- register caddr_t *kmemtop; /* Note: this is a *virtual* address! */
{
- unsigned int ctxtblptr;
- int wierdviking = 0;
+ unsigned int rom_ctxtbl;
register int te;
- register caddr_t tableptr;
- unsigned int mmupcrsav;
+ unsigned int mmupcrsave;
-/*XXX-GCC!*/mmupcrsav = 0;
+/*XXX-GCC!*/mmupcrsave = 0;
/*
* XXX: although the Sun4M can handle 36 bits of physical
@@ -993,36 +1018,24 @@ mmu_reservemon4m(kpmap, kmemtop)
* physical memory.
*/
- ctxtblptr = (lda(SRMMU_CXTPTR,ASI_SRMMU) << SRMMU_PPNPASHIFT);
+ rom_ctxtbl = (lda(SRMMU_CXTPTR,ASI_SRMMU) << SRMMU_PPNPASHIFT);
/* We're going to have to use MMU passthrough. If we're on a
* Viking MicroSparc without an mbus, we need to turn off traps
* and set the AC bit at 0x8000 in the MMU's control register. Ugh.
* XXX: Once we've done this, can we still access kernel vm?
*/
- if ((getpsr() & 0x40000000) && (!(lda(SRMMU_PCR,ASI_SRMMU) & 0x800))) {
- wierdviking = 1;
+ if (cpuinfo.cpu_vers == 4 && cpuinfo.mxcc) {
sta(SRMMU_PCR, ASI_SRMMU, /* set MMU AC bit */
- ((mmupcrsav = lda(SRMMU_PCR,ASI_SRMMU)) | SRMMU_PCR_AC));
- }
- if (ncontext < 1024) {
- /* to keep supersparc happy, still align on 4K boundary */
- ctx_phys_tbl = (int *)roundup((u_int) *kmemtop, 4096);
- *kmemtop = (caddr_t)((u_int)ctx_phys_tbl + 4096);
- qzero(ctx_phys_tbl, 4096);
- } else {
- ctx_phys_tbl = (int *)roundup((u_int) *kmemtop,
- ncontext * sizeof(int));
- *kmemtop = (caddr_t)((u_int)ctx_phys_tbl +
- (ncontext * sizeof(int)));
- qzero(ctx_phys_tbl, ncontext * sizeof(int));
+ ((mmupcrsave = lda(SRMMU_PCR,ASI_SRMMU)) | VIKING_PCR_AC));
}
- te = lda(ctxtblptr, ASI_BYPASS);
+ te = lda(rom_ctxtbl, ASI_BYPASS); /* i.e. context 0 */
switch (te & SRMMU_TETYPE) {
case SRMMU_TEINVALID:
- ctx_phys_tbl[0] = SRMMU_TEINVALID;
- panic("mmu_reservemon4m: no existing L0 mapping! (How are we running?");
+ cpuinfo.ctx_tbl[0] = SRMMU_TEINVALID;
+ panic("mmu_reservemon4m: no existing L0 mapping! "
+ "(How are we running?");
break;
case SRMMU_TEPTE:
#ifdef DEBUG
@@ -1032,93 +1045,68 @@ mmu_reservemon4m(kpmap, kmemtop)
/* XXX: Should make this work, however stupid it is */
break;
case SRMMU_TEPTD:
- tableptr = (caddr_t) roundup((u_int) *kmemtop,
- SRMMU_L1SIZE * sizeof(long));
- *kmemtop = tableptr + (SRMMU_L1SIZE * sizeof(long));
- bzero(tableptr, *kmemtop - tableptr);
- ctx_phys_tbl[0] = (VA2PA(tableptr) >> SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- kpmap->pm_reg_ptps = (int *)tableptr;
- kpmap->pm_reg_ptps_pa = VA2PA(tableptr);
- mmu_setup4m_L1(te, tableptr, kpmap, kmemtop);
+ mmu_setup4m_L1(te, kpmap);
break;
default:
panic("mmu_reservemon4m: unknown pagetable entry type");
}
- if (wierdviking == 1) {
- sta(SRMMU_PCR, ASI_SRMMU, mmupcrsav);
+ if (cpuinfo.cpu_vers == 4 && cpuinfo.mxcc) {
+ sta(SRMMU_PCR, ASI_SRMMU, mmupcrsave);
}
}
void
-mmu_setup4m_L1(regtblptd, newtableptr, kpmap, kmemtop)
+mmu_setup4m_L1(regtblptd, kpmap)
int regtblptd; /* PTD for region table to be remapped */
- caddr_t newtableptr; /* Virtual ptr to new region table */
struct pmap *kpmap;
- register caddr_t *kmemtop;
{
register unsigned int regtblrover;
register int i;
unsigned int te;
- caddr_t segtblptr;
- register caddr_t pagtblptr;
- struct regmap *thisregmap = NULL;
- struct segmap *segmaps;
+ struct regmap *rp;
int j, k;
- /* Here we scan the region table to copy any entries which appear.
+ /*
+ * Here we scan the region table to copy any entries which appear.
* We are only concerned with regions in kernel space and above
* (i.e. regions 0xf8 to 0xff). We also ignore region 0xf8, since
* that is the 16MB L1 mapping that the ROM used to map the kernel
* in initially. Later, we will rebuild a new L3 mapping for the
* kernel and install it before switching to the new pagetables.
*/
- regtblrover = ((regtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT) +
- (VA_VREG(KERNBASE)+1) * sizeof(long); /* kernel only */
+ regtblrover =
+ ((regtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT) +
+ (VA_VREG(KERNBASE)+1) * sizeof(long); /* kernel only */
for (i = VA_VREG(KERNBASE) + 1; i < SRMMU_L1SIZE;
i++, regtblrover += sizeof(long)) {
+
+ /* The region we're dealing with */
+ rp = &kpmap->pm_regmap[i];
+
te = lda(regtblrover, ASI_BYPASS);
switch(te & SRMMU_TETYPE) {
case SRMMU_TEINVALID:
- ((int *)newtableptr)[i] = SRMMU_TEINVALID;
break;
+
case SRMMU_TEPTE:
#ifdef DEBUG
- printf("mmu_reservemon4m: converting region 0x%x from L1->L3\n",i);
+ printf("mmu_setup4m_L1: "
+ "converting region 0x%x from L1->L3\n", i);
#endif
- /* We must build segment and page tables, then
- * fill them in
+ /*
+ * This region entry covers 64MB of memory -- or
+ * (NSEGRG * NPTESG) pages -- which we must convert
+ * into a 3-level description.
*/
- thisregmap = &kpmap->pm_regmap[i];
- bzero(thisregmap, sizeof(struct regmap));
- segmaps = &kernel_segmap_store[(i-VA_VREG(KERNBASE))*NSEGRG];
- segtblptr = (caddr_t) roundup((u_int) *kmemtop,
- SRMMU_L2SIZE * sizeof(long));
- *kmemtop = segtblptr + (SRMMU_L2SIZE * sizeof(long));
- bzero(segtblptr, *kmemtop - segtblptr);
- bzero(segmaps, NSEGRG * sizeof(struct segmap));
- thisregmap->rg_segmap = segmaps;
- thisregmap->rg_seg_ptps = (int *)segtblptr;
- ((int *)newtableptr)[i] = (VA2PA(segtblptr) >>
- SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
+
for (j = 0; j < SRMMU_L2SIZE; j++) {
- thisregmap->rg_nsegmap++;
- pagtblptr = (caddr_t) roundup((u_int) *kmemtop,
- SRMMU_L3SIZE * sizeof(int));
- *kmemtop = segtblptr + (SRMMU_L3SIZE *
- sizeof(long));
- bzero(pagtblptr, *kmemtop - pagtblptr);
- ((int *)segtblptr)[j] = (VA2PA(pagtblptr) >>
- SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- segmaps[j].sg_pte = (int *)pagtblptr;
+ struct segmap *sp = &rp->rg_segmap[j];
for (k = 0; k < SRMMU_L3SIZE; k++) {
- segmaps[j].sg_npte++;
- ((int *)pagtblptr)[k] =
+ sp->sg_npte++;
+ (sp->sg_pte)[k] =
(te & SRMMU_L1PPNMASK) |
(j << SRMMU_L2PPNSHFT) |
(k << SRMMU_L3PPNSHFT) |
@@ -1129,22 +1117,11 @@ mmu_setup4m_L1(regtblptd, newtableptr, kpmap, kmemtop)
}
}
break;
+
case SRMMU_TEPTD:
- thisregmap = &kpmap->pm_regmap[i];
- bzero(thisregmap, sizeof(struct regmap));
- segtblptr = (caddr_t) roundup((u_int)*kmemtop,
- SRMMU_L2SIZE * sizeof(long));
- *kmemtop = segtblptr + (SRMMU_L2SIZE * sizeof(long));
- segmaps = &kernel_segmap_store[(i-(KERNBASE >> RGSHIFT))*NSEGRG];
- bzero(segtblptr, *kmemtop - segtblptr);
- bzero(segmaps, NSEGRG * sizeof(struct segmap));
- thisregmap->rg_segmap = segmaps;
- thisregmap->rg_seg_ptps = (int *)segtblptr;
- ((int *)newtableptr)[i] = (VA2PA(segtblptr) >>
- SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- mmu_setup4m_L2(te, segtblptr, thisregmap, kmemtop, segmaps);
+ mmu_setup4m_L2(te, rp);
break;
+
default:
panic("mmu_setup4m_L1: unknown pagetable entry type");
}
@@ -1152,45 +1129,37 @@ mmu_setup4m_L1(regtblptd, newtableptr, kpmap, kmemtop)
}
void
-mmu_setup4m_L2(segtblptd, newtableptr, pregmap, kmemtop, segmaps)
+mmu_setup4m_L2(segtblptd, rp)
int segtblptd;
- caddr_t newtableptr;
- struct regmap *pregmap;
- register caddr_t *kmemtop;
- struct segmap *segmaps;
+ struct regmap *rp;
{
register unsigned int segtblrover;
register int i, k;
unsigned int te;
- register caddr_t pagtblptr;
- struct segmap *thissegmap = NULL;
+ struct segmap *sp;
segtblrover = (segtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT;
for (i = 0; i < SRMMU_L2SIZE; i++, segtblrover += sizeof(long)) {
+
+ sp = &rp->rg_segmap[i];
+
te = lda(segtblrover, ASI_BYPASS);
switch(te & SRMMU_TETYPE) {
case SRMMU_TEINVALID:
- ((int *)newtableptr)[i] = SRMMU_TEINVALID;
break;
+
case SRMMU_TEPTE:
#ifdef DEBUG
- printf("mmu_reservemon4m: converting L2 entry at segment 0x%x to L3\n",i);
-#endif
- pregmap->rg_nsegmap++;
- /* We must build page tables and fill them in */
- pagtblptr = (caddr_t) roundup((u_int) *kmemtop,
- SRMMU_L3SIZE*sizeof(int));
- *kmemtop = pagtblptr + (SRMMU_L3SIZE *
- sizeof(int));
- bzero(pagtblptr, *kmemtop - pagtblptr);
- ((int *)newtableptr)[i] = (VA2PA(pagtblptr) >>
- SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- segmaps[i].sg_pte = (int *) pagtblptr;
-
+ printf("mmu_setup4m_L2: converting L2 entry at segment 0x%x to L3\n",i);
+#endif
+ /*
+ * This segment entry covers 256KB of memory -- or
+ * (NPTESG) pages -- which we must convert
+ * into a 3-level description.
+ */
for (k = 0; k < SRMMU_L3SIZE; k++) {
- segmaps[i].sg_npte++;
- ((int *)pagtblptr)[k] =
+ sp->sg_npte++;
+ (sp->sg_pte)[k] =
(te & SRMMU_L1PPNMASK) |
(te & SRMMU_L2PPNMASK) |
(k << SRMMU_L3PPNSHFT) |
@@ -1200,32 +1169,24 @@ mmu_setup4m_L2(segtblptd, newtableptr, pregmap, kmemtop, segmaps)
SRMMU_TEPTE;
}
break;
+
case SRMMU_TEPTD:
- pregmap->rg_nsegmap++;
- thissegmap = &segmaps[i];
- pagtblptr = (caddr_t) roundup((u_int) *kmemtop,
- SRMMU_L3SIZE*sizeof(int));
- *kmemtop = pagtblptr + (SRMMU_L3SIZE * sizeof(int));
- bzero(pagtblptr, *kmemtop - pagtblptr);
- ((int *)newtableptr)[i] = (VA2PA(pagtblptr) >>
- SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- thissegmap->sg_pte = (int *) pagtblptr;
- thissegmap->sg_npte += mmu_setup4m_L3(te, pagtblptr);
+ mmu_setup4m_L3(te, sp);
break;
+
default:
panic("mmu_setup4m_L2: unknown pagetable entry type");
}
}
}
-int
-mmu_setup4m_L3(pagtblptd, newtableptr)
+void
+mmu_setup4m_L3(pagtblptd, sp)
register int pagtblptd;
- register caddr_t newtableptr;
+ struct segmap *sp;
{
register unsigned int pagtblrover;
- register int i, n = 0;
+ register int i;
register unsigned int te;
pagtblrover = (pagtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT;
@@ -1233,11 +1194,10 @@ mmu_setup4m_L3(pagtblptd, newtableptr)
te = lda(pagtblrover, ASI_BYPASS);
switch(te & SRMMU_TETYPE) {
case SRMMU_TEINVALID:
- ((int *)newtableptr)[i] = SRMMU_TEINVALID;
break;
case SRMMU_TEPTE:
- ((int *)newtableptr)[i] = te | PPROT_U2S_OMASK;
- n++;
+ sp->sg_npte++;
+ sp->sg_pte[i] = te | PPROT_U2S_OMASK;
break;
case SRMMU_TEPTD:
panic("mmu_setup4m_L3: PTD found in L3 page table");
@@ -1245,15 +1205,9 @@ mmu_setup4m_L3(pagtblptd, newtableptr)
panic("mmu_setup4m_L3: unknown pagetable entry type");
}
}
- return n;
}
#endif /* defined SUN4M */
-/*
- * TODO: agree with the ROM on physical pages by taking them away
- * from the page list, rather than having a dinky BTSIZE above.
- */
-
/*----------------------------------------------------------------*/
/*
@@ -1316,6 +1270,13 @@ me_alloc(mh, newpm, newvreg, newvseg)
/* onto on pmap chain; pmap is already locked, if needed */
TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain);
+#ifdef DIAGNOSTIC
+ pmap_stats.ps_npmeg_free--;
+ if (mh == &segm_locked)
+ pmap_stats.ps_npmeg_locked++;
+ else
+ pmap_stats.ps_npmeg_lru++;
+#endif
/* into pmap segment table, with backpointers */
newpm->pm_regmap[newvreg].rg_segmap[newvseg].sg_pmeg = me->me_cookie;
@@ -1337,7 +1298,7 @@ me_alloc(mh, newpm, newvreg, newvseg)
panic("me_alloc: stealing from kernel");
#ifdef DEBUG
if (pmapdebug & (PDB_MMU_ALLOC | PDB_MMU_STEAL))
- printf("me_alloc: stealing pmeg %x from pmap %p\n",
+ printf("me_alloc: stealing pmeg 0x%x from pmap %p\n",
me->me_cookie, pm);
#endif
/*
@@ -1347,6 +1308,13 @@ me_alloc(mh, newpm, newvreg, newvseg)
TAILQ_REMOVE(&segm_lru, me, me_list);
TAILQ_INSERT_TAIL(mh, me, me_list);
+#ifdef DIAGNOSTIC
+ if (mh == &segm_locked) {
+ pmap_stats.ps_npmeg_lru--;
+ pmap_stats.ps_npmeg_locked++;
+ }
+#endif
+
rp = &pm->pm_regmap[me->me_vreg];
if (rp->rg_segmap == NULL)
panic("me_alloc: LRU entry's pmap has no segments");
@@ -1366,18 +1334,15 @@ me_alloc(mh, newpm, newvreg, newvseg)
* XXX for ncpus>1 must use per-cpu VA?
* XXX do not have to flush cache immediately
*/
- ctx = getcontext();
+ ctx = getcontext4();
if (CTX_USABLE(pm,rp)) {
CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
- if (vactype != VAC_NONE)
- cache_flush_segment(me->me_vreg, me->me_vseg);
+ cache_flush_segment(me->me_vreg, me->me_vseg);
va = VSTOVA(me->me_vreg,me->me_vseg);
} else {
CHANGE_CONTEXTS(ctx, 0);
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, me->me_cookie);
/*
* No cache flush needed: it happened earlier when
@@ -1412,7 +1377,7 @@ me_alloc(mh, newpm, newvreg, newvseg)
/* off old pmap chain */
TAILQ_REMOVE(&pm->pm_seglist, me, me_pmchain);
simple_unlock(&pm->pm_lock);
- setcontext(ctx); /* done with old context */
+ setcontext4(ctx); /* done with old context */
/* onto new pmap chain; new pmap is already locked, if needed */
TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain);
@@ -1465,12 +1430,10 @@ me_free(pm, pmeg)
va = VSTOVA(vr,me->me_vseg);
} else {
#ifdef DEBUG
-if (getcontext() != 0) panic("me_free: ctx != 0");
+if (getcontext4() != 0) panic("me_free: ctx != 0");
#endif
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, me->me_cookie);
va = 0;
}
@@ -1495,16 +1458,25 @@ if (getcontext() != 0) panic("me_free: ctx != 0");
/* off LRU or lock chain */
if (pm == pmap_kernel()) {
TAILQ_REMOVE(&segm_locked, me, me_list);
+#ifdef DIAGNOSTIC
+ pmap_stats.ps_npmeg_locked--;
+#endif
} else {
TAILQ_REMOVE(&segm_lru, me, me_list);
+#ifdef DIAGNOSTIC
+ pmap_stats.ps_npmeg_lru--;
+#endif
}
/* no associated pmap; on free list */
me->me_pmap = NULL;
TAILQ_INSERT_TAIL(&segm_freelist, me, me_list);
+#ifdef DIAGNOSTIC
+ pmap_stats.ps_npmeg_free++;
+#endif
}
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
/* XXX - Merge with segm_alloc/segm_free ? */
@@ -1526,7 +1498,7 @@ region_alloc(mh, newpm, newvr)
if (me->me_pmap != NULL)
panic("region_alloc: freelist entry has pmap");
if (pmapdebug & PDB_MMUREG_ALLOC)
- printf("region_alloc: got smeg %x\n", me->me_cookie);
+ printf("region_alloc: got smeg 0x%x\n", me->me_cookie);
#endif
TAILQ_INSERT_TAIL(mh, me, me_list);
@@ -1552,7 +1524,7 @@ region_alloc(mh, newpm, newvr)
panic("region_alloc: stealing from kernel");
#ifdef DEBUG
if (pmapdebug & (PDB_MMUREG_ALLOC | PDB_MMUREG_STEAL))
- printf("region_alloc: stealing smeg %x from pmap %p\n",
+ printf("region_alloc: stealing smeg 0x%x from pmap %p\n",
me->me_cookie, pm);
#endif
/*
@@ -1563,11 +1535,10 @@ region_alloc(mh, newpm, newvr)
TAILQ_INSERT_TAIL(mh, me, me_list);
rp = &pm->pm_regmap[me->me_vreg];
- ctx = getcontext();
+ ctx = getcontext4();
if (pm->pm_ctx) {
CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
- if (vactype != VAC_NONE)
- cache_flush_region(me->me_vreg);
+ cache_flush_region(me->me_vreg);
}
/* update region tables */
@@ -1579,7 +1550,7 @@ region_alloc(mh, newpm, newvr)
/* off old pmap chain */
TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain);
simple_unlock(&pm->pm_lock);
- setcontext(ctx); /* done with old context */
+ setcontext4(ctx); /* done with old context */
/* onto new pmap chain; new pmap is already locked, if needed */
TAILQ_INSERT_TAIL(&newpm->pm_reglist, me, me_pmchain);
@@ -1610,7 +1581,7 @@ region_free(pm, smeg)
#ifdef DEBUG
if (pmapdebug & PDB_MMUREG_ALLOC)
- printf("region_free: freeing smeg %x from pmap %p\n",
+ printf("region_free: freeing smeg 0x%x from pmap %p\n",
me->me_cookie, pm);
if (me->me_cookie != smeg)
panic("region_free: wrong mmuentry");
@@ -1619,8 +1590,7 @@ region_free(pm, smeg)
#endif
if (pm->pm_ctx)
- if (vactype != VAC_NONE)
- cache_flush_region(me->me_vreg);
+ cache_flush_region(me->me_vreg);
/* take mmu entry off pmap chain */
TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain);
@@ -1650,8 +1620,7 @@ region_free(pm, smeg)
int
mmu_pagein(pm, va, prot)
register struct pmap *pm;
- register vm_offset_t va;
- vm_prot_t prot;
+ register int va, prot;
{
register int *pte;
register int vr, vs, pmeg, i, s, bits;
@@ -1668,14 +1637,14 @@ mmu_pagein(pm, va, prot)
rp = &pm->pm_regmap[vr];
#ifdef DEBUG
if (pm == pmap_kernel())
-printf("mmu_pagein: kernel wants map at va %x, vr %d, vs %d\n", va, vr, vs);
+printf("mmu_pagein: kernel wants map at va 0x%x, vr %d, vs %d\n", va, vr, vs);
#endif
/* return 0 if we have no PMEGs to load */
if (rp->rg_segmap == NULL)
return (0);
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg == reginval) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
smeg_t smeg;
unsigned int tva = VA_ROUNDDOWNTOREG(va);
struct segmap *sp = rp->rg_segmap;
@@ -1716,56 +1685,6 @@ printf("mmu_pagein: kernel wants map at va %x, vr %d, vs %d\n", va, vr, vs);
}
#endif /* defined SUN4 or SUN4C */
-#if defined(DEBUG) && defined(SUN4M)
-/*
- * `Page in' (load or inspect) an MMU entry; called on page faults.
- * Returns -1 if the desired page was marked valid (in which case the
- * fault must be a bus error or something), or 0 (segment loaded but
- * PTE not valid, or segment not loaded at all).
- *
- * The SRMMU does not have the concept of `loading PMEGs into the MMU'.
- * For now, we use it to debug certain sporadic and strange memory
- * fault traps.
- */
-int
-mmu_pagein4m(pm, va, prot)
- register struct pmap *pm;
- register vm_offset_t va;
- register int prot;
-{
- register int pte;
- register int bits;
-
- pte = getpte4m(va);
- if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE)
- /* pte not found == not valid */
- return 0;
-
- /*
- * If pte has "correct" protection (according to bits), then
- * something bizarre has happened, so we return -1 to generate
- * a fault. Otherwise, we return 0 and let the VM code reload
- * the page.
- * XXX: Does this actually work, or will it cause a loop?
- */
-
- if (prot != VM_PROT_NONE)
- bits = ((prot & VM_PROT_WRITE) ? PPROT_RWX_RWX : PPROT_RX_RX);
- else
- bits = 0;
- /* If we're in kernelland, mask out user RWX */
-/* if (getcontext() == 0)
- bits |= PPROT_S;
-*/
- if (bits && (pte & bits) == bits) {
- printf("pagein4m(%s[%d]): OOPS: prot=%x, va=%x, pte=%x, bits=%x\n",
- curproc->p_comm, curproc->p_pid, prot, va, pte, bits);
- return -1;
- }
- return 0;
-}
-#endif
-
/*
* Allocate a context. If necessary, steal one from someone else.
* Changes hardware context number and loads segment map.
@@ -1798,7 +1717,7 @@ ctx_alloc(pm)
s = splpmap();
if ((c = ctx_freelist) != NULL) {
ctx_freelist = c->c_nextfree;
- cnum = c - ctxinfo;
+ cnum = c - cpuinfo.ctxinfo;
doflush = 0;
} else {
if ((ctx_kick += ctx_kickdir) >= ncontext) {
@@ -1808,7 +1727,7 @@ ctx_alloc(pm)
ctx_kick = 1;
ctx_kickdir = 1;
}
- c = &ctxinfo[cnum = ctx_kick];
+ c = &cpuinfo.ctxinfo[cnum = ctx_kick];
#ifdef DEBUG
if (c->c_pmap == NULL)
panic("ctx_alloc cu_pmap");
@@ -1817,7 +1736,7 @@ ctx_alloc(pm)
cnum, c->c_pmap);
#endif
c->c_pmap->pm_ctx = NULL;
- doflush = (vactype != VAC_NONE);
+ doflush = (CACHEINFO.c_vactype != VAC_NONE);
if (CPU_ISSUN4OR4C) {
if (gap_start < c->c_pmap->pm_gap_start)
gap_start = c->c_pmap->pm_gap_start;
@@ -1851,7 +1770,7 @@ ctx_alloc(pm)
* disjuction of the new and the previous map.
*/
- setcontext(cnum);
+ setcontext4(cnum);
splx(s);
if (doflush)
cache_flush_context();
@@ -1867,13 +1786,10 @@ ctx_alloc(pm)
/* mustn't re-enter this branch */
gap_start = NUREG;
}
-#ifdef MMU_3L
- if (mmu_3l) {
+ if (HASSUN4_MMU3L) {
setregmap(va, rp++->rg_smeg);
va += NBPRG;
- } else
-#endif
- {
+ } else {
register int j;
register struct segmap *sp = rp->rg_segmap;
for (j = NSEGRG; --j >= 0; va += NBPSG)
@@ -1885,6 +1801,7 @@ ctx_alloc(pm)
} else if (CPU_ISSUN4M) {
+#if defined(SUN4M)
/*
* Reload page and context tables to activate the page tables
* for this context.
@@ -1906,38 +1823,20 @@ ctx_alloc(pm)
* XXX: Do we have to flush cache after reloading ctx tbl?
*/
- /*
- * We install kernel mappings into the pmap here, since when
- * the kernel expands it only propagates the expansion to pmaps
- * corresponding to valid contexts. Thus it is possible (and
- * it has happened!) that a pmap is created just before
- * the kernel expands, but the pmap gets a context *after*
- * the kernel expands, thus missing getting mappings.
- */
- qcopy(&pmap_kernel()->pm_reg_ptps[VA_VREG(KERNBASE)],
- &pm->pm_reg_ptps[VA_VREG(KERNBASE)],
- NKREG * sizeof(int));
- /*
- * We must also install the regmap/segmap/etc stuff for
- * kernel maps.
- */
- qcopy(&pmap_kernel()->pm_regmap[VA_VREG(KERNBASE)],
- &pm->pm_regmap[VA_VREG(KERNBASE)],
- NKREG * sizeof(struct regmap));
-
- ctxbusyvector[cnum] = 1; /* mark context as busy */
#ifdef DEBUG
+#if 0
+ ctxbusyvector[cnum] = 1; /* mark context as busy */
+#endif
if (pm->pm_reg_ptps_pa == 0)
panic("ctx_alloc: no region table in current pmap");
#endif
/*setcontext(0); * paranoia? can we modify curr. ctx? */
- ctx_phys_tbl[cnum] =
- (pm->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
+ setpgt4m(&cpuinfo.ctx_tbl[cnum],
+ (pm->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
- setcontext(cnum);
+ setcontext4m(cnum);
if (doflush)
cache_flush_context();
-#if defined(SUN4M)
tlb_flush_context(); /* remove any remnant garbage from tlb */
#endif
splx(s);
@@ -1959,7 +1858,7 @@ ctx_free(pm)
pm->pm_ctx = NULL;
oldc = getcontext();
- if (vactype != VAC_NONE) {
+ if (CACHEINFO.c_vactype != VAC_NONE) {
newc = pm->pm_ctxnum;
CHANGE_CONTEXTS(oldc, newc);
cache_flush_context();
@@ -1970,23 +1869,28 @@ ctx_free(pm)
setcontext(0);
} else {
#if defined(SUN4M)
- if (CPU_ISSUN4M)
+ if (CPU_ISSUN4M) {
+ newc = pm->pm_ctxnum;
+ CHANGE_CONTEXTS(oldc, newc);
tlb_flush_context();
+ }
#endif
CHANGE_CONTEXTS(oldc, 0);
}
c->c_nextfree = ctx_freelist;
ctx_freelist = c;
+#if 0
#if defined(SUN4M)
if (CPU_ISSUN4M) {
/* Map kernel back into unused context */
newc = pm->pm_ctxnum;
- ctx_phys_tbl[newc] = ctx_phys_tbl[0];
+ cpuinfo.ctx_tbl[newc] = cpuinfo.ctx_tbl[0];
if (newc)
ctxbusyvector[newc] = 0; /* mark as free */
}
#endif
+#endif
}
@@ -2020,8 +1924,7 @@ pv_changepte4_4c(pv0, bis, bic)
register int *pte;
register struct pvlist *pv;
register struct pmap *pm;
- register vm_offset_t va;
- register int vr, vs, flags;
+ register int va, vr, vs, flags;
int ctx, s;
struct regmap *rp;
struct segmap *sp;
@@ -2033,11 +1936,14 @@ pv_changepte4_4c(pv0, bis, bic)
splx(s);
return;
}
- ctx = getcontext();
+ ctx = getcontext4();
flags = pv0->pv_flags;
for (pv = pv0; pv != NULL; pv = pv->pv_next) {
pm = pv->pv_pmap;
-if(pm==NULL)panic("pv_changepte 1");
+#ifdef DIAGNOSTIC
+ if(pm == NULL)
+ panic("pv_changepte: pm == NULL");
+#endif
va = pv->pv_va;
vr = VA_VREG(va);
vs = VA_VSEG(va);
@@ -2051,7 +1957,7 @@ if(pm==NULL)panic("pv_changepte 1");
if (sp->sg_pmeg == seginval) {
/* not in hardware: just fix software copy */
if (pte == NULL)
- panic("pv_changepte 2");
+ panic("pv_changepte: pte == NULL");
pte += VA_VPG(va);
*pte = (*pte | bis) & ~bic;
} else {
@@ -2071,24 +1977,26 @@ if(pm==NULL)panic("pv_changepte 1");
if (bic == PG_NC &&
va >= DVMA_BASE && va < DVMA_END)
continue;
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
/* XXX should flush only when necessary */
tpte = getpte4(va);
- if (vactype != VAC_NONE && (tpte & PG_M))
- cache_flush_page(va);
+ /*
+ * XXX: always flush cache; conservative, but
+ * needed to invalidate cache tag protection
+ * bits and when disabling caching.
+ */
+ cache_flush_page(va);
} else {
/* XXX per-cpu va? */
- setcontext(0);
-#ifdef MMU_3L
- if (mmu_3l)
+ setcontext4(0);
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, sp->sg_pmeg);
va = VA_VPG(va) << PGSHIFT;
tpte = getpte4(va);
}
if (tpte & PG_V)
- flags |= (tpte >> PG_M_SHIFT) & (PV_MOD|PV_REF);
+ flags |= MR4_4C(tpte);
tpte = (tpte | bis) & ~bic;
setpte4(va, tpte);
if (pte != NULL) /* update software copy */
@@ -2096,7 +2004,7 @@ if(pm==NULL)panic("pv_changepte 1");
}
}
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4(ctx);
splx(s);
}
@@ -2125,7 +2033,7 @@ pv_syncflags4_4c(pv0)
splx(s);
return (0);
}
- ctx = getcontext();
+ ctx = getcontext4();
flags = pv0->pv_flags;
for (pv = pv0; pv != NULL; pv = pv->pv_next) {
pm = pv->pv_pmap;
@@ -2141,31 +2049,28 @@ pv_syncflags4_4c(pv0)
continue;
if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
/* XXX should flush only when necessary */
tpte = getpte4(va);
- if (vactype != VAC_NONE && (tpte & PG_M))
+ if (tpte & PG_M)
cache_flush_page(va);
} else {
/* XXX per-cpu va? */
- setcontext(0);
-#ifdef MMU_3L
- if (mmu_3l)
+ setcontext4(0);
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, pmeg);
va = VA_VPG(va) << PGSHIFT;
tpte = getpte4(va);
}
if (tpte & (PG_M|PG_U) && tpte & PG_V) {
- flags |= (tpte >> PG_M_SHIFT) &
- (PV_MOD|PV_REF);
+ flags |= MR4_4C(tpte);
tpte &= ~(PG_M|PG_U);
setpte4(va, tpte);
}
}
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4(ctx);
splx(s);
return (flags);
}
@@ -2190,10 +2095,8 @@ pv_unlink4_4c(pv, pm, va)
register struct pvlist *npv;
#ifdef DIAGNOSTIC
- if (pv == NULL)
- panic("pv_unlink: pv==NULL");
if (pv->pv_pmap == NULL)
- panic("pv_unlink: pv->pv_pmap==NULL");
+ panic("pv_unlink0");
#endif
/*
* First entry is special (sigh).
@@ -2205,9 +2108,10 @@ pv_unlink4_4c(pv, pm, va)
pv->pv_next = npv->pv_next;
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
- free(npv, M_VMPVENT);
+ FREE(npv, M_VMPVENT);
} else {
pv->pv_pmap = NULL;
+ pv->pv_flags &= ~PV_NC;
return;
}
} else {
@@ -2216,12 +2120,12 @@ pv_unlink4_4c(pv, pm, va)
for (prev = pv;; prev = npv, npv = npv->pv_next) {
pmap_stats.ps_unlink_pvsearch++;
if (npv == NULL)
- panic("pv_unlink: npv==NULL");
+ panic("pv_unlink");
if (npv->pv_pmap == pm && npv->pv_va == va)
break;
}
prev->pv_next = npv->pv_next;
- free(npv, M_VMPVENT);
+ FREE(npv, M_VMPVENT);
}
if (pv->pv_flags & PV_NC) {
/*
@@ -2273,10 +2177,12 @@ pv_link4_4c(pv, pm, va)
for (npv = pv; npv != NULL; npv = npv->pv_next) {
if (BADALIAS(va, npv->pv_va)) {
#ifdef DEBUG
- if (pmapdebug) printf(
- "pv_link: badalias: pid %d, %lx<=>%x, pa %lx\n",
- curproc?curproc->p_pid:-1, va, npv->pv_va,
- vm_first_phys + (pv-pv_table)*NBPG);
+ if (pmapdebug & PDB_CACHESTUFF)
+ printf(
+ "pv_link: badalias: pid %d, 0x%lx<=>0x%lx, pa 0x%lx\n",
+ curproc ? curproc->p_pid : -1,
+ va, npv->pv_va,
+ vm_first_phys + (pv-pv_table)*NBPG);
#endif
pv->pv_flags |= PV_NC;
pv_changepte4_4c(pv, ret = PG_NC, 0);
@@ -2284,7 +2190,7 @@ pv_link4_4c(pv, pm, va)
}
}
}
- npv = (struct pvlist *)malloc(sizeof *npv, M_VMPVENT, M_WAITOK);
+ MALLOC(npv, struct pvlist *, sizeof *npv, M_VMPVENT, M_WAITOK);
npv->pv_next = pv->pv_next;
npv->pv_pmap = pm;
npv->pv_va = va;
@@ -2315,10 +2221,10 @@ pv_changepte4m(pv0, bis, bic)
{
register struct pvlist *pv;
register struct pmap *pm;
- register vm_offset_t va;
- register int vr, flags;
+ register int va, vr, flags;
int ctx, s;
struct regmap *rp;
+ struct segmap *sp;
write_user_windows(); /* paranoid? */
@@ -2327,20 +2233,24 @@ pv_changepte4m(pv0, bis, bic)
splx(s);
return;
}
- ctx = getcontext();
+ ctx = getcontext4m();
flags = pv0->pv_flags;
for (pv = pv0; pv != NULL; pv = pv->pv_next) {
register int tpte;
pm = pv->pv_pmap;
+#ifdef DIAGNOSTIC
if (pm == NULL)
- panic("pv_changepte 1");
+ panic("pv_changepte: pm == NULL");
+#endif
va = pv->pv_va;
vr = VA_VREG(va);
rp = &pm->pm_regmap[vr];
if (rp->rg_segmap == NULL)
panic("pv_changepte: no segments");
- if (CTX_USABLE(pm,rp)) {
+ sp = &rp->rg_segmap[VA_VSEG(va)];
+
+ if (pm->pm_ctx) {
extern vm_offset_t pager_sva, pager_eva;
/*
@@ -2353,27 +2263,34 @@ pv_changepte4m(pv0, bis, bic)
if ((bis & SRMMU_PG_C) &&
va >= DVMA_BASE && va < DVMA_END)
continue;
- setcontext(pm->pm_ctxnum);
- /* %%%: Do we need to always flush? */
- tpte = getpte4m(va);
- if (vactype != VAC_NONE && (tpte & SRMMU_PG_M))
- cache_flush_page(va);
- } else {
- /* PTE that we want has no context. Use sw getpte*/
- tpte = getptesw4m(pm, va);
+
+ setcontext4m(pm->pm_ctxnum);
+
+ /*
+ * XXX: always flush cache; conservative, but
+ * needed to invalidate cache tag protection
+ * bits and when disabling caching.
+ */
+ cache_flush_page(va);
+
+ /* Flush TLB so memory copy is up-to-date */
+ tlb_flush_page(va);
+
+ }
+
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
+ if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
+ printf("pv_changepte: invalid PTE for 0x%x\n", va);
+ continue;
}
- if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) /* i.e. if valid pte */
- flags |= (tpte >> PG_M_SHIFT4M) & (PV_MOD4M|PV_REF4M|PV_C4M);
+ flags |= (tpte >> PG_M_SHIFT4M) & (PV_MOD4M|PV_REF4M|PV_C4M);
tpte = (tpte | bis) & ~bic;
- if (CTX_USABLE(pm,rp))
- setpte4m(va, tpte);
- else
- setptesw4m(pm, va, tpte);
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], tpte);
}
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4m(ctx);
splx(s);
}
@@ -2401,7 +2318,7 @@ pv_syncflags4m(pv0)
splx(s);
return (0);
}
- ctx = getcontext();
+ ctx = getcontext4m();
flags = pv0->pv_flags;
for (pv = pv0; pv != NULL; pv = pv->pv_next) {
pm = pv->pv_pmap;
@@ -2420,26 +2337,30 @@ pv_syncflags4m(pv0)
* We need the PTE from memory as the TLB version will
* always have the SRMMU_PG_R bit on.
*/
- if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
+ if (pm->pm_ctx) {
+ setcontext4m(pm->pm_ctxnum);
tlb_flush_page(va);
}
- tpte = getptesw4m(pm, va);
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && /* if valid pte */
(tpte & (SRMMU_PG_M|SRMMU_PG_R))) { /* and mod/refd */
+
flags |= (tpte >> PG_M_SHIFT4M) &
(PV_MOD4M|PV_REF4M|PV_C4M);
- tpte &= ~(SRMMU_PG_M | SRMMU_PG_R);
- /* TLB has been invalidated, so just update memory */
- setptesw4m(pm, va, tpte);
- if (vactype != VAC_NONE &&
- CTX_USABLE(pm,rp) && (tpte & SRMMU_PG_M))
+
+ if (pm->pm_ctx && (tpte & SRMMU_PG_M)) {
cache_flush_page(va); /* XXX: do we need this?*/
+ tlb_flush_page(va); /* paranoid? */
+ }
+
+ /* Clear mod/ref bits from PTE and write it back */
+ tpte &= ~(SRMMU_PG_M | SRMMU_PG_R);
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], tpte);
}
}
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4m(ctx);
splx(s);
return (flags);
}
@@ -2453,10 +2374,8 @@ pv_unlink4m(pv, pm, va)
register struct pvlist *npv;
#ifdef DIAGNOSTIC
- if (pv == NULL)
- panic("pv_unlink: pv==NULL");
if (pv->pv_pmap == NULL)
- panic("pv_unlink: pv->pv_pmap==NULL");
+ panic("pv_unlink0");
#endif
/*
* First entry is special (sigh).
@@ -2468,9 +2387,10 @@ pv_unlink4m(pv, pm, va)
pv->pv_next = npv->pv_next;
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
- free(npv, M_VMPVENT);
+ FREE(npv, M_VMPVENT);
} else {
pv->pv_pmap = NULL;
+ pv->pv_flags |= PV_C4M;
return;
}
} else {
@@ -2479,12 +2399,12 @@ pv_unlink4m(pv, pm, va)
for (prev = pv;; prev = npv, npv = npv->pv_next) {
pmap_stats.ps_unlink_pvsearch++;
if (npv == NULL)
- panic("pv_unlink: npv==NULL");
+ panic("pv_unlink");
if (npv->pv_pmap == pm && npv->pv_va == va)
break;
}
prev->pv_next = npv->pv_next;
- free(npv, M_VMPVENT);
+ FREE(npv, M_VMPVENT);
}
if (!(pv->pv_flags & PV_C4M)) {
/*
@@ -2536,10 +2456,12 @@ pv_link4m(pv, pm, va)
for (npv = pv; npv != NULL; npv = npv->pv_next) {
if (BADALIAS(va, npv->pv_va)) {
#ifdef DEBUG
- if (pmapdebug & PDB_CACHESTUFF) printf(
- "pv_link: badalias: pid %d, %lx<=>%x, pa %lx\n",
- curproc?curproc->p_pid:-1, va, npv->pv_va,
- vm_first_phys + (pv-pv_table)*NBPG);
+ if (pmapdebug & PDB_CACHESTUFF)
+ printf(
+ "pv_link: badalias: pid %d, 0x%lx<=>0x%lx, pa 0x%lx\n",
+ curproc ? curproc->p_pid : -1,
+ va, npv->pv_va,
+ vm_first_phys + (pv-pv_table)*NBPG);
#endif
pv->pv_flags &= ~PV_C4M;
pv_changepte4m(pv, 0, ret = SRMMU_PG_C);
@@ -2548,7 +2470,7 @@ pv_link4m(pv, pm, va)
}
}
}
- npv = (struct pvlist *)malloc(sizeof *npv, M_VMPVENT, M_WAITOK);
+ MALLOC(npv, struct pvlist *, sizeof *npv, M_VMPVENT, M_WAITOK);
npv->pv_next = pv->pv_next;
npv->pv_pmap = pm;
npv->pv_va = va;
@@ -2626,7 +2548,9 @@ pmap_bootstrap(nctx, nregion, nsegment)
nptesg = (NBPSG >> pgshift);
#endif
+#if 0
ncontext = nctx;
+#endif
#if defined(SUN4M)
if (CPU_ISSUN4M) {
@@ -2649,7 +2573,7 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
{
register union ctxinfo *ci;
register struct mmuentry *mmuseg;
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
register struct mmuentry *mmureg;
#endif
struct regmap *rp;
@@ -2663,7 +2587,6 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
extern char end[];
#ifdef DDB
extern char *esym;
- char *theend = end;
#endif
switch (cputyp) {
@@ -2671,7 +2594,7 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
mmu_has_hole = 1;
break;
case CPU_SUN4:
- if (cpumod != SUN4_400) {
+ if (cpuinfo.cpu_type != CPUTYP_4_400) {
mmu_has_hole = 1;
break;
}
@@ -2716,8 +2639,8 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
*/
seginval = --nsegment;
-#ifdef MMU_3L
- if (mmu_3l)
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L)
reginval = --nregion;
#endif
@@ -2727,14 +2650,14 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
/* kernel_pmap_store.pm_ctxnum = 0; */
simple_lock_init(kernel_pmap_store.pm_lock);
kernel_pmap_store.pm_refcount = 1;
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
TAILQ_INIT(&kernel_pmap_store.pm_reglist);
#endif
TAILQ_INIT(&kernel_pmap_store.pm_seglist);
kernel_pmap_store.pm_regmap = &kernel_regmap_store[-NUREG];
for (i = NKREG; --i >= 0;) {
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
kernel_regmap_store[i].rg_smeg = reginval;
#endif
kernel_regmap_store[i].rg_segmap =
@@ -2752,7 +2675,7 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
mmu_reservemon4_4c(&nregion, &nsegment);
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
/* Reserve one region for temporary mappings */
tregion = --nregion;
#endif
@@ -2763,24 +2686,22 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
p = end;
#ifdef DDB
if (esym != 0)
- theend = p = esym;
+ p = esym;
#endif
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
mmuregions = mmureg = (struct mmuentry *)p;
p += nregion * sizeof(struct mmuentry);
+ bzero(mmuregions, nregion * sizeof(struct mmuentry));
#endif
mmusegments = mmuseg = (struct mmuentry *)p;
p += nsegment * sizeof(struct mmuentry);
- pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p;
+ bzero(mmusegments, nsegment * sizeof(struct mmuentry));
+
+ pmap_kernel()->pm_ctx = cpuinfo.ctxinfo = ci = (union ctxinfo *)p;
p += nctx * sizeof *ci;
-#ifdef DDB
- bzero(theend, p - theend);
-#else
- bzero(end, p - end);
-#endif
/* Initialize MMU resource queues */
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
TAILQ_INIT(&region_freelist);
TAILQ_INIT(&region_lru);
TAILQ_INIT(&region_locked);
@@ -2890,8 +2811,8 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
#endif
vr++, rp++;
}
-#ifdef MMU_3L
- if (mmu_3l) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L) {
for (i = 1; i < nctx; i++)
rom_setmap(i, p, rcookie);
@@ -2909,8 +2830,8 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
#endif
}
-#ifdef MMU_3L
- if (!mmu_3l)
+#if defined(SUN4_MMU3L)
+ if (!HASSUN4_MMU3L)
#endif
for (i = 1; i < nctx; i++)
rom_setmap(i, p, scookie);
@@ -2918,6 +2839,7 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
/* set up the mmu entry */
TAILQ_INSERT_TAIL(&segm_locked, mmuseg, me_list);
TAILQ_INSERT_TAIL(&pmap_kernel()->pm_seglist, mmuseg, me_pmchain);
+ pmap_stats.ps_npmeg_locked++;
mmuseg->me_cookie = scookie;
mmuseg->me_pmap = pmap_kernel();
mmuseg->me_vreg = vr;
@@ -2940,8 +2862,8 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
for (p += npte << PGSHIFT; npte < NPTESG; npte++, p += NBPG)
setpte4(p, 0);
-#ifdef MMU_3L
- if (mmu_3l) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L) {
/*
* Unmap the segments, if any, that are not part of
* the final region.
@@ -2953,8 +2875,8 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
break;
}
-#ifdef MMU_3L
- if (mmu_3l)
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L)
for (; rcookie < nregion; rcookie++, mmureg++) {
mmureg->me_cookie = rcookie;
TAILQ_INSERT_TAIL(&region_freelist, mmureg, me_list);
@@ -2964,17 +2886,16 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
for (; scookie < nsegment; scookie++, mmuseg++) {
mmuseg->me_cookie = scookie;
TAILQ_INSERT_TAIL(&segm_freelist, mmuseg, me_list);
+ pmap_stats.ps_npmeg_free++;
}
/* Erase all spurious user-space segmaps */
for (i = 1; i < ncontext; i++) {
- setcontext(i);
-#ifdef MMU_3L
- if (mmu_3l)
+ setcontext4(i);
+ if (HASSUN4_MMU3L)
for (p = 0, j = NUREG; --j >= 0; p += NBPRG)
setregmap(p, reginval);
else
-#endif
for (p = 0, vr = 0; vr < NUREG; vr++) {
if (VA_INHOLE(p)) {
p = (caddr_t)MMU_HOLE_END;
@@ -2984,7 +2905,7 @@ pmap_bootstrap4_4c(nctx, nregion, nsegment)
setsegmap(p, seginval);
}
}
- setcontext(0);
+ setcontext4(0);
/*
* write protect & encache kernel text;
@@ -3014,25 +2935,19 @@ static void
pmap_bootstrap4m(void)
{
register int i, j;
- caddr_t p, p2;
+ caddr_t p;
register caddr_t q;
register union ctxinfo *ci;
register struct memarr *mp;
- struct regmap *rmapp = NULL;
- struct segmap *smapp = NULL;
register int reg, seg;
-#if 0
- int nkreg, nkseg, nkpag, kernsize, newpgs;
-#endif
- caddr_t kphyssegtbl, kphyspagtbl = NULL;
- int deadfill, deadspace;
+ unsigned int ctxtblsize;
+ caddr_t pagetables_start, pagetables_end;
extern char end[];
extern char etext[];
+ extern caddr_t reserve_dumppages(caddr_t);
#ifdef DDB
extern char *esym;
- char *theend = end;
#endif
- extern caddr_t reserve_dumppages(caddr_t);
#if defined(SUN4) || defined(SUN4C) /* setup 4M fn. ptrs for dual-arch kernel */
pmap_clear_modify_p = pmap_clear_modify4m;
@@ -3054,9 +2969,11 @@ pmap_bootstrap4m(void)
* Intialize the kernel pmap.
*/
/* kernel_pmap_store.pm_ctxnum = 0; */
- simple_lock_init(kernel_pmap_store.pm_lock);
+ simple_lock_init(&kernel_pmap_store.pm_lock);
kernel_pmap_store.pm_refcount = 1;
- /* Set up pm_regmap for kernel to point NUREG *below* the beginning
+
+ /*
+ * Set up pm_regmap for kernel to point NUREG *below* the beginning
* of kernel regmap storage. Since the kernel only uses regions
* above NUREG, we save storage space and can index kernel and
* user regions in the same way
@@ -3077,85 +2994,87 @@ pmap_bootstrap4m(void)
p = end; /* p points to top of kernel mem */
#ifdef DDB
if (esym != 0)
- theend = p = esym;
+ p = esym;
#endif
- /*
- * Preserve the monitor ROM's reserved VM region, so that
- * we can use L1-A or the monitor's debugger.
- */
-
- mmu_reservemon4m(&kernel_pmap_store, &p);
- pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p;
+ /* Allocate context administration */
+ pmap_kernel()->pm_ctx = cpuinfo.ctxinfo = ci = (union ctxinfo *)p;
p += ncontext * sizeof *ci;
- bzero((caddr_t)ctxinfo, (u_int)p - (u_int)ctxinfo);
+ bzero((caddr_t)ci, (u_int)p - (u_int)ci);
+#if 0
ctxbusyvector = p;
p += ncontext;
bzero(ctxbusyvector, ncontext);
ctxbusyvector[0] = 1; /* context 0 is always in use */
+#endif
+
+
+ /*
+ * Set up the `constants' for the call to vm_init()
+ * in main(). All pages beginning at p (rounded up to
+ * the next whole page) and continuing through the number
+ * of available pages are free.
+ */
+ p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
+ avail_start = (int)p - KERNBASE;
+ /*
+ * Grab physical memory list use it to compute `physmem' and
+ * `avail_end'. The latter is used in conjuction with
+ * `avail_start' and `avail_next' to dispatch left-over
+ * physical pages to the VM system.
+ */
+ npmemarr = makememarr(pmemarr, MA_SIZE, MEMARR_AVAILPHYS);
+ sortm(pmemarr, npmemarr);
+ if (pmemarr[0].addr != 0) {
+ printf("pmap_bootstrap: no kernel memory?!\n");
+ callrom();
+ }
+ avail_end = pmemarr[npmemarr-1].addr + pmemarr[npmemarr-1].len;
+ avail_next = avail_start;
+ for (physmem = 0, mp = pmemarr, j = npmemarr; --j >= 0; mp++)
+ physmem += btoc(mp->len);
/*
- * reserve memory for I/O pagetables. This takes 64k of memory
+ * Reserve memory for MMU pagetables. Some of these have severe
+ * alignment restrictions. We allocate in a sequence that
+ * minimizes alignment gaps.
+ * The amount of physical memory that becomes unavailable for
+ * general VM use is marked by [unavail_start, unavail_end>.
+ */
+
+ /*
+ * Reserve memory for I/O pagetables. This takes 64k of memory
* since we want to have 64M of dvma space (this actually depends
- * on the definition of DVMA4M_BASE...we may drop it back to 32M)
- * but since the table must be aligned, we might end up using
- * as much as 128K. (note 1024 = NBPG / sizeof(iopte_t))
- *
- * We optimize with some space saving song and dance to
- * squeeze other pagetables in the dead space.
+ * on the definition of DVMA4M_BASE...we may drop it back to 32M).
+ * The table must be aligned on a (-DVMA4M_BASE/NBPG) boundary
+ * (i.e. 64K for 64M of dvma space).
*/
#ifdef DEBUG
if ((0 - DVMA4M_BASE) % (16*1024*1024))
- panic("pmap_bootstrap4m: invalid DVMA4M_BASE of 0x%x",DVMA4M_BASE);
-#endif
-
- deadfill = 0;
- p = (caddr_t) roundup((u_int) p, max(SRMMU_L1SIZE * sizeof(long),
- max(SRMMU_L2SIZE * sizeof(long),
- SRMMU_L3SIZE * sizeof(long))));
-
- deadspace = (int) (((caddr_t)roundup((u_int)p,
- (0 - DVMA4M_BASE) / 1024)) - p);
-
- if (deadspace >= SRMMU_L3SIZE * sizeof(long) * NKREG * NSEGRG) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L3SIZE * sizeof(long));
- kernel_pagtable_store = (u_int *)p;
- p += ((SRMMU_L3SIZE * sizeof(long)) * NKREG) * NSEGRG;
- bzero(kernel_pagtable_store,
- p - (caddr_t) kernel_pagtable_store);
- deadfill |= 4;
- deadspace -= (int)(p - (caddr_t) kernel_pagtable_store);
- }
- if (deadspace >= SRMMU_L2SIZE * sizeof(long) * NKREG) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L2SIZE * sizeof(long));
- kernel_segtable_store = (u_int *)p;
- p += (SRMMU_L2SIZE * sizeof(long)) * NKREG;
- bzero(kernel_segtable_store,
- p - (caddr_t) kernel_segtable_store);
- deadfill |= 2;
- deadspace -= (int)(p - (caddr_t) kernel_segtable_store);
- }
- if (deadspace >= SRMMU_L1SIZE * sizeof(long)) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L1SIZE * sizeof(long));
- kernel_regtable_store = (u_int *)p;
- p += SRMMU_L1SIZE * sizeof(long);
- bzero(kernel_regtable_store,
- p - (caddr_t) kernel_regtable_store);
- deadfill |= 1;
- deadspace -= (int)(p - (caddr_t) kernel_regtable_store);
- }
- if (deadspace < 0)
- printf("pmap_bootstrap4m: botch in memory-saver\n");
+ panic("pmap_bootstrap4m: invalid DVMA4M_BASE of 0x%x", DVMA4M_BASE);
+#endif
p = (caddr_t) roundup((u_int)p, (0 - DVMA4M_BASE) / 1024);
+ unavail_start = (int)p - KERNBASE;
+
kernel_iopte_table = (u_int *)p;
kernel_iopte_table_pa = VA2PA((caddr_t)kernel_iopte_table);
p += (0 - DVMA4M_BASE) / 1024;
bzero(kernel_iopte_table, p - (caddr_t) kernel_iopte_table);
+ pagetables_start = p;
+ /*
+ * Allocate context table.
+ * To keep supersparc happy, minimum aligment is on a 4K boundary.
+ */
+ ctxtblsize = max(ncontext,1024) * sizeof(int);
+ cpuinfo.ctx_tbl = (int *)roundup((u_int)p, ctxtblsize);
+ p = (caddr_t)((u_int)cpuinfo.ctx_tbl + ctxtblsize);
+ qzero(cpuinfo.ctx_tbl, ctxtblsize);
+
/*
- * reserve memory for segment and page tables needed to map the entire
+ * Reserve memory for segment and page tables needed to map the entire
* kernel (from regions 0xf8 -> 0xff). This takes 130k of space, but
* unfortunately is necessary since pmap_enk *must* be able to enter
* a kernel mapping without resorting to malloc, or else the
@@ -3164,87 +3083,103 @@ pmap_bootstrap4m(void)
* pmap_enk4m to enter the new malloc'd page; pmap_enk4m needs to
* malloc a page table to enter _that_ mapping; malloc deadlocks since
* it is already allocating that object).
- *
- * We only do this if it wasn't done above...
*/
- if (!(deadfill & 2)) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L2SIZE * sizeof(long));
- kernel_segtable_store = (u_int *)p;
- p += (SRMMU_L2SIZE * sizeof(long)) * NKREG;
- bzero(kernel_segtable_store,
- p - (caddr_t) kernel_segtable_store);
- }
- if (!(deadfill & 4)) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L3SIZE * sizeof(long));
- kernel_pagtable_store = (u_int *)p;
- p += ((SRMMU_L3SIZE * sizeof(long)) * NKREG) * NSEGRG;
- bzero(kernel_pagtable_store,
- p - (caddr_t) kernel_pagtable_store);
- }
- if (!(deadfill & 1)) {
- p = (caddr_t) roundup((u_int)p, SRMMU_L1SIZE * sizeof(long));
- kernel_regtable_store = (u_int *)p;
- p += SRMMU_L1SIZE * sizeof(long);
- bzero(kernel_regtable_store,
- p - (caddr_t) kernel_regtable_store);
- }
+ p = (caddr_t) roundup((u_int)p, SRMMU_L1SIZE * sizeof(long));
+ kernel_regtable_store = (u_int *)p;
+ p += SRMMU_L1SIZE * sizeof(long);
+ bzero(kernel_regtable_store,
+ p - (caddr_t) kernel_regtable_store);
+
+ p = (caddr_t) roundup((u_int)p, SRMMU_L2SIZE * sizeof(long));
+ kernel_segtable_store = (u_int *)p;
+ p += (SRMMU_L2SIZE * sizeof(long)) * NKREG;
+ bzero(kernel_segtable_store,
+ p - (caddr_t) kernel_segtable_store);
+
+ p = (caddr_t) roundup((u_int)p, SRMMU_L3SIZE * sizeof(long));
+ kernel_pagtable_store = (u_int *)p;
+ p += ((SRMMU_L3SIZE * sizeof(long)) * NKREG) * NSEGRG;
+ bzero(kernel_pagtable_store,
+ p - (caddr_t) kernel_pagtable_store);
+
+ /* Round to next page and mark end of stolen pages */
+ p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
+ pagetables_end = p;
+ unavail_end = (int)p - KERNBASE;
-#if 0
- /* At this point, "p" is the highest location of kernel memory that
- * we need to lock in/map initially. We now need to calculate the
- * size of this kernel image and allocate memory for its page tables,
- * which we won't set up until the end of this function. After this
- * point, it is NOT POSSIBLE to allocate kernel physical memory
- * by bumping up p!!!
+ /*
+ * Since we've statically allocated space to map the entire kernel,
+ * we might as well pre-wire the mappings to save time in pmap_enter.
+ * This also gets around nasty problems with caching of L1/L2 ptp's.
+ *
+ * XXX WHY DO WE HAVE THIS CACHING PROBLEM WITH L1/L2 PTPS????? %%%
*/
- p = (caddr_t) roundup((u_int)p,SRMMU_L1SIZE * sizeof(long));
- kernsize = (u_int)p - KERNBASE;
- /* We keep adding pages until the number of added pages is sufficient
- * to hold the map for both the kernel and the new pages. This
- * converges since it takes at most about 1152 bytes to map one page.
- */
- newpgs = 0;
- do {
- newpgs++;
- nkreg = (kernsize + (newpgs * NBPG) + NBPRG - 1) / NBPRG;
- nkseg = (kernsize + (newpgs * NBPG) + NBPSG - 1) / NBPSG;
- nkpag = (kernsize + NBPG - 1) / NBPG + newpgs;
- } while (((SRMMU_L1SIZE + (nkreg * SRMMU_L2SIZE) +
- (nkseg * SRMMU_L3SIZE) + (nkpag)) * sizeof(long)) >
- newpgs * NBPG);
+ pmap_kernel()->pm_reg_ptps = (int *) kernel_regtable_store;
+ pmap_kernel()->pm_reg_ptps_pa =
+ VA2PA((caddr_t)pmap_kernel()->pm_reg_ptps);
- kernsize += newpgs * NBPG;
- p2 = p; /* Page tables go from p2 to p. */
- p += newpgs * NBPG; /* p is now the _real_ top of kernel mem. */
-#endif
+ /* Install L1 table in context 0 */
+ setpgt4m(&cpuinfo.ctx_tbl[0],
+ (pmap_kernel()->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
+
+ /* XXX:rethink - Store pointer to region table address */
+ cpuinfo.L1_ptps = pmap_kernel()->pm_reg_ptps;
+
+ for (reg = VA_VREG(KERNBASE); reg < NKREG+VA_VREG(KERNBASE); reg++) {
+ struct regmap *rp;
+ caddr_t kphyssegtbl;
+
+ /*
+ * Entering new region; install & build segtbl
+ */
+ int kregnum = reg - VA_VREG(KERNBASE);
+
+ rp = &pmap_kernel()->pm_regmap[reg];
+
+ kphyssegtbl = (caddr_t)
+ &kernel_segtable_store[kregnum * SRMMU_L2SIZE];
+
+ setpgt4m(&pmap_kernel()->pm_reg_ptps[reg],
+ (VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
+
+ rp->rg_seg_ptps = (int *)kphyssegtbl;
+
+ if (rp->rg_segmap == NULL) {
+ printf("rp->rg_segmap == NULL!\n");
+ rp->rg_segmap = &kernel_segmap_store[kregnum * NSEGRG];
+ }
+
+ for (seg = 0; seg < NSEGRG; seg++) {
+ struct segmap *sp;
+ caddr_t kphyspagtbl;
+
+ rp->rg_nsegmap++;
+
+ sp = &rp->rg_segmap[seg];
+ kphyspagtbl = (caddr_t)
+ &kernel_pagtable_store
+ [((kregnum * NSEGRG) + seg) * SRMMU_L3SIZE];
+
+ setpgt4m(&rp->rg_seg_ptps[seg],
+ (VA2PA(kphyspagtbl) >> SRMMU_PPNPASHIFT) |
+ SRMMU_TEPTD);
+ sp->sg_pte = (int *) kphyspagtbl;
+ }
+ }
/*
- * Set up the `constants' for the call to vm_init()
- * in main(). All pages beginning at p (rounded up to
- * the next whole page) and continuing through the number
- * of available pages are free, but they start at a higher
- * virtual address. This gives us two mappable MD pages
- * for pmap_zero_page and pmap_copy_page, and one MI page
- * for /dev/mem, all with no associated physical memory.
+ * Preserve the monitor ROM's reserved VM region, so that
+ * we can use L1-A or the monitor's debugger.
*/
- p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
- avail_start = (int)p - KERNBASE;
+ mmu_reservemon4m(&kernel_pmap_store);
+
/*
- * Grab physical memory list, so pmap_next_page() can do its bit.
+ * Reserve virtual address space for two mappable MD pages
+ * for pmap_zero_page and pmap_copy_page, one MI page
+ * for /dev/mem, and some more for dumpsys().
*/
- npmemarr = makememarr(pmemarr, MA_SIZE, MEMARR_AVAILPHYS);
- sortm(pmemarr, npmemarr);
- if (pmemarr[0].addr != 0) {
- printf("pmap_bootstrap: no kernel memory?!\n");
- callrom();
- }
- avail_end = pmemarr[npmemarr-1].addr + pmemarr[npmemarr-1].len;
- avail_next = avail_start;
- for (physmem = 0, mp = pmemarr, j = npmemarr; --j >= 0; mp++)
- physmem += btoc(mp->len);
-
- i = (int)p;
+ q = p;
vpage[0] = p, p += NBPG;
vpage[1] = p, p += NBPG;
vmmap = p, p += NBPG;
@@ -3260,9 +3195,10 @@ pmap_bootstrap4m(void)
virtual_avail = (vm_offset_t)p;
virtual_end = VM_MAX_KERNEL_ADDRESS;
- p = (caddr_t)i; /* retract to first free phys */
+ p = q; /* retract to first free phys */
- /* Set up the ctxinfo structures (freelist of contexts)
+ /*
+ * Set up the ctxinfo structures (freelist of contexts)
*/
ci->c_pmap = pmap_kernel();
ctx_freelist = ci + 1;
@@ -3274,148 +3210,49 @@ pmap_bootstrap4m(void)
ctx_kick = 0;
ctx_kickdir = -1;
- /* Now map the kernel into our new set of page tables, then
+ /*
+ * Now map the kernel into our new set of page tables, then
* (finally) switch over to our running page tables.
* We map from KERNBASE to p into context 0's page tables (and
* the kernel pmap).
*/
#ifdef DEBUG /* Sanity checks */
if ((u_int)p % NBPG != 0)
- panic("pmap_bootstrap4m: p misaligned?!?");
+ panic("pmap_bootstrap4m: p misaligned?!?");
if (KERNBASE % NBPRG != 0)
- panic("pmap_bootstrap4m: KERNBASE not region-aligned");
+ panic("pmap_bootstrap4m: KERNBASE not region-aligned");
#endif
- if (pmap_kernel()->pm_reg_ptps == NULL) {
-#ifdef DEBUG
- printf("pmap_bootstrap4m: no kernel regiontable; creating.\n");
-#endif
- pmap_kernel()->pm_reg_ptps = (int *) kernel_regtable_store;
- pmap_kernel()->pm_reg_ptps_pa =
- VA2PA((caddr_t)pmap_kernel()->pm_reg_ptps);
- p2 = (caddr_t) pmap_kernel()->pm_reg_ptps +
- (SRMMU_L1SIZE * sizeof(int));
- bzero(pmap_kernel()->pm_reg_ptps, SRMMU_L1SIZE * sizeof(long));
- }
- reg = -1;
- seg = -1;
+
for (q = (caddr_t) KERNBASE; q < p; q += NBPG) {
- if ((VA_VSEG(q) % NSEGRG == 0) && VA_VREG(q) != reg) {
- /* entering new region; install & build segtbl
- * XXX: WE TRASH ANY EXISTING MAPPINGS IN THE KERNEL
- * REGION. SHOULD BE FIXED!
- */
- reg = VA_VREG(q);
- rmapp = &(pmap_kernel()->pm_regmap[reg]);
- kphyssegtbl = (caddr_t)
- &kernel_segtable_store[(reg - VA_VREG(KERNBASE)) *
- SRMMU_L2SIZE];
- bzero(kphyssegtbl, SRMMU_L2SIZE * sizeof(long));
-
- ((int *)pmap_kernel()->pm_reg_ptps)[VA_VREG(q)] =
- (VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
-
- rmapp->rg_seg_ptps = (int *)kphyssegtbl;
-
- if (rmapp->rg_segmap == NULL)
- rmapp->rg_segmap = &kernel_segmap_store[(reg -
- VA_VREG(KERNBASE)) * NSEGRG];
- }
- if (((VA_VPG(q) % NPTESG) == 0) && VA_VSEG(q) != seg) {
- rmapp->rg_nsegmap++;
- /* Entering new segment. XXX: trashes existing maps */
- seg = VA_VSEG(q);
- smapp = &(rmapp->rg_segmap[seg]);
- kphyspagtbl = (caddr_t)
- &kernel_pagtable_store[(((reg-VA_VREG(KERNBASE))*
- NSEGRG) + seg)*SRMMU_L3SIZE];
- bzero(kphyspagtbl, SRMMU_L3SIZE * sizeof(long));
-
- rmapp->rg_seg_ptps[VA_VSEG(q)] =
- (VA2PA(kphyspagtbl) >> SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- smapp->sg_pte = (int *) kphyspagtbl;
- }
- /* Now install entry for current page. Cache and write-protect
- * kernel text.
- */
- smapp->sg_npte++;
- if (q == (caddr_t) KERNBASE) {
- /* Must map in message buffer in low page. */
- ((int *)kphyspagtbl)[VA_VPG(q)] = PPROT_N_RWX |
- SRMMU_PG_C | SRMMU_TEPTE;
+ struct regmap *rp;
+ struct segmap *sp;
+ int pte;
+
+ if ((int)q >= KERNBASE + avail_start &&
+ (int)q < KERNBASE + unavail_start)
+ /* This gap is part of VM-managed pages */
continue;
- }
- else if (q < (caddr_t) (KERNBASE+0x4000)) {
- /* Special case: retain interrupt register mapping */
- ((int *)kphyspagtbl)[VA_VPG(q)] =
- getpte4m((vm_offset_t)q);
- }
- if (q >= (caddr_t) trapbase && q < etext)
- ((int *)kphyspagtbl)[VA_VPG(q)] =
- (VA2PA(q) >> SRMMU_PPNPASHIFT) |
- PPROT_N_RX | SRMMU_PG_C | SRMMU_TEPTE;
- else
- ((int *)kphyspagtbl)[VA_VPG(q)] =
- (VA2PA(q) >> SRMMU_PPNPASHIFT) |
- PPROT_N_RWX | SRMMU_PG_C | SRMMU_TEPTE;
- }
- /*
- * We must also create a segment table for region 0xfe and any
- * needed page tables necessary to map the special (important)
- * devices that get mapped at the beginning of this I/O segment.
- * This is necessary since we have to map the interrupt registers
- * at the start of region 0xfe in bootstrap().
- *
- * Since we've statically allocated space to map the entire kernel,
- * we might as well pre-wire the mappings to save time in pmap_enter.
- * This also gets around nasty problems with caching of L1/L2 ptp's.
- *
- * XXX WHY DO WE HAVE THIS CACHING PROBLEM WITH L1/L2 PTPS????? %%%
- */
- for (reg = VA_VREG(KERNBASE); reg < NKREG+VA_VREG(KERNBASE); reg++) {
- rmapp = &(pmap_kernel()->pm_regmap[reg]);
-
- if (((int *)pmap_kernel()->pm_reg_ptps)[reg] == NULL) {
- kphyssegtbl = (caddr_t)
- &kernel_segtable_store[(reg - VA_VREG(KERNBASE)) *
- SRMMU_L2SIZE];
- bzero(kphyssegtbl, SRMMU_L2SIZE * sizeof(long));
- ((int *)pmap_kernel()->pm_reg_ptps)[reg] =
- (VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
-
- rmapp->rg_seg_ptps = (int *)kphyssegtbl;
-
- if (rmapp->rg_segmap == NULL)
- rmapp->rg_segmap = &kernel_segmap_store
- [(reg - VA_VREG(KERNBASE)) * NSEGRG];
- }
- for (seg = 0; seg < NSEGRG; seg++) {
- if (rmapp->rg_seg_ptps[seg] == NULL) {
- rmapp->rg_nsegmap++;
-
- smapp = &(rmapp->rg_segmap[seg]);
- kphyspagtbl = (caddr_t)
- &kernel_pagtable_store[(((reg-
- VA_VREG(KERNBASE))*
- NSEGRG) + seg)*
- SRMMU_L3SIZE];
- bzero(kphyspagtbl,
- SRMMU_L3SIZE * sizeof(long));
-
- rmapp->rg_seg_ptps[seg] =
- (VA2PA(kphyspagtbl) >> SRMMU_PPNPASHIFT) |
- SRMMU_TEPTD;
- smapp->sg_pte = (int *) kphyspagtbl;
- }
- }
+ /*
+ * Now install entry for current page.
+ */
+ rp = &pmap_kernel()->pm_regmap[VA_VREG(q)];
+ sp = &rp->rg_segmap[VA_VSEG(q)];
+ sp->sg_npte++;
+
+ pte = ((int)q - KERNBASE) >> SRMMU_PPNPASHIFT;
+ pte |= PPROT_N_RX | SRMMU_PG_C | SRMMU_TEPTE;
+ /* write-protect kernel text */
+ if (q < (caddr_t) trapbase || q >= etext)
+ pte |= PPROT_WRITE;
+
+ setpgt4m(&sp->sg_pte[VA_VPG(q)], pte);
}
+#if 0
/*
* We also install the kernel mapping into all other contexts by
- * copying the context 0 L1 PTP from ctx_phys_tbl[0] into the
+ * copying the context 0 L1 PTP from cpuinfo.ctx_tbl[0] into the
* remainder of the context table (i.e. we share the kernel page-
* tables). Each user pmap automatically gets the kernel mapped
* into it when it is created, but we do this extra step early on
@@ -3423,98 +3260,110 @@ pmap_bootstrap4m(void)
* pmap associated with it.
*/
for (i = 1; i < ncontext; i++)
- ctx_phys_tbl[i] = ctx_phys_tbl[0];
+ cpuinfo.ctx_tbl[i] = cpuinfo.ctx_tbl[0];
+#endif
/*
* Now switch to kernel pagetables (finally!)
*/
+ mmu_install_tables(&cpuinfo);
+
+ /* Mark all MMU tables uncacheable, if required */
+ if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0)
+ kvm_uncache(pagetables_start,
+ (pagetables_end - pagetables_start) >> PGSHIFT);
+
+}
+
+void
+mmu_install_tables(sc)
+ struct cpu_softc *sc;
+{
+
#ifdef DEBUG
printf("pmap_bootstrap: installing kernel page tables...");
#endif
- setcontext(0); /* paranoia? %%%: Make 0x3 a define! below */
+ setcontext4m(0); /* paranoia? %%%: Make 0x3 a define! below */
/* Enable MMU tablewalk caching, flush TLB */
-
- i = lda(SRMMU_PCR, ASI_SRMMU);
- switch(mmumod) {
-/* case SUN4M_MMU_MS: */ /* These have the same model # as SS */
- case SUN4M_MMU_SS:
- if ((cpumod & 0xf0) == (SUN4M_SS & 0xf0))
- sta(SRMMU_PCR, ASI_SRMMU, (i | SRMMU_PCR_TC));
- else /* microsparc */
- printf("(if this doesn't work, "
- "fix pmap_bootstrap4m in pmap.c)");
- break;
- case SUN4M_MMU_HS:
- printf("(if this doesn't work, fix pmap_bootstrap4m in pmap.c)");
- sta(SRMMU_PCR, ASI_SRMMU, (i | SRMMU_PCR_C) & ~SRMMU_PCR_CE);
- /* above: CHECKFIX %%% below: add microsparc*/
- break;
- case SUN4M_MMU_MS1:
- printf("(if this doesn't work, fix pmap_bootstrap4m in pmap.c)");
- break;
- default:
- panic("Unimplemented MMU architecture %d",mmumod);
- }
+ if (sc->mmu_enable != 0)
+ sc->mmu_enable();
tlb_flush_all();
sta(SRMMU_CXTPTR, ASI_SRMMU,
- (VA2PA((caddr_t)ctx_phys_tbl) >> SRMMU_PPNPASHIFT) & ~0x3);
+ (VA2PA((caddr_t)sc->ctx_tbl) >> SRMMU_PPNPASHIFT) & ~0x3);
tlb_flush_all();
#ifdef DEBUG
printf("done.\n");
#endif
+}
+
+/*
+ * Allocate per-CPU page tables.
+ * Note: this routine is called in the context of the boot CPU
+ * during autoconfig.
+ */
+void
+pmap_alloc_cpu(sc)
+ struct cpu_softc *sc;
+{
+ caddr_t cpustore;
+ int *ctxtable;
+ int *regtable;
+ int *segtable;
+ int *pagtable;
+ int vr, vs, vpg;
+ struct regmap *rp;
+ struct segmap *sp;
+
+ /* Allocate properly aligned and physically contiguous memory here */
+ cpustore = 0;
+ ctxtable = 0;
+ regtable = 0;
+ segtable = 0;
+ pagtable = 0;
+
+ vr = VA_VREG(CPUINFO_VA);
+ vs = VA_VSEG(CPUINFO_VA);
+ vpg = VA_VPG(CPUINFO_VA);
+ rp = &pmap_kernel()->pm_regmap[vr];
+ sp = &rp->rg_segmap[vs];
/*
- * On SuperSPARC machines without a MXCC, we *cannot* cache the
- * page tables.
- * XXX: this needs to be cleaned up with the cpu_softc stuff...
+ * Copy page tables, then modify entry for CPUINFO_VA so that
+ * it points at the per-CPU pages.
*/
- if (mmumod == SUN4M_MMU_SS &&
- (lda(SRMMU_PCR, ASI_SRMMU) & SRMMU_PCR_MB)) {
+ bcopy(cpuinfo.L1_ptps, regtable, SRMMU_L1SIZE * sizeof(int));
+ regtable[vr] =
+ (VA2PA((caddr_t)segtable) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
- int bytes, numpages;
- cant_cache_pagetables = 1;
+ bcopy(rp->rg_seg_ptps, segtable, SRMMU_L2SIZE * sizeof(int));
+ segtable[vs] =
+ (VA2PA((caddr_t)pagtable) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
-#define DO_THE_MATH(math) \
- bytes = (math); \
- numpages = (bytes >> PGSHIFT) + (bytes % NBPG ? 1 : 0);
+ bcopy(sp->sg_pte, pagtable, SRMMU_L3SIZE * sizeof(int));
+ pagtable[vpg] =
+ (VA2PA((caddr_t)cpustore) >> SRMMU_PPNPASHIFT) |
+ (SRMMU_TEPTE | PPROT_RWX_RWX | SRMMU_PG_C);
- DO_THE_MATH(SRMMU_L3SIZE * sizeof(long) * NKREG * NSEGRG);
-#ifdef DEBUG
- printf("pmap_bootstrap4m: uncaching %d PT pages at 0x%lx\n",
- numpages, (long)kernel_pagtable_store);
-#endif
- kvm_uncache((caddr_t)kernel_pagtable_store, numpages);
-
- DO_THE_MATH(SRMMU_L2SIZE * sizeof(long) * NKREG);
-#ifdef DEBUG
- printf("pmap_bootstrap4m: uncaching %d ST pages at 0x%lx\n",
- numpages, (long)kernel_segtable_store);
-#endif
- kvm_uncache((caddr_t)kernel_segtable_store, numpages);
+ /* Install L1 table in context 0 */
+ ctxtable[0] = ((u_int)regtable >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
- DO_THE_MATH(SRMMU_L1SIZE * sizeof(long));
-#ifdef DEBUG
- printf("pmap_bootstrap4m: uncaching %d RT pages at 0x%lx\n",
- numpages, (long)kernel_regtable_store);
-#endif
- kvm_uncache((caddr_t)kernel_regtable_store, numpages);
+ sc->ctx_tbl = ctxtable;
+ sc->L1_ptps = regtable;
-#undef DO_THE_MATH
+#if 0
+ if ((sc->flags & CPUFLG_CACHEPAGETABLES) == 0) {
+ kvm_uncache((caddr_t)0, 1);
}
-
-#ifdef DEBUG
- printf("\n"); /* Might as well make it pretty... */
#endif
-
- /* All done! */
}
#endif /* defined sun4m */
+
void
pmap_init()
{
@@ -3560,16 +3409,10 @@ pass2:
sva = trunc_page(va);
if (sva < eva) {
-#if defined(DEBUG) && !defined(SUN4M)
- /*
- * crowded chunks are normal on SS20s; don't clutter
- * screen with messages
- */
- printf("note: crowded chunk at 0x%x\n", mp->addr);
-#endif
+ /* This chunk overlaps the previous in pv_table[] */
sva += PAGE_SIZE;
if (sva < eva)
- panic("pmap_init: sva(%lx) < eva(%lx)",
+ panic("pmap_init: sva(0x%lx) < eva(0x%lx)",
sva, eva);
}
eva = round_page(va + len);
@@ -3667,29 +3510,35 @@ pmap_pinit(pm)
if (CPU_ISSUN4OR4C) {
TAILQ_INIT(&pm->pm_seglist);
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
TAILQ_INIT(&pm->pm_reglist);
- if (mmu_3l)
- for (i = NUREG; --i >= 0;)
- pm->pm_regmap[i].rg_smeg = reginval;
+ if (HASSUN4_MMU3L) {
+ int i;
+ for (i = NUREG; --i >= 0;)
+ pm->pm_regmap[i].rg_smeg = reginval;
+ }
#endif
}
#if defined(SUN4M)
else {
+ int i;
+
/*
* We must allocate and initialize hardware-readable (MMU)
* pagetables. We must also map the kernel regions into this
* pmap's pagetables, so that we can access the kernel from
- * user mode!
+ * this user context.
*
* Note: pm->pm_regmap's have been zeroed already, so we don't
* need to explicitly mark them as invalid (a null
* rg_seg_ptps pointer indicates invalid for the 4m)
*/
urp = malloc(SRMMU_L1SIZE * sizeof(int), M_VMPMAP, M_WAITOK);
- if (cant_cache_pagetables)
+#if 0
+ if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0)
kvm_uncache(urp,
((SRMMU_L1SIZE*sizeof(int))+NBPG-1)/NBPG);
+#endif
#ifdef DEBUG
if ((u_int) urp % (SRMMU_L1SIZE * sizeof(int)))
@@ -3697,8 +3546,14 @@ pmap_pinit(pm)
#endif
pm->pm_reg_ptps = urp;
pm->pm_reg_ptps_pa = VA2PA(urp);
- qzero(urp, SRMMU_L1SIZE * sizeof(int));
+ for (i = 0; i < NUREG; i++)
+ setpgt4m(&pm->pm_reg_ptps[i], SRMMU_TEINVALID);
+ /* Copy kernel regions */
+ for (i = 0; i < NKREG; i++) {
+ setpgt4m(&pm->pm_reg_ptps[VA_VREG(KERNBASE) + i],
+ cpuinfo.L1_ptps[VA_VREG(KERNBASE) + i]);
+ }
}
#endif
@@ -3749,7 +3604,7 @@ pmap_release(pm)
#endif
if (CPU_ISSUN4OR4C) {
-#ifdef MMU_3L
+#if defined(SUN4_MMU3L)
if (pm->pm_reglist.tqh_first)
panic("pmap_release: region list not empty");
#endif
@@ -3840,7 +3695,7 @@ pmap_remove(pm, va, endva)
#ifdef DEBUG
if (pmapdebug & PDB_REMOVE)
- printf("pmap_remove(%p, %lx, %lx)\n", pm, va, endva);
+ printf("pmap_remove(%p, 0x%lx, 0x%lx)\n", pm, va, endva);
#endif
if (pm == pmap_kernel()) {
@@ -3866,7 +3721,8 @@ pmap_remove(pm, va, endva)
nva = VSTOVA(vr, vs + 1);
if (nva == 0 || nva > endva)
nva = endva;
- (*rm)(pm, va, nva, vr, vs);
+ if (pm->pm_regmap[vr].rg_nsegmap != 0)
+ (*rm)(pm, va, nva, vr, vs);
}
simple_unlock(&pm->pm_lock);
splx(s);
@@ -3932,17 +3788,16 @@ pmap_rmk4_4c(pm, va, endva, vr, vs)
panic("pmap_rmk: lost context");
#endif
- setcontext(0);
+ setcontext4(0);
/* decide how to flush cache */
npg = (endva - va) >> PGSHIFT;
if (npg > PMAP_RMK_MAGIC) {
/* flush the whole segment */
perpage = 0;
- if (vactype != VAC_NONE)
- cache_flush_segment(vr, vs);
+ cache_flush_segment(vr, vs);
} else {
/* flush each page individually; some never need flushing */
- perpage = (vactype != VAC_NONE);
+ perpage = (CACHEINFO.c_vactype != VAC_NONE);
}
while (va < endva) {
tpte = getpte4(va);
@@ -3972,21 +3827,21 @@ pmap_rmk4_4c(pm, va, endva, vr, vs)
*/
if ((sp->sg_npte = nleft) == 0) {
va = VSTOVA(vr,vs); /* retract */
-#ifdef MMU_3L
- if (mmu_3l)
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L)
setsegmap(va, seginval);
else
#endif
for (i = ncontext; --i >= 0;) {
- setcontext(i);
+ setcontext4(i);
setsegmap(va, seginval);
}
me_free(pm, pmeg);
if (--rp->rg_nsegmap == 0) {
-#ifdef MMU_3L
- if (mmu_3l) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L) {
for (i = ncontext; --i >= 0;) {
- setcontext(i);
+ setcontext4(i);
setregmap(va, reginval);
}
/* note: context is 0 */
@@ -4034,28 +3889,34 @@ pmap_rmk4m(pm, va, endva, vr, vs)
panic("pmap_rmk: lost context");
#endif
- setcontext(0);
+ setcontext4m(0);
/* decide how to flush cache */
npg = (endva - va) >> PGSHIFT;
if (npg > PMAP_RMK_MAGIC) {
/* flush the whole segment */
perpage = 0;
- if (vactype != VAC_NONE)
+ if (CACHEINFO.c_vactype != VAC_NONE)
cache_flush_segment(vr, vs);
} else {
/* flush each page individually; some never need flushing */
- perpage = (vactype != VAC_NONE);
+ perpage = (CACHEINFO.c_vactype != VAC_NONE);
}
while (va < endva) {
- tpte = getpte4m(va);
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
+#ifdef DEBUG
+ if ((pmapdebug & PDB_SANITYCHK) &&
+ (getpte4m(va) & SRMMU_TETYPE) == SRMMU_TEPTE)
+ panic("pmap_rmk: Spurious kTLB entry for 0x%lx",
+ va);
+#endif
va += NBPG;
continue;
}
if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
/* if cacheable, flush page as needed */
if (perpage && (tpte & SRMMU_PG_C))
- cache_flush_page(va);
+ cache_flush_page(va);
i = ptoa((tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT);
if (managed(i)) {
pv = pvhead(i);
@@ -4064,7 +3925,8 @@ pmap_rmk4m(pm, va, endva, vr, vs)
}
}
nleft--;
- setpte4m(va, SRMMU_TEINVALID);
+ tlb_flush_page(va);
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_TEINVALID);
va += NBPG;
}
@@ -4163,13 +4025,13 @@ pmap_rmu4_4c(pm, va, endva, vr, vs)
if (--rp->rg_nsegmap == 0) {
free(rp->rg_segmap, M_VMPMAP);
rp->rg_segmap = NULL;
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg != reginval) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
if (pm->pm_ctx) {
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
setregmap(va, reginval);
} else
- setcontext(0);
+ setcontext4(0);
region_free(pm, rp->rg_smeg);
}
#endif
@@ -4185,21 +4047,18 @@ pmap_rmu4_4c(pm, va, endva, vr, vs)
if (CTX_USABLE(pm,rp)) {
/* process has a context, must flush cache */
npg = (endva - va) >> PGSHIFT;
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
if (npg > PMAP_RMU_MAGIC) {
perpage = 0; /* flush the whole segment */
- if (vactype != VAC_NONE)
- cache_flush_segment(vr, vs);
+ cache_flush_segment(vr, vs);
} else
- perpage = (vactype != VAC_NONE);
+ perpage = (CACHEINFO.c_vactype != VAC_NONE);
pteva = va;
} else {
/* no context, use context 0; cache flush unnecessary */
- setcontext(0);
-#ifdef MMU_3L
- if (mmu_3l)
+ setcontext4(0);
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
/* XXX use per-cpu pteva? */
setsegmap(0, pmeg);
pteva = VA_VPG(va) << PGSHIFT;
@@ -4222,10 +4081,7 @@ pmap_rmu4_4c(pm, va, endva, vr, vs)
}
nleft--;
setpte4(pteva, 0);
-#define PMAP_PTESYNC
-#ifdef PMAP_PTESYNC
pte0[VA_VPG(pteva)] = 0;
-#endif
}
/*
@@ -4241,13 +4097,11 @@ if (pm->pm_ctx == NULL) {
va = VSTOVA(vr,vs); /* retract */
if (CTX_USABLE(pm,rp))
setsegmap(va, seginval);
-#ifdef MMU_3L
- else if (mmu_3l && rp->rg_smeg != reginval) {
+ else if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
/* note: context already set earlier */
setregmap(0, rp->rg_smeg);
setsegmap(vs << SGSHIFT, seginval);
}
-#endif
free(pte0, M_VMPMAP);
sp->sg_pte = NULL;
me_free(pm, pmeg);
@@ -4257,8 +4111,8 @@ if (pm->pm_ctx == NULL) {
rp->rg_segmap = NULL;
GAP_WIDEN(pm,vr);
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg != reginval) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
/* note: context already set */
if (pm->pm_ctx)
setregmap(va, reginval);
@@ -4280,7 +4134,7 @@ pmap_rmu4m(pm, va, endva, vr, vs)
register vm_offset_t va, endva;
register int vr, vs;
{
- register int *pte0, i, tpte, perpage, npg;
+ register int *pte0, i, perpage, npg;
register struct pvlist *pv;
register int nleft;
struct regmap *rp;
@@ -4295,6 +4149,7 @@ pmap_rmu4m(pm, va, endva, vr, vs)
sp = &rp->rg_segmap[vs];
if ((nleft = sp->sg_npte) == 0)
return;
+
if (sp->sg_pte == NULL)
panic("pmap_rmu: no pages");
@@ -4303,10 +4158,10 @@ pmap_rmu4m(pm, va, endva, vr, vs)
/*
* Invalidate PTE in MMU pagetables. Flush cache if necessary.
*/
- if (CTX_USABLE(pm,rp)) {
+ if (pm->pm_ctx) {
/* process has a context, must flush cache */
- setcontext(pm->pm_ctxnum);
- if (vactype != VAC_NONE) {
+ setcontext4m(pm->pm_ctxnum);
+ if (CACHEINFO.c_vactype != VAC_NONE) {
npg = (endva - va) >> PGSHIFT;
if (npg > PMAP_RMU_MAGIC) {
perpage = 0; /* flush the whole segment */
@@ -4320,16 +4175,20 @@ pmap_rmu4m(pm, va, endva, vr, vs)
perpage = 0;
}
for (; va < endva; va += NBPG) {
- /* Note: we use sw pagetables here since pages have been
- * flushed already. This avoids over-zealous cache flushing.
- */
- if (CTX_USABLE(pm,rp)) { /* %%% XXX: Performance hit? */
- tpte = getpte4m(va); /* should we just flush seg? */
- tlb_flush_page(va);
- } else
- tpte = getptesw4m(pm, va);
- if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE)
+
+ int tpte = pte0[VA_SUN4M_VPG(va)];
+
+ if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
+#ifdef DEBUG
+ if ((pmapdebug & PDB_SANITYCHK) &&
+ pm->pm_ctx &&
+ (getpte4m(va) & SRMMU_TEPTE) == SRMMU_TEPTE)
+ panic("pmap_rmu: Spurious uTLB entry for 0x%lx",
+ va);
+#endif
continue;
+ }
+
if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
/* if cacheable, flush page as needed */
if (perpage && (tpte & SRMMU_PG_C))
@@ -4342,14 +4201,16 @@ pmap_rmu4m(pm, va, endva, vr, vs)
}
}
nleft--;
- setptesw4m(pm, va, SRMMU_TEINVALID); /* Update pagetables */
+ if (pm->pm_ctx)
+ tlb_flush_page(va);
+ setpgt4m(&pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID);
}
/*
* If the segment is all gone, and the context is loaded, give
* the segment back.
*/
- if ((sp->sg_npte = nleft) == 0 /* ??? && pm->pm_ctx != NULL*/) {
+ if ((sp->sg_npte = nleft) == 0) {
#ifdef DEBUG
if (pm->pm_ctx == NULL) {
printf("pmap_rmu: no context here...");
@@ -4357,17 +4218,19 @@ pmap_rmu4m(pm, va, endva, vr, vs)
#endif
va = VSTOVA(vr,vs); /* retract */
- tlb_flush_segment(vr, vs); /* Paranoia? */
- rp->rg_seg_ptps[vs] = SRMMU_TEINVALID;
+ if (pm->pm_ctx)
+ tlb_flush_segment(vr, vs); /* Paranoia? */
+ setpgt4m(&rp->rg_seg_ptps[vs], SRMMU_TEINVALID);
free(pte0, M_VMPMAP);
sp->sg_pte = NULL;
if (--rp->rg_nsegmap == 0) {
+ if (pm->pm_ctx)
+ tlb_flush_context(); /* Paranoia? */
+ setpgt4m(&pm->pm_reg_ptps[vr], SRMMU_TEINVALID);
free(rp->rg_segmap, M_VMPMAP);
rp->rg_segmap = NULL;
free(rp->rg_seg_ptps, M_VMPMAP);
- pm->pm_reg_ptps[vr] = SRMMU_TEINVALID;
- GAP_WIDEN(pm,vr);
}
}
}
@@ -4390,24 +4253,23 @@ pmap_page_protect4_4c(pa, prot)
{
register struct pvlist *pv, *pv0, *npv;
register struct pmap *pm;
- register vm_offset_t va;
- register int vr, vs, pteva, tpte;
+ register int va, vr, vs, pteva, tpte;
register int flags, nleft, i, s, ctx;
struct regmap *rp;
struct segmap *sp;
#ifdef DEBUG
if (!pmap_pa_exists(pa))
- panic("pmap_page_protect: no such address: %lx", pa);
+ panic("pmap_page_protect: no such address: 0x%lx", pa);
if ((pmapdebug & PDB_CHANGEPROT) ||
(pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE))
- printf("pmap_page_protect(%lx, %x)\n", pa, prot);
+ printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot);
#endif
/*
* Skip unmanaged pages, or operations that do not take
* away write permission.
*/
- if ((pa & (PMAP_TNC & ~PMAP_NC)) ||
+ if ((pa & (PMAP_TNC_4 & ~PMAP_NC)) ||
!managed(pa) || prot & VM_PROT_WRITE)
return;
write_user_windows(); /* paranoia */
@@ -4428,7 +4290,7 @@ pmap_page_protect4_4c(pa, prot)
splx(s);
return;
}
- ctx = getcontext();
+ ctx = getcontext4();
pv0 = pv;
flags = pv->pv_flags & ~PV_NC;
for (;; pm = pv->pv_pmap) {
@@ -4455,13 +4317,13 @@ pmap_page_protect4_4c(pa, prot)
free(rp->rg_segmap, M_VMPMAP);
rp->rg_segmap = NULL;
GAP_WIDEN(pm,vr);
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg != reginval) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
if (pm->pm_ctx) {
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
setregmap(va, reginval);
} else
- setcontext(0);
+ setcontext4(0);
region_free(pm, rp->rg_smeg);
}
#endif
@@ -4469,94 +4331,96 @@ pmap_page_protect4_4c(pa, prot)
}
goto nextpv;
}
+
if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
pteva = va;
- if (vactype != VAC_NONE)
- cache_flush_page(va);
+ cache_flush_page(va);
} else {
- setcontext(0);
+ setcontext4(0);
/* XXX use per-cpu pteva? */
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, sp->sg_pmeg);
pteva = VA_VPG(va) << PGSHIFT;
}
tpte = getpte4(pteva);
if ((tpte & PG_V) == 0)
- panic("pmap_page_protect !PG_V");
+ panic("pmap_page_protect !PG_V: ctx %d, va 0x%x, pte 0x%x",
+ pm->pm_ctxnum, va, tpte);
flags |= MR4_4C(tpte);
if (nleft) {
setpte4(pteva, 0);
-#ifdef PMAP_PTESYNC
if (sp->sg_pte != NULL)
sp->sg_pte[VA_VPG(pteva)] = 0;
+ goto nextpv;
+ }
+
+ /* Entire segment is gone */
+ if (pm == pmap_kernel()) {
+#if defined(SUN4_MMU3L)
+ if (!HASSUN4_MMU3L)
#endif
- } else {
- if (pm == pmap_kernel()) {
-#ifdef MMU_3L
- if (!mmu_3l)
-#endif
+ for (i = ncontext; --i >= 0;) {
+ setcontext4(i);
+ setsegmap(va, seginval);
+ }
+ me_free(pm, sp->sg_pmeg);
+ if (--rp->rg_nsegmap == 0) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L) {
for (i = ncontext; --i >= 0;) {
- setcontext(i);
- setsegmap(va, seginval);
- }
- me_free(pm, sp->sg_pmeg);
- if (--rp->rg_nsegmap == 0) {
-#ifdef MMU_3L
- if (mmu_3l) {
- for (i = ncontext; --i >= 0;) {
- setcontext(i);
- setregmap(va, reginval);
- }
- region_free(pm, rp->rg_smeg);
+ setcontext4(i);
+ setregmap(va, reginval);
}
-#endif
- }
- } else {
- if (CTX_USABLE(pm,rp))
- /* `pteva'; we might be using tregion */
- setsegmap(pteva, seginval);
-#ifdef MMU_3L
- else if (mmu_3l && rp->rg_smeg != reginval) {
- /* note: context already set earlier */
- setregmap(0, rp->rg_smeg);
- setsegmap(vs << SGSHIFT, seginval);
+ region_free(pm, rp->rg_smeg);
}
#endif
- free(sp->sg_pte, M_VMPMAP);
- sp->sg_pte = NULL;
- me_free(pm, sp->sg_pmeg);
-
- if (--rp->rg_nsegmap == 0) {
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg != reginval) {
- if (pm->pm_ctx)
- setregmap(va, reginval);
- region_free(pm, rp->rg_smeg);
- }
+ }
+ } else {
+ if (CTX_USABLE(pm,rp))
+ /* `pteva'; we might be using tregion */
+ setsegmap(pteva, seginval);
+#if defined(SUN4_MMU3L)
+ else if (HASSUN4_MMU3L &&
+ rp->rg_smeg != reginval) {
+ /* note: context already set earlier */
+ setregmap(0, rp->rg_smeg);
+ setsegmap(vs << SGSHIFT, seginval);
+ }
#endif
- free(rp->rg_segmap, M_VMPMAP);
- rp->rg_segmap = NULL;
- GAP_WIDEN(pm,vr);
+ free(sp->sg_pte, M_VMPMAP);
+ sp->sg_pte = NULL;
+ me_free(pm, sp->sg_pmeg);
+
+ if (--rp->rg_nsegmap == 0) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L &&
+ rp->rg_smeg != reginval) {
+ if (pm->pm_ctx)
+ setregmap(va, reginval);
+ region_free(pm, rp->rg_smeg);
}
+#endif
+ free(rp->rg_segmap, M_VMPMAP);
+ rp->rg_segmap = NULL;
+ GAP_WIDEN(pm,vr);
}
}
+
nextpv:
npv = pv->pv_next;
if (pv != pv0)
- free(pv, M_VMPVENT);
+ FREE(pv, M_VMPVENT);
if ((pv = npv) == NULL)
break;
}
pv0->pv_pmap = NULL;
pv0->pv_next = NULL; /* ? */
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4(ctx);
splx(s);
}
@@ -4575,8 +4439,7 @@ pmap_protect4_4c(pm, sva, eva, prot)
vm_offset_t sva, eva;
vm_prot_t prot;
{
- register vm_offset_t va, nva;
- register int vr, vs;
+ register int va, nva, vr, vs;
register int s, ctx;
struct regmap *rp;
struct segmap *sp;
@@ -4590,7 +4453,7 @@ pmap_protect4_4c(pm, sva, eva, prot)
}
write_user_windows();
- ctx = getcontext();
+ ctx = getcontext4();
s = splpmap();
simple_lock(&pm->pm_lock);
@@ -4635,15 +4498,14 @@ if (nva == 0) panic("pmap_protect: last segment"); /* cannot happen */
* tags are updated. This is really only
* needed for PTEs that lose PG_W.
*/
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
for (; va < nva; va += NBPG) {
tpte = getpte4(va);
pmap_stats.ps_npg_prot_all++;
if ((tpte & (PG_W|PG_TYPE)) ==
(PG_W|PG_OBMEM)) {
pmap_stats.ps_npg_prot_actual++;
- if (vactype != VAC_NONE)
- cache_flush_page(va);
+ cache_flush_page(va);
setpte4(va, tpte & ~PG_W);
}
}
@@ -4654,12 +4516,10 @@ if (nva == 0) panic("pmap_protect: last segment"); /* cannot happen */
* No context, hence not cached;
* just update PTEs.
*/
- setcontext(0);
+ setcontext4(0);
/* XXX use per-cpu pteva? */
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, sp->sg_pmeg);
pteva = VA_VPG(va) << PGSHIFT;
for (; va < nva; pteva += NBPG, va += NBPG)
@@ -4669,7 +4529,7 @@ if (nva == 0) panic("pmap_protect: last segment"); /* cannot happen */
}
simple_unlock(&pm->pm_lock);
splx(s);
- setcontext(ctx);
+ setcontext4(ctx);
}
/*
@@ -4690,7 +4550,7 @@ pmap_changeprot4_4c(pm, va, prot, wired)
#ifdef DEBUG
if (pmapdebug & PDB_CHANGEPROT)
- printf("pmap_changeprot(%p, %lx, %x, %x)\n",
+ printf("pmap_changeprot(%p, 0x%lx, 0x%x, 0x%x)\n",
pm, va, prot, wired);
#endif
@@ -4732,42 +4592,37 @@ pmap_changeprot4_4c(pm, va, prot, wired)
*pte = (*pte & ~PG_PROT) | newprot;
} else {
/* update in hardware */
- ctx = getcontext();
+ ctx = getcontext4();
if (CTX_USABLE(pm,rp)) {
- /* use current context; flush writeback cache */
- setcontext(pm->pm_ctxnum);
+ /*
+ * Use current context.
+ * Flush cache if page has been referenced to
+ * avoid stale protection bits in the cache tags.
+ */
+ setcontext4(pm->pm_ctxnum);
tpte = getpte4(va);
if ((tpte & PG_PROT) == newprot) {
- setcontext(ctx);
+ setcontext4(ctx);
goto useless;
}
-
- /*
- * the latter check deals with a writethrough cache
- * problem on the 4/300
- */
- if ((vactype==VAC_WRITEBACK ||
- (vactype==VAC_WRITETHROUGH && cputyp==CPU_SUN4)) &&
- (tpte & (PG_U|PG_NC|PG_TYPE)) == (PG_U|PG_OBMEM))
+ if ((tpte & (PG_U|PG_NC|PG_TYPE)) == (PG_U|PG_OBMEM))
cache_flush_page((int)va);
} else {
- setcontext(0);
+ setcontext4(0);
/* XXX use per-cpu va? */
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, sp->sg_pmeg);
va = VA_VPG(va) << PGSHIFT;
tpte = getpte4(va);
if ((tpte & PG_PROT) == newprot) {
- setcontext(ctx);
+ setcontext4(ctx);
goto useless;
}
}
tpte = (tpte & ~PG_PROT) | newprot;
setpte4(va, tpte);
- setcontext(ctx);
+ setcontext4(ctx);
}
splx(s);
return;
@@ -4796,8 +4651,7 @@ pmap_page_protect4m(pa, prot)
{
register struct pvlist *pv, *pv0, *npv;
register struct pmap *pm;
- register vm_offset_t va;
- register int vr, vs, tpte;
+ register int va, vr, vs, tpte;
register int flags, nleft, s, ctx;
struct regmap *rp;
struct segmap *sp;
@@ -4807,7 +4661,7 @@ pmap_page_protect4m(pa, prot)
panic("pmap_page_protect: no such address: 0x%lx", pa);
if ((pmapdebug & PDB_CHANGEPROT) ||
(pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE))
- printf("pmap_page_protect(%lx, %x)\n", pa, prot);
+ printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot);
#endif
/*
* Skip unmanaged pages, or operations that do not take
@@ -4833,7 +4687,7 @@ pmap_page_protect4m(pa, prot)
splx(s);
return;
}
- ctx = getcontext();
+ ctx = getcontext4m();
pv0 = pv;
flags = pv->pv_flags /*| PV_C4M*/; /* %%%: ???? */
for (;; pm = pv->pv_pmap) {
@@ -4850,63 +4704,71 @@ pmap_page_protect4m(pa, prot)
sp->sg_npte = nleft;
/* Invalidate PTE in MMU pagetables. Flush cache if necessary */
- if (CTX_USABLE(pm,rp)) { /* Must flush */
- setcontext(pm->pm_ctxnum);
- tpte = getpte4m(va);
- if (vactype != VAC_NONE)
- cache_flush_page(va);
+ if (pm->pm_ctx) {
+ setcontext4m(pm->pm_ctxnum);
+ cache_flush_page(va);
tlb_flush_page(va);
- } else
- tpte = getptesw4m(pm, va);
+ }
+
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE)
panic("pmap_page_protect !PG_V");
+
flags |= MR4M(tpte);
- if (nleft)
- setptesw4m(pm, va, SRMMU_TEINVALID);
- else {
- if (pm == pmap_kernel()) {
- tlb_flush_segment(vr, vs); /* Paranoid? */
- if (va < virtual_avail) {
+ if (nleft) {
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_TEINVALID);
+ goto nextpv;
+ }
+
+ /* Entire segment is gone */
+ if (pm == pmap_kernel()) {
+ tlb_flush_segment(vr, vs); /* Paranoid? */
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_TEINVALID);
+ if (va < virtual_avail) {
#ifdef DEBUG
- printf("pmap_rmk4m: attempt to free "
- "base kernel allocation\n");
+ printf(
+ "pmap_page_protect: attempt to free"
+ " base kernel allocation\n");
+#endif
+ goto nextpv;
+ }
+#if 0 /* no need for this */
+ /* no need to free the table; it is static */
+ qzero(sp->sg_pte, SRMMU_L3SIZE * sizeof(int));
#endif
- goto nextpv;
- }
- /* no need to free the table; it is static */
- qzero(sp->sg_pte, SRMMU_L3SIZE * sizeof(int));
- /* if we're done with a region, leave it */
+ /* if we're done with a region, leave it */
- } else { /* User mode mapping */
- if (CTX_USABLE(pm,rp))
- tlb_flush_segment(vr, vs);
- rp->rg_seg_ptps[vs] = SRMMU_TEINVALID;
- free(sp->sg_pte, M_VMPMAP);
- sp->sg_pte = NULL;
+ } else { /* User mode mapping */
+ if (pm->pm_ctx)
+ tlb_flush_segment(vr, vs);
+ setpgt4m(&rp->rg_seg_ptps[vs], SRMMU_TEINVALID);
+ free(sp->sg_pte, M_VMPMAP);
+ sp->sg_pte = NULL;
- if (--rp->rg_nsegmap == 0) {
- free(rp->rg_segmap, M_VMPMAP);
- rp->rg_segmap = NULL;
- free(rp->rg_seg_ptps, M_VMPMAP);
- pm->pm_reg_ptps[vr] = SRMMU_TEINVALID;
- GAP_WIDEN(pm,vr);
- }
+ if (--rp->rg_nsegmap == 0) {
+ if (pm->pm_ctx)
+ tlb_flush_context();
+ setpgt4m(&pm->pm_reg_ptps[vr], SRMMU_TEINVALID);
+ free(rp->rg_segmap, M_VMPMAP);
+ rp->rg_segmap = NULL;
+ free(rp->rg_seg_ptps, M_VMPMAP);
}
}
+
nextpv:
npv = pv->pv_next;
if (pv != pv0)
- free(pv, M_VMPVENT);
+ FREE(pv, M_VMPVENT);
if ((pv = npv) == NULL)
break;
}
pv0->pv_pmap = NULL;
pv0->pv_next = NULL; /* ? */
pv0->pv_flags = flags;
- setcontext(ctx);
+ setcontext4m(ctx);
splx(s);
}
@@ -4925,8 +4787,7 @@ pmap_protect4m(pm, sva, eva, prot)
vm_offset_t sva, eva;
vm_prot_t prot;
{
- register vm_offset_t va, nva;
- register int vr, vs;
+ register int va, nva, vr, vs;
register int s, ctx;
struct regmap *rp;
struct segmap *sp;
@@ -4940,7 +4801,7 @@ pmap_protect4m(pm, sva, eva, prot)
}
write_user_windows();
- ctx = getcontext();
+ ctx = getcontext4m();
s = splpmap();
simple_lock(&pm->pm_lock);
@@ -4970,43 +4831,34 @@ pmap_protect4m(pm, sva, eva, prot)
if (sp->sg_pte == NULL)
panic("pmap_protect: no pages");
#endif
- /* in MMU: take away write bits from MMU PTEs */
- if (CTX_USABLE(pm,rp)) {
+ /* pages loaded: take away write bits from MMU PTEs */
+ if (pm->pm_ctx)
+ setcontext4m(pm->pm_ctxnum);
+
+ pmap_stats.ps_npg_prot_all = (nva - va) >> PGSHIFT;
+ for (; va < nva; va += NBPG) {
+ int tpte;
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
/*
* Flush cache so that any existing cache
* tags are updated. This is really only
* needed for PTEs that lose PG_W.
*/
- setcontext(pm->pm_ctxnum);
- for (; va < nva; va += NBPG) {
- register int tpte = getpte4m(va);
- pmap_stats.ps_npg_prot_all++;
- if ((tpte & (PPROT_WRITE|SRMMU_PGTYPE)) ==
- (PPROT_WRITE|PG_SUN4M_OBMEM)) {
- pmap_stats.ps_npg_prot_actual++;
- if (vactype != VAC_NONE)
- cache_flush_page(va);
- setpte4m(va, tpte & ~PPROT_WRITE);
+ if ((tpte & (PPROT_WRITE|SRMMU_PGTYPE)) ==
+ (PPROT_WRITE|PG_SUN4M_OBMEM)) {
+ pmap_stats.ps_npg_prot_actual++;
+ if (pm->pm_ctx) {
+ cache_flush_page(va);
+ tlb_flush_page(va);
}
- }
- } else {
- /*
- * No context, hence not cached;
- * just update PTEs.
- */
- setcontext(0);
- for (; va < nva; va += NBPG) {
- register int tpte = getptesw4m(pm, va);
- pmap_stats.ps_npg_prot_all++;
- if ((tpte & (PPROT_WRITE)))
- pmap_stats.ps_npg_prot_actual++;
- setptesw4m(pm, va, tpte & ~PPROT_WRITE);
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)],
+ tpte & ~PPROT_WRITE);
}
}
}
simple_unlock(&pm->pm_lock);
splx(s);
- setcontext(ctx);
+ setcontext4m(ctx);
}
/*
@@ -5025,7 +4877,7 @@ pmap_changeprot4m(pm, va, prot, wired)
#ifdef DEBUG
if (pmapdebug & PDB_CHANGEPROT)
- printf("pmap_changeprot(%p, %lx, %x, %x)\n",
+ printf("pmap_changeprot(%p, 0x%lx, 0x%x, 0x%x)\n",
pm, va, prot, wired);
#endif
@@ -5040,31 +4892,33 @@ pmap_changeprot4m(pm, va, prot, wired)
pmap_stats.ps_changeprots++;
s = splpmap(); /* conservative */
- ctx = getcontext();
+ ctx = getcontext4m();
if (pm->pm_ctx) {
- setcontext(pm->pm_ctxnum);
+ /*
+ * Use current context.
+ * Flush cache if page has been referenced to
+ * avoid stale protection bits in the cache tags.
+ */
+ setcontext4m(pm->pm_ctxnum);
tpte = getpte4m(va);
- if (vactype == VAC_WRITEBACK &&
- (tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM)
- cache_flush_page(va); /* XXX: paranoia? */
+ if ((tpte & (SRMMU_PG_C|SRMMU_PGTYPE)) ==
+ (SRMMU_PG_C|PG_SUN4M_OBMEM))
+ cache_flush_page(va);
} else {
tpte = getptesw4m(pm, va);
}
if ((tpte & SRMMU_PROT_MASK) == newprot) {
- setcontext(ctx);
- goto useless;
+ /* only wiring changed, and we ignore wiring */
+ pmap_stats.ps_useless_changeprots++;
+ goto out;
}
if (pm->pm_ctx)
setpte4m(va, (tpte & ~SRMMU_PROT_MASK) | newprot);
else
setptesw4m(pm, va, (tpte & ~SRMMU_PROT_MASK) | newprot);
- setcontext(ctx);
- splx(s);
- return;
-useless:
- /* only wiring changed, and we ignore wiring */
- pmap_stats.ps_useless_changeprots++;
+out:
+ setcontext4m(ctx);
splx(s);
}
#endif /* 4m */
@@ -5099,7 +4953,7 @@ pmap_enter4_4c(pm, va, pa, prot, wired)
if (VA_INHOLE(va)) {
#ifdef DEBUG
- printf("pmap_enter: pm %p, va %lx, pa %lx: in MMU hole\n",
+ printf("pmap_enter: pm %p, va 0x%lx, pa 0x%lx: in MMU hole\n",
pm, va, pa);
#endif
return;
@@ -5107,12 +4961,12 @@ pmap_enter4_4c(pm, va, pa, prot, wired)
#ifdef DEBUG
if (pmapdebug & PDB_ENTER)
- printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
+ printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
pm, va, pa, prot, wired);
#endif
- pteproto = PG_V | ((pa & PMAP_TNC) << PG_TNC_SHIFT);
- pa &= ~PMAP_TNC;
+ pteproto = PG_V | PMAP_T2PTE_4(pa);
+ pa &= ~PMAP_TNC_4;
/*
* Set up prototype for new PTE. Cannot set PG_NC from PV_NC yet
* since the pvlist no-cache bit might change as a result of the
@@ -5121,7 +4975,7 @@ pmap_enter4_4c(pm, va, pa, prot, wired)
if ((pteproto & PG_TYPE) == PG_OBMEM && managed(pa)) {
#ifdef DIAGNOSTIC
if (!pmap_pa_exists(pa))
- panic("pmap_enter: no such address: %lx", pa);
+ panic("pmap_enter: no such address: 0x%lx", pa);
#endif
pv = pvhead(pa);
} else {
@@ -5131,12 +4985,12 @@ pmap_enter4_4c(pm, va, pa, prot, wired)
if (prot & VM_PROT_WRITE)
pteproto |= PG_W;
- ctx = getcontext();
+ ctx = getcontext4();
if (pm == pmap_kernel())
pmap_enk4_4c(pm, va, prot, wired, pv, pteproto | PG_S);
else
pmap_enu4_4c(pm, va, prot, wired, pv, pteproto);
- setcontext(ctx);
+ setcontext4(ctx);
}
/* enter new (or change existing) kernel mapping */
@@ -5159,13 +5013,13 @@ pmap_enk4_4c(pm, va, prot, wired, pv, pteproto)
sp = &rp->rg_segmap[vs];
s = splpmap(); /* XXX way too conservative */
-#ifdef MMU_3L
- if (mmu_3l && rp->rg_smeg == reginval) {
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
vm_offset_t tva;
rp->rg_smeg = region_alloc(&region_locked, pm, vr)->me_cookie;
i = ncontext - 1;
do {
- setcontext(i);
+ setcontext4(i);
setregmap(va, rp->rg_smeg);
} while (--i >= 0);
@@ -5185,13 +5039,13 @@ pmap_enk4_4c(pm, va, prot, wired, pv, pteproto)
(pteproto & (PG_PFNUM|PG_TYPE))) {
/* just changing protection and/or wiring */
splx(s);
- pmap_changeprot(pm, va, prot, wired);
+ pmap_changeprot4_4c(pm, va, prot, wired);
return;
}
if ((tpte & PG_TYPE) == PG_OBMEM) {
#ifdef DEBUG
-printf("pmap_enk: changing existing va=>pa entry: va %lx, pteproto %x\n",
+printf("pmap_enk: changing existing va=>pa entry: va 0x%lx, pteproto 0x%x\n",
va, pteproto);
#endif
/*
@@ -5203,9 +5057,8 @@ printf("pmap_enk: changing existing va=>pa entry: va %lx, pteproto %x\n",
if (managed(addr))
pv_unlink4_4c(pvhead(addr), pm, va);
if ((tpte & PG_NC) == 0) {
- setcontext(0); /* ??? */
- if (vactype != VAC_NONE)
- cache_flush_page((int)va);
+ setcontext4(0); /* ??? */
+ cache_flush_page((int)va);
}
}
} else {
@@ -5237,15 +5090,15 @@ printf("pmap_enk: changing existing va=>pa entry: va %lx, pteproto %x\n",
sp->sg_pmeg = me_alloc(&segm_locked, pm, vr, vs)->me_cookie;
rp->rg_nsegmap++;
-#ifdef MMU_3L
- if (mmu_3l)
+#if defined(SUN4_MMU3L)
+ if (HASSUN4_MMU3L)
setsegmap(va, sp->sg_pmeg);
else
#endif
{
i = ncontext - 1;
do {
- setcontext(i);
+ setcontext4(i);
setsegmap(va, sp->sg_pmeg);
} while (--i >= 0);
}
@@ -5297,7 +5150,7 @@ pmap_enu4_4c(pm, va, prot, wired, pv, pteproto)
#ifdef DEBUG
if (pm->pm_gap_end < pm->pm_gap_start) {
- printf("pmap_enu: gap_start %x, gap_end %x",
+ printf("pmap_enu: gap_start 0x%x, gap_end 0x%x",
pm->pm_gap_start, pm->pm_gap_end);
panic("pmap_enu: gap botch");
}
@@ -5352,16 +5205,14 @@ printf("pmap_enter: pte filled during sleep\n"); /* can this happen? */
} else {
/* hardware pte */
if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
tpte = getpte4(va);
- doflush = 1;
+ doflush = CACHEINFO.c_vactype != VAC_NONE;
} else {
- setcontext(0);
+ setcontext4(0);
/* XXX use per-cpu pteva? */
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, pmeg);
tpte = getpte4(VA_VPG(va) << PGSHIFT);
}
@@ -5387,14 +5238,15 @@ printf("pmap_enter: pte filled during sleep\n"); /* can this happen? */
* If old pa was managed, remove from pvlist.
* If old page was cached, flush cache.
*/
-/*printf("%s[%d]: pmap_enu: changing existing va(%x)=>pa entry\n",
-curproc->p_comm, curproc->p_pid, va);*/
+#if 0
+printf("%s[%d]: pmap_enu: changing existing va(0x%x)=>pa entry\n",
+ curproc->p_comm, curproc->p_pid, va);
+#endif
if ((tpte & PG_TYPE) == PG_OBMEM) {
addr = ptoa(tpte & PG_PFNUM);
if (managed(addr))
pv_unlink4_4c(pvhead(addr), pm, va);
- if (vactype != VAC_NONE &&
- doflush && (tpte & PG_NC) == 0)
+ if (doflush && (tpte & PG_NC) == 0)
cache_flush_page((int)va);
}
} else {
@@ -5416,16 +5268,14 @@ curproc->p_comm, curproc->p_pid, va);*/
* Update hardware & software PTEs.
*/
if ((pmeg = sp->sg_pmeg) != seginval) {
- /* ptes are in hardare */
+ /* ptes are in hardware */
if (CTX_USABLE(pm,rp))
- setcontext(pm->pm_ctxnum);
+ setcontext4(pm->pm_ctxnum);
else {
- setcontext(0);
+ setcontext4(0);
/* XXX use per-cpu pteva? */
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, pmeg);
va = VA_VPG(va) << PGSHIFT;
}
@@ -5469,24 +5319,26 @@ pmap_enter4m(pm, va, pa, prot, wired)
#ifdef DEBUG
if (pmapdebug & PDB_ENTER)
- printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
+ printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
pm, va, pa, prot, wired);
#endif
/* Initialise pteproto with cache bit */
pteproto = (pa & PMAP_NC) == 0 ? SRMMU_PG_C : 0;
- if (pa & PMAP_TYPE4M) { /* this page goes in an iospace */
- if (cpumod == SUN4M_MS)
+#ifdef DEBUG
+ if (pa & PMAP_TYPE_SRMMU) { /* this page goes in an iospace */
+ if (cpuinfo.cpu_type == CPUTYP_MS1)
panic("pmap_enter4m: attempt to use 36-bit iospace on"
" MicroSPARC");
- pteproto |= (pa & PMAP_TYPE4M) << PMAP_PTESHFT4M;
}
+#endif
+ pteproto |= PMAP_T2PTE_SRMMU(pa);
/* Make sure we get a pte with appropriate perms! */
pteproto |= SRMMU_TEPTE | PPROT_RX_RX;
- pa &= ~PMAP_TNC;
+ pa &= ~PMAP_TNC_SRMMU;
/*
* Set up prototype for new PTE. Cannot set PG_NC from PV_NC yet
* since the pvlist no-cache bit might change as a result of the
@@ -5495,7 +5347,7 @@ pmap_enter4m(pm, va, pa, prot, wired)
if ((pteproto & SRMMU_PGTYPE) == PG_SUN4M_OBMEM && managed(pa)) {
#ifdef DIAGNOSTIC
if (!pmap_pa_exists(pa))
- panic("pmap_enter: no such address: %lx", pa);
+ panic("pmap_enter: no such address: 0x%lx", pa);
#endif
pv = pvhead(pa);
} else {
@@ -5506,14 +5358,14 @@ pmap_enter4m(pm, va, pa, prot, wired)
if (prot & VM_PROT_WRITE)
pteproto |= PPROT_WRITE;
- ctx = getcontext();
+ ctx = getcontext4m();
if (pm == pmap_kernel())
pmap_enk4m(pm, va, prot, wired, pv, pteproto | PPROT_S);
else
pmap_enu4m(pm, va, prot, wired, pv, pteproto);
- setcontext(ctx);
+ setcontext4m(ctx);
}
/* enter new (or change existing) kernel mapping */
@@ -5532,7 +5384,7 @@ pmap_enk4m(pm, va, prot, wired, pv, pteproto)
#ifdef DEBUG
if (va < KERNBASE)
- panic("pmap_enk4m: can't enter va 0x%lx below KERNBASE",va);
+ panic("pmap_enk4m: can't enter va 0x%lx below KERNBASE", va);
#endif
vr = VA_VREG(va);
vs = VA_VSEG(va);
@@ -5542,9 +5394,10 @@ pmap_enk4m(pm, va, prot, wired, pv, pteproto)
s = splpmap(); /* XXX way too conservative */
if (rp->rg_seg_ptps == NULL) /* enter new region */
- panic("pmap_enk4m: missing kernel region table for va %lx",va);
+ panic("pmap_enk4m: missing kernel region table for va 0x%lx",va);
- if (((tpte = getpte4m(va)) & SRMMU_TETYPE) == SRMMU_TEPTE) {
+ tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
+ if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) {
register int addr;
/* old mapping exists, and is of the same pa type */
@@ -5552,14 +5405,14 @@ pmap_enk4m(pm, va, prot, wired, pv, pteproto)
if ((tpte & SRMMU_PPNMASK) == (pteproto & SRMMU_PPNMASK)) {
/* just changing protection and/or wiring */
splx(s);
- pmap_changeprot(pm, va, prot, wired);
+ pmap_changeprot4m(pm, va, prot, wired);
return;
}
if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
#ifdef DEBUG
-printf("pmap_enk4m: changing existing va=>pa entry: va %lx, pteproto %x, "
- "oldpte %x\n", va, pteproto, tpte);
+printf("pmap_enk4m: changing existing va=>pa entry: va 0x%lx, pteproto 0x%x, "
+ "oldpte 0x%x\n", va, pteproto, tpte);
#endif
/*
* Switcheroo: changing pa for this va.
@@ -5570,9 +5423,8 @@ printf("pmap_enk4m: changing existing va=>pa entry: va %lx, pteproto %x, "
if (managed(addr))
pv_unlink4m(pvhead(addr), pm, va);
if (tpte & SRMMU_PG_C) {
- setcontext(0); /* ??? */
- if (vactype != VAC_NONE)
- cache_flush_page((int)va);
+ setcontext4m(0); /* ??? */
+ cache_flush_page((int)va);
}
}
} else {
@@ -5588,11 +5440,13 @@ printf("pmap_enk4m: changing existing va=>pa entry: va %lx, pteproto %x, "
if (pv != NULL)
pteproto &= ~(pv_link4m(pv, pm, va));
+#ifdef DEBUG
if (sp->sg_pte == NULL) /* If no existing pagetable */
panic("pmap_enk4m: missing segment table for va 0x%lx",va);
+#endif
- /* ptes kept in hardware only */
- setpte4m(va, pteproto);
+ tlb_flush_page(va);
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto);
splx(s);
}
@@ -5607,24 +5461,21 @@ pmap_enu4m(pm, va, prot, wired, pv, pteproto)
register struct pvlist *pv;
register int pteproto;
{
- register int vr, vs, *pte, tpte, s, doflush;
+ register int vr, vs, *pte, tpte, s;
struct regmap *rp;
struct segmap *sp;
+#ifdef DEBUG
+ if (KERNBASE < va)
+ panic("pmap_enu4m: can't enter va 0x%lx above KERNBASE", va);
+#endif
+
write_user_windows(); /* XXX conservative */
vr = VA_VREG(va);
vs = VA_VSEG(va);
rp = &pm->pm_regmap[vr];
s = splpmap(); /* XXX conservative */
-#ifdef DEBUG
- if (pm->pm_gap_end < pm->pm_gap_start) {
- printf("pmap_enu: gap_start %x, gap_end %x",
- pm->pm_gap_start, pm->pm_gap_end);
- panic("pmap_enu: gap botch");
- }
-#endif
-
rretry:
if (rp->rg_segmap == NULL) {
/* definitely a new mapping */
@@ -5646,24 +5497,27 @@ printf("pmap_enu4m: segment filled during sleep\n"); /* can this happen? */
rgretry:
if (rp->rg_seg_ptps == NULL) {
/* Need a segment table */
- register int size;
- register caddr_t tblp;
+ int size, i, *ptd;
+
size = SRMMU_L2SIZE * sizeof(long);
- tblp = malloc(size, M_VMPMAP, M_WAITOK);
+ ptd = (int *)malloc(size, M_VMPMAP, M_WAITOK);
if (rp->rg_seg_ptps != NULL) {
#ifdef DEBUG
printf("pmap_enu4m: bizarre segment table fill during sleep\n");
#endif
- free(tblp,M_VMPMAP);
+ free(ptd, M_VMPMAP);
goto rgretry;
}
- if (cant_cache_pagetables)
- kvm_uncache(tblp, (size+NBPG-1)/NBPG);
+#if 0
+ if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0)
+ kvm_uncache((char *)ptd, (size+NBPG-1)/NBPG);
+#endif
- rp->rg_seg_ptps = (int *)tblp;
- qzero(tblp, size);
- pm->pm_reg_ptps[vr] =
- (VA2PA(tblp) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
+ rp->rg_seg_ptps = ptd;
+ for (i = 0; i < SRMMU_L2SIZE; i++)
+ setpgt4m(&ptd[i], SRMMU_TEINVALID);
+ setpgt4m(&pm->pm_reg_ptps[vr],
+ (VA2PA((caddr_t)ptd) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
}
sp = &rp->rg_segmap[vs];
@@ -5671,7 +5525,7 @@ printf("pmap_enu4m: bizarre segment table fill during sleep\n");
sretry:
if ((pte = sp->sg_pte) == NULL) {
/* definitely a new mapping */
- register int size = SRMMU_L3SIZE * sizeof(*pte);
+ int i, size = SRMMU_L3SIZE * sizeof(*pte);
pte = (int *)malloc((u_long)size, M_VMPMAP, M_WAITOK);
if (sp->sg_pte != NULL) {
@@ -5679,26 +5533,26 @@ printf("pmap_enter: pte filled during sleep\n"); /* can this happen? */
free(pte, M_VMPMAP);
goto sretry;
}
- if (cant_cache_pagetables)
+#if 0
+ if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0)
kvm_uncache((caddr_t)pte, (size+NBPG-1)/NBPG);
+#endif
- qzero((caddr_t)pte, size);
sp->sg_pte = pte;
sp->sg_npte = 1;
rp->rg_nsegmap++;
- rp->rg_seg_ptps[vs] =
- (VA2PA((caddr_t)pte) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
+ for (i = 0; i < SRMMU_L3SIZE; i++)
+ setpgt4m(&pte[i], SRMMU_TEINVALID);
+ setpgt4m(&rp->rg_seg_ptps[vs],
+ (VA2PA((caddr_t)pte) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
} else {
- /* might be a change: fetch old pte */
- doflush = 0;
+ /*
+ * Might be a change: fetch old pte
+ * Note we're only interested in the PTE's page frame
+ * number and type bits, so the memory copy will do.
+ */
+ tpte = pte[VA_SUN4M_VPG(va)];
- if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
- tpte = getpte4m(va);
- doflush = 1;
- } else {
- tpte = getptesw4m(pm, va);
- }
if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) {
register int addr;
@@ -5721,17 +5575,16 @@ printf("pmap_enter: pte filled during sleep\n"); /* can this happen? */
* If old page was cached, flush cache.
*/
#ifdef DEBUG
-if (pmapdebug & PDB_ENTER)
-printf("%s[%d]: pmap_enu: changing existing va(%x)=>pa(pte=%x) entry\n",
-curproc->p_comm, curproc->p_pid, (int)va, (int)pte);
+if (pmapdebug & PDB_SWITCHMAP)
+printf("%s[%d]: pmap_enu: changing existing va(0x%x)=>pa(pte=0x%x) entry\n",
+ curproc->p_comm, curproc->p_pid, (int)va, (int)pte);
#endif
if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
addr = ptoa( (tpte & SRMMU_PPNMASK) >>
SRMMU_PPNSHIFT);
if (managed(addr))
pv_unlink4m(pvhead(addr), pm, va);
- if (vactype != VAC_NONE &&
- doflush && (tpte & SRMMU_PG_C))
+ if (pm->pm_ctx && (tpte & SRMMU_PG_C))
cache_flush_page((int)va);
}
} else {
@@ -5749,14 +5602,13 @@ curproc->p_comm, curproc->p_pid, (int)va, (int)pte);
pteproto &= ~(pv_link4m(pv, pm, va));
/*
- * Update hardware & software PTEs.
+ * Update PTEs, flush TLB as necessary.
*/
- if (CTX_USABLE(pm,rp)) {
- setcontext(pm->pm_ctxnum);
- setpte4m(va, pteproto);
- } else
- setptesw4m(pm, va, pteproto);
- /* XXX: restore previous context here? */
+ if (pm->pm_ctx) {
+ setcontext4m(pm->pm_ctxnum);
+ tlb_flush_page(va);
+ }
+ setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto);
splx(s);
}
@@ -5794,45 +5646,55 @@ pmap_extract4_4c(pm, va)
struct segmap *sp;
if (pm == NULL) {
- printf("pmap_extract: null pmap\n");
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: null pmap\n");
+#endif
return (0);
}
vr = VA_VREG(va);
vs = VA_VSEG(va);
rp = &pm->pm_regmap[vr];
if (rp->rg_segmap == NULL) {
- printf("pmap_extract: invalid segment (%d)\n", vr);
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: invalid segment (%d)\n", vr);
+#endif
return (0);
}
sp = &rp->rg_segmap[vs];
if (sp->sg_pmeg != seginval) {
- register int ctx = getcontext();
+ register int ctx = getcontext4();
if (CTX_USABLE(pm,rp)) {
CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
tpte = getpte4(va);
} else {
CHANGE_CONTEXTS(ctx, 0);
-#ifdef MMU_3L
- if (mmu_3l)
+ if (HASSUN4_MMU3L)
setregmap(0, tregion);
-#endif
setsegmap(0, sp->sg_pmeg);
tpte = getpte4(VA_VPG(va) << PGSHIFT);
}
- setcontext(ctx);
+ setcontext4(ctx);
} else {
register int *pte = sp->sg_pte;
if (pte == NULL) {
- printf("pmap_extract: invalid segment\n");
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: invalid segment\n");
+#endif
return (0);
}
tpte = pte[VA_VPG(va)];
}
if ((tpte & PG_V) == 0) {
- printf("pmap_extract: invalid pte\n");
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: invalid pte\n");
+#endif
return (0);
}
tpte &= PG_PFNUM;
@@ -5852,30 +5714,46 @@ pmap_extract4m(pm, va)
register struct pmap *pm;
vm_offset_t va;
{
- register int tpte, ctx;
+ struct regmap *rm;
+ struct segmap *sm;
+ int pte;
if (pm == NULL) {
- printf("pmap_extract: null pmap\n");
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: null pmap\n");
+#endif
return (0);
}
- if (pm->pm_ctx) {
- ctx = getcontext();
- CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
- tpte = getpte4m(va);
+ rm = &pm->pm_regmap[VA_VREG(va)];
+ if (rm == NULL) {
#ifdef DEBUG
- if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
- printf("pmap_extract: invalid pte of type %d\n",
- tpte & SRMMU_TETYPE);
- return (0);
- }
+ if (pmapdebug & PDB_FOLLOW)
+ printf("getptesw4m: no regmap entry");
#endif
- setcontext(ctx);
- } else
- tpte = getptesw4m(pm, va);
+ return (0);
+ }
+ sm = &rm->rg_segmap[VA_VSEG(va)];
+ if (sm == NULL) {
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ panic("getptesw4m: no segmap");
+#endif
+ return (0);
+ }
+ pte = sm->sg_pte[VA_SUN4M_VPG(va)];
+ if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) {
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract: invalid pte of type %d\n",
+ pte & SRMMU_TETYPE);
+#endif
+ return (0);
+ }
- return (ptoa((tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT) | VA_OFF(va));
+ return (ptoa((pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT) | VA_OFF(va));
}
#endif /* sun4m */
@@ -5954,7 +5832,7 @@ pmap_clear_modify4_4c(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_4 & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
(void) pv_syncflags4_4c(pv);
pv->pv_flags &= ~PV_MOD;
@@ -5970,7 +5848,7 @@ pmap_is_modified4_4c(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_4 & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
if (pv->pv_flags & PV_MOD || pv_syncflags4_4c(pv) & PV_MOD)
return (1);
@@ -5987,7 +5865,7 @@ pmap_clear_reference4_4c(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_4 & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
(void) pv_syncflags4_4c(pv);
pv->pv_flags &= ~PV_REF;
@@ -6003,7 +5881,7 @@ pmap_is_referenced4_4c(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_4 & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
if (pv->pv_flags & PV_REF || pv_syncflags4_4c(pv) & PV_REF)
return (1);
@@ -6032,7 +5910,7 @@ pmap_clear_modify4m(pa) /* XXX %%%: Should service from swpagetbl for 4m */
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
(void) pv_syncflags4m(pv);
pv->pv_flags &= ~PV_MOD4M;
@@ -6048,7 +5926,7 @@ pmap_is_modified4m(pa) /* Test performance with SUN4M && SUN4/4C. XXX */
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
if (pv->pv_flags & PV_MOD4M || pv_syncflags4m(pv) & PV_MOD4M)
return(1);
@@ -6065,7 +5943,7 @@ pmap_clear_reference4m(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
(void) pv_syncflags4m(pv);
pv->pv_flags &= ~PV_REF4M;
@@ -6081,7 +5959,7 @@ pmap_is_referenced4m(pa)
{
register struct pvlist *pv;
- if ((pa & (PMAP_TNC & ~PMAP_NC)) == 0 && managed(pa)) {
+ if ((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0 && managed(pa)) {
pv = pvhead(pa);
if (pv->pv_flags & PV_REF4M || pv_syncflags4m(pv) & PV_REF4M)
return(1);
@@ -6125,14 +6003,13 @@ pmap_zero_page4_4c(pa)
register caddr_t va;
register int pte;
- if (((pa & (PMAP_TNC & ~PMAP_NC)) == 0) && managed(pa)) {
+ if (((pa & (PMAP_TNC_4 & ~PMAP_NC)) == 0) && managed(pa)) {
/*
* The following might not be necessary since the page
* is being cleared because it is about to be allocated,
* i.e., is in use by no one.
*/
- if (vactype != VAC_NONE)
- pv_flushcache(pvhead(pa));
+ pv_flushcache(pvhead(pa));
}
pte = PG_V | PG_S | PG_W | PG_NC | (atop(pa) & PG_PFNUM);
@@ -6159,14 +6036,14 @@ pmap_copy_page4_4c(src, dst)
register int spte, dpte;
if (managed(src)) {
- if (vactype == VAC_WRITEBACK)
+ if (CACHEINFO.c_vactype == VAC_WRITEBACK)
pv_flushcache(pvhead(src));
}
spte = PG_V | PG_S | (atop(src) & PG_PFNUM);
if (managed(dst)) {
/* similar `might not be necessary' comment applies */
- if (vactype != VAC_NONE)
+ if (CACHEINFO.c_vactype != VAC_NONE)
pv_flushcache(pvhead(dst));
}
dpte = PG_V | PG_S | PG_W | PG_NC | (atop(dst) & PG_PFNUM);
@@ -6176,8 +6053,7 @@ pmap_copy_page4_4c(src, dst)
setpte4(sva, spte);
setpte4(dva, dpte);
qcopy(sva, dva, NBPG); /* loads cache, so we must ... */
- if (vactype != VAC_NONE)
- cache_flush_page((int)sva);
+ cache_flush_page((int)sva);
setpte4(sva, 0);
setpte4(dva, 0);
}
@@ -6196,28 +6072,32 @@ pmap_zero_page4m(pa)
{
register caddr_t va;
register int pte;
+ int ctx;
- if (((pa & (PMAP_TNC & ~PMAP_NC)) == 0) && managed(pa)) {
+ if (((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0) && managed(pa)) {
/*
* The following might not be necessary since the page
* is being cleared because it is about to be allocated,
* i.e., is in use by no one.
*/
- if (vactype != VAC_NONE)
+ if (CACHEINFO.c_vactype != VAC_NONE)
pv_flushcache(pvhead(pa));
}
- /*
- * there really needs to be a conditional ecache flush here, but
- * making the page cacheable avoids problems with potentially
- * leaving dirty cache lines pending in the e-cache while the page
- * is marked non-cachable. Per Chris Torek and Aaron Brown...
- */
- pte = SRMMU_PG_C | (SRMMU_TEPTE | PPROT_S | PPROT_WRITE |
- (atop(pa) << SRMMU_PPNSHIFT));
+ pte = (SRMMU_TEPTE | PPROT_S | PPROT_WRITE |
+ (atop(pa) << SRMMU_PPNSHIFT));
+ if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
+ pte |= SRMMU_PG_C;
+ else
+ pte &= ~SRMMU_PG_C;
+
+ /* XXX - must use context 0 or else setpte4m() will fail */
+ ctx = getcontext4m();
+ setcontext4m(0);
va = vpage[0];
setpte4m((vm_offset_t) va, pte);
qzero(va, NBPG);
setpte4m((vm_offset_t) va, SRMMU_TEINVALID);
+ setcontext4m(ctx);
}
/*
@@ -6235,9 +6115,10 @@ pmap_copy_page4m(src, dst)
{
register caddr_t sva, dva;
register int spte, dpte;
+ int ctx;
if (managed(src)) {
- if (vactype == VAC_WRITEBACK)
+ if (CACHEINFO.c_vactype == VAC_WRITEBACK)
pv_flushcache(pvhead(src));
}
spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_S |
@@ -6245,27 +6126,28 @@ pmap_copy_page4m(src, dst)
if (managed(dst)) {
/* similar `might not be necessary' comment applies */
- if (vactype != VAC_NONE)
+ if (CACHEINFO.c_vactype != VAC_NONE)
pv_flushcache(pvhead(dst));
}
- /*
- * there really needs to be a conditional ecache flush here, but
- * making the page cacheable avoids problems with potentially
- * leaving dirty cache lines pending in the e-cache while the page
- * is marked non-cachable. Per Chris Torek and Aaron Brown...
- */
- dpte = SRMMU_PG_C | (SRMMU_TEPTE | PPROT_S | PPROT_WRITE |
- (atop(dst) << SRMMU_PPNSHIFT));
+ dpte = (SRMMU_TEPTE | PPROT_S | PPROT_WRITE |
+ (atop(dst) << SRMMU_PPNSHIFT));
+ if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
+ dpte |= SRMMU_PG_C;
+ else
+ dpte &= ~SRMMU_PG_C;
+ /* XXX - must use context 0 or else setpte4m() will fail */
+ ctx = getcontext4m();
+ setcontext4m(0);
sva = vpage[0];
dva = vpage[1];
setpte4m((vm_offset_t) sva, spte);
setpte4m((vm_offset_t) dva, dpte);
qcopy(sva, dva, NBPG); /* loads cache, so we must ... */
- if (vactype != VAC_NONE)
- cache_flush_page((int)sva);
+ cache_flush_page((int)sva);
setpte4m((vm_offset_t) sva, SRMMU_TEINVALID);
setpte4m((vm_offset_t) dva, SRMMU_TEINVALID);
+ setcontext4m(ctx);
}
#endif /* Sun4M */
@@ -6294,6 +6176,7 @@ kvm_uncache(va, npages)
register int npages;
{
register int pte;
+
if (CPU_ISSUN4M) {
#if defined(SUN4M)
for (; --npages >= 0; va += NBPG) {
@@ -6302,7 +6185,7 @@ kvm_uncache(va, npages)
panic("kvm_uncache: table entry not pte");
pte &= ~SRMMU_PG_C;
setpte4m((vm_offset_t) va, pte);
- if (vactype != VAC_NONE && (pte & PG_TYPE) == PG_OBMEM)
+ if ((pte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM)
cache_flush_page((int)va);
}
#endif
@@ -6314,7 +6197,7 @@ kvm_uncache(va, npages)
panic("kvm_uncache !pg_v");
pte |= PG_NC;
setpte4(va, pte);
- if (vactype != VAC_NONE && (pte & PG_TYPE) == PG_OBMEM)
+ if ((pte & PG_TYPE) == PG_OBMEM)
cache_flush_page((int)va);
}
#endif
@@ -6437,20 +6320,21 @@ pm_check_u(s, pm)
int n, vs, vr, j, m, *pte;
if (pm->pm_regmap == NULL)
- panic("%s: CHK(pmap %p): no region mapping", s, pm);
+ panic("%s: CHK(pmap %p): no region mapping", s, pm);
#if defined(SUN4M)
if (CPU_ISSUN4M &&
(pm->pm_reg_ptps == NULL ||
pm->pm_reg_ptps_pa != VA2PA((caddr_t)pm->pm_reg_ptps)))
- panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: tblva=%p, tblpa=0x%x",
- s, pm, pm->pm_reg_ptps, pm->pm_reg_ptps_pa);
+ panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: "
+ "tblva=%p, tblpa=0x%x",
+ s, pm, pm->pm_reg_ptps, pm->pm_reg_ptps_pa);
if (CPU_ISSUN4M && pm->pm_ctx != NULL &&
- (ctx_phys_tbl[pm->pm_ctxnum] != ((VA2PA((caddr_t)pm->pm_reg_ptps)
+ (cpuinfo.ctx_tbl[pm->pm_ctxnum] != ((VA2PA((caddr_t)pm->pm_reg_ptps)
>> SRMMU_PPNPASHIFT) |
SRMMU_TEPTD)))
- panic("%s: CHK(pmap %p): SRMMU region table at %x not installed "
+ panic("%s: CHK(pmap %p): SRMMU region table at 0x%x not installed "
"for context %d", s, pm, pm->pm_reg_ptps_pa, pm->pm_ctxnum);
#endif
@@ -6529,13 +6413,13 @@ pm_check_k(s, pm) /* Note: not as extensive as pm_check_u. */
if (CPU_ISSUN4M &&
(pm->pm_reg_ptps == NULL ||
pm->pm_reg_ptps_pa != VA2PA((caddr_t)pm->pm_reg_ptps)))
- panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: tblva=%p, tblpa=%x",
+ panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: tblva=%p, tblpa=0x%x",
s, pm, pm->pm_reg_ptps, pm->pm_reg_ptps_pa);
if (CPU_ISSUN4M &&
- (ctx_phys_tbl[0] != ((VA2PA((caddr_t)pm->pm_reg_ptps) >>
+ (cpuinfo.ctx_tbl[0] != ((VA2PA((caddr_t)pm->pm_reg_ptps) >>
SRMMU_PPNPASHIFT) | SRMMU_TEPTD)))
- panic("%s: CHK(pmap %p): SRMMU region table at %x not installed "
+ panic("%s: CHK(pmap %p): SRMMU region table at 0x%x not installed "
"for context %d", s, pm, pm->pm_reg_ptps_pa, 0);
#endif
for (vr = NUREG; vr < NUREG+NKREG; vr++) {
@@ -6554,10 +6438,13 @@ pm_check_k(s, pm) /* Note: not as extensive as pm_check_u. */
SRMMU_PPNPASHIFT) | SRMMU_TEPTD))
panic("%s: CHK(vr %d): SRMMU segtbl not installed",s,vr);
#endif
- n = 0;
- for (vs = 0; vs < NSEGRG; vs++) {
- if (rp->rg_segmap[vs].sg_npte)
- n++;
+ if (CPU_ISSUN4M) {
+ n = NSEGRG;
+ } else {
+ for (n = 0, vs = 0; vs < NSEGRG; vs++) {
+ if (rp->rg_segmap[vs].sg_npte)
+ n++;
+ }
}
if (n != rp->rg_nsegmap)
printf("%s: kernel CHK(vr %d): inconsistent "
@@ -6588,10 +6475,9 @@ pmap_dumpsize()
}
/*
- * Write the dump header and memory mapping information at the front
- * of the dumpfile to make life easy for savecore and libkvm. Also
- * dump the MMU contents for Sun 4/4c systems since they don't have
- * a separate incore copy of the kernel memory mappings.
+ * Write the mmu contents to the dump device.
+ * This gets appended to the end of a crash dump since
+ * there is no in-core copy of kernel memory mappings on a 4/4c machine.
*/
int
pmap_dumpmmu(dump, blkno)
@@ -6601,9 +6487,9 @@ pmap_dumpmmu(dump, blkno)
kcore_seg_t *ksegp;
cpu_kcore_hdr_t *kcpup;
phys_ram_seg_t memseg;
- register int error = 0;
+ register int error = 0;
register int i, memsegoffset, pmegoffset;
- int buffer[dbtob(1) / sizeof(int)];
+ int buffer[dbtob(1) / sizeof(int)];
int *bp, *ep;
#if defined(SUN4C) || defined(SUN4)
register int pmeg;
@@ -6622,7 +6508,7 @@ pmap_dumpmmu(dump, blkno)
++blkno; \
bp = buffer; \
} \
- sz -= sizeof *sp; \
+ sz -= 4; \
} \
} while (0)
@@ -6653,7 +6539,7 @@ pmap_dumpmmu(dump, blkno)
/* Align storage for upcoming quad-aligned segment array */
while (bp != (int *)ALIGN(bp)) {
int dummy = 0;
- EXPEDITE(&dummy, sizeof dummy);
+ EXPEDITE(&dummy, 4);
}
for (i = 0; i < npmemarr; i++) {
memseg.start = pmemarr[i].addr;
@@ -6679,7 +6565,7 @@ pmap_dumpmmu(dump, blkno)
* Go through the pmegs and dump each one.
*/
for (pmeg = 0; pmeg <= seginval; ++pmeg) {
- register vm_offset_t va = 0;
+ register int va = 0;
setsegmap(va, pmeg);
i = NPTESG;
@@ -6712,7 +6598,7 @@ debug_pagetables()
printf("\nncontext=%d. ",ncontext);
printf("Context table is at va 0x%x. Level 0 PTP: 0x%x\n",
- ctx_phys_tbl, ctx_phys_tbl[0]);
+ cpuinfo.ctx_tbl, cpuinfo.ctx_tbl[0]);
printf("Context 0 region table is at va 0x%x, pa 0x%x. Contents:\n",
pmap_kernel()->pm_reg_ptps, pmap_kernel()->pm_reg_ptps_pa);
@@ -6761,7 +6647,7 @@ VA2PAsw(ctx, addr, pte)
printf("Looking up addr 0x%x in context 0x%x\n",addr,ctx);
#endif
/* L0 */
- *pte = curpte = ctx_phys_tbl[ctx];
+ *pte = curpte = cpuinfo.ctx_tbl[ctx];
#ifdef EXTREME_EXTREME_DEBUG
printf("Got L0 pte 0x%x\n",pte);
#endif
@@ -6866,7 +6752,7 @@ void print_fe_map(void)
for (i = 0xfe000000; i < 0xff000000; i+=4096) {
if (((pte = getpte4m(i)) & SRMMU_TETYPE) != SRMMU_TEPTE)
continue;
- printf("0x%x -> 0x%x%x (pte %x)\n", i, pte >> 28,
+ printf("0x%x -> 0x%x%x (pte 0x%x)\n", i, pte >> 28,
(pte & ~0xff) << 4, pte);
}
printf("done\n");
diff --git a/sys/arch/sparc/sparc/process_machdep.c b/sys/arch/sparc/sparc/process_machdep.c
index 3ea7669ede6..afaa37a2342 100644
--- a/sys/arch/sparc/sparc/process_machdep.c
+++ b/sys/arch/sparc/sparc/process_machdep.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: process_machdep.c,v 1.3 1997/08/08 08:27:39 downsj Exp $ */
/* $NetBSD: process_machdep.c,v 1.6 1996/03/14 21:09:26 christos Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/rd_root.c b/sys/arch/sparc/sparc/rd_root.c
index 6474f0d2188..7cffb24430f 100644
--- a/sys/arch/sparc/sparc/rd_root.c
+++ b/sys/arch/sparc/sparc/rd_root.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: rd_root.c,v 1.2 1997/08/08 08:27:40 downsj Exp $ */
/* $NetBSD: rd_root.c,v 1.2 1996/03/27 16:38:33 perry Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/sunos_machdep.c b/sys/arch/sparc/sparc/sunos_machdep.c
index 1a572199112..d013f076741 100644
--- a/sys/arch/sparc/sparc/sunos_machdep.c
+++ b/sys/arch/sparc/sparc/sunos_machdep.c
@@ -1,7 +1,8 @@
-/* $NetBSD: sunos_machdep.c,v 1.3 1995/10/07 06:26:08 mycroft Exp $ */
+/* $OpenBSD: sunos_machdep.c,v 1.2 1997/08/08 08:27:41 downsj Exp $ */
+/* $NetBSD: sunos_machdep.c,v 1.4 1996/10/05 23:44:33 mrg Exp $ */
/*
- * Copyright (c) 1995 Matthew Green
+ * Copyright (c) 1995 Matthew R. Green
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -12,18 +13,27 @@
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Matthew R. Green for
+ * the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * 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.
+ */
+
+/*
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
diff --git a/sys/arch/sparc/sparc/svr4_machdep.c b/sys/arch/sparc/sparc/svr4_machdep.c
index 0100d8bf9bb..92bb3522029 100644
--- a/sys/arch/sparc/sparc/svr4_machdep.c
+++ b/sys/arch/sparc/sparc/svr4_machdep.c
@@ -1,4 +1,5 @@
-/* $NetBSD: svr4_machdep.c,v 1.17.4.1 1996/06/11 01:46:42 jtc Exp $ */
+/* $OpenBSD: svr4_machdep.c,v 1.9 1997/08/08 08:27:42 downsj Exp $ */
+/* $NetBSD: svr4_machdep.c,v 1.24 1997/07/29 10:04:45 fair Exp $ */
/*
* Copyright (c) 1994 Christos Zoulas
@@ -40,6 +41,7 @@
#include <sys/signalvar.h>
#include <sys/malloc.h>
#include <sys/buf.h>
+#include <sys/exec.h>
#include <sys/syscallargs.h>
#include <compat/svr4/svr4_types.h>
@@ -77,31 +79,31 @@ svr4_printcontext(fun, uc)
printf("%s at %p\n", fun, uc);
printf("Regs: ");
- printf("PSR = %x ", r[SVR4_SPARC_PSR]);
- printf("PC = %x ", r[SVR4_SPARC_PC]);
- printf("nPC = %x ", r[SVR4_SPARC_nPC]);
- printf("Y = %x ", r[SVR4_SPARC_Y]);
- printf("G1 = %x ", r[SVR4_SPARC_G1]);
- printf("G2 = %x ", r[SVR4_SPARC_G2]);
- printf("G3 = %x ", r[SVR4_SPARC_G3]);
- printf("G4 = %x ", r[SVR4_SPARC_G4]);
- printf("G5 = %x ", r[SVR4_SPARC_G5]);
- printf("G6 = %x ", r[SVR4_SPARC_G6]);
- printf("G7 = %x ", r[SVR4_SPARC_G7]);
- printf("O0 = %x ", r[SVR4_SPARC_O0]);
- printf("O1 = %x ", r[SVR4_SPARC_O1]);
- printf("O2 = %x ", r[SVR4_SPARC_O2]);
- printf("O3 = %x ", r[SVR4_SPARC_O3]);
- printf("O4 = %x ", r[SVR4_SPARC_O4]);
- printf("O5 = %x ", r[SVR4_SPARC_O5]);
- printf("O6 = %x ", r[SVR4_SPARC_O6]);
- printf("O7 = %x ", r[SVR4_SPARC_O7]);
+ printf("PSR = 0x%x ", r[SVR4_SPARC_PSR]);
+ printf("PC = 0x%x ", r[SVR4_SPARC_PC]);
+ printf("nPC = 0x%x ", r[SVR4_SPARC_nPC]);
+ printf("Y = 0x%x ", r[SVR4_SPARC_Y]);
+ printf("G1 = 0x%x ", r[SVR4_SPARC_G1]);
+ printf("G2 = 0x%x ", r[SVR4_SPARC_G2]);
+ printf("G3 = 0x%x ", r[SVR4_SPARC_G3]);
+ printf("G4 = 0x%x ", r[SVR4_SPARC_G4]);
+ printf("G5 = 0x%x ", r[SVR4_SPARC_G5]);
+ printf("G6 = 0x%x ", r[SVR4_SPARC_G6]);
+ printf("G7 = 0x%x ", r[SVR4_SPARC_G7]);
+ printf("O0 = 0x%x ", r[SVR4_SPARC_O0]);
+ printf("O1 = 0x%x ", r[SVR4_SPARC_O1]);
+ printf("O2 = 0x%x ", r[SVR4_SPARC_O2]);
+ printf("O3 = 0x%x ", r[SVR4_SPARC_O3]);
+ printf("O4 = 0x%x ", r[SVR4_SPARC_O4]);
+ printf("O5 = 0x%x ", r[SVR4_SPARC_O5]);
+ printf("O6 = 0x%x ", r[SVR4_SPARC_O6]);
+ printf("O7 = 0x%x ", r[SVR4_SPARC_O7]);
printf("\n");
- printf("Signal Stack: sp %p, size %d, flags %x\n",
- s->ss_sp, s->ss_size, s->ss_flags);
+ printf("Signal Stack: sp %p, size %d, flags 0x%x\n",
+ s->ss_sp, s->ss_size, s->ss_flags);
- printf("Flags: %lx\n", uc->uc_flags);
+ printf("Flags: 0x%lx\n", uc->uc_flags);
}
#endif
@@ -167,7 +169,7 @@ svr4_getcontext(p, uc, mask, oonstack)
if (copyout(fps->fs_queue, f->fp_q, sz) != 0) {
#ifdef DIAGNOSTIC
printf("getcontext: copy of fp_queue failed %d\n",
- error);
+ error);
#endif
return;
}
diff --git a/sys/arch/sparc/sparc/sys_machdep.c b/sys/arch/sparc/sparc/sys_machdep.c
index e83270eaf3b..80dd232bb53 100644
--- a/sys/arch/sparc/sparc/sys_machdep.c
+++ b/sys/arch/sparc/sparc/sys_machdep.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: sys_machdep.c,v 1.3 1997/08/08 08:27:44 downsj Exp $ */
/* $NetBSD: sys_machdep.c,v 1.7 1996/03/14 21:09:33 christos Exp $ */
/*
diff --git a/sys/arch/sparc/sparc/timerreg.h b/sys/arch/sparc/sparc/timerreg.h
index 26bc2a57ca3..b6f41dcf1f3 100644
--- a/sys/arch/sparc/sparc/timerreg.h
+++ b/sys/arch/sparc/sparc/timerreg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: timerreg.h,v 1.5 1996/05/02 18:17:33 pk Exp $ */
+/* $OpenBSD: timerreg.h,v 1.3 1997/08/08 08:27:44 downsj Exp $ */
+/* $NetBSD: timerreg.h,v 1.6 1996/10/28 00:20:32 abrown Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -74,12 +75,6 @@
* they count in 500ns increments (bit 9 being the least
* significant bit).
*
- * Note that we still use the `sun4c' masks and shifts to compute
- * the bit pattern, given the tick period in microseconds, resulting
- * in a limit value that is 1 too high. This means that (with HZ=100)
- * the clock will err on the slow side by 500ns/10ms (or 0.00005 %).
- * We dont bother.
- *
*/
#ifndef _LOCORE
struct timer_4 {
@@ -118,8 +113,18 @@ struct counter_4m { /* counter that interrupts at ipl 14 */
#define TMR_SHIFT 10 /* shift to obtain microseconds */
#define TMR_MASK 0x1fffff /* 21 bits */
-/* Compute a limit that causes the timer to fire every n microseconds. */
+/*
+ * Compute a limit that causes the timer to fire every n microseconds.
+ * The Sun4c requires that the timer register be initialized for n+1
+ * microseconds, while the Sun4m requires it be initialized for n. Thus
+ * the two versions of this function.
+ *
+ * Note that the manual for the chipset used in the Sun4m suggests that
+ * the timer be set at n+0.5 microseconds; in practice, this produces
+ * a 50 ppm clock skew, which means that the 0.5 should not be there...
+ */
#define tmr_ustolim(n) (((n) + 1) << TMR_SHIFT)
/*efine TMR_SHIFT4M 9 -* shift to obtain microseconds */
-/*efine tmr_ustolim(n) (((2*(n)) + 1) << TMR_SHIFT4M)*/
+/*efine tmr_ustolim4m(n) (((2*(n)) + 1) << TMR_SHIFT4M)*/
+#define tmr_ustolim4m(n) ((n) << TMR_SHIFT)
diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c
index f23f537381e..34c2f049c2a 100644
--- a/sys/arch/sparc/sparc/trap.c
+++ b/sys/arch/sparc/sparc/trap.c
@@ -1,4 +1,5 @@
-/* $NetBSD: trap.c,v 1.42.4.2 1996/07/03 00:06:40 jtc Exp $ */
+/* $OpenBSD: trap.c,v 1.11 1997/08/08 08:27:46 downsj Exp $ */
+/* $NetBSD: trap.c,v 1.57 1997/07/29 09:42:15 fair Exp $ */
/*
* Copyright (c) 1996
@@ -84,6 +85,7 @@
#include <sparc/fpu/fpu_extern.h>
#include <sparc/sparc/memreg.h>
+#include <sparc/sparc/cpuvar.h>
#define offsetof(s, f) ((int)&((s *)0)->f)
@@ -201,6 +203,8 @@ void mem_access_fault __P((unsigned, int, u_int, int, int, struct trapframe *));
void mem_access_fault4m __P((unsigned, u_int, u_int, u_int, u_int, struct trapframe *));
void syscall __P((register_t, struct trapframe *, register_t));
+int ignore_bogus_traps = 0;
+
/*
* Define the code needed before returning to user mode, for
* trap, mem_access_fault, and syscall.
@@ -318,7 +322,11 @@ trap(type, psr, pc, tf)
ADVANCE;
return;
}
- goto dopanic;
+ dopanic:
+ printf("trap type 0x%x: pc=0x%x npc=0x%x psr=%b\n",
+ type, pc, tf->tf_npc, psr, PSR_BITS);
+ panic(type < N_TRAP_TYPES ? trap_type[type] : T);
+ /* NOTREACHED */
}
if ((p = curproc) == NULL)
p = &proc0;
@@ -329,25 +337,21 @@ trap(type, psr, pc, tf)
switch (type) {
default:
-#if defined(SUN4M)
- if (type == 0x29)
- /* Mysterious trap 29.. for now print&signal process */
- goto badtrap;
-#endif
if (type < 0x80) {
-dopanic:
- printf("trap type 0x%x: pc=%x npc=%x psr=%b\n",
+ if (!ignore_bogus_traps)
+ goto dopanic;
+ printf("trap type 0x%x: pc=0x%x npc=0x%x psr=%b\n",
type, pc, tf->tf_npc, psr, PSR_BITS);
- panic(type < N_TRAP_TYPES ? trap_type[type] : T);
- /* NOTREACHED */
+ trapsignal(p, SIGILL, type, ILL_ILLOPC, (caddr_t)pc);
+ break;
}
-#if defined(COMPAT_SVR4) || defined(SUN4M)
+#if defined(COMPAT_SVR4)
badtrap:
#endif
/* the following message is gratuitous */
/* ... but leave it in until we find anything */
printf("%s[%d]: unimplemented software trap 0x%x\n",
- p->p_comm, p->p_pid, type);
+ p->p_comm, p->p_pid, type);
trapsignal(p, SIGILL, type, ILL_ILLOPC, (caddr_t)pc);
break;
@@ -368,6 +372,10 @@ badtrap:
break; /* the work is all in userret() */
case T_ILLINST:
+ if ((n = emulinstr(pc, tf)) == 0) {
+ ADVANCE;
+ break;
+ }
trapsignal(p, SIGILL, 0, ILL_ILLOPC, (caddr_t)pc);
break;
@@ -435,7 +443,7 @@ badtrap:
panic("trap T_RWRET 1");
#ifdef DEBUG
if (rwindow_debug)
- printf("%s[%d]: rwindow: pcb<-stack: %x\n",
+ printf("%s[%d]: rwindow: pcb<-stack: 0x%x\n",
p->p_comm, p->p_pid, tf->tf_out[6]);
#endif
if (read_rw(tf->tf_out[6], &pcb->pcb_rw[0]))
@@ -457,7 +465,7 @@ badtrap:
*/
#ifdef DEBUG
if (rwindow_debug)
- printf("%s[%d]: rwindow: T_WINUF 0: pcb<-stack: %x\n",
+ printf("%s[%d]: rwindow: T_WINUF 0: pcb<-stack: 0x%x\n",
p->p_comm, p->p_pid, tf->tf_out[6]);
#endif
write_user_windows();
@@ -465,7 +473,7 @@ badtrap:
sigexit(p, SIGILL);
#ifdef DEBUG
if (rwindow_debug)
- printf("%s[%d]: rwindow: T_WINUF 1: pcb<-stack: %x\n",
+ printf("%s[%d]: rwindow: T_WINUF 1: pcb<-stack: 0x%x\n",
p->p_comm, p->p_pid, pcb->pcb_rw[0].rw_in[6]);
#endif
if (read_rw(pcb->pcb_rw[0].rw_in[6], &pcb->pcb_rw[1]))
@@ -476,6 +484,11 @@ badtrap:
break;
case T_ALIGN:
+ if ((p->p_md.md_flags & MDP_FIXALIGN) != 0 &&
+ fixalign(p, tf) == 0) {
+ ADVANCE;
+ break;
+ }
trapsignal(p, SIGBUS, 0, BUS_ADRALN, (caddr_t)pc);
break;
@@ -514,6 +527,7 @@ badtrap:
break;
case T_DIV0:
+ case T_IDIV0:
ADVANCE;
trapsignal(p, SIGFPE, 0, FPE_INTDIV, (caddr_t)pc);
break;
@@ -539,7 +553,11 @@ badtrap:
break;
case T_FIXALIGN:
- uprintf("T_FIXALIGN\n"); /* XXX */
+#ifdef DEBUG_ALIGN
+ uprintf("T_FIXALIGN\n");
+#endif
+ /* User wants us to fix alignment faults */
+ p->p_md.md_flags |= MDP_FIXALIGN;
ADVANCE;
break;
@@ -585,7 +603,7 @@ rwindow_save(p)
do {
#ifdef DEBUG
if (rwindow_debug)
- printf(" %x", rw[1].rw_in[6]);
+ printf(" 0x%x", rw[1].rw_in[6]);
#endif
if (copyout((caddr_t)rw, (caddr_t)rw[1].rw_in[6],
sizeof *rw))
@@ -666,8 +684,8 @@ mem_access_fault(type, ser, v, pc, psr, tf)
extern char Lfsbail[];
if (type == T_TEXTFAULT) {
(void) splhigh();
- printf("text fault: pc=%x ser=%b\n", pc,
- ser, SER_BITS);
+ printf("text fault: pc=0x%x ser=%b\n", pc,
+ ser, SER_BITS);
panic("kernel fault");
/* NOTREACHED */
}
@@ -699,7 +717,7 @@ mem_access_fault(type, ser, v, pc, psr, tf)
* that got bumped out via LRU replacement.
*/
vm = p->p_vmspace;
- rv = mmu_pagein(&vm->vm_pmap, va,
+ rv = mmu_pagein(vm->vm_map.pmap, va,
ser & SER_WRITE ? VM_PROT_WRITE : VM_PROT_READ);
if (rv < 0)
goto fault;
@@ -731,7 +749,7 @@ mem_access_fault(type, ser, v, pc, psr, tf)
* entries for `wired' pages). Instead, we call
* mmu_pagein here to make sure the new PTE gets installed.
*/
- (void) mmu_pagein(&vm->vm_pmap, va, VM_PROT_NONE);
+ (void) mmu_pagein(vm->vm_map.pmap, va, VM_PROT_NONE);
} else {
/*
* Pagein failed. If doing copyin/out, return to onfault
@@ -745,8 +763,8 @@ kfault:
(int)p->p_addr->u_pcb.pcb_onfault : 0;
if (!onfault) {
(void) splhigh();
- printf("data fault: pc=%x addr=%x ser=%b\n",
- pc, v, ser, SER_BITS);
+ printf("data fault: pc=0x%x addr=0x%x ser=%b\n",
+ pc, v, ser, SER_BITS);
panic("kernel fault");
/* NOTREACHED */
}
@@ -790,9 +808,6 @@ mem_access_fault4m(type, sfsr, sfva, afsr, afva, tf)
vm_prot_t ftype, vftype;
int onfault;
u_quad_t sticks;
-#if DEBUG
-static int lastdouble;
-#endif
cnt.v_trap++;
if ((p = curproc) == NULL) /* safety check */
@@ -819,7 +834,7 @@ static int lastdouble;
memerr4m(type, sfsr, sfva, afsr, afva, tf);
/*
* If we get here, exit the trap handler and wait for the
- * trap to reoccur
+ * trap to re-occur.
*/
goto out;
}
@@ -849,26 +864,12 @@ static int lastdouble;
goto out; /* No fault. Why were we called? */
/*
- * This next section is a mess since some chips use sfva, and others
- * don't on text faults. We want to use sfva where possible, since
- * we _could_ be dealing with an ASI 0x8,0x9 data access to text space,
- * which would trap as a text fault, at least on a HyperSPARC. Ugh.
- * XXX: Find out about MicroSPARCs.
+ * NOTE: the per-CPU fault status register readers (in locore)
+ * may already have decided to pass `pc' in `sfva', so we avoid
+ * testing CPU types here.
+ * Q: test SFSR_FAV in the locore stubs too?
*/
-
- if (type == T_TEXTFAULT && mmumod == SUN4M_MMU_SS &&
- (cpumod & 0xf0) == (SUN4M_SS) && (sfsr & SFSR_FAV)) {
- sfva = pc; /* can't trust fav on supersparc/text fault */
- } else if (type == T_TEXTFAULT && mmumod != SUN4M_MMU_HS) {
- sfva = pc;
- } else if (!(sfsr & SFSR_FAV)) {
-#ifdef DEBUG
- if (type != T_TEXTFAULT)
- printf("mem_access_fault: got fault without valid SFVA\n");
- if (mmumod == SUN4M_MMU_HS)
- printf("mem_access_fault: got fault without valid SFVA on "
- "HyperSPARC!\n");
-#endif
+ if ((sfsr & SFSR_FAV) == 0) {
if (type == T_TEXTFAULT)
sfva = pc;
else
@@ -877,7 +878,7 @@ static int lastdouble;
if ((sfsr & SFSR_FT) == SFSR_FT_TRANSERR) {
/* Translation errors are always fatal, as they indicate
- * a corrupt translation (page) table heirarchy.
+ * a corrupt translation (page) table hierarchy.
*/
if (tfaultaddr == sfva) /* Prevent infinite loops w/a static */
goto fault;
@@ -890,41 +891,17 @@ static int lastdouble;
va = trunc_page(sfva);
-#ifdef DEBUG
- if (lastdouble) {
- printf("stacked tfault @ %x (pc %x); sfsr %x", sfva, pc, sfsr);
- lastdouble = 0;
- if (curproc == NULL)
- printf("NULL proc\n");
- else
- printf("pid %d(%s); sigmask %x, sigcatch %x\n",
- curproc->p_pid, curproc->p_comm,
- curproc->p_sigmask, curproc->p_sigcatch);
- }
-#endif
if (((sfsr & SFSR_AT_TEXT) || type == T_TEXTFAULT) &&
!(sfsr & SFSR_AT_STORE) && (sfsr & SFSR_OW)) {
if (psr & PSR_PS) /* never allow in kernel */
goto kfault;
+#if 0
/*
* Double text fault. The evil "case 5" from the HS manual...
* Attempt to handle early fault. Ignores ASI 8,9 issue...may
* do a useless VM read.
* XXX: Is this really necessary?
*/
-#ifdef DEBUG
- if (dfdebug) {
- lastdouble = 1;
- printf("mem_access_fault: double text fault @ %x (pc %x); sfsr %x",
- sfva, pc, sfsr);
- if (curproc == NULL)
- printf("NULL proc\n");
- else
- printf(" pid %d(%s); sigmask %x, sigcatch %x\n",
- curproc->p_pid, curproc->p_comm,
- curproc->p_sigmask, curproc->p_sigcatch);
- }
-#endif
if (mmumod == SUN4M_MMU_HS) { /* On HS, we have va for both */
if (vm_fault(kernel_map, trunc_page(pc),
VM_PROT_READ, 0) != KERN_SUCCESS)
@@ -934,6 +911,7 @@ static int lastdouble;
#endif
;
}
+#endif
}
/* Now munch on protections... */
@@ -944,7 +922,7 @@ static int lastdouble;
extern char Lfsbail[];
if (sfsr & SFSR_AT_TEXT || type == T_TEXTFAULT) {
(void) splhigh();
- printf("text fault: pc=%x sfsr=%b sfva=%x\n", pc,
+ printf("text fault: pc=0x%x sfsr=%b sfva=0x%x\n", pc,
sfsr, SFSR_BITS, sfva);
panic("kernel fault");
/* NOTREACHED */
@@ -972,21 +950,6 @@ static int lastdouble;
p->p_md.md_tf = tf;
vm = p->p_vmspace;
-#ifdef DEBUG
- /*
- * mmu_pagein returns -1 if the page is already valid, in which
- * case we have a hard fault.. now why would *that* happen?
- * But it happens sporadically, and vm_fault() seems to clear it..
- */
- rv = mmu_pagein4m(&vm->vm_pmap, va,
- sfsr & SFSR_AT_STORE ? VM_PROT_WRITE : VM_PROT_READ);
- if (rv < 0)
- printf(" sfsr=%x(FT=%x,AT=%x,LVL=%x), sfva=%x, pc=%x, psr=%x\n",
- sfsr, (sfsr >> 2) & 7, (sfsr >> 5) & 7, (sfsr >> 8) & 3,
- sfva, pc, psr);
- if (rv > 0)
- panic("mmu_pagein4m returns %d", rv);
-#endif
/* alas! must call the horrible vm code */
rv = vm_fault(&vm->vm_map, (vm_offset_t)va, ftype, FALSE);
@@ -1019,8 +982,8 @@ kfault:
(int)p->p_addr->u_pcb.pcb_onfault : 0;
if (!onfault) {
(void) splhigh();
- printf("data fault: pc=%x addr=%x sfsr=%b\n",
- pc, sfva, sfsr, SFSR_BITS);
+ printf("data fault: pc=0x%x addr=0x%x sfsr=%b\n",
+ pc, sfva, sfsr, SFSR_BITS);
panic("kernel fault");
/* NOTREACHED */
}
diff --git a/sys/arch/sparc/sparc/vaddrs.h b/sys/arch/sparc/sparc/vaddrs.h
index 0beedac2545..66ebb45b094 100644
--- a/sys/arch/sparc/sparc/vaddrs.h
+++ b/sys/arch/sparc/sparc/vaddrs.h
@@ -1,4 +1,5 @@
-/* $NetBSD: vaddrs.h,v 1.7 1996/05/16 15:57:28 abrown Exp $ */
+/* $OpenBSD: vaddrs.h,v 1.4 1997/08/08 08:27:47 downsj Exp $ */
+/* $NetBSD: vaddrs.h,v 1.8 1997/03/10 23:54:41 pk Exp $ */
/*
* Copyright (c) 1996
@@ -68,16 +69,12 @@
* use one of the two `wasted' pages at KERNBASE+_MAXNBPG (see locore.s).
*/
-
#ifndef IODEV_0
#define IODEV_0 0xfe000000 /* must match VM_MAX_KERNEL_ADDRESS */
#define _MAXNBPG 8192 /* fixed VAs, independent of actual NBPG */
#define _MAXNCPU 4 /* fixed VA allocation allows 4 CPUs */
-/* [4c:] interrupt register as described above */
-#define INTRREG_VA ( KERNBASE + _MAXNBPG) /* [4c] */
-
/* [4m:] interrupt and counter registers take (1 + NCPU) pages. */
#define TIMERREG_VA (IODEV_0)
@@ -87,6 +84,7 @@
#define AUXREG_VA ( ZS1_VA + _MAXNBPG)
#define TMPMAP_VA ( AUXREG_VA + _MAXNBPG)
#define MSGBUF_VA ( TMPMAP_VA + _MAXNBPG)
+#define INTRREG_VA ( MSGBUF_VA + _MAXNBPG) /* [4/4c] */
#define PI_INTR_VA ( MSGBUF_VA + _MAXNBPG) /* [4m] */
#define SI_INTR_VA ( PI_INTR_VA + _MAXNBPG*_MAXNCPU) /* [4m] */
#define IODEV_BASE ( SI_INTR_VA + _MAXNBPG)
@@ -119,4 +117,9 @@
#define DVMA4M_START 0xfd000000 /* 16M of DVMA */
#define DVMA4M_END 0xfe000000 /* XXX is this enough? */
+/*
+ * Virtual address of the per cpu `cpu_softc' structure.
+ */
+#define CPUINFO_VA (KERNBASE+8192)
+
#endif /* IODEV_0 */
diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c
index 0a0bc838935..521588c8350 100644
--- a/sys/arch/sparc/sparc/vm_machdep.c
+++ b/sys/arch/sparc/sparc/vm_machdep.c
@@ -1,4 +1,5 @@
-/* $NetBSD: vm_machdep.c,v 1.27.4.1 1996/08/02 21:35:20 jtc Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.5 1997/08/08 08:27:48 downsj Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */
/*
* Copyright (c) 1996
@@ -66,7 +67,7 @@
#include <machine/frame.h>
#include <machine/trap.h>
-#include <sparc/sparc/cache.h>
+#include <sparc/sparc/cpuvar.h>
/*
* Move pages from one kernel virtual address to another.
@@ -114,12 +115,20 @@ dvma_malloc(len, kaddr, flags)
{
vm_offset_t kva;
vm_offset_t dva;
+#if defined(SUN4M)
+ extern int has_iocache;
+#endif
len = round_page(len);
kva = (vm_offset_t)malloc(len, M_DEVBUF, flags);
if (kva == NULL)
return (NULL);
+#if defined(SUN4M)
+ if (!has_iocache)
+#endif
+ kvm_uncache((caddr_t)kva, len >> PGSHIFT);
+
*(vm_offset_t *)kaddr = kva;
dva = dvma_mapin(kernel_map, kva, len, (flags & M_NOWAIT) ? 0 : 1);
if (dva == NULL) {
@@ -155,20 +164,17 @@ dvma_mapin(map, va, len, canwait)
register int npf, s;
register vm_offset_t pa;
long off, pn;
-#if defined(SUN4M)
- extern int has_iocache;
-#endif
+ vm_offset_t ova;
+ int olen;
+
+ ova = va;
+ olen = len;
off = (int)va & PGOFSET;
va -= off;
len = round_page(len + off);
npf = btoc(len);
-#if defined(SUN4M)
- if (!has_iocache)
- kvm_uncache((caddr_t)va, len >> PGSHIFT);
-#endif
-
s = splimp();
for (;;) {
@@ -194,7 +200,7 @@ dvma_mapin(map, va, len, canwait)
pa = trunc_page(pa);
#if defined(SUN4M)
- if (cputyp == CPU_SUN4M) {
+ if (CPU_ISSUN4M) {
iommu_enter(tva, pa);
} else
#endif
@@ -217,6 +223,13 @@ dvma_mapin(map, va, len, canwait)
tva += PAGE_SIZE;
va += PAGE_SIZE;
}
+
+ /*
+ * XXX Only have to do this on write.
+ */
+ if (CACHEINFO.c_vactype == VAC_WRITEBACK) /* XXX */
+ cpuinfo.cache_flush((caddr_t)ova, olen); /* XXX */
+
return kva + off;
}
@@ -246,8 +259,8 @@ dvma_mapout(kva, va, len)
wakeup(dvmamap);
splx(s);
- if (vactype != VAC_NONE)
- cache_flush((caddr_t)va, len);
+ if (CACHEINFO.c_vactype != VAC_NONE)
+ cpuinfo.cache_flush((caddr_t)va, len);
}
/*
@@ -316,8 +329,8 @@ vunmapbuf(bp, sz)
kmem_free_wakeup(kernel_map, trunc_page(kva), size);
bp->b_data = bp->b_saveaddr;
bp->b_saveaddr = NULL;
- if (vactype != VAC_NONE)
- cache_flush(bp->b_un.b_addr, bp->b_bcount - bp->b_resid);
+ if (CACHEINFO.c_vactype != VAC_NONE)
+ cpuinfo.cache_flush(bp->b_un.b_addr, bp->b_bcount - bp->b_resid);
}