summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/Makefile2
-rw-r--r--sys/arch/alpha/README51
-rw-r--r--sys/arch/alpha/STATUS40
-rw-r--r--sys/arch/alpha/TODO.users31
-rw-r--r--sys/arch/alpha/alpha/autoconf.c68
-rw-r--r--sys/arch/alpha/alpha/clock.c13
-rw-r--r--sys/arch/alpha/alpha/clockvar.h2
-rw-r--r--sys/arch/alpha/alpha/conf.c52
-rw-r--r--sys/arch/alpha/alpha/cpu.c30
-rw-r--r--sys/arch/alpha/alpha/dec_2100_a50.c49
-rw-r--r--sys/arch/alpha/alpha/dec_2100_a50.h4
-rw-r--r--sys/arch/alpha/alpha/dec_3000_300.c53
-rw-r--r--sys/arch/alpha/alpha/dec_3000_300.h4
-rw-r--r--sys/arch/alpha/alpha/dec_3000_500.c53
-rw-r--r--sys/arch/alpha/alpha/dec_3000_500.h4
-rw-r--r--sys/arch/alpha/alpha/dec_axppci_33.c49
-rw-r--r--sys/arch/alpha/alpha/dec_axppci_33.h4
-rw-r--r--sys/arch/alpha/alpha/dec_kn20aa.c49
-rw-r--r--sys/arch/alpha/alpha/dec_kn20aa.h4
-rw-r--r--sys/arch/alpha/alpha/disksubr.c14
-rw-r--r--sys/arch/alpha/alpha/genassym.c65
-rw-r--r--sys/arch/alpha/alpha/in_cksum.c7
-rw-r--r--sys/arch/alpha/alpha/interrupt.c127
-rw-r--r--sys/arch/alpha/alpha/locore.s821
-rw-r--r--sys/arch/alpha/alpha/machdep.c511
-rw-r--r--sys/arch/alpha/alpha/mainbus.c11
-rw-r--r--sys/arch/alpha/alpha/mcclock.c4
-rw-r--r--sys/arch/alpha/alpha/mcclockvar.h2
-rw-r--r--sys/arch/alpha/alpha/mem.c25
-rw-r--r--sys/arch/alpha/alpha/pal.s227
-rw-r--r--sys/arch/alpha/alpha/pmap.c4452
-rw-r--r--sys/arch/alpha/alpha/pmap.old.c2283
-rw-r--r--sys/arch/alpha/alpha/process_machdep.c19
-rw-r--r--sys/arch/alpha/alpha/prom.c107
-rw-r--r--sys/arch/alpha/alpha/prom_disp.s8
-rw-r--r--sys/arch/alpha/alpha/promcons.c26
-rw-r--r--sys/arch/alpha/alpha/rd_root.c84
-rw-r--r--sys/arch/alpha/alpha/support.c2
-rw-r--r--sys/arch/alpha/alpha/swapgeneric.c4
-rw-r--r--sys/arch/alpha/alpha/sys_machdep.c4
-rw-r--r--sys/arch/alpha/alpha/trap.c854
-rw-r--r--sys/arch/alpha/alpha/vm_machdep.c84
-rw-r--r--sys/arch/alpha/compile/.cvsignore2
-rw-r--r--sys/arch/alpha/compile/.keep_me2
-rw-r--r--sys/arch/alpha/compile/build_all6
-rw-r--r--sys/arch/alpha/compile/rebuild_all6
-rw-r--r--sys/arch/alpha/conf/ALPHA33
-rw-r--r--sys/arch/alpha/conf/BUNNY10
-rw-r--r--sys/arch/alpha/conf/GENERIC32
-rw-r--r--sys/arch/alpha/conf/GENERIC.PROF153
-rw-r--r--sys/arch/alpha/conf/JURA7
-rw-r--r--sys/arch/alpha/conf/Makefile.alpha71
-rw-r--r--sys/arch/alpha/conf/NOSY7
-rw-r--r--sys/arch/alpha/conf/OPAL10
-rw-r--r--sys/arch/alpha/conf/RAMDISK154
-rw-r--r--sys/arch/alpha/conf/files.alpha37
-rw-r--r--sys/arch/alpha/conf/std.alpha7
-rw-r--r--sys/arch/alpha/eisa/eisa_machdep.h2
-rw-r--r--sys/arch/alpha/include/alpha_cpu.h281
-rw-r--r--sys/arch/alpha/include/ansi.h7
-rw-r--r--sys/arch/alpha/include/aout_machdep.h (renamed from sys/arch/alpha/include/trap.h)25
-rw-r--r--sys/arch/alpha/include/asm.h85
-rw-r--r--sys/arch/alpha/include/autoconf.h14
-rw-r--r--sys/arch/alpha/include/bus.h4
-rw-r--r--sys/arch/alpha/include/cdefs.h36
-rw-r--r--sys/arch/alpha/include/cfbreg.h2
-rw-r--r--sys/arch/alpha/include/cpu.h32
-rw-r--r--sys/arch/alpha/include/db_machdep.h8
-rw-r--r--sys/arch/alpha/include/disklabel.h2
-rw-r--r--sys/arch/alpha/include/ecoff.h11
-rw-r--r--sys/arch/alpha/include/ecoff_machdep.h95
-rw-r--r--sys/arch/alpha/include/elf_machdep.h9
-rw-r--r--sys/arch/alpha/include/endian.h23
-rw-r--r--sys/arch/alpha/include/fbio.h7
-rw-r--r--sys/arch/alpha/include/float.h2
-rw-r--r--sys/arch/alpha/include/frame.h49
-rw-r--r--sys/arch/alpha/include/ieee.h2
-rw-r--r--sys/arch/alpha/include/ieeefp.h2
-rw-r--r--sys/arch/alpha/include/intr.h34
-rw-r--r--sys/arch/alpha/include/intrcnt.h4
-rw-r--r--sys/arch/alpha/include/kbio.h2
-rw-r--r--sys/arch/alpha/include/kcore.h40
-rw-r--r--sys/arch/alpha/include/limits.h2
-rw-r--r--sys/arch/alpha/include/param.h37
-rw-r--r--sys/arch/alpha/include/pcb.h27
-rw-r--r--sys/arch/alpha/include/pmap.h133
-rw-r--r--sys/arch/alpha/include/pmap.new.h363
-rw-r--r--sys/arch/alpha/include/pmap.old.h131
-rw-r--r--sys/arch/alpha/include/proc.h7
-rw-r--r--sys/arch/alpha/include/profile.h27
-rw-r--r--sys/arch/alpha/include/prom.h14
-rw-r--r--sys/arch/alpha/include/psl.h101
-rw-r--r--sys/arch/alpha/include/pte.h53
-rw-r--r--sys/arch/alpha/include/ptrace.h2
-rw-r--r--sys/arch/alpha/include/reg.h4
-rw-r--r--sys/arch/alpha/include/rpb.h14
-rw-r--r--sys/arch/alpha/include/setjmp.h2
-rw-r--r--sys/arch/alpha/include/sfbreg.h2
-rw-r--r--sys/arch/alpha/include/signal.h2
-rw-r--r--sys/arch/alpha/include/stdarg.h6
-rw-r--r--sys/arch/alpha/include/tgareg.h2
-rw-r--r--sys/arch/alpha/include/types.h6
-rw-r--r--sys/arch/alpha/include/varargs.h6
-rw-r--r--sys/arch/alpha/include/vmparam.h40
-rw-r--r--sys/arch/alpha/include/vuid_event.h2
-rw-r--r--sys/arch/alpha/include/wsconsio.h2
-rw-r--r--sys/arch/alpha/isa/isa_machdep.h2
-rw-r--r--sys/arch/alpha/isa/isafcns_jensen.c4
-rw-r--r--sys/arch/alpha/isa/mcclock_isa.c2
-rw-r--r--sys/arch/alpha/isa/pckbd.c308
-rw-r--r--sys/arch/alpha/isa/pckbdreg.h2
-rw-r--r--sys/arch/alpha/isa/pms.c21
-rw-r--r--sys/arch/alpha/isa/spkrreg.h2
-rw-r--r--sys/arch/alpha/isa/timerreg.h2
-rw-r--r--sys/arch/alpha/pci/apecs.c16
-rw-r--r--sys/arch/alpha/pci/apecs_lca.h35
-rw-r--r--sys/arch/alpha/pci/apecs_lca_bus_io.c6
-rw-r--r--sys/arch/alpha/pci/apecs_lca_bus_mem.c6
-rw-r--r--sys/arch/alpha/pci/apecs_pci.c26
-rw-r--r--sys/arch/alpha/pci/apecsreg.h6
-rw-r--r--sys/arch/alpha/pci/apecsvar.h2
-rw-r--r--sys/arch/alpha/pci/bt485reg.h2
-rw-r--r--sys/arch/alpha/pci/cia.c14
-rw-r--r--sys/arch/alpha/pci/cia_bus_io.c5
-rw-r--r--sys/arch/alpha/pci/cia_bus_mem.c5
-rw-r--r--sys/arch/alpha/pci/cia_pci.c26
-rw-r--r--sys/arch/alpha/pci/ciareg.h6
-rw-r--r--sys/arch/alpha/pci/ciavar.h4
-rw-r--r--sys/arch/alpha/pci/lca.c21
-rw-r--r--sys/arch/alpha/pci/lca_pci.c26
-rw-r--r--sys/arch/alpha/pci/lcareg.h6
-rw-r--r--sys/arch/alpha/pci/lcavar.h2
-rw-r--r--sys/arch/alpha/pci/pci_2100_a50.c11
-rw-r--r--sys/arch/alpha/pci/pci_2100_a50.h2
-rw-r--r--sys/arch/alpha/pci/pci_axppci_33.c11
-rw-r--r--sys/arch/alpha/pci/pci_axppci_33.h2
-rw-r--r--sys/arch/alpha/pci/pci_kn20aa.c54
-rw-r--r--sys/arch/alpha/pci/pci_kn20aa.h2
-rw-r--r--sys/arch/alpha/pci/pci_machdep.c2
-rw-r--r--sys/arch/alpha/pci/pci_machdep.h7
-rw-r--r--sys/arch/alpha/pci/pcivga.c12
-rw-r--r--sys/arch/alpha/pci/pcivgavar.h2
-rw-r--r--sys/arch/alpha/pci/pcs_bus_io_common.c34
-rw-r--r--sys/arch/alpha/pci/pcs_bus_mem_common.c30
-rw-r--r--sys/arch/alpha/pci/sio.c10
-rw-r--r--sys/arch/alpha/pci/sio_pic.c25
-rw-r--r--sys/arch/alpha/pci/sioreg.h2
-rw-r--r--sys/arch/alpha/pci/siovar.h6
-rw-r--r--sys/arch/alpha/pci/tga.c20
-rw-r--r--sys/arch/alpha/pci/tga_bt463.c2
-rw-r--r--sys/arch/alpha/pci/tga_bt485.c17
-rw-r--r--sys/arch/alpha/pci/tga_conf.c2
-rw-r--r--sys/arch/alpha/pci/tgavar.h2
-rw-r--r--sys/arch/alpha/stand/Makefile6
-rw-r--r--sys/arch/alpha/stand/Makefile.inc11
-rw-r--r--sys/arch/alpha/stand/OSFpal.c4
-rw-r--r--sys/arch/alpha/stand/bbinfo.h2
-rw-r--r--sys/arch/alpha/stand/boot/Makefile27
-rw-r--r--sys/arch/alpha/stand/boot/boot.c209
-rw-r--r--sys/arch/alpha/stand/boot/conf.c2
-rw-r--r--sys/arch/alpha/stand/boot/devopen.c2
-rw-r--r--sys/arch/alpha/stand/boot/disk.c2
-rw-r--r--sys/arch/alpha/stand/boot/disk.h2
-rw-r--r--sys/arch/alpha/stand/boot/filesystem.c2
-rw-r--r--sys/arch/alpha/stand/boot/newvers.sh8
-rw-r--r--sys/arch/alpha/stand/boot/prom_swpal.S11
-rw-r--r--sys/arch/alpha/stand/boot/test.c2
-rw-r--r--sys/arch/alpha/stand/boot/version7
-rw-r--r--sys/arch/alpha/stand/bootxx.c6
-rw-r--r--sys/arch/alpha/stand/bootxx/Makefile20
-rw-r--r--sys/arch/alpha/stand/headersize.c58
-rw-r--r--sys/arch/alpha/stand/installboot.c2
-rw-r--r--sys/arch/alpha/stand/installboot/Makefile2
-rw-r--r--sys/arch/alpha/stand/loadfile.c216
-rw-r--r--sys/arch/alpha/stand/netboot/Makefile61
-rw-r--r--sys/arch/alpha/stand/netboot/conf.c26
-rw-r--r--sys/arch/alpha/stand/netboot/dev_net.c255
-rw-r--r--sys/arch/alpha/stand/netboot/dev_net.h8
-rw-r--r--sys/arch/alpha/stand/netboot/devopen.c162
-rw-r--r--sys/arch/alpha/stand/netboot/getsecs.c34
-rw-r--r--sys/arch/alpha/stand/netboot/if_prom.c201
-rw-r--r--sys/arch/alpha/stand/netboot/netboot.c99
-rw-r--r--sys/arch/alpha/stand/netboot/newvers.sh45
-rw-r--r--sys/arch/alpha/stand/netboot/rpcc.S10
-rw-r--r--sys/arch/alpha/stand/netboot/version5
-rw-r--r--sys/arch/alpha/stand/prom.c2
-rw-r--r--sys/arch/alpha/stand/prom_disp.S8
-rw-r--r--sys/arch/alpha/stand/puts.c2
-rw-r--r--sys/arch/alpha/stand/start.S14
-rw-r--r--sys/arch/alpha/tc/cfb.c12
-rw-r--r--sys/arch/alpha/tc/cfbvar.h2
-rw-r--r--sys/arch/alpha/tc/esp.c1207
-rw-r--r--sys/arch/alpha/tc/espreg.h11
-rw-r--r--sys/arch/alpha/tc/espvar.h178
-rw-r--r--sys/arch/alpha/tc/ioasic.c14
-rw-r--r--sys/arch/alpha/tc/ioasicreg.h2
-rw-r--r--sys/arch/alpha/tc/mcclock_ioasic.c2
-rw-r--r--sys/arch/alpha/tc/scc.c540
-rw-r--r--sys/arch/alpha/tc/sccreg.h2
-rw-r--r--sys/arch/alpha/tc/sccvar.h6
-rw-r--r--sys/arch/alpha/tc/sfb.c12
-rw-r--r--sys/arch/alpha/tc/sfbvar.h2
-rw-r--r--sys/arch/alpha/tc/tc_3000_300.c20
-rw-r--r--sys/arch/alpha/tc/tc_3000_300.h2
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.c20
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.h2
-rw-r--r--sys/arch/alpha/tc/tc_bus_io.c6
-rw-r--r--sys/arch/alpha/tc/tc_bus_mem.c27
-rw-r--r--sys/arch/alpha/tc/tc_conf.h8
-rw-r--r--sys/arch/alpha/tc/tc_machdep.h13
-rw-r--r--sys/arch/alpha/tc/tcasic.c11
-rw-r--r--sys/arch/alpha/tc/tcds.c28
-rw-r--r--sys/arch/alpha/tc/tcds_dma.c162
-rw-r--r--sys/arch/alpha/tc/tcdsreg.h10
-rw-r--r--sys/arch/alpha/tc/tcdsvar.h16
-rw-r--r--sys/arch/alpha/wscons/ascii.h2
-rw-r--r--sys/arch/alpha/wscons/event.c31
-rw-r--r--sys/arch/alpha/wscons/event_var.h8
-rw-r--r--sys/arch/alpha/wscons/kbd.c18
-rw-r--r--sys/arch/alpha/wscons/kbd.h49
-rw-r--r--sys/arch/alpha/wscons/ms.c22
-rw-r--r--sys/arch/alpha/wscons/ms.h45
-rw-r--r--sys/arch/alpha/wscons/wscons.c8
-rw-r--r--sys/arch/alpha/wscons/wscons_emul.c22
-rw-r--r--sys/arch/alpha/wscons/wscons_emul.h2
-rw-r--r--sys/arch/alpha/wscons/wscons_raster.h8
-rw-r--r--sys/arch/alpha/wscons/wscons_rfont.h2
-rw-r--r--sys/arch/alpha/wscons/wscons_rinit.c8
-rw-r--r--sys/arch/alpha/wscons/wscons_rops.c2
-rw-r--r--sys/arch/alpha/wscons/wsconsvar.h2
230 files changed, 12255 insertions, 5237 deletions
diff --git a/sys/arch/alpha/Makefile b/sys/arch/alpha/Makefile
index 116bfe45f14..7724b7b9656 100644
--- a/sys/arch/alpha/Makefile
+++ b/sys/arch/alpha/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.2 1996/07/29 22:57:03 niklas Exp $
+# $OpenBSD: Makefile,v 1.3 1996/10/30 22:37:51 niklas Exp $
# $NetBSD: Makefile,v 1.3 1995/02/27 16:36:07 cgd Exp $
# Makefile for alpha tags file and boot blocks
diff --git a/sys/arch/alpha/README b/sys/arch/alpha/README
index c0d5b25262d..eeb22268302 100644
--- a/sys/arch/alpha/README
+++ b/sys/arch/alpha/README
@@ -1,16 +1,19 @@
-$OpenBSD: README,v 1.4 1996/07/29 22:57:06 niklas Exp $
-$NetBSD: README,v 1.8.4.1 1996/06/13 20:49:01 cgd Exp $
+$OpenBSD: README,v 1.5 1996/10/30 22:37:53 niklas Exp $
+$NetBSD: README,v 1.10 1996/07/09 22:08:28 cgd Exp $
-Obtaining NetBSD/Alpha sources and binaries:
+[ Don't trust this file yet, it contains a lot of inaccuracies. When it's
+ ready, this notice will be removed. -NH ]
- NetBSD/Alpha's sources, with the exceptions of the GNU
- toolchain and X11 code, are integrated into NetBSD-current,
+Obtaining OpenBSD/Alpha sources and binaries:
+
+ OpenBSD/Alpha's sources, with the exceptions of the GNU
+ toolchain and X11 code, are integrated into OpenBSD-current,
and are available from:
- ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-current/
+ ftp://ftp.openbsd.org/pub/OpenBSD/
- The latest NetBSD/Alpha binary snapshot, and source snapshots
+ The latest OpenBSD/Alpha binary snapshot, and source snapshots
for the toolchain and X11 code, can be found at:
- ftp://ftp.netbsd.org/pub/NetBSD/arch/alpha
+ ftp://ftp.openbsd.org/pub/OpenBSD/arch/alpha
Binary snapshots include two different set of system binaries:
(1) an rz25 disk image, for first-time installation
@@ -25,24 +28,24 @@ Obtaining NetBSD/Alpha sources and binaries:
Binary snapshots include a kernel image which is the same
as the one on the rz25 disk image.
- The sources provided seperately from the normal NetBSD-current
+ The sources provided seperately from the normal OpenBSD-current
distribution are:
(1) complete compiler toolchain sources
(2) diffs against the XFree86 3.1.2 distribution to
- make X work with NetBSD/Alpha. (Note that
+ make X work with OpenBSD/Alpha. (Note that
at this time, the diffs are against 3.1.2,
i.e. not against 3.1.2D, etc.)
- If you are using or are interested in the NetBSD/Alpha port, I
- suggest that you subscribe to the NetBSD "port-alpha" mailing list
- by sending an email message to majordomo@netbsd.org with no
+ If you are using or are interested in the OpenBSD/Alpha port, I
+ suggest that you subscribe to the OpenBSD "port-alpha" mailing list
+ by sending an email message to majordomo@openbsd.org with no
subject and with a body of "subscribe port-alpha" (without the
quotes). For help on using majordomo, send it mail with an empty
- subject and body. In general, questions about NetBSD/Alpha
+ subject and body. In general, questions about OpenBSD/Alpha
are best asked on that mailing list (rather than by sending me
mail directly).
-Installing the NetBSD/Alpha distribution:
+Installing the OpenBSD/Alpha distribution:
[ Note that these instructions are minimal; it's assumed that if
you're going to be installing this, you're knowledgeable about
@@ -51,7 +54,7 @@ Installing the NetBSD/Alpha distribution:
good enough to get you running, get in touch with me and I'll try
to help you. ]
- To install the NetBSD/Alpha distribution, you'll need a disk at
+ To install the OpenBSD/Alpha distribution, you'll need a disk at
least the size of an RZ25 -- about 406Mb. Once you've gotten the
binary distribution, gunzip it and dd it to the raw disk. The binary
distribution includes a disklabel and boot block, so you don't need
@@ -60,7 +63,7 @@ Installing the NetBSD/Alpha distribution:
Berkeley Fast File System format, so that you can mount, read, and
write them under Digital UNIX.
- If your are using one of the supported systems that includes a
+ If you are using one of the supported systems that includes a
PCI bus, and have either a PCI VGA frame buffer of any type or
a ZLXp-E1 frame buffer, you may use it as console. (If you
are using your frame buffer as the console, you should use the
@@ -68,8 +71,8 @@ Installing the NetBSD/Alpha distribution:
Alpha or have a different kind of frame buffer, you have to use
a serial console.)
- Boot the Alpha with the NetBSD disk, supplying the boot flag "-s".
- It should print something like "NetBSD/Alpha Boot program", load
+ Boot the Alpha with the OpenBSD disk, supplying the boot flag "-s".
+ It should print something like "OpenBSD/Alpha Boot program", load
the kernel, print a copyright, and print various startup messages.
After a short while, you should be asked for the name of a shell
@@ -109,12 +112,16 @@ Installing the NetBSD/Alpha distribution:
Once those files are created, you should be able to boot the system
multi-user. To do so, halt the system and boot again from the
- NetBSD disk, this time supplying the boot flag "-a".
+ OpenBSD disk, this time supplying the boot flag "-a".
If you used a disk other than an RZ25, you may want to edit the
disk's disklabel, and create one or more partitions after the
existing partitions to use the extra space.
-Chris Demetriou
-cgd@cs.cmu.edu
+This document was derived from the NetBSD version originally written by
+Chris Demetriou <cgd@cs.cmu.edu>,
+
+Niklas Hallqvist
+niklas@openbsd.org
+
diff --git a/sys/arch/alpha/STATUS b/sys/arch/alpha/STATUS
index b0d70786deb..62539c2ea7d 100644
--- a/sys/arch/alpha/STATUS
+++ b/sys/arch/alpha/STATUS
@@ -1,17 +1,16 @@
-$OpenBSD: STATUS,v 1.4 1996/07/29 22:57:07 niklas Exp $
-$NetBSD: STATUS,v 1.3.4.1 1996/06/13 20:49:04 cgd Exp $
+$OpenBSD: STATUS,v 1.5 1996/10/30 22:37:54 niklas Exp $
+$NetBSD: STATUS,v 1.5 1996/09/06 04:01:37 cgd Exp $
-NetBSD/Alpha's Status
+OpenBSD/Alpha's Status
If you find an inaccuracy in this file, can clarify it in any place,
-etc., please send mail to me (cgd@cs.cmu.edu).
+etc., please send mail to me (niklas@appli.se).
Supported hardware:
- DEC 3000/[456789]00 (I've only tested it on the 400 and
- 600, but the rest should "just work) using the following
- peripherals:
+ DEC 3000/[456789]00 (I've not tested them, but they should
+ "just work") using the following peripherals:
Supported hardware:
Built-in serial ports
@@ -58,12 +57,11 @@ Supported hardware:
DEC ZLXp-E2 and ZLXp-E3 PCI video boards.
Other PCI boards.
- AlphaStation 600 systems, with the same supported hardware
- list as the AlphaStation {200,250,255,400} systems. (NOTE
- THAT THAT MEANS THE AlphaStation 600's BUILT-IN SCSI
+ AlphaStation 500 and 600 systems, with the same supported
+ hardware list as the AlphaStation {200,250,255,400} systems.
+ (NOTE THAT THAT MEANS THE AlphaStation 600's BUILT-IN SCSI
CONTROLLERS DO NOT WORK. You'll need to get a 53c810 board,
- or run diskless.) AlphaStation 500 systems may work, but
- have not been tested.
+ or run diskless.)
AXPpci systems (including Multia), with the same supported
hardware list as the AlphaStation {200,250,255,400} systems.
@@ -75,16 +73,9 @@ At this time none of the following systems are supported:
in disguise).
Multiprocessor Alpha systems
-I was hoping to get a DECpc AXP port working "for free" based on
-the PCI work, but the DECpc AXP is a very different (and, in my
-opinion, very alien) piece of hardware. If somebody wants to make
-NetBSD/Alpha run on the DECpc AXP system, get in touch and I'll do
-what I can to help you get started.
-
-
Console frame buffers & keyboard are supported only with the frame
buffers and keyboards mentioned as supported above. On other systems
-(including all TurboChannel-based machines), NetBSD/Alpha _must_ be used
+(including all TurboChannel-based machines), OpenBSD/Alpha _must_ be used
with a serial console. To configure various Alpha systems to use a serial
console, do the following depending on the model:
@@ -108,10 +99,13 @@ See the file src/sys/arch/alpha/README to find out how to get the
latest sources and binaries.
Please see the file src/sys/arch/alpha/TODO.users for a list of things
-that users can do to help NetBSD/Alpha improve. If you're interested
+that users can do to help OpenBSD/Alpha improve. If you're interested
in doing any of them, or porting to new hardware, get in touch and
I'll do what I can to help.
-Chris Demetriou
-cgd@cs.cmu.edu
+This document was derived from the NetBSD version originally written by
+Chris Demetriou <cgd@cs.cmu.edu>.
+
+Niklas Hallqvist
+niklas@openbsd.org
diff --git a/sys/arch/alpha/TODO.users b/sys/arch/alpha/TODO.users
index 7991cb7ae27..f9e29249e0b 100644
--- a/sys/arch/alpha/TODO.users
+++ b/sys/arch/alpha/TODO.users
@@ -1,10 +1,10 @@
-$OpenBSD: TODO.users,v 1.4 1996/07/29 22:57:08 niklas Exp $
-$NetBSD: TODO.users,v 1.3.4.1 1996/06/13 20:49:07 cgd Exp $
+$OpenBSD: TODO.users,v 1.5 1996/10/30 22:37:55 niklas Exp $
+$NetBSD: TODO.users,v 1.5 1996/10/01 21:24:37 cgd Exp $
-The NetBSD/Alpha "User" To-Do List
+The OpenBSD/Alpha "User" To-Do List
-The following are things that I'd like to see "users" of NetBSD/Alpha
+The following are things that I'd like to see "users" of OpenBSD/Alpha
do. It's unlikely that I'll get around to them in any reasonable time
frame, and I think they should get done.
@@ -16,24 +16,23 @@ tell me about it, so that I can keep people from duplicating work.
Once you've done something on this list, send me context diffs.
-Chris Demetriou
-cgd@cs.cmu.edu
+This document is derived from the NetBSD version originally written by
+Chris Demetriou <cgd@cs.cmu.edu>.
+
+Niklas Hallqvist
+niklas@openbsd.org
--
Test programs; find and fix bugs. In particular:
(1) make sure accounting works
- (2) last i checked, 'file' core dumped
- (3) /usr/games
+ (2) /usr/games
Test TurboChannel option slot support. Write TurboChannel option
board drivers. Test PMAD-A (TC le) driver.
-Get the GNU tools to generate a.out binaries for the alpha. Once that
-is done, make the rest of the NetBSD a.out-manipulation tools (e.g. nm)
-work.
+Make DDB work.
+
+Add isadma support.
-Make DDB work. (For completeness, may require a.out kernel binaries
-and/or some ecoff symbol handling code to be written; the former is
-strongly preferred.)
+Add floppy support (requires isadma).
-Track down any bugs caused by compiling the kernel with -O. (At least
-some of these may be code generation bugs.)
+Add WSS (audio) support (requires isadma). \ No newline at end of file
diff --git a/sys/arch/alpha/alpha/autoconf.c b/sys/arch/alpha/alpha/autoconf.c
index 3f0bbe7b631..7231ee3d031 100644
--- a/sys/arch/alpha/alpha/autoconf.c
+++ b/sys/arch/alpha/alpha/autoconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: autoconf.c,v 1.3 1996/07/29 22:57:12 niklas Exp $ */
-/* $NetBSD: autoconf.c,v 1.3.4.3 1996/06/14 20:42:41 cgd Exp $ */
+/* $OpenBSD: autoconf.c,v 1.4 1996/10/30 22:37:57 niklas Exp $ */
+/* $NetBSD: autoconf.c,v 1.14 1996/10/13 02:59:23 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -54,8 +54,11 @@
#include <sys/device.h>
#include <machine/autoconf.h>
+#include <machine/rpb.h>
#include <machine/prom.h>
+#include <dev/cons.h>
+
extern char root_device[17]; /* XXX */
struct device *booted_device;
@@ -65,8 +68,11 @@ char boot_dev[128];
void parse_prom_bootdev __P((void));
int atoi __P((char *));
+void setroot __P((void));
+void swapconf __P((void));
-struct device *parsedisk __P((char *str, int len, int defpart, dev_t *devp));
+static struct device *parsedisk __P((char *str, int len, int defpart,
+ dev_t *devp));
static struct device *getdisk __P((char *str, int len, int defpart,
dev_t *devp));
static int findblkmajor __P((struct device *dv));
@@ -100,6 +106,7 @@ configure()
/*
* Configure swap space and related parameters.
*/
+void
swapconf()
{
struct swdevt *swp;
@@ -126,12 +133,17 @@ struct nam2blk {
} nam2blk[] = {
{ "st", 2 },
{ "cd", 3 },
+ { "rd", 6 },
{ "sd", 8 },
#if 0
{ "fd", XXX },
#endif
};
+#ifdef RAMDISK_HOOKS
+static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL };
+#endif
+
static int
findblkmajor(dv)
struct device *dv;
@@ -168,6 +180,9 @@ getdisk(str, len, defpart, devp)
if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
printf("use one of:");
+#ifdef RAMDISK_HOOKS
+ printf(" %s[a-h]", fakerdrootdev.dv_xname);
+#endif
for (dv = alldevs.tqh_first; dv != NULL;
dv = dv->dv_list.tqe_next) {
if (dv->dv_class == DV_DISK)
@@ -177,12 +192,12 @@ getdisk(str, len, defpart, devp)
printf(" %s", dv->dv_xname);
#endif
}
- printf("\n");
+ printf(" halt\n");
}
return (dv);
}
-struct device *
+static struct device *
parsedisk(str, len, defpart, devp)
char *str;
int len, defpart;
@@ -194,6 +209,10 @@ parsedisk(str, len, defpart, devp)
if (len == 0)
return (NULL);
+
+ if (len == 4 && !strcmp(str, "halt"))
+ boot(RB_HALT /* , NULL */);
+
cp = str + len - 1;
c = *cp;
if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
@@ -202,9 +221,18 @@ parsedisk(str, len, defpart, devp)
} else
part = defpart;
+#ifdef RAMDISK_HOOKS
+ if (strcmp(str, fakerdrootdev.dv_xname) == 0) {
+ dv = &fakerdrootdev;
+ goto gotdisk;
+ }
+#endif
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
if (dv->dv_class == DV_DISK &&
strcmp(str, dv->dv_xname) == 0) {
+#ifdef RAMDISK_HOOKS
+gotdisk:
+#endif
majdev = findblkmajor(dv);
if (majdev < 0)
panic("parsedisk");
@@ -233,6 +261,7 @@ parsedisk(str, len, defpart, devp)
* (ie. DV_DISK or DV_IFNET) because of how (*mountroot) is written.
* That should be fixed.
*/
+void
setroot()
{
struct swdevt *swp;
@@ -252,8 +281,13 @@ setroot()
extern int ffs_mountroot __P((void *));
#endif
+#ifdef RAMDISK_HOOKS
+ bootdv = &fakerdrootdev;
+ bootpartition = 0;
+#else
bootdv = booted_device;
bootpartition = booted_partition;
+#endif
/*
* If 'swap generic' and we couldn't determine root device,
@@ -265,19 +299,18 @@ setroot()
if (boothowto & RB_ASKNAME) {
for (;;) {
printf("root device");
- if (bootdv != NULL)
- printf(" (default %s%c)",
- bootdv->dv_xname,
- bootdv->dv_class == DV_DISK
- ? bootpartition + 'a' : ' ');
+ if (bootdv != NULL) {
+ printf(" (default %s", bootdv->dv_xname);
+ if (bootdv->dv_class == DV_DISK)
+ printf("%c", bootpartition + 'a');
+ printf(")");
+ }
printf(": ");
len = getstr(buf, sizeof(buf));
if (len == 0 && bootdv != NULL) {
strcpy(buf, bootdv->dv_xname);
len = strlen(buf);
}
- if (len == 4 && !strcmp(buf, "halt"))
- boot(RB_HALT);
if (len > 0 && buf[len - 1] == '*') {
buf[--len] = '\0';
dv = getdisk(buf, len, 1, &nrootdev);
@@ -304,8 +337,10 @@ setroot()
}
for (;;) {
printf("swap device");
- printf(" (default %s%c)", rootdv->dv_xname,
- rootdv->dv_class == DV_DISK?'b':' ');
+ printf(" (default %s", rootdv->dv_xname);
+ if (rootdv->dv_class == DV_DISK)
+ printf("b");
+ printf(")");
printf(": ");
len = getstr(buf, sizeof(buf));
if (len == 0) {
@@ -326,8 +361,6 @@ setroot()
swapdv = rootdv;
break;
}
- if (len == 4 && !strcmp(buf, "halt"))
- boot(RB_HALT);
dv = getdisk(buf, len, 1, &nswapdev);
if (dv) {
if (dv->dv_class == DV_IFNET)
@@ -368,7 +401,7 @@ gotswap:
swdevt[1].sw_dev = NODEV;
} else {
/*
- * `root DEV swap DEV': honour rootdev/swdevt.
+ * `root DEV swap DEV': honor rootdev/swdevt.
* rootdev/swdevt/mountroot already properly set.
*/
@@ -545,7 +578,6 @@ atoi(s)
char *s;
{
int n, neg;
- char c;
n = 0;
neg = 0;
diff --git a/sys/arch/alpha/alpha/clock.c b/sys/arch/alpha/alpha/clock.c
index 82a455b716c..3b69e90b6b2 100644
--- a/sys/arch/alpha/alpha/clock.c
+++ b/sys/arch/alpha/alpha/clock.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: clock.c,v 1.5 1996/07/29 22:57:13 niklas Exp $ */
-/* $NetBSD: clock.c,v 1.10 1996/04/23 15:26:06 cgd Exp $ */
+/* $OpenBSD: clock.c,v 1.6 1996/10/30 22:37:58 niklas Exp $ */
+/* $NetBSD: clock.c,v 1.13 1996/10/13 02:59:25 christos Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -49,6 +49,7 @@
#include <sys/device.h>
#include <machine/rpb.h>
+#include <machine/autoconf.h>
#include <alpha/alpha/clockvar.h>
@@ -105,8 +106,6 @@ void
cpu_initclocks()
{
extern int tickadj;
- struct clock_softc *csc;
- int fractick;
if (clockfns == NULL)
panic("cpu_initclocks: no clock attached");
@@ -160,8 +159,8 @@ inittodr(base)
{
register int days, yr;
struct clocktime ct;
- long deltat;
- int badbase, s;
+ time_t deltat;
+ int badbase;
if (base < 5*SECYR) {
printf("WARNING: preposterous time in file system");
@@ -227,7 +226,6 @@ resettodr()
{
register int t, t2;
struct clocktime ct;
- int s;
if (!clockinitted)
return;
@@ -238,6 +236,7 @@ resettodr()
/* compute the year */
ct.year = 69;
+ t = t2; /* XXX ? */
while (t2 >= 0) { /* whittle off years */
t = t2;
ct.year++;
diff --git a/sys/arch/alpha/alpha/clockvar.h b/sys/arch/alpha/alpha/clockvar.h
index 05c0d6ad797..bdf66e16909 100644
--- a/sys/arch/alpha/alpha/clockvar.h
+++ b/sys/arch/alpha/alpha/clockvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clockvar.h,v 1.3 1996/07/29 22:57:15 niklas Exp $ */
+/* $OpenBSD: clockvar.h,v 1.4 1996/10/30 22:37:59 niklas Exp $ */
/* $NetBSD: clockvar.h,v 1.2 1996/04/17 22:01:21 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/alpha/conf.c b/sys/arch/alpha/alpha/conf.c
index 84ce29f2af1..6cb3cb311a0 100644
--- a/sys/arch/alpha/alpha/conf.c
+++ b/sys/arch/alpha/alpha/conf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: conf.c,v 1.7 1996/10/19 13:26:03 mickey Exp $ */
-/* $NetBSD: conf.c,v 1.11 1996/04/12 02:07:23 cgd Exp $ */
+/* $OpenBSD: conf.c,v 1.8 1996/10/30 22:38:00 niklas Exp $ */
+/* $NetBSD: conf.c,v 1.16 1996/10/18 21:26:57 cgd Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -44,14 +44,6 @@
#include <sys/conf.h>
#include <sys/vnode.h>
-int ttselect __P((dev_t, int, struct proc *));
-
-#ifndef LKM
-#define lkmenodev enodev
-#else
-int lkmenodev();
-#endif
-
bdev_decl(sw);
#include "st.h"
bdev_decl(st);
@@ -63,6 +55,8 @@ bdev_decl(sd);
bdev_decl(vnd);
#include "ccd.h"
bdev_decl(ccd);
+#include "rd.h"
+bdev_decl(rd);
struct bdevsw bdevsw[] =
{
@@ -72,7 +66,7 @@ struct bdevsw bdevsw[] =
bdev_disk_init(NCD,cd), /* 3: SCSI CD-ROM */
bdev_notdef(), /* 4 */
bdev_notdef(), /* 5 */
- bdev_notdef(), /* 6 */
+ bdev_disk_init(NRD,rd), /* 6: ram disk driver */
bdev_disk_init(NCCD,ccd), /* 7: concatenated disk driver */
bdev_disk_init(NSD,sd), /* 8: SCSI disk */
bdev_disk_init(NVND,vnd), /* 9: vnode disk driver */
@@ -89,7 +83,7 @@ int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]);
#define cdev_wscons_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
- dev_init(c,n,tty), ttselect, dev_init(c,n,mmap), D_TTY }
+ dev_init(c,n,tty), ttselect /* ttpoll */, dev_init(c,n,mmap), D_TTY }
/* open, close, write, ioctl */
#define cdev_lpt_init(c,n) { \
@@ -126,12 +120,6 @@ cdev_decl(cd);
cdev_decl(ch);
#include "scc.h"
cdev_decl(scc);
-#ifdef LKM
-#define NLKM 1
-#else
-#define NLKM 0
-#endif
-cdev_decl(lkm);
#include "audio.h"
cdev_decl(audio);
#include "wscons.h"
@@ -142,6 +130,9 @@ cdev_decl(kbd);
cdev_decl(ms);
#include "lpt.h"
cdev_decl(lpt);
+cdev_decl(rd);
+#include "ss.h"
+cdev_decl(ss);
#include "uk.h"
cdev_decl(uk);
@@ -178,12 +169,13 @@ struct cdevsw cdevsw[] =
cdev_wscons_init(NWSCONS,wscons), /* 25: workstation console */
cdev_tty_init(NCOM,com), /* 26: ns16550 UART */
cdev_disk_init(NCCD,ccd), /* 27: concatenated disk driver */
- cdev_notdef(), /* 28 */
+ cdev_disk_init(NRD,rd), /* 28: ram disk driver */
cdev_mouse_init(NWSCONS,kbd), /* 29: /dev/kbd XXX */
cdev_mouse_init(NWSCONS,ms), /* 30: /dev/mouse XXX */
cdev_lpt_init(NLPT,lpt), /* 31: parallel printer */
- cdev_uk_init(NUK,uk), /* 32: unknown SCSI */
- cdev_random_init(1,random), /* 33: random data source */
+ cdev_scanner_init(NSS,ss), /* 32: SCSI scanner */
+ cdev_uk_init(NUK,uk), /* 33: SCSI unknown */
+ cdev_random_init(1,random), /* 34: random data source */
};
int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
@@ -203,6 +195,7 @@ dev_t swapdev = makedev(1, 0);
/*
* Returns true if dev is /dev/mem or /dev/kmem.
*/
+int
iskmemdev(dev)
dev_t dev;
{
@@ -213,6 +206,7 @@ iskmemdev(dev)
/*
* Returns true if dev is /dev/zero.
*/
+int
iszerodev(dev)
dev_t dev;
{
@@ -231,12 +225,12 @@ static int chrtoblktbl[] = {
/* 5 */ NODEV,
/* 6 */ NODEV,
/* 7 */ NODEV,
- /* 8 */ 8,
- /* 9 */ 9,
+ /* 8 */ 8, /* sd */
+ /* 9 */ 9, /* vnd */
/* 10 */ NODEV,
/* 11 */ NODEV,
- /* 12 */ NODEV,
- /* 13 */ 3,
+ /* 12 */ 2, /* st */
+ /* 13 */ 3, /* cd */
/* 14 */ NODEV,
/* 15 */ NODEV,
/* 16 */ NODEV,
@@ -250,16 +244,20 @@ static int chrtoblktbl[] = {
/* 24 */ NODEV,
/* 25 */ NODEV,
/* 26 */ NODEV,
- /* 27 */ 7,
- /* 28 */ NODEV,
+ /* 27 */ 7, /* ccd */
+ /* 28 */ 6, /* rd */
/* 29 */ NODEV,
/* 30 */ NODEV,
/* 31 */ NODEV,
+ /* 32 */ NODEV,
+ /* 33 */ NODEV,
+ /* 34 */ NODEV,
};
/*
* Convert a character device number to a block device number.
*/
+dev_t
chrtoblk(dev)
dev_t dev;
{
diff --git a/sys/arch/alpha/alpha/cpu.c b/sys/arch/alpha/alpha/cpu.c
index 4e79e5ca346..ccace66662d 100644
--- a/sys/arch/alpha/alpha/cpu.c
+++ b/sys/arch/alpha/alpha/cpu.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cpu.c,v 1.4 1996/07/29 22:57:18 niklas Exp $ */
-/* $NetBSD: cpu.c,v 1.9 1996/04/29 16:36:19 cgd Exp $ */
+/* $OpenBSD: cpu.c,v 1.5 1996/10/30 22:38:01 niklas Exp $ */
+/* $NetBSD: cpu.c,v 1.12 1996/10/13 02:59:26 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,14 +29,15 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/rpb.h>
/* Definition of the driver for autoconfig. */
-static int cpumatch(struct device *, void *, void *);
-static void cpuattach(struct device *, struct device *, void *);
+int cpumatch __P((struct device *, void *, void *));
+void cpuattach __P((struct device *, struct device *, void *));
struct cfattach cpu_ca = {
sizeof(struct device), cpumatch, cpuattach
@@ -46,15 +47,12 @@ struct cfdriver cpu_cd = {
NULL, "cpu", DV_DULL
};
-static int cpuprint __P((void *, char *pnp));
-
-static int
+int
cpumatch(parent, cfdata, aux)
struct device *parent;
void *cfdata;
void *aux;
{
- struct cfdata *cf = cfdata;
struct confargs *ca = aux;
/* make sure that we're looking for a CPU. */
@@ -64,7 +62,7 @@ cpumatch(parent, cfdata, aux)
return (1);
}
-static void
+void
cpuattach(parent, dev, aux)
struct device *parent;
struct device *dev;
@@ -88,7 +86,7 @@ cpuattach(parent, dev, aux)
int ndc21064_cpu_minor =
sizeof(dc21064_cpu_minor) / sizeof(dc21064_cpu_minor[0]);
u_int32_t major, minor;
- int needcomma, needrev, i;
+ int needcomma;
p = (struct pcs*)((char *)hwrpb + hwrpb->rpb_pcs_off +
(dev->dv_unit * hwrpb->rpb_pcs_size));
@@ -160,15 +158,3 @@ cpuattach(parent, dev, aux)
* and more compact if done the 'normal' way.
*/
}
-
-static int
-cpuprint(aux, pnp)
- void *aux;
- char *pnp;
-{
- register struct confargs *ca = aux;
-
- if (pnp)
- printf("%s at %s", ca->ca_name, pnp);
- return (UNCONF);
-}
diff --git a/sys/arch/alpha/alpha/dec_2100_a50.c b/sys/arch/alpha/alpha/dec_2100_a50.c
index 9d61c61deff..27fc4f3a196 100644
--- a/sys/arch/alpha/alpha/dec_2100_a50.c
+++ b/sys/arch/alpha/alpha/dec_2100_a50.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_2100_a50.c,v 1.4 1996/07/29 22:57:20 niklas Exp $ */
-/* $NetBSD: dec_2100_a50.c,v 1.6.4.2 1996/06/14 20:42:23 cgd Exp $ */
+/* $OpenBSD: dec_2100_a50.c,v 1.5 1996/10/30 22:38:01 niklas Exp $ */
+/* $NetBSD: dec_2100_a50.c,v 1.14 1996/10/13 02:59:28 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
@@ -99,9 +100,7 @@ dec_2100_a50_consinit()
/* serial console ... */
/* XXX */
{
- extern bus_chipset_tag_t comconsbc; /* set */
- extern bus_io_handle_t comcomsioh; /* set */
- extern int comconsaddr, comconsinit; /* set */
+ extern int comconsinit; /* set */
extern int comdefaultrate;
extern int comcngetc __P((dev_t));
extern void comcnputc __P((dev_t, int));
@@ -148,7 +147,7 @@ dec_2100_a50_device_register(dev, aux)
struct device *dev;
void *aux;
{
- static int found;
+ static int found, initted, scsiboot, netboot;
static struct device *pcidev, *scsidev;
struct bootdev_data *b = bootdev_data;
struct device *parent = dev->dv_parent;
@@ -158,6 +157,15 @@ dec_2100_a50_device_register(dev, aux)
if (found)
return;
+ if (!initted) {
+ scsiboot = (strcmp(b->protocol, "SCSI") == 0);
+ netboot = (strcmp(b->protocol, "BOOTP") == 0);
+#if 0
+ printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
+#endif
+ initted =1;
+ }
+
if (pcidev == NULL) {
if (strcmp(cd->cd_name, "pci"))
return;
@@ -175,7 +183,7 @@ dec_2100_a50_device_register(dev, aux)
}
}
- if (scsidev == NULL) {
+ if (scsiboot && (scsidev == NULL)) {
if (parent != pcidev)
return;
else {
@@ -194,9 +202,10 @@ dec_2100_a50_device_register(dev, aux)
}
}
- if (!strcmp(cd->cd_name, "sd") ||
- !strcmp(cd->cd_name, "st") ||
- !strcmp(cd->cd_name, "cd")) {
+ if (scsiboot &&
+ (!strcmp(cd->cd_name, "sd") ||
+ !strcmp(cd->cd_name, "st") ||
+ !strcmp(cd->cd_name, "cd"))) {
struct scsibus_attach_args *sa = aux;
if (parent->dv_parent != scsidev)
@@ -228,4 +237,24 @@ dec_2100_a50_device_register(dev, aux)
#endif
found = 1;
}
+
+ if (netboot) {
+ if (parent != pcidev)
+ return;
+ else {
+ struct pci_attach_args *pa = aux;
+
+ if (b->slot != pa->pa_device)
+ return;
+
+ /* XXX function? */
+
+ booted_device = dev;
+#if 0
+ printf("\nbooted_device = %s\n", booted_device->dv_xname);
+#endif
+ found = 1;
+ return;
+ }
+ }
}
diff --git a/sys/arch/alpha/alpha/dec_2100_a50.h b/sys/arch/alpha/alpha/dec_2100_a50.h
index 6574866c1e8..69ffc6a1e30 100644
--- a/sys/arch/alpha/alpha/dec_2100_a50.h
+++ b/sys/arch/alpha/alpha/dec_2100_a50.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_2100_a50.h,v 1.3 1996/07/29 22:57:21 niklas Exp $ */
-/* $NetBSD: dec_2100_a50.h,v 1.2.6.2 1996/06/13 18:35:10 cgd Exp $ */
+/* $OpenBSD: dec_2100_a50.h,v 1.4 1996/10/30 22:38:02 niklas Exp $ */
+/* $NetBSD: dec_2100_a50.h,v 1.6 1996/06/13 18:31:49 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/dec_3000_300.c b/sys/arch/alpha/alpha/dec_3000_300.c
index 73729f5e812..0947428fb98 100644
--- a/sys/arch/alpha/alpha/dec_3000_300.c
+++ b/sys/arch/alpha/alpha/dec_3000_300.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_3000_300.c,v 1.3 1996/07/29 22:57:23 niklas Exp $ */
-/* $NetBSD: dec_3000_300.c,v 1.2.6.2 1996/06/13 18:35:12 cgd Exp $ */
+/* $OpenBSD: dec_3000_300.c,v 1.4 1996/10/30 22:38:03 niklas Exp $ */
+/* $NetBSD: dec_3000_300.c,v 1.9 1996/10/13 02:59:30 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -42,6 +42,10 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+char *dec_3000_300_modelname __P((void));
+void dec_3000_300_consinit __P((void));
+void dec_3000_300_device_register __P((struct device *, void *));
+
char *
dec_3000_300_modelname()
{
@@ -69,7 +73,6 @@ dec_3000_300_modelname()
void
dec_3000_300_consinit()
{
-
}
void
@@ -77,7 +80,7 @@ dec_3000_300_device_register(dev, aux)
struct device *dev;
void *aux;
{
- static int found;
+ static int found, initted, scsiboot, netboot;
static struct device *scsidev;
struct bootdev_data *b = bootdev_data;
struct device *parent = dev->dv_parent;
@@ -87,7 +90,16 @@ dec_3000_300_device_register(dev, aux)
if (found)
return;
- if (strcmp(cd->cd_name, "esp") == 0) {
+ if (!initted) {
+ scsiboot = (strcmp(b->protocol, "SCSI") == 0);
+ netboot = (strcmp(b->protocol, "BOOTP") == 0);
+#if 0
+ printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
+#endif
+ initted =1;
+ }
+
+ if (scsiboot && (strcmp(cd->cd_name, "esp") == 0)) {
if (b->slot == 4 &&
strcmp(parent->dv_cfdata->cf_driver->cd_name, "tcds")
== 0) {
@@ -100,9 +112,12 @@ dec_3000_300_device_register(dev, aux)
#endif
}
}
- } else if (strcmp(cd->cd_name, "sd") == 0 ||
- strcmp(cd->cd_name, "st") == 0 ||
- strcmp(cd->cd_name, "cd") == 0) {
+ }
+
+ if (scsiboot &&
+ (strcmp(cd->cd_name, "sd") == 0 ||
+ strcmp(cd->cd_name, "st") == 0 ||
+ strcmp(cd->cd_name, "cd") == 0)) {
struct scsibus_attach_args *sa = aux;
if (scsidev == NULL)
@@ -137,4 +152,26 @@ dec_3000_300_device_register(dev, aux)
#endif
found = 1;
}
+
+ if (netboot) {
+ if (b->slot == 5 && strcmp(cd->cd_name, "le") == 0 &&
+ strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic")
+ == 0) {
+ /*
+ * no need to check ioasic_attach_args, since only
+ * one le on ioasic.
+ */
+
+ booted_device = dev;
+#if 0
+ printf("\nbooted_device = %s\n", booted_device->dv_xname);
+#endif
+ found = 1;
+ return;
+ }
+
+ /*
+ * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS
+ */
+ }
}
diff --git a/sys/arch/alpha/alpha/dec_3000_300.h b/sys/arch/alpha/alpha/dec_3000_300.h
index b1d7e3e90bb..c7d9c27b7c7 100644
--- a/sys/arch/alpha/alpha/dec_3000_300.h
+++ b/sys/arch/alpha/alpha/dec_3000_300.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_3000_300.h,v 1.3 1996/07/29 22:57:24 niklas Exp $ */
-/* $NetBSD: dec_3000_300.h,v 1.2.6.2 1996/06/13 18:35:13 cgd Exp $ */
+/* $OpenBSD: dec_3000_300.h,v 1.4 1996/10/30 22:38:04 niklas Exp $ */
+/* $NetBSD: dec_3000_300.h,v 1.6 1996/06/13 18:32:00 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/dec_3000_500.c b/sys/arch/alpha/alpha/dec_3000_500.c
index ace50cef152..c1c08d08fd5 100644
--- a/sys/arch/alpha/alpha/dec_3000_500.c
+++ b/sys/arch/alpha/alpha/dec_3000_500.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_3000_500.c,v 1.3 1996/07/29 22:57:26 niklas Exp $ */
-/* $NetBSD: dec_3000_500.c,v 1.1.6.2 1996/06/13 18:35:15 cgd Exp $ */
+/* $OpenBSD: dec_3000_500.c,v 1.4 1996/10/30 22:38:05 niklas Exp $ */
+/* $NetBSD: dec_3000_500.c,v 1.8 1996/10/13 02:59:31 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -42,6 +42,10 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+char *dec_3000_500_modelname __P((void));
+void dec_3000_500_consinit __P((void));
+void dec_3000_500_device_register __P((struct device *, void *));
+
char *
dec_3000_500_modelname()
{
@@ -87,7 +91,6 @@ systype_flamingo:
void
dec_3000_500_consinit()
{
-
}
void
@@ -95,7 +98,7 @@ dec_3000_500_device_register(dev, aux)
struct device *dev;
void *aux;
{
- static int found;
+ static int found, initted, scsiboot, netboot;
static struct device *scsidev;
struct bootdev_data *b = bootdev_data;
struct device *parent = dev->dv_parent;
@@ -105,7 +108,16 @@ dec_3000_500_device_register(dev, aux)
if (found)
return;
- if (strcmp(cd->cd_name, "esp") == 0) {
+ if (!initted) {
+ scsiboot = (strcmp(b->protocol, "SCSI") == 0);
+ netboot = (strcmp(b->protocol, "BOOTP") == 0);
+#if 0
+ printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
+#endif
+ initted =1;
+ }
+
+ if (scsiboot && (strcmp(cd->cd_name, "esp") == 0)) {
if (b->slot == 6 &&
strcmp(parent->dv_cfdata->cf_driver->cd_name, "tcds")
== 0) {
@@ -118,9 +130,12 @@ dec_3000_500_device_register(dev, aux)
#endif
}
}
- } else if (strcmp(cd->cd_name, "sd") == 0 ||
- strcmp(cd->cd_name, "st") == 0 ||
- strcmp(cd->cd_name, "cd") == 0) {
+ }
+
+ if (scsiboot &&
+ (strcmp(cd->cd_name, "sd") == 0 ||
+ strcmp(cd->cd_name, "st") == 0 ||
+ strcmp(cd->cd_name, "cd") == 0)) {
struct scsibus_attach_args *sa = aux;
if (scsidev == NULL)
@@ -155,4 +170,26 @@ dec_3000_500_device_register(dev, aux)
#endif
found = 1;
}
+
+ if (netboot) {
+ if (b->slot == 7 && strcmp(cd->cd_name, "le") == 0 &&
+ strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic")
+ == 0) {
+ /*
+ * no need to check ioasic_attach_args, since only
+ * one le on ioasic.
+ */
+
+ booted_device = dev;
+#if 0
+ printf("\nbooted_device = %s\n", booted_device->dv_xname);
+#endif
+ found = 1;
+ return;
+ }
+
+ /*
+ * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS
+ */
+ }
}
diff --git a/sys/arch/alpha/alpha/dec_3000_500.h b/sys/arch/alpha/alpha/dec_3000_500.h
index 1dd53322834..c4e68b30b97 100644
--- a/sys/arch/alpha/alpha/dec_3000_500.h
+++ b/sys/arch/alpha/alpha/dec_3000_500.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_3000_500.h,v 1.3 1996/07/29 22:57:27 niklas Exp $ */
-/* $NetBSD: dec_3000_500.h,v 1.2.6.2 1996/06/13 18:35:17 cgd Exp $ */
+/* $OpenBSD: dec_3000_500.h,v 1.4 1996/10/30 22:38:05 niklas Exp $ */
+/* $NetBSD: dec_3000_500.h,v 1.6 1996/06/13 18:32:04 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/dec_axppci_33.c b/sys/arch/alpha/alpha/dec_axppci_33.c
index 74e4ab96a60..43ce14c25cb 100644
--- a/sys/arch/alpha/alpha/dec_axppci_33.c
+++ b/sys/arch/alpha/alpha/dec_axppci_33.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_axppci_33.c,v 1.3 1996/07/29 22:57:29 niklas Exp $ */
-/* $NetBSD: dec_axppci_33.c,v 1.4.4.2 1996/06/14 20:42:24 cgd Exp $ */
+/* $OpenBSD: dec_axppci_33.c,v 1.4 1996/10/30 22:38:06 niklas Exp $ */
+/* $NetBSD: dec_axppci_33.c,v 1.12 1996/10/13 02:59:32 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
@@ -82,9 +83,7 @@ dec_axppci_33_consinit()
/* serial console ... */
/* XXX */
{
- extern bus_chipset_tag_t comconsbc; /* set */
- extern bus_io_handle_t comcomsioh; /* set */
- extern int comconsaddr, comconsinit; /* set */
+ extern int comconsinit; /* set */
extern int comdefaultrate;
extern int comcngetc __P((dev_t));
extern void comcnputc __P((dev_t, int));
@@ -131,7 +130,7 @@ dec_axppci_33_device_register(dev, aux)
struct device *dev;
void *aux;
{
- static int found;
+ static int found, initted, scsiboot, netboot;
static struct device *pcidev, *scsidev;
struct bootdev_data *b = bootdev_data;
struct device *parent = dev->dv_parent;
@@ -141,6 +140,15 @@ dec_axppci_33_device_register(dev, aux)
if (found)
return;
+ if (!initted) {
+ scsiboot = (strcmp(b->protocol, "SCSI") == 0);
+ netboot = (strcmp(b->protocol, "BOOTP") == 0);
+#if 0
+ printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
+#endif
+ initted =1;
+ }
+
if (pcidev == NULL) {
if (strcmp(cd->cd_name, "pci"))
return;
@@ -158,7 +166,7 @@ dec_axppci_33_device_register(dev, aux)
}
}
- if (scsidev == NULL) {
+ if (scsiboot && (scsidev == NULL)) {
if (parent != pcidev)
return;
else {
@@ -177,9 +185,10 @@ dec_axppci_33_device_register(dev, aux)
}
}
- if (!strcmp(cd->cd_name, "sd") ||
- !strcmp(cd->cd_name, "st") ||
- !strcmp(cd->cd_name, "cd")) {
+ if (scsiboot &&
+ (!strcmp(cd->cd_name, "sd") ||
+ !strcmp(cd->cd_name, "st") ||
+ !strcmp(cd->cd_name, "cd"))) {
struct scsibus_attach_args *sa = aux;
if (parent->dv_parent != scsidev)
@@ -211,4 +220,24 @@ dec_axppci_33_device_register(dev, aux)
#endif
found = 1;
}
+
+ if (netboot) {
+ if (parent != pcidev)
+ return;
+ else {
+ struct pci_attach_args *pa = aux;
+
+ if (b->slot != pa->pa_device)
+ return;
+
+ /* XXX function? */
+
+ booted_device = dev;
+#if 0
+ printf("\nbooted_device = %s\n", booted_device->dv_xname);
+#endif
+ found = 1;
+ return;
+ }
+ }
}
diff --git a/sys/arch/alpha/alpha/dec_axppci_33.h b/sys/arch/alpha/alpha/dec_axppci_33.h
index 105e9317e18..dbf4ffd4df2 100644
--- a/sys/arch/alpha/alpha/dec_axppci_33.h
+++ b/sys/arch/alpha/alpha/dec_axppci_33.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_axppci_33.h,v 1.3 1996/07/29 22:57:30 niklas Exp $ */
-/* $NetBSD: dec_axppci_33.h,v 1.1.4.2 1996/06/13 18:35:18 cgd Exp $ */
+/* $OpenBSD: dec_axppci_33.h,v 1.4 1996/10/30 22:38:07 niklas Exp $ */
+/* $NetBSD: dec_axppci_33.h,v 1.5 1996/06/13 18:32:05 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/dec_kn20aa.c b/sys/arch/alpha/alpha/dec_kn20aa.c
index 1b599144710..1639883b04f 100644
--- a/sys/arch/alpha/alpha/dec_kn20aa.c
+++ b/sys/arch/alpha/alpha/dec_kn20aa.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_kn20aa.c,v 1.3 1996/07/29 22:57:32 niklas Exp $ */
-/* $NetBSD: dec_kn20aa.c,v 1.4.4.2 1996/06/14 20:42:25 cgd Exp $ */
+/* $OpenBSD: dec_kn20aa.c,v 1.4 1996/10/30 22:38:08 niklas Exp $ */
+/* $NetBSD: dec_kn20aa.c,v 1.12 1996/10/13 02:59:33 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
@@ -82,9 +83,7 @@ dec_kn20aa_consinit()
/* serial console ... */
/* XXX */
{
- extern bus_chipset_tag_t comconsbc; /* set */
- extern bus_io_handle_t comcomsioh; /* set */
- extern int comconsaddr, comconsinit; /* set */
+ extern int comconsinit; /* set */
extern int comdefaultrate;
extern int comcngetc __P((dev_t));
extern void comcnputc __P((dev_t, int));
@@ -131,7 +130,7 @@ dec_kn20aa_device_register(dev, aux)
struct device *dev;
void *aux;
{
- static int found;
+ static int found, initted, scsiboot, netboot;
static struct device *pcidev, *scsidev;
struct bootdev_data *b = bootdev_data;
struct device *parent = dev->dv_parent;
@@ -141,6 +140,15 @@ dec_kn20aa_device_register(dev, aux)
if (found)
return;
+ if (!initted) {
+ scsiboot = (strcmp(b->protocol, "SCSI") == 0);
+ netboot = (strcmp(b->protocol, "BOOTP") == 0);
+#if 0
+ printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
+#endif
+ initted =1;
+ }
+
if (pcidev == NULL) {
if (strcmp(cd->cd_name, "pci"))
return;
@@ -158,7 +166,7 @@ dec_kn20aa_device_register(dev, aux)
}
}
- if (scsidev == NULL) {
+ if (scsiboot && (scsidev == NULL)) {
if (parent != pcidev)
return;
else {
@@ -177,9 +185,10 @@ dec_kn20aa_device_register(dev, aux)
}
}
- if (!strcmp(cd->cd_name, "sd") ||
- !strcmp(cd->cd_name, "st") ||
- !strcmp(cd->cd_name, "cd")) {
+ if (scsiboot &&
+ (!strcmp(cd->cd_name, "sd") ||
+ !strcmp(cd->cd_name, "st") ||
+ !strcmp(cd->cd_name, "cd"))) {
struct scsibus_attach_args *sa = aux;
if (parent->dv_parent != scsidev)
@@ -211,4 +220,24 @@ dec_kn20aa_device_register(dev, aux)
#endif
found = 1;
}
+
+ if (netboot) {
+ if (parent != pcidev)
+ return;
+ else {
+ struct pci_attach_args *pa = aux;
+
+ if (b->slot != pa->pa_device)
+ return;
+
+ /* XXX function? */
+
+ booted_device = dev;
+#if 0
+ printf("\nbooted_device = %s\n", booted_device->dv_xname);
+#endif
+ found = 1;
+ return;
+ }
+ }
}
diff --git a/sys/arch/alpha/alpha/dec_kn20aa.h b/sys/arch/alpha/alpha/dec_kn20aa.h
index c8be73911b1..ae165766657 100644
--- a/sys/arch/alpha/alpha/dec_kn20aa.h
+++ b/sys/arch/alpha/alpha/dec_kn20aa.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: dec_kn20aa.h,v 1.3 1996/07/29 22:57:33 niklas Exp $ */
-/* $NetBSD: dec_kn20aa.h,v 1.1.4.2 1996/06/13 18:35:19 cgd Exp $ */
+/* $OpenBSD: dec_kn20aa.h,v 1.4 1996/10/30 22:38:09 niklas Exp $ */
+/* $NetBSD: dec_kn20aa.h,v 1.5 1996/06/13 18:32:07 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/disksubr.c b/sys/arch/alpha/alpha/disksubr.c
index 78b90a4fa83..769c5a5fd0f 100644
--- a/sys/arch/alpha/alpha/disksubr.c
+++ b/sys/arch/alpha/alpha/disksubr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: disksubr.c,v 1.4 1996/07/29 22:57:35 niklas Exp $ */
-/* $NetBSD: disksubr.c,v 1.6 1996/04/29 16:34:50 cgd Exp $ */
+/* $OpenBSD: disksubr.c,v 1.5 1996/10/30 22:38:10 niklas Exp $ */
+/* $NetBSD: disksubr.c,v 1.8 1996/10/13 02:59:35 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -77,7 +77,7 @@ dk_establish(dk, dev)
char *
readdisklabel(dev, strat, lp, clp)
dev_t dev;
- void (*strat)();
+ void (*strat) __P ((struct buf *));
struct disklabel *lp;
struct cpu_disklabel *clp;
{
@@ -113,7 +113,7 @@ readdisklabel(dev, strat, lp, clp)
dlp = (struct disklabel *)(bp->b_un.b_addr + LABELOFFSET);
if (dlp->d_magic == DISKMAGIC) {
if (dkcksum(dlp)) {
- msg = "NetBSD disk label corrupted";
+ msg = "OpenBSD disk label corrupted";
goto done;
}
*lp = *dlp;
@@ -190,13 +190,13 @@ setdisklabel(olp, nlp, openmask, clp)
int
writedisklabel(dev, strat, lp, clp)
dev_t dev;
- void (*strat)();
+ void (*strat) __P((struct buf *));
register struct disklabel *lp;
struct cpu_disklabel *clp;
{
struct buf *bp;
struct disklabel *dlp;
- int error = 0, cyl, i;
+ int error = 0;
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
@@ -205,7 +205,7 @@ writedisklabel(dev, strat, lp, clp)
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_READ; /* get current label */
(*strat)(bp);
- if (error = biowait(bp))
+ if ((error = biowait(bp)) != 0)
goto done;
dlp = (struct disklabel *)(bp->b_un.b_addr + LABELOFFSET);
diff --git a/sys/arch/alpha/alpha/genassym.c b/sys/arch/alpha/alpha/genassym.c
index cdac4f4b5a2..cfe3ddabf00 100644
--- a/sys/arch/alpha/alpha/genassym.c
+++ b/sys/arch/alpha/alpha/genassym.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: genassym.c,v 1.4 1996/07/29 22:57:36 niklas Exp $ */
-/* $NetBSD: genassym.c,v 1.4 1996/05/17 18:29:41 cgd Exp $ */
+/* $OpenBSD: genassym.c,v 1.5 1996/10/30 22:38:10 niklas Exp $ */
+/* $NetBSD: genassym.c,v 1.9 1996/08/20 23:00:24 cgd Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@@ -50,7 +50,6 @@
#include <machine/reg.h>
#include <machine/frame.h>
#include <machine/rpb.h>
-#include <machine/trap.h>
#include <stddef.h>
#include <stdio.h>
@@ -83,8 +82,6 @@ main(argc, argv)
def("VM_MAX_ADDRESS", VM_MAX_ADDRESS);
/* Register offsets, for stack frames. */
- def("FRAMESIZE", sizeof(struct trapframe));
- def("FRAME_NSAVEREGS", FRAME_NSAVEREGS);
def("FRAME_V0", FRAME_V0);
def("FRAME_T0", FRAME_T0);
def("FRAME_T1", FRAME_T1);
@@ -112,25 +109,30 @@ main(argc, argv)
def("FRAME_T12", FRAME_T12);
def("FRAME_AT", FRAME_AT);
def("FRAME_SP", FRAME_SP);
- off("TF_PS", struct trapframe, tf_ps);
- off("TF_PC", struct trapframe, tf_ps);
- off("TF_A0", struct trapframe, tf_a0);
- off("TF_A1", struct trapframe, tf_a1);
- off("TF_A2", struct trapframe, tf_a2);
+
+ def("FRAME_SW_SIZE", FRAME_SW_SIZE);
+
+ def("FRAME_PS", FRAME_PS);
+ def("FRAME_PC", FRAME_PC);
+ def("FRAME_GP", FRAME_GP);
+ def("FRAME_A0", FRAME_A0);
+ def("FRAME_A1", FRAME_A1);
+ def("FRAME_A2", FRAME_A2);
+
+ def("FRAME_SIZE", FRAME_SIZE);
/* bits of the PS register */
- def("PSL_U", PSL_U);
- def("PSL_IPL", PSL_IPL);
- def("PSL_IPL_0", PSL_IPL_0);
- def("PSL_IPL_SOFT", PSL_IPL_SOFT);
- def("PSL_IPL_HIGH", PSL_IPL_HIGH);
+ def("ALPHA_PSL_USERMODE", ALPHA_PSL_USERMODE);
+ def("ALPHA_PSL_IPL_MASK", ALPHA_PSL_IPL_MASK);
+ def("ALPHA_PSL_IPL_0", ALPHA_PSL_IPL_0);
+ def("ALPHA_PSL_IPL_SOFT", ALPHA_PSL_IPL_SOFT);
+ def("ALPHA_PSL_IPL_HIGH", ALPHA_PSL_IPL_HIGH);
/* pte bits */
- def("PG_V", PG_V);
- def("PG_ASM", PG_ASM);
- def("PG_KRE", PG_KRE);
- def("PG_KWE", PG_KWE);
- def("PG_SHIFT", PG_SHIFT);
+ def("ALPHA_PTE_VALID", ALPHA_PTE_VALID);
+ def("ALPHA_PTE_ASM", ALPHA_PTE_ASM);
+ def("ALPHA_PTE_KR", ALPHA_PTE_KR);
+ def("ALPHA_PTE_KW", ALPHA_PTE_KW);
/* Important offsets into the proc struct & associated constants */
off("P_FORW", struct proc, p_forw);
@@ -142,16 +144,22 @@ main(argc, argv)
off("PH_LINK", struct prochd, ph_link);
off("PH_RLINK", struct prochd, ph_rlink);
+#ifndef NEW_PMAP
/* offsets needed by cpu_switch(), et al., to switch mappings. */
off("VM_PMAP_STPTE", struct vmspace, vm_pmap.pm_stpte);
def("USTP_OFFSET", kvtol1pte(VM_MIN_ADDRESS) * sizeof(pt_entry_t));
+#else /* NEW_PMAP */
+ off("VM_PMAP", struct vmspace, vm_pmap);
+#endif /* NEW_PMAP */
/* Important offsets into the user struct & associated constants */
def("UPAGES", UPAGES);
off("U_PCB", struct user, u_pcb);
- off("U_PCB_KSP", struct user, u_pcb.pcb_ksp);
- off("U_PCB_CONTEXT", struct user, u_pcb.pcb_context[0]);
- off("U_PCB_ONFAULT", struct user, u_pcb.pcb_onfault);
+ off("PCB_HWPCB", struct pcb, pcb_hw);
+ off("PCB_HWPCB_KSP", struct pcb, pcb_hw.apcb_ksp);
+ off("PCB_CONTEXT", struct pcb, pcb_context[0]);
+ off("PCB_ONFAULT", struct pcb, pcb_onfault);
+ off("PCB_ACCESSADDR", struct pcb, pcb_accessaddr);
/* Offsets into struct fpstate, for save, restore */
off("FPREG_FPR_REGS", struct fpreg, fpr_regs[0]);
@@ -161,12 +169,11 @@ main(argc, argv)
def("HWRPB_ADDR", HWRPB_ADDR); /* Restart parameter block */
def("VPTBASE", VPTBASE); /* Virtual Page Table base */
- /* Trap types and qualifiers */
- def("T_ASTFLT", T_ASTFLT);
- def("T_UNAFLT", T_UNAFLT);
- def("T_ARITHFLT", T_ARITHFLT);
- def("T_IFLT", T_IFLT); /* qualifier */
- def("T_MMFLT", T_MMFLT); /* qualifier */
+ /* Kernel entries */
+ def("ALPHA_KENTRY_ARITH", ALPHA_KENTRY_ARITH);
+ def("ALPHA_KENTRY_MM", ALPHA_KENTRY_MM);
+ def("ALPHA_KENTRY_IF", ALPHA_KENTRY_IF);
+ def("ALPHA_KENTRY_UNA", ALPHA_KENTRY_UNA);
/* errno values */
def("ENAMETOOLONG", ENAMETOOLONG);
diff --git a/sys/arch/alpha/alpha/in_cksum.c b/sys/arch/alpha/alpha/in_cksum.c
index 816d7f06139..5b303da7f00 100644
--- a/sys/arch/alpha/alpha/in_cksum.c
+++ b/sys/arch/alpha/alpha/in_cksum.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: in_cksum.c,v 1.2 1996/07/29 22:57:37 niklas Exp $ */
-/* $NetBSD: in_cksum.c,v 1.2.4.1 1996/05/30 23:12:50 cgd Exp $ */
+/* $OpenBSD: in_cksum.c,v 1.3 1996/10/30 22:38:11 niklas Exp $ */
+/* $NetBSD: in_cksum.c,v 1.3 1996/05/30 23:08:36 cgd Exp $ */
/*
* Copyright (c) 1988, 1992, 1993
@@ -43,6 +43,8 @@
#include <sys/systm.h>
#include <netinet/in.h>
+u_int64_t in_cksumdata __P((caddr_t, int));
+
/*
* Checksum routine for Internet Protocol family headers
* (Portable Alpha version).
@@ -93,7 +95,6 @@ in_cksumdata(buf, len)
u_int64_t prefilled;
int offset;
union q_util q_util;
- union l_util l_util;
if ((3 & (long) lw) == 0 && len == 20) {
sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
diff --git a/sys/arch/alpha/alpha/interrupt.c b/sys/arch/alpha/alpha/interrupt.c
index 8520d5b4b66..8c112198e24 100644
--- a/sys/arch/alpha/alpha/interrupt.c
+++ b/sys/arch/alpha/alpha/interrupt.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: interrupt.c,v 1.4 1996/07/29 22:57:39 niklas Exp $ */
-/* $NetBSD: interrupt.c,v 1.5 1996/04/23 13:54:32 cgd Exp $ */
+/* $OpenBSD: interrupt.c,v 1.5 1996/10/30 22:38:12 niklas Exp $ */
+/* $NetBSD: interrupt.c,v 1.12 1996/10/13 19:57:49 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -35,6 +35,7 @@
#include <machine/autoconf.h>
#include <machine/reg.h>
+#include <machine/frame.h>
#ifdef EVCNT_COUNTERS
#include <sys/device.h>
@@ -49,47 +50,55 @@ struct logout {
/* Unspecified. */
};
-void machine_check __P((struct trapframe *, struct logout *,
- u_int64_t));
-static void nullintr __P((void *, int));
+void interrupt __P((u_long, u_long, u_long, struct trapframe *));
+void machine_check __P((struct trapframe *, u_long, u_long));
+void real_clockintr __P((void *, u_long));
+void nullintr __P((void *, u_long));
-static void (*iointr) __P((void *, int)) = nullintr;
-static void (*clockintr) __P((void *, int)) = nullintr;
-static int mc_expected, mc_received;
+static void (*iointr) __P((void *, u_long)) = nullintr;
+static void (*clockintr) __P((void *, u_long)) = nullintr;
+static volatile int mc_expected, mc_received;
#ifdef EVCNT_COUNTERS
struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
#endif
void
-interrupt(framep, type, vec, logoutp)
+interrupt(a0, a1, a2, framep)
+ u_long a0, a1, a2;
struct trapframe *framep;
- u_int64_t type, vec;
- struct logout *logoutp;
{
- if (type == 1) /* clock interrupt */
- (*clockintr)(framep, vec);
- else if (type == 3) /* I/O device interrupt */
- (*iointr)(framep, vec);
- else if (type == 2)
- machine_check(framep, logoutp, vec);
- else
- panic("unexpected interrupt: type %ld, vec %ld\n",
- (long)type, (long)vec);
+ if (a0 == 1) { /* clock interrupt */
+ cnt.v_intr++;
+ (*clockintr)(framep, a1);
+ } else if (a0 == 3) { /* I/O device interrupt */
+ cnt.v_intr++;
+ (*iointr)(framep, a1);
+ } else if (a0 == 2) /* machine check or correctable error */
+ machine_check(framep, a1, a2);
+ else {
+ /*
+ * Not expected or handled:
+ * 0 Interprocessor interrupt
+ * 4 Performance counter
+ */
+ panic("unexpected interrupt: type 0x%lx, vec 0x%lx\n",
+ a0, a1);
+ }
}
-static void
+void
nullintr(framep, vec)
void *framep;
- int vec;
+ u_long vec;
{
}
-static void
+void
real_clockintr(framep, vec)
void *framep;
- int vec;
+ u_long vec;
{
#ifdef EVCNT_COUNTERS
@@ -112,7 +121,7 @@ set_clockintr()
void
set_iointr(niointr)
- void (*niointr) __P((void *, int));
+ void (*niointr) __P((void *, u_long));
{
if (iointr != nullintr)
@@ -122,59 +131,91 @@ set_iointr(niointr)
}
void
-machine_check(framep, logoutp, vec)
+machine_check(framep, vector, param)
struct trapframe *framep;
- struct logout *logoutp;
- u_int64_t vec;
+ u_long vector, param;
{
+ u_long mces;
+ const char *type;
- if (!mc_expected)
- panic("machine check: vec 0x%lx, pc = 0x%lx, ra = 0x%lx",
- vec, framep->tf_pc, framep->tf_regs[FRAME_RA]);
+ mces = alpha_pal_rdmces();
+
+ /* If not a machine check, we have no clue ho we got here. */
+ if ((mces & ALPHA_MCES_MIP) == 0) {
+ type = "fatal machine check or error (unknown type)";
+ goto fatal;
+ }
+
+ /* If we weren't expecting it, then we punt. */
+ if (!mc_expected) {
+ type = "unexpected machine check";
+ goto fatal;
+ }
mc_expected = 0;
mc_received = 1;
- logoutp->q1 &= ~LOGOUT_RETRY; /* XXX: Necessary? */
- pal_mtpr_mces(0x19); /* XXX: VMS PAL! */
+ /* Clear pending machine checks and correctable errors */
+ alpha_pal_wrmces(mces);
+ return;
+
+fatal:
+ printf("\n");
+ printf("%s:\n", type);
+ printf("\n");
+ printf(" mces = 0x%lx\n", mces);
+ printf(" vector = 0x%lx\n", vector);
+ printf(" param = 0x%lx\n", param);
+ printf(" pc = 0x%lx\n", framep->tf_regs[FRAME_PC]);
+ printf(" ra = 0x%lx\n", framep->tf_regs[FRAME_RA]);
+ printf(" curproc = %p\n", curproc);
+ if (curproc != NULL)
+ printf(" pid = %d, comm = %s\n", curproc->p_pid,
+ curproc->p_comm);
+ printf("\n");
+ panic("machine check");
}
int
badaddr(addr, size)
void *addr;
- u_int64_t size;
+ size_t size;
{
- int rv;
- volatile long rcpt;
+ long rcpt;
+
+ /* Get rid of any stale machine checks that have been waiting. */
+ alpha_pal_draina();
/* Tell the trap code to expect a machine check. */
mc_received = 0;
mc_expected = 1;
/* Read from the test address, and make sure the read happens. */
- wbflush();
+ alpha_mb();
switch (size) {
case sizeof (u_int8_t):
- rcpt = *(u_int8_t *)addr;
+ rcpt = *(volatile u_int8_t *)addr;
break;
case sizeof (u_int16_t):
- rcpt = *(u_int16_t *)addr;
+ rcpt = *(volatile u_int16_t *)addr;
break;
case sizeof (u_int32_t):
- rcpt = *(u_int32_t *)addr;
+ rcpt = *(volatile u_int32_t *)addr;
break;
case sizeof (u_int64_t):
- rcpt = *(u_int64_t *)addr;
+ rcpt = *(volatile u_int64_t *)addr;
break;
default:
panic("badaddr: invalid size (%ld)\n", size);
}
- wbflush();
- pal_draina();
+ alpha_mb();
+
+ /* Make sure we took the machine check, if we caused one. */
+ alpha_pal_draina();
/* disallow further machine checks */
mc_expected = 0;
diff --git a/sys/arch/alpha/alpha/locore.s b/sys/arch/alpha/alpha/locore.s
index 9790d7b74c3..0589b15c26e 100644
--- a/sys/arch/alpha/alpha/locore.s
+++ b/sys/arch/alpha/alpha/locore.s
@@ -1,5 +1,5 @@
-/* $OpenBSD: locore.s,v 1.4 1996/07/29 22:57:41 niklas Exp $ */
-/* $NetBSD: locore.s,v 1.13.4.1 1996/06/13 18:06:59 cgd Exp $ */
+/* $OpenBSD: locore.s,v 1.5 1996/10/30 22:38:13 niklas Exp $ */
+/* $NetBSD: locore.s,v 1.26 1996/10/17 02:50:38 cgd Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -62,29 +62,28 @@ bootstack:
* All arguments are passed to alpha_init().
*/
NESTED_NOPROFILE(__start,1,0,ra,0,0)
- br pv,1f
-1: SETGP(pv)
+ br pv,Lstart1
+Lstart1: LDGP(pv)
- /* Save a0, used by pal_wrkgp. */
- or a0,zero,s0
+ /* Switch to the boot stack. */
+ lda sp,bootstack
/* Load KGP with current GP. */
+ or a0,zero,s0 /* save pfn */
or gp,zero,a0
- CALL(pal_wrkgp)
-
- /* Switch to the boot stack. */
- lda sp,bootstack
+ call_pal PAL_OSF1_wrkgp /* clobbers a0, t0, t8-t11 */
+ or s0,zero,a0 /* restore pfn */
/*
- * Call alpha_init() to do pre-main initialization. Restore
- * a0, and pass alpha_init the arguments we were called with.
+ * Call alpha_init() to do pre-main initialization.
+ * alpha_init() gets the arguments we were called with,
+ * which are already in a0 and a1.
*/
- or s0,zero,a0
CALL(alpha_init)
/* Set up the virtual page table pointer. */
- CONST(VPTBASE, a0)
- CALL(pal_wrvptptr)
+ ldiq a0, VPTBASE
+ call_pal PAL_OSF1_wrvptptr /* clobbers a0, t0, t8-t11 */
/*
* Switch to proc0's PCB, which is at U_PCB off of proc0paddr.
@@ -92,32 +91,23 @@ NESTED_NOPROFILE(__start,1,0,ra,0,0)
lda t0,proc0 /* get phys addr of pcb */
ldq a0,P_MD_PCBPADDR(t0)
call_pal PAL_OSF1_swpctx
- CONST(-1, a0)
+ ldiq a0, -2
call_pal PAL_OSF1_tbi
/*
- * put a fake RA (0 XXX) on the stack, to panic if anything
- * ever tries to return off the end of the stack
- */
- lda sp,-8(sp)
- stq zero,0(sp)
-
- /*
* Construct a fake trap frame, so execve() can work normally.
* Note that setregs() is responsible for setting its contents
* to 'reasonable' values.
*/
- lda sp,-(FRAMESIZE)(sp) /* space for struct trapframe */
-
+ lda sp,-(FRAME_SIZE * 8)(sp) /* space for struct trapframe */
mov sp, a0 /* main()'s arg is frame ptr */
CALL(main) /* go to main()! */
/*
- * Call REI, to restore the faked up trap frame and return
- * to proc 1 == init!
+ * Call exception_return, to simulate return from (fake)
+ * exception to user-land, running process 1, init!
*/
- mov zero, a0
- JMP(rei) /* "And that's all she wrote." */
+ jmp zero, exception_return /* "And that's all she wrote." */
END(__start)
/**************************************************************************/
@@ -166,29 +156,27 @@ NESTED(sigcode,0,0,ra,0,0)
jsr ra, (t12) /* call the signal handler (t12==pv) */
ldq a0, 0(sp) /* get the sigcontext pointer */
lda sp, 16(sp)
- CONST(SYS_sigreturn, v0) /* and call sigreturn() with it. */
- call_pal PAL_OSF1_callsys
+ CALLSYS_NOERROR(sigreturn) /* and call sigreturn() with it. */
mov v0, a0 /* if that failed, get error code */
- CONST(SYS_exit, v0) /* and call exit() with it. */
- call_pal PAL_OSF1_callsys
+ CALLSYS_NOERROR(exit) /* and call exit() with it. */
XNESTED(esigcode,0)
END(sigcode)
/**************************************************************************/
/*
- * rei: pseudo-emulation of VAX REI.
+ * exception_return: return from trap, exception, or syscall
*/
BSS(ssir, 8)
IMPORT(astpending, 8)
-LEAF(rei, 1) /* XXX should be NESTED */
- br pv, 1f
-1: SETGP(pv)
+LEAF(exception_return, 1) /* XXX should be NESTED */
+ br pv, Ler1
+Ler1: LDGP(pv)
- ldq s1, TF_PS(sp) /* get the saved PS */
- and s1, PSL_IPL, t0 /* look at the saved IPL */
+ ldq s1, (FRAME_PS * 8)(sp) /* get the saved PS */
+ and s1, ALPHA_PSL_IPL_MASK, t0 /* look at the saved IPL */
bne t0, Lrestoreregs /* != 0: can't do AST or SIR */
/* see if we can do an SIR */
@@ -196,26 +184,23 @@ LEAF(rei, 1) /* XXX should be NESTED */
beq t1, Lchkast /* no, try an AST*/
/* We've got a SIR. */
- CONST(PSL_IPL_SOFT, a0) /* yes, lower IPL to soft */
+ ldiq a0, ALPHA_PSL_IPL_SOFT /* yes, lower IPL to soft */
call_pal PAL_OSF1_swpipl
CALL(do_sir) /* do the SIR */
Lchkast:
- CONST(PSL_IPL_0, a0) /* drop IPL to zero*/
+ ldiq a0, ALPHA_PSL_IPL_0 /* drop IPL to zero*/
call_pal PAL_OSF1_swpipl
- and s1, PSL_U, t0 /* are we returning to user? */
+ and s1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */
beq t0, Lrestoreregs /* no: just return */
ldq t2, astpending /* AST pending? */
beq t2, Lsetfpenable /* no: return & deal with FP */
- /* we've got an AST. call trap to handle it */
- CONST(T_ASTFLT, a0) /* type = T_ASTFLT */
- mov zero, a1 /* code = 0 */
- mov zero, a2 /* v = 0 */
- mov sp, a3 /* frame */
- CALL(trap)
+ /* We've got an AST. Handle it. */
+ mov sp, a0 /* only arg is frame */
+ CALL(ast)
Lsetfpenable:
/* enable FPU based on whether the current proc is fpcurproc */
@@ -227,12 +212,57 @@ Lsetfpenable:
call_pal PAL_OSF1_wrfen
Lrestoreregs:
- /* restore the USP and the registers, and return */
- ldq a0,(FRAME_SP*8)(sp)
- call_pal PAL_OSF1_wrusp
-
+ /* restore the registers, and return */
+ bsr ra, exception_restore_regs /* jmp/CALL trashes pv/t12 */
+ ldq ra,(FRAME_RA*8)(sp)
.set noat
+ ldq at_reg,(FRAME_AT*8)(sp)
+
+ lda sp,(FRAME_SW_SIZE*8)(sp)
+ call_pal PAL_OSF1_rti
+ .set at
+ END(exception_return)
+
+LEAF(exception_save_regs, 0)
+ stq v0,(FRAME_V0*8)(sp)
+ stq a3,(FRAME_A3*8)(sp)
+ stq a4,(FRAME_A4*8)(sp)
+ stq a5,(FRAME_A5*8)(sp)
+ stq s0,(FRAME_S0*8)(sp)
+ stq s1,(FRAME_S1*8)(sp)
+ stq s2,(FRAME_S2*8)(sp)
+ stq s3,(FRAME_S3*8)(sp)
+ stq s4,(FRAME_S4*8)(sp)
+ stq s5,(FRAME_S5*8)(sp)
+ stq s6,(FRAME_S6*8)(sp)
+ stq t0,(FRAME_T0*8)(sp)
+ stq t1,(FRAME_T1*8)(sp)
+ stq t2,(FRAME_T2*8)(sp)
+ stq t3,(FRAME_T3*8)(sp)
+ stq t4,(FRAME_T4*8)(sp)
+ stq t5,(FRAME_T5*8)(sp)
+ stq t6,(FRAME_T6*8)(sp)
+ stq t7,(FRAME_T7*8)(sp)
+ stq t8,(FRAME_T8*8)(sp)
+ stq t9,(FRAME_T9*8)(sp)
+ stq t10,(FRAME_T10*8)(sp)
+ stq t11,(FRAME_T11*8)(sp)
+ stq t12,(FRAME_T12*8)(sp)
+ RET
+ END(exception_save_regs)
+
+LEAF(exception_restore_regs, 0)
ldq v0,(FRAME_V0*8)(sp)
+ ldq a3,(FRAME_A3*8)(sp)
+ ldq a4,(FRAME_A4*8)(sp)
+ ldq a5,(FRAME_A5*8)(sp)
+ ldq s0,(FRAME_S0*8)(sp)
+ ldq s1,(FRAME_S1*8)(sp)
+ ldq s2,(FRAME_S2*8)(sp)
+ ldq s3,(FRAME_S3*8)(sp)
+ ldq s4,(FRAME_S4*8)(sp)
+ ldq s5,(FRAME_S5*8)(sp)
+ ldq s6,(FRAME_S6*8)(sp)
ldq t0,(FRAME_T0*8)(sp)
ldq t1,(FRAME_T1*8)(sp)
ldq t2,(FRAME_T2*8)(sp)
@@ -241,27 +271,15 @@ Lrestoreregs:
ldq t5,(FRAME_T5*8)(sp)
ldq t6,(FRAME_T6*8)(sp)
ldq t7,(FRAME_T7*8)(sp)
- ldq s0,(FRAME_S0*8)(sp)
- ldq s1,(FRAME_S1*8)(sp)
- ldq s2,(FRAME_S2*8)(sp)
- ldq s3,(FRAME_S3*8)(sp)
- ldq s4,(FRAME_S4*8)(sp)
- ldq s5,(FRAME_S5*8)(sp)
- ldq s6,(FRAME_S6*8)(sp)
- ldq a3,(FRAME_A3*8)(sp)
- ldq a4,(FRAME_A4*8)(sp)
- ldq a5,(FRAME_A5*8)(sp)
ldq t8,(FRAME_T8*8)(sp)
ldq t9,(FRAME_T9*8)(sp)
ldq t10,(FRAME_T10*8)(sp)
ldq t11,(FRAME_T11*8)(sp)
- ldq ra,(FRAME_RA*8)(sp)
ldq t12,(FRAME_T12*8)(sp)
- ldq at_reg,(FRAME_AT*8)(sp)
-
- lda sp,(FRAME_NSAVEREGS*8)(sp)
- call_pal PAL_OSF1_rti
- END(rei)
+#ifndef __OpenBSD__
+ RET
+#endif
+ END(exception_restore_regs)
/**************************************************************************/
@@ -272,51 +290,18 @@ Lrestoreregs:
LEAF(XentArith, 2) /* XXX should be NESTED */
.set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
- stq v0,(FRAME_V0*8)(sp)
- stq t0,(FRAME_T0*8)(sp)
- stq t1,(FRAME_T1*8)(sp)
- stq t2,(FRAME_T2*8)(sp)
- stq t3,(FRAME_T3*8)(sp)
- stq t4,(FRAME_T4*8)(sp)
- stq t5,(FRAME_T5*8)(sp)
- stq t6,(FRAME_T6*8)(sp)
- stq t7,(FRAME_T7*8)(sp)
- stq s0,(FRAME_S0*8)(sp)
- stq s1,(FRAME_S1*8)(sp)
- stq s2,(FRAME_S2*8)(sp)
- mov a0,s0
- stq s3,(FRAME_S3*8)(sp)
- stq s4,(FRAME_S4*8)(sp)
- stq s5,(FRAME_S5*8)(sp)
- stq s6,(FRAME_S6*8)(sp)
- mov a1,s1
- stq a3,(FRAME_A3*8)(sp)
- stq a4,(FRAME_A4*8)(sp)
- stq a5,(FRAME_A5*8)(sp)
- stq t8,(FRAME_T8*8)(sp)
- stq t9,(FRAME_T9*8)(sp)
- stq t10,(FRAME_T10*8)(sp)
- stq t11,(FRAME_T11*8)(sp)
- stq ra,(FRAME_RA*8)(sp)
- stq t12,(FRAME_T12*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq at_reg,(FRAME_AT*8)(sp)
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
.set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
- br pv, 1f
-1: SETGP(pv)
-
- CONST(T_ARITHFLT, a0) /* type = T_ARITHFLT */
- mov s0, a1 /* code = "summary" */
- mov s1, a2 /* v = "reguster mask" */
- mov sp, a3 /* frame */
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_ARITH
+ mov sp, a4
CALL(trap)
- JMP(rei)
+ jmp zero, exception_return
END(XentArith)
/**************************************************************************/
@@ -328,50 +313,18 @@ LEAF(XentArith, 2) /* XXX should be NESTED */
LEAF(XentIF, 1) /* XXX should be NESTED */
.set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
- stq v0,(FRAME_V0*8)(sp)
- stq t0,(FRAME_T0*8)(sp)
- stq t1,(FRAME_T1*8)(sp)
- stq t2,(FRAME_T2*8)(sp)
- stq t3,(FRAME_T3*8)(sp)
- stq t4,(FRAME_T4*8)(sp)
- stq t5,(FRAME_T5*8)(sp)
- stq t6,(FRAME_T6*8)(sp)
- stq t7,(FRAME_T7*8)(sp)
- stq s0,(FRAME_S0*8)(sp)
- stq s1,(FRAME_S1*8)(sp)
- stq s2,(FRAME_S2*8)(sp)
- mov a0,s0
- stq s3,(FRAME_S3*8)(sp)
- stq s4,(FRAME_S4*8)(sp)
- stq s5,(FRAME_S5*8)(sp)
- stq s6,(FRAME_S6*8)(sp)
- stq a3,(FRAME_A3*8)(sp)
- stq a4,(FRAME_A4*8)(sp)
- stq a5,(FRAME_A5*8)(sp)
- stq t8,(FRAME_T8*8)(sp)
- stq t9,(FRAME_T9*8)(sp)
- stq t10,(FRAME_T10*8)(sp)
- stq t11,(FRAME_T11*8)(sp)
- stq ra,(FRAME_RA*8)(sp)
- stq t12,(FRAME_T12*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq at_reg,(FRAME_AT*8)(sp)
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
.set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
- br pv, 1f
-1: SETGP(pv)
-
- or s0, T_IFLT, a0 /* type = T_IFLT|type*/
- mov s0, a1 /* code = type */
- ldq a2, TF_PC(sp) /* v = frame's pc */
- mov sp, a3 /* frame */
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_IF
+ mov sp, a4
CALL(trap)
- JMP(rei)
+ jmp zero, exception_return
END(XentIF)
/**************************************************************************/
@@ -383,52 +336,17 @@ LEAF(XentIF, 1) /* XXX should be NESTED */
LEAF(XentInt, 2) /* XXX should be NESTED */
.set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
- stq v0,(FRAME_V0*8)(sp)
- stq t0,(FRAME_T0*8)(sp)
- stq t1,(FRAME_T1*8)(sp)
- stq t2,(FRAME_T2*8)(sp)
- stq t3,(FRAME_T3*8)(sp)
- stq t4,(FRAME_T4*8)(sp)
- stq t5,(FRAME_T5*8)(sp)
- stq t6,(FRAME_T6*8)(sp)
- stq t7,(FRAME_T7*8)(sp)
- stq s0,(FRAME_S0*8)(sp)
- stq s1,(FRAME_S1*8)(sp)
- stq s2,(FRAME_S2*8)(sp)
- mov a0,s0
- stq s3,(FRAME_S3*8)(sp)
- stq s4,(FRAME_S4*8)(sp)
- stq s5,(FRAME_S5*8)(sp)
- stq s6,(FRAME_S6*8)(sp)
- mov a1,s1
- stq a3,(FRAME_A3*8)(sp)
- stq a4,(FRAME_A4*8)(sp)
- stq a5,(FRAME_A5*8)(sp)
- stq t8,(FRAME_T8*8)(sp)
- mov a2,s2
- stq t9,(FRAME_T9*8)(sp)
- stq t10,(FRAME_T10*8)(sp)
- stq t11,(FRAME_T11*8)(sp)
- stq ra,(FRAME_RA*8)(sp)
- stq t12,(FRAME_T12*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq at_reg,(FRAME_AT*8)(sp)
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
.set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
- br pv, 1f
-1: SETGP(pv)
-
- mov s2,a3
- mov s1,a2
- mov s0,a1
- mov sp,a0
+ /* a0, a1, & a2 already set up */
+ mov sp, a3
CALL(interrupt)
- JMP(rei)
+ jmp zero, exception_return
END(XentInt)
/**************************************************************************/
@@ -440,52 +358,18 @@ LEAF(XentInt, 2) /* XXX should be NESTED */
LEAF(XentMM, 3) /* XXX should be NESTED */
.set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
- stq v0,(FRAME_V0*8)(sp)
- stq t0,(FRAME_T0*8)(sp)
- stq t1,(FRAME_T1*8)(sp)
- stq t2,(FRAME_T2*8)(sp)
- stq t3,(FRAME_T3*8)(sp)
- stq t4,(FRAME_T4*8)(sp)
- stq t5,(FRAME_T5*8)(sp)
- stq t6,(FRAME_T6*8)(sp)
- stq t7,(FRAME_T7*8)(sp)
- stq s0,(FRAME_S0*8)(sp)
- stq s1,(FRAME_S1*8)(sp)
- stq s2,(FRAME_S2*8)(sp)
- mov a0,s0
- stq s3,(FRAME_S3*8)(sp)
- stq s4,(FRAME_S4*8)(sp)
- stq s5,(FRAME_S5*8)(sp)
- stq s6,(FRAME_S6*8)(sp)
- mov a1,s1
- stq a3,(FRAME_A3*8)(sp)
- stq a4,(FRAME_A4*8)(sp)
- stq a5,(FRAME_A5*8)(sp)
- stq t8,(FRAME_T8*8)(sp)
- mov a2,s2
- stq t9,(FRAME_T9*8)(sp)
- stq t10,(FRAME_T10*8)(sp)
- stq t11,(FRAME_T11*8)(sp)
- stq ra,(FRAME_RA*8)(sp)
- stq t12,(FRAME_T12*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq at_reg,(FRAME_AT*8)(sp)
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
.set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
- br pv, 1f
-1: SETGP(pv)
-
- or s1, T_MMFLT, a0 /* type = T_MMFLT|MMCSR */
- mov s2, a1 /* code = "cause" */
- mov s0, a2 /* v = VA */
- mov sp, a3 /* frame */
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_MM
+ mov sp, a4
CALL(trap)
- JMP(rei)
+ jmp zero, exception_return
END(XentMM)
/**************************************************************************/
@@ -496,8 +380,7 @@ LEAF(XentMM, 3) /* XXX should be NESTED */
*/
LEAF(XentSys, 0) /* XXX should be NESTED */
- .set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq v0,(FRAME_V0*8)(sp) /* in case we need to restart */
stq s0,(FRAME_S0*8)(sp)
stq s1,(FRAME_S1*8)(sp)
@@ -506,30 +389,20 @@ LEAF(XentSys, 0) /* XXX should be NESTED */
stq s4,(FRAME_S4*8)(sp)
stq s5,(FRAME_S5*8)(sp)
stq s6,(FRAME_S6*8)(sp)
- stq a0,TF_A0(sp)
- stq a1,TF_A1(sp)
- stq a2,TF_A2(sp)
+ stq a0,(FRAME_A0*8)(sp)
+ stq a1,(FRAME_A1*8)(sp)
+ stq a2,(FRAME_A2*8)(sp)
stq a3,(FRAME_A3*8)(sp)
stq a4,(FRAME_A4*8)(sp)
stq a5,(FRAME_A5*8)(sp)
stq ra,(FRAME_RA*8)(sp)
- /* save syscall number, which was passed in v0. */
- mov v0,s0
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
- .set at
-
- br pv, 1f
-1: SETGP(pv)
-
- mov s0,a0
+ /* syscall number, passed in v0, is first arg, frame pointer second */
+ mov v0,a0
mov sp,a1
CALL(syscall)
- JMP(rei)
+ jmp zero, exception_return
END(XentSys)
/**************************************************************************/
@@ -541,52 +414,18 @@ LEAF(XentSys, 0) /* XXX should be NESTED */
LEAF(XentUna, 3) /* XXX should be NESTED */
.set noat
- lda sp,-(FRAME_NSAVEREGS*8)(sp)
- stq v0,(FRAME_V0*8)(sp)
- stq t0,(FRAME_T0*8)(sp)
- stq t1,(FRAME_T1*8)(sp)
- stq t2,(FRAME_T2*8)(sp)
- stq t3,(FRAME_T3*8)(sp)
- stq t4,(FRAME_T4*8)(sp)
- stq t5,(FRAME_T5*8)(sp)
- stq t6,(FRAME_T6*8)(sp)
- stq t7,(FRAME_T7*8)(sp)
- stq s0,(FRAME_S0*8)(sp)
- stq s1,(FRAME_S1*8)(sp)
- stq s2,(FRAME_S2*8)(sp)
- mov a0,s0
- stq s3,(FRAME_S3*8)(sp)
- stq s4,(FRAME_S4*8)(sp)
- stq s5,(FRAME_S5*8)(sp)
- stq s6,(FRAME_S6*8)(sp)
- mov a1,s1
- stq a3,(FRAME_A3*8)(sp)
- stq a4,(FRAME_A4*8)(sp)
- stq a5,(FRAME_A5*8)(sp)
- stq t8,(FRAME_T8*8)(sp)
- mov a2,s2
- stq t9,(FRAME_T9*8)(sp)
- stq t10,(FRAME_T10*8)(sp)
- stq t11,(FRAME_T11*8)(sp)
- stq ra,(FRAME_RA*8)(sp)
- stq t12,(FRAME_T12*8)(sp)
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
stq at_reg,(FRAME_AT*8)(sp)
-
- call_pal PAL_OSF1_rdusp
- stq v0,(FRAME_SP*8)(sp)
-
.set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
- br pv, 1f
-1: SETGP(pv)
-
- CONST(T_UNAFLT, a0) /* type = T_UNAFLT */
- mov zero, a1 /* code = 0 */
- mov zero, a2 /* v = 0 */
- mov sp, a3 /* frame */
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_UNA
+ mov sp, a4
CALL(trap)
- JMP(rei)
+ jmp zero, exception_return
END(XentUna)
/**************************************************************************/
@@ -599,7 +438,7 @@ LEAF(XentUna, 3) /* XXX should be NESTED */
*/
LEAF(savefpstate, 1)
- SETGP(pv)
+ LDGP(pv)
/* save all of the FP registers */
lda t1, FPREG_FPR_REGS(a0) /* get address of FP reg. save area */
stt $f0, (0 * 8)(t1) /* save first register, using hw name */
@@ -630,7 +469,9 @@ LEAF(savefpstate, 1)
stt $f25, (25 * 8)(t1)
stt $f26, (26 * 8)(t1)
stt $f27, (27 * 8)(t1)
+ .set noat
stt $f28, (28 * 8)(t1)
+ .set at
stt $f29, (29 * 8)(t1)
stt $f30, (30 * 8)(t1)
@@ -638,7 +479,7 @@ LEAF(savefpstate, 1)
* Then save the FPCR; note that the necessary 'trapb's are taken
* care of on kernel entry and exit.
*/
- MF_FPCR(ft0)
+ mf_fpcr ft0
stt ft0, FPREG_FPR_CR(a0) /* store to FPCR save area */
RET
@@ -654,13 +495,13 @@ LEAF(savefpstate, 1)
*/
LEAF(restorefpstate, 1)
- SETGP(pv)
+ LDGP(pv)
/*
* Restore the FPCR; note that the necessary 'trapb's are taken care of
* on kernel entry and exit.
*/
ldt ft0, FPREG_FPR_CR(a0) /* load from FPCR save area */
- MT_FPCR(ft0)
+ mt_fpcr ft0
/* Restore all of the FP registers. */
lda t1, FPREG_FPR_REGS(a0) /* get address of FP reg. save area */
@@ -710,7 +551,7 @@ LEAF(restorefpstate, 1)
* from if called from boot().)
*
* Arguments:
- * a0 'struct user *' of the process that needs its context saved
+ * a0 'struct pcb *' of the process that needs its context saved
*
* Return:
* v0 0. (note that for child processes, it seems
@@ -719,19 +560,19 @@ LEAF(restorefpstate, 1)
*/
LEAF(savectx, 1)
- br pv, 1f
-1: SETGP(pv)
- stq sp, U_PCB_KSP(a0) /* store sp */
- stq s0, U_PCB_CONTEXT+(0 * 8)(a0) /* store s0 - s6 */
- stq s1, U_PCB_CONTEXT+(1 * 8)(a0)
- stq s2, U_PCB_CONTEXT+(2 * 8)(a0)
- stq s3, U_PCB_CONTEXT+(3 * 8)(a0)
- stq s4, U_PCB_CONTEXT+(4 * 8)(a0)
- stq s5, U_PCB_CONTEXT+(5 * 8)(a0)
- stq s6, U_PCB_CONTEXT+(6 * 8)(a0)
- stq ra, U_PCB_CONTEXT+(7 * 8)(a0) /* store ra */
+ br pv, Lsavectx1
+Lsavectx1: LDGP(pv)
+ stq sp, PCB_HWPCB_KSP(a0) /* store sp */
+ stq s0, PCB_CONTEXT+(0 * 8)(a0) /* store s0 - s6 */
+ stq s1, PCB_CONTEXT+(1 * 8)(a0)
+ stq s2, PCB_CONTEXT+(2 * 8)(a0)
+ stq s3, PCB_CONTEXT+(3 * 8)(a0)
+ stq s4, PCB_CONTEXT+(4 * 8)(a0)
+ stq s5, PCB_CONTEXT+(5 * 8)(a0)
+ stq s6, PCB_CONTEXT+(6 * 8)(a0)
+ stq ra, PCB_CONTEXT+(7 * 8)(a0) /* store ra */
call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
- stq v0, U_PCB_CONTEXT+(8 * 8)(a0) /* store ps, for ipl */
+ stq v0, PCB_CONTEXT+(8 * 8)(a0) /* store ps, for ipl */
mov zero, v0
RET
@@ -752,17 +593,17 @@ IMPORT(Lev1map, 8)
* profiling.
*/
LEAF(idle, 0)
- br pv, 1f
-1: SETGP(pv)
+ br pv, Lidle1
+Lidle1: LDGP(pv)
stq zero, curproc /* curproc <- NULL for stats */
mov zero, a0 /* enable all interrupts */
call_pal PAL_OSF1_swpipl
-2:
+Lidle2:
ldl t0, whichqs /* look for non-empty queue */
- beq t0, 2b
- CONST(PSL_IPL_HIGH, a0) /* disable all interrupts */
+ beq t0, Lidle2
+ ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
call_pal PAL_OSF1_swpipl
- JMP(sw1) /* jump back into the fray */
+ jmp zero, sw1 /* jump back into the fray */
END(idle)
/*
@@ -771,41 +612,44 @@ LEAF(idle, 0)
* XXX should optimiize, and not do the switch if switching to curproc
*/
LEAF(cpu_switch, 0)
- SETGP(pv)
+ LDGP(pv)
/* do an inline savectx(), to save old context */
ldq a0, curproc
- ldq a0, P_ADDR(a0)
+ ldq a1, P_ADDR(a0)
/* NOTE: ksp is stored by the swpctx */
- stq s0, U_PCB_CONTEXT+(0 * 8)(a0) /* store s0 - s6 */
- stq s1, U_PCB_CONTEXT+(1 * 8)(a0)
- stq s2, U_PCB_CONTEXT+(2 * 8)(a0)
- stq s3, U_PCB_CONTEXT+(3 * 8)(a0)
- stq s4, U_PCB_CONTEXT+(4 * 8)(a0)
- stq s5, U_PCB_CONTEXT+(5 * 8)(a0)
- stq s6, U_PCB_CONTEXT+(6 * 8)(a0)
- stq ra, U_PCB_CONTEXT+(7 * 8)(a0) /* store ra */
+ stq s0, U_PCB+PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
+ stq s1, U_PCB+PCB_CONTEXT+(1 * 8)(a1)
+ stq s2, U_PCB+PCB_CONTEXT+(2 * 8)(a1)
+ stq s3, U_PCB+PCB_CONTEXT+(3 * 8)(a1)
+ stq s4, U_PCB+PCB_CONTEXT+(4 * 8)(a1)
+ stq s5, U_PCB+PCB_CONTEXT+(5 * 8)(a1)
+ stq s6, U_PCB+PCB_CONTEXT+(6 * 8)(a1)
+ stq ra, U_PCB+PCB_CONTEXT+(7 * 8)(a1) /* store ra */
call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
- stq v0, U_PCB_CONTEXT+(8 * 8)(a0) /* store ps, for ipl */
+ stq v0, U_PCB+PCB_CONTEXT+(8 * 8)(a1) /* store ps, for ipl */
+
+ mov a0, s0 /* save old curproc */
+ mov a1, s1 /* save old U-area */
ldl t0, whichqs /* look for non-empty queue */
beq t0, idle /* and if none, go idle */
- CONST(PSL_IPL_HIGH, a0) /* disable all interrupts */
+ ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
call_pal PAL_OSF1_swpipl
sw1:
- br pv, 1f
-1: SETGP(pv)
+ br pv, Lcs1
+Lcs1: LDGP(pv)
ldl t0, whichqs /* look for non-empty queue */
beq t0, idle /* and if none, go idle */
mov t0, t3 /* t3 = saved whichqs */
mov zero, t2 /* t2 = lowest bit set */
- blbs t0, 3f /* if low bit set, done! */
+ blbs t0, Lcs3 /* if low bit set, done! */
-2: srl t0, 1, t0 /* try next bit */
+Lcs2: srl t0, 1, t0 /* try next bit */
addq t2, 1, t2
- blbc t0, 2b /* if clear, try again */
+ blbc t0, Lcs2 /* if clear, try again */
-3:
+Lcs3:
/*
* Remove process from queue
*/
@@ -815,22 +659,22 @@ sw1:
ldq t4, PH_LINK(t0) /* t4 = p = highest pri proc */
ldq t5, P_FORW(t4) /* t5 = p->p_forw */
- bne t4, 4f /* make sure p != NULL */
- PANIC("cpu_switch") /* nothing in queue! */
+ bne t4, Lcs4 /* make sure p != NULL */
+ PANIC("cpu_switch",Lcpu_switch_pmsg) /* nothing in queue! */
-4:
+Lcs4:
stq t5, PH_LINK(t0) /* qp->ph_link = p->p_forw */
stq t0, P_BACK(t5) /* p->p_forw->p_back = qp */
stq zero, P_BACK(t4) /* firewall: p->p_back = NULL */
cmpeq t0, t5, t0 /* see if queue is empty */
- beq t0, 5f /* nope, it's not! */
+ beq t0, Lcs5 /* nope, it's not! */
- CONST(1, t0) /* compute bit in whichqs */
+ ldiq t0, 1 /* compute bit in whichqs */
sll t0, t2, t0
xor t3, t0, t3 /* clear bit in whichqs */
stl t3, whichqs
-5:
+Lcs5:
/*
* Switch to the new context
*/
@@ -842,6 +686,7 @@ sw1:
ldq t5, P_MD_PCBPADDR(t4) /* t5 = p->p_md.md_pcbpaddr */
stq t5, curpcb /* and store it in curpcb */
+#ifndef NEW_PMAP
/*
* Do the context swap, and invalidate old TLB entries (XXX).
* XXX should do the ASN thing, and therefore not have to invalidate.
@@ -852,7 +697,7 @@ sw1:
stq t2, USTP_OFFSET(t3)
mov t5, a0 /* swap the context */
call_pal PAL_OSF1_swpctx
- CONST(-1, a0) /* & invalidate old TLB ents */
+ ldiq a0, -1 /* & invalidate old TLB ents */
call_pal PAL_OSF1_tbi
/*
@@ -861,25 +706,54 @@ sw1:
*/
ldq t0, curproc
ldq t0, P_ADDR(t0)
+#else /* NEW_PMAP */
+ mov t4, s2 /* save new curproc */
+ mov t5, s3 /* save new pcbpaddr */
+ ldq s4, P_ADDR(t4) /* load/save new U-AREA */
+
+ ldq a0, P_VMSPACE(s2) /* p->p_vmspace */
+ lda a1, U_PCB+PCB_HWPCB(s4) /* &hardware PCB */
+ mov zero, a2
+ lda a0, VM_PMAP(a0) /* &p->p_vmspace->vm_pmap */
+ CALL(pmap_activate)
+
+ mov s3, a0 /* swap the context */
+ call_pal PAL_OSF1_swpctx
+ ldiq a0, -2 /* & invalidate old TLB ents */
+ call_pal PAL_OSF1_tbi
+
+ ldq a0, P_VMSPACE(s0)
+ lda a1, U_PCB+PCB_HWPCB(s1)
+ mov zero, a2
+ lda a0, VM_PMAP(a0)
+ CALL(pmap_deactivate)
+
+ /*
+ * Now running on the new u struct.
+ * Restore registers and return.
+ */
+ mov s4, t0
+#endif /* NEW_PMAP */
/* NOTE: ksp is restored by the swpctx */
- ldq s0, U_PCB_CONTEXT+(0 * 8)(t0) /* restore s0 - s6 */
- ldq s1, U_PCB_CONTEXT+(1 * 8)(t0)
- ldq s2, U_PCB_CONTEXT+(2 * 8)(t0)
- ldq s3, U_PCB_CONTEXT+(3 * 8)(t0)
- ldq s4, U_PCB_CONTEXT+(4 * 8)(t0)
- ldq s5, U_PCB_CONTEXT+(5 * 8)(t0)
- ldq s6, U_PCB_CONTEXT+(6 * 8)(t0)
- ldq ra, U_PCB_CONTEXT+(7 * 8)(t0) /* restore ra */
- ldq a0, U_PCB_CONTEXT+(8 * 8)(t0) /* restore ipl */
- and a0, PSL_IPL, a0
+ ldq s0, U_PCB+PCB_CONTEXT+(0 * 8)(t0) /* restore s0 - s6 */
+ ldq s1, U_PCB+PCB_CONTEXT+(1 * 8)(t0)
+ ldq s2, U_PCB+PCB_CONTEXT+(2 * 8)(t0)
+ ldq s3, U_PCB+PCB_CONTEXT+(3 * 8)(t0)
+ ldq s4, U_PCB+PCB_CONTEXT+(4 * 8)(t0)
+ ldq s5, U_PCB+PCB_CONTEXT+(5 * 8)(t0)
+ ldq s6, U_PCB+PCB_CONTEXT+(6 * 8)(t0)
+ ldq ra, U_PCB+PCB_CONTEXT+(7 * 8)(t0) /* restore ra */
+ ldq a0, U_PCB+PCB_CONTEXT+(8 * 8)(t0) /* restore ipl */
+ and a0, ALPHA_PSL_IPL_MASK, a0
call_pal PAL_OSF1_swpipl
- CONST(1, v0) /* possible ret to savectx() */
+ ldiq v0, 1 /* possible ret to savectx() */
RET
END(cpu_switch)
+
/*
- * proc_trampoline()
+ * switch_trampoline()
*
* Arrange for a function to be invoked neatly, after a cpu_switch().
*
@@ -887,12 +761,12 @@ sw1:
* address specified by the s1 register and with one argument, a
* pointer to the executing process's proc structure.
*/
-LEAF(proc_trampoline, 0)
+LEAF(switch_trampoline, 0)
mov s0, pv
mov s1, ra
ldq a0, curproc
jmp zero, (pv)
- END(proc_trampoline)
+ END(switch_trampoline)
/*
* switch_exit(struct proc *p)
@@ -901,28 +775,37 @@ LEAF(proc_trampoline, 0)
* to switch into a few process. MUST BE CALLED AT SPLHIGH.
*/
LEAF(switch_exit, 1)
- SETGP(pv)
+ LDGP(pv)
/* save the exiting proc pointer */
- mov a0, s0
+ mov a0, s2
/* Switch to proc0. */
lda t4, proc0 /* t4 = &proc0 */
ldq t5, P_MD_PCBPADDR(t4) /* t5 = p->p_md.md_pcbpaddr */
stq t5, curpcb /* and store it in curpcb */
+#ifndef NEW_PMAP
+ mov t4, s0
+ ldq s1, P_ADDR(t4)
+#endif
+
/*
* Do the context swap, and invalidate old TLB entries (XXX).
* XXX should do the ASN thing, and therefore not have to invalidate.
*/
+#ifndef NEW_PMAP
ldq t2, P_VMSPACE(t4) /* t2 = p->p_vmspace */
ldq t2, VM_PMAP_STPTE(t2) /* = p_vmspace.vm_pmap.pm_ste */
ldq t3, Lev1map /* and store pte into Lev1map */
stq t2, USTP_OFFSET(t3)
+#endif /* NEW_PMAP */
mov t5, a0 /* swap the context */
call_pal PAL_OSF1_swpctx
- CONST(-1, a0) /* & invalidate old TLB ents */
+#ifndef NEW_PMAP
+ ldiq a0, -1 /* & invalidate old TLB ents */
call_pal PAL_OSF1_tbi
+#endif /* NEW_PMAP */
/*
* Now running as proc0, except for the value of 'curproc' and
@@ -931,12 +814,15 @@ LEAF(switch_exit, 1)
/* blow away the old user struct */
ldq a0, kernel_map
- ldq a1, P_ADDR(s0)
- CONST(UPAGES*NBPG, a2)
+ ldq a1, P_ADDR(s2)
+ ldiq a2, (UPAGES * NBPG)
CALL(kmem_free)
/* and jump into the middle of cpu_switch. */
- JMP(sw1)
+#ifdef NEW_PMAP
+ /* XXX XXX LOSE */
+#endif
+ jmp zero, sw1
END(switch_exit)
/**************************************************************************/
@@ -948,12 +834,12 @@ LEAF(switch_exit, 1)
* int copystr(char *from, char *to, size_t len, size_t *lenp);
*/
LEAF(copystr, 4)
- SETGP(pv)
+ LDGP(pv)
mov a2, t0 /* t0 = i = len */
- beq a2, 2f /* if (len == 0), bail out */
+ beq a2, Lcopystr2 /* if (len == 0), bail out */
-1:
+Lcopystr1:
ldq_u t1, 0(a0) /* t1 = *from */
extbl t1, a0, t1
ldq_u t3, 0(a1) /* set up t2 with quad around *to */
@@ -963,44 +849,44 @@ LEAF(copystr, 4)
stq_u t3, 0(a1) /* write out that quad */
subl a2, 1, a2 /* len-- */
- beq t1, 2f /* if (*from == 0), bail out */
+ beq t1, Lcopystr2 /* if (*from == 0), bail out */
addq a1, 1, a1 /* to++ */
addq a0, 1, a0 /* from++ */
- bne a2, 1b /* if (len != 0) copy more */
+ bne a2, Lcopystr1 /* if (len != 0) copy more */
-2:
- beq a3, 3f /* if (lenp != NULL) */
+Lcopystr2:
+ beq a3, Lcopystr3 /* if (lenp != NULL) */
subl t0, a2, t0 /* *lenp = (i - len) */
stq t0, 0(a3)
-3:
- beq t1, 4f /* *from == '\0'; leave quietly */
+Lcopystr3:
+ beq t1, Lcopystr4 /* *from == '\0'; leave quietly */
- CONST(ENAMETOOLONG, v0) /* *from != '\0'; error. */
+ ldiq v0, ENAMETOOLONG /* *from != '\0'; error. */
RET
-4:
+Lcopystr4:
mov zero, v0 /* return 0. */
RET
END(copystr)
NESTED(copyinstr, 4, 16, ra, 0, 0)
- SETGP(pv)
+ LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
- CONST(VM_MAX_ADDRESS, t0) /* make sure that src addr */
+ ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq v0, U_PCB_ONFAULT(at_reg)
+ stq v0, U_PCB+PCB_ONFAULT(at_reg)
.set at
CALL(copystr) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
lda sp, 16(sp) /* kill stack frame. */
@@ -1008,23 +894,23 @@ NESTED(copyinstr, 4, 16, ra, 0, 0)
END(copyinstr)
NESTED(copyoutstr, 4, 16, ra, 0, 0)
- SETGP(pv)
+ LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
- CONST(VM_MAX_ADDRESS, t0) /* make sure that dest addr */
+ ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
cmpult a1, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq v0, U_PCB_ONFAULT(at_reg)
+ stq v0, U_PCB+PCB_ONFAULT(at_reg)
.set at
CALL(copystr) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
lda sp, 16(sp) /* kill stack frame. */
@@ -1266,23 +1152,23 @@ bcopy_ov_short:
END(bcopy)
NESTED(copyin, 3, 16, ra, 0, 0)
- SETGP(pv)
+ LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
- CONST(VM_MAX_ADDRESS, t0) /* make sure that src addr */
+ ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq v0, U_PCB_ONFAULT(at_reg)
+ stq v0, U_PCB+PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
lda sp, 16(sp) /* kill stack frame. */
@@ -1291,23 +1177,23 @@ NESTED(copyin, 3, 16, ra, 0, 0)
END(copyin)
NESTED(copyout, 3, 16, ra, 0, 0)
- SETGP(pv)
+ LDGP(pv)
lda sp, -16(sp) /* set up stack frame */
stq ra, (16-8)(sp) /* save ra */
- CONST(VM_MAX_ADDRESS, t0) /* make sure that dest addr */
+ ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
cmpult a1, t0, t1 /* is in user space. */
beq t1, copyerr /* if it's not, error out. */
lda v0, copyerr /* set up fault handler. */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq v0, U_PCB_ONFAULT(at_reg)
+ stq v0, U_PCB+PCB_ONFAULT(at_reg)
.set at
CALL(bcopy) /* do the copy. */
.set noat
ldq at_reg, curproc /* kill the fault handler. */
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
ldq ra, (16-8)(sp) /* restore ra. */
lda sp, 16(sp) /* kill stack frame. */
@@ -1316,10 +1202,10 @@ NESTED(copyout, 3, 16, ra, 0, 0)
END(copyout)
LEAF(copyerr, 0)
- SETGP(pv)
+ LDGP(pv)
ldq ra, (16-8)(sp) /* restore ra. */
lda sp, 16(sp) /* kill stack frame. */
- CONST(EFAULT, v0) /* return EFAULT. */
+ ldiq v0, EFAULT /* return EFAULT. */
RET
END(copyerr)
@@ -1334,85 +1220,85 @@ END(copyerr)
#ifdef notdef
LEAF(fuword, 1)
XLEAF(fuiword, 1)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
ldq v0, 0(a0)
zap v0, 0xf0, v0
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
RET
END(fuword)
LEAF(fusword, 1)
XLEAF(fuisword, 1)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
RET
END(fusword)
LEAF(fubyte, 1)
XLEAF(fuibyte, 1)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
RET
END(fubyte)
#endif /* notdef */
LEAF(suword, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
stq a1, 0(a0) /* do the wtore. */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
mov zero, v0
RET
@@ -1420,21 +1306,21 @@ LEAF(suword, 2)
#ifdef notdef
LEAF(suiword, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
call_pal PAL_OSF1_imb /* sync instruction stream */
mov zero, v0
@@ -1442,42 +1328,42 @@ LEAF(suiword, 2)
END(suiword)
LEAF(susword, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
mov zero, v0
RET
END(susword)
LEAF(suisword, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
call_pal PAL_OSF1_imb /* sync instruction stream */
mov zero, v0
@@ -1486,15 +1372,15 @@ LEAF(suisword, 2)
#endif /* notdef */
LEAF(subyte, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
zap a1, 0xfe, a1 /* kill arg's high bytes */
insbl a1, a0, a1 /* move it to the right byte */
@@ -1505,22 +1391,22 @@ LEAF(subyte, 2)
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
mov zero, v0
RET
END(subyte)
LEAF(suibyte, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswberr /* if it's not, error out. */
lda t0, fswberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
.set at
zap a1, 0xfe, a1 /* kill arg's high bytes */
insbl a1, a0, a1 /* move it to the right byte */
@@ -1531,7 +1417,7 @@ LEAF(suibyte, 2)
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
call_pal PAL_OSF1_imb /* sync instruction stream */
mov zero, v0
@@ -1539,8 +1425,8 @@ LEAF(suibyte, 2)
END(suibyte)
LEAF(fswberr, 0)
- SETGP(pv)
- CONST(-1, v0)
+ LDGP(pv)
+ ldiq v0, -1
RET
END(fswberr)
@@ -1554,41 +1440,43 @@ LEAF(fswberr, 0)
*/
LEAF(fuswintr, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswintrberr /* if it's not, error out. */
lda t0, fswintrberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
+ stq a0, U_PCB+PCB_ACCESSADDR(at_reg)
.set at
/* XXX FETCH IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
RET
END(fuswintr)
LEAF(suswintr, 2)
- SETGP(pv)
- CONST(VM_MAX_ADDRESS, t0) /* make sure that addr */
+ LDGP(pv)
+ ldiq t0, VM_MAX_ADDRESS /* make sure that addr */
cmpult a0, t0, t1 /* is in user space. */
beq t1, fswintrberr /* if it's not, error out. */
lda t0, fswintrberr
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq t0, U_PCB_ONFAULT(at_reg)
+ stq t0, U_PCB+PCB_ONFAULT(at_reg)
+ stq a0, U_PCB+PCB_ACCESSADDR(at_reg)
.set at
/* XXX STORE IT */
.set noat
ldq at_reg, curproc
ldq at_reg, P_ADDR(at_reg)
- stq zero, U_PCB_ONFAULT(at_reg)
+ stq zero, U_PCB+PCB_ONFAULT(at_reg)
.set at
mov zero, v0
RET
@@ -1598,8 +1486,8 @@ LEAF(suswintr, 2)
LEAF(fswintrberr, 0)
XLEAF(fuswintr, 2) /* XXX what is a 'word'? */
XLEAF(suswintr, 2) /* XXX what is a 'word'? */
- SETGP(pv)
- CONST(-1, v0)
+ LDGP(pv)
+ ldiq v0, -1
RET
END(fswberr)
@@ -1625,10 +1513,67 @@ EXPORT(eintrcnt)
/**************************************************************************/
- .text
-LEAF(rpcc,1)
- rpcc v0
+/*
+ * Object:
+ * swpctxt EXPORTED function
+ *
+ * Change HW process context
+ *
+ * Arguments:
+ * pcb PHYSICAL struct pcb_hw *
+ * old_ksp VIRTUAL long *
+ *
+ * If old_ksp is non-zero it saves the current KSP in it.
+ * Execute the PAL call.
+ */
+LEAF(swpctxt,2)
+ beq a1,Lswpctxt1
+ stq sp,0(a1)
+Lswpctxt1: call_pal PAL_OSF1_swpctx
RET
- END(pal_mtpr_mces)
+ END(swpctxt)
-/**************************************************************************/
+/*
+ * console 'restart' routine to be placed in HWRPB.
+ */
+LEAF(XentRestart, 1) /* XXX should be NESTED */
+ .set noat
+ lda sp,-(FRAME_SIZE*8)(sp)
+ stq at_reg,(FRAME_AT*8)(sp)
+ .set at
+ stq v0,(FRAME_V0*8)(sp)
+ stq a3,(FRAME_A3*8)(sp)
+ stq a4,(FRAME_A4*8)(sp)
+ stq a5,(FRAME_A5*8)(sp)
+ stq s0,(FRAME_S0*8)(sp)
+ stq s1,(FRAME_S1*8)(sp)
+ stq s2,(FRAME_S2*8)(sp)
+ stq s3,(FRAME_S3*8)(sp)
+ stq s4,(FRAME_S4*8)(sp)
+ stq s5,(FRAME_S5*8)(sp)
+ stq s6,(FRAME_S6*8)(sp)
+ stq t0,(FRAME_T0*8)(sp)
+ stq t1,(FRAME_T1*8)(sp)
+ stq t2,(FRAME_T2*8)(sp)
+ stq t3,(FRAME_T3*8)(sp)
+ stq t4,(FRAME_T4*8)(sp)
+ stq t5,(FRAME_T5*8)(sp)
+ stq t6,(FRAME_T6*8)(sp)
+ stq t7,(FRAME_T7*8)(sp)
+ stq t8,(FRAME_T8*8)(sp)
+ stq t9,(FRAME_T9*8)(sp)
+ stq t10,(FRAME_T10*8)(sp)
+ stq t11,(FRAME_T11*8)(sp)
+ stq t12,(FRAME_T12*8)(sp)
+ stq ra,(FRAME_RA*8)(sp)
+
+ br pv,LXconsole_restart1
+LXconsole_restart1: LDGP(pv)
+
+ ldq a0,(FRAME_RA*8)(sp) /* a0 = ra */
+ ldq a1,(FRAME_T11*8)(sp) /* a1 = ai */
+ ldq a2,(FRAME_T12*8)(sp) /* a2 = pv */
+ CALL(console_restart)
+
+ call_pal PAL_halt
+ END(XentRestart)
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index 2c04c966fb4..075966bd54d 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: machdep.c,v 1.10 1996/07/29 22:57:43 niklas Exp $ */
-/* $NetBSD: machdep.c,v 1.19.4.5 1996/06/15 03:56:33 cgd Exp $ */
+/* $OpenBSD: machdep.c,v 1.11 1996/10/30 22:38:14 niklas Exp $ */
+/* $NetBSD: machdep.c,v 1.49 1996/10/18 20:35:23 cgd Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -52,6 +52,9 @@
#include <sys/exec.h>
#include <sys/exec_ecoff.h>
#include <sys/sysctl.h>
+#include <sys/core.h>
+#include <sys/kcore.h>
+#include <machine/kcore.h>
#ifdef SYSVMSG
#include <sys/msg.h>
#endif
@@ -65,10 +68,12 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <dev/cons.h>
+#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/reg.h>
#include <machine/rpb.h>
@@ -94,13 +99,37 @@
#endif
#include <net/netisr.h>
-#include "ether.h"
+#include <net/if.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#endif
+#ifdef NS
+#include <netns/ns_var.h>
+#endif
+#ifdef ISO
+#include <netiso/iso.h>
+#include <netiso/clnp.h>
+#endif
+#include "ppp.h"
+#if NPPP > 0
+#include <net/ppp_defs.h>
+#include <net/if_ppp.h>
+#endif
#include "le_ioasic.h" /* for le_iomem creation */
vm_map_t buffer_map;
void dumpsys __P((void));
+int cpu_dumpsize __P((void));
+int cpu_dump __P((void));
+void printregs __P((struct reg *));
+void regdump __P((struct trapframe *framep));
+void netintr __P((void));
+void do_sir __P((void));
/*
* Declare these as initialized data so we can patch them.
@@ -120,7 +149,7 @@ int msgbufmapped = 0; /* set when safe to use msgbuf */
int maxmem; /* max memory per process */
int totalphysmem; /* total amount of physical memory in system */
-int physmem; /* physical memory used by NetBSD + some rsvd */
+int physmem; /* physical memory used by OpenBSD + some rsvd */
int firstusablepage; /* first usable memory page */
int lastusablepage; /* last usable memory page */
int resvmem; /* amount of memory reserved for PROM */
@@ -169,7 +198,8 @@ u_int64_t cycles_per_usec;
caddr_t le_iomem; /* XXX iomem for LANCE DMA */
/* Interrupt vectors (in locore) */
-extern int XentInt(), XentArith(), XentMM(), XentIF(), XentUna(), XentSys();
+extern int XentInt __P((void)), XentArith __P((void)), XentMM __P((void)),
+ XentIF __P((void)), XentUna __P((void)), XentSys __P((void));
/* number of cpus in the box. really! */
int ncpus;
@@ -183,7 +213,13 @@ char *cpu_iobus;
char boot_flags[64];
/* for cpu_sysctl() */
-char root_device[17];
+char root_device[17];
+int alpha_unaligned_print = 1; /* warn about unaligned accesses */
+int alpha_unaligned_fix = 1; /* fix up unaligned accesses */
+int alpha_unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */
+
+void identifycpu __P((void));
+int alpha_init __P((u_long, u_long));
int
alpha_init(pfn, ptb)
@@ -201,15 +237,16 @@ alpha_init(pfn, ptb)
* Make sure the instruction and data streams are consistent.
*/
(void)splhigh();
- pal_wrfen(0);
- TBIA();
- IMB();
+ alpha_pal_wrfen(0);
+ ALPHA_TBIA();
+ alpha_pal_imb();
/*
* get address of the restart block, while we the bootstrap
* mapping is still around.
*/
- hwrpb = (struct rpb *) phystok0seg(*(struct rpb **)HWRPB_ADDR);
+ hwrpb = (struct rpb *)ALPHA_PHYS_TO_K0SEG(
+ (vm_offset_t)(*(struct rpb **)HWRPB_ADDR));
/*
* Remember how many cycles there are per microsecond,
@@ -226,12 +263,18 @@ alpha_init(pfn, ptb)
/*
* Point interrupt/exception vectors to our own.
*/
- pal_wrent(XentInt, 0);
- pal_wrent(XentArith, 1);
- pal_wrent(XentMM, 2);
- pal_wrent(XentIF, 3);
- pal_wrent(XentUna, 4);
- pal_wrent(XentSys, 5);
+ alpha_pal_wrent(XentInt, ALPHA_KENTRY_INT);
+ alpha_pal_wrent(XentArith, ALPHA_KENTRY_ARITH);
+ alpha_pal_wrent(XentMM, ALPHA_KENTRY_MM);
+ alpha_pal_wrent(XentIF, ALPHA_KENTRY_IF);
+ alpha_pal_wrent(XentUna, ALPHA_KENTRY_UNA);
+ alpha_pal_wrent(XentSys, ALPHA_KENTRY_SYS);
+
+ /*
+ * Disable System and Processor Correctable Error reporting.
+ * Clear pending machine checks and error reports, etc.
+ */
+ alpha_pal_wrmces(alpha_pal_rdmces() | ALPHA_MCES_DSC | ALPHA_MCES_DPC);
/*
* Find out how much memory is available, by looking at
@@ -253,13 +296,13 @@ alpha_init(pfn, ptb)
#define cnt mddtp->mddt_cluster_cnt
#define usage(n) mddtp->mddt_clusters[(n)].mddt_usage
if (cnt != 2 && cnt != 3) {
- printf("WARNING: weird number (%d) of mem clusters\n", cnt);
+ printf("WARNING: weird number (%ld) of mem clusters\n", cnt);
mddtweird = 1;
} else if (usage(0) != MDDT_PALCODE ||
usage(1) != MDDT_SYSTEM ||
(cnt == 3 && usage(2) != MDDT_PALCODE)) {
mddtweird = 1;
- printf("WARNING: %d mem clusters, but weird config\n", cnt);
+ printf("WARNING: %ld mem clusters, but weird config\n", cnt);
}
for (i = 0; i < cnt; i++) {
@@ -455,7 +498,8 @@ alpha_init(pfn, ptb)
if (cputype == ST_DEC_3000_500 ||
cputype == ST_DEC_3000_300) { /* XXX possibly others? */
lastusablepage -= btoc(128 * 1024);
- le_iomem = (caddr_t)phystok0seg(ctob(lastusablepage + 1));
+ le_iomem =
+ (caddr_t)ALPHA_PHYS_TO_K0SEG(ctob(lastusablepage + 1));
}
#endif /* NLE_IOASIC */
@@ -463,7 +507,8 @@ alpha_init(pfn, ptb)
* Initialize error message buffer (at end of core).
*/
lastusablepage -= btoc(sizeof (struct msgbuf));
- msgbufp = (struct msgbuf *)phystok0seg(ctob(lastusablepage + 1));
+ msgbufp =
+ (struct msgbuf *)ALPHA_PHYS_TO_K0SEG(ctob(lastusablepage + 1));
msgbufmapped = 1;
/*
@@ -530,22 +575,31 @@ alpha_init(pfn, ptb)
* Initialize the virtual memory system, and set the
* page table base register in proc 0's PCB.
*/
- pmap_bootstrap((vm_offset_t)v, phystok0seg(ptb << PGSHIFT));
+#ifndef NEW_PMAP
+ pmap_bootstrap((vm_offset_t)v, ALPHA_PHYS_TO_K0SEG(ptb << PGSHIFT));
+#else
+ pmap_bootstrap((vm_offset_t)v, ALPHA_PHYS_TO_K0SEG(ptb << PGSHIFT),
+ hwrpb->rpb_max_asn);
+#endif
/*
* Initialize the rest of proc 0's PCB, and cache its physical
* address.
*/
proc0.p_md.md_pcbpaddr =
- (struct pcb *)k0segtophys(&proc0paddr->u_pcb);
+ (struct pcb *)ALPHA_K0SEG_TO_PHYS((vm_offset_t)&proc0paddr->u_pcb);
/*
* Set the kernel sp, reserving space for an (empty) trapframe,
* and make proc0's trapframe pointer point to it for sanity.
*/
- proc0paddr->u_pcb.pcb_ksp =
+ proc0paddr->u_pcb.pcb_hw.apcb_ksp =
(u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe);
- proc0.p_md.md_tf = (struct trapframe *)proc0paddr->u_pcb.pcb_ksp;
+ proc0.p_md.md_tf = (struct trapframe *)proc0paddr->u_pcb.pcb_hw.apcb_ksp;
+
+#ifdef NEW_PMAP
+ pmap_activate(kernel_pmap, &proc0paddr->u_pcb.pcb_hw, 0);
+#endif
/*
* Look at arguments passed to us and compute boothowto.
@@ -571,9 +625,21 @@ alpha_init(pfn, ptb)
boothowto &= ~RB_SINGLE;
break;
- case 'n': /* askname */
- case 'N':
- boothowto |= RB_ASKNAME;
+ case 'c': /* enter user kernel configuration */
+ case 'C':
+ boothowto |= RB_CONFIG;
+ break;
+
+#ifdef DEBUG
+ case 'd': /* crash dump immediately after autoconfig */
+ case 'D':
+ boothowto |= RB_DUMP;
+ break;
+#endif
+
+ case 'h': /* always halt, never reboot */
+ case 'H':
+ boothowto |= RB_HALT;
break;
#if 0
@@ -582,6 +648,11 @@ alpha_init(pfn, ptb)
boothowto |= RB_MINIROOT;
break;
#endif
+
+ case 'n': /* askname */
+ case 'N':
+ boothowto |= RB_ASKNAME;
+ break;
}
}
@@ -613,11 +684,10 @@ void
cpu_startup()
{
register unsigned i;
- register caddr_t v;
int base, residual;
vm_offset_t minaddr, maxaddr;
vm_size_t size;
-#ifdef DEBUG
+#if defined(DEBUG)
extern int pmapdebug;
int opmapdebug = pmapdebug;
@@ -629,7 +699,7 @@ cpu_startup()
*/
printf(version);
identifycpu();
- printf("real mem = %d (%d reserved for PROM, %d used by NetBSD)\n",
+ printf("real mem = %d (%d reserved for PROM, %d used by OpenBSD)\n",
ctob(totalphysmem), ctob(resvmem), ctob(physmem));
if (unusedmem)
printf("WARNING: unused memory = %d bytes\n", ctob(unusedmem));
@@ -697,7 +767,7 @@ cpu_startup()
callout[i-1].c_next = &callout[i];
callout[i-1].c_next = NULL;
-#ifdef DEBUG
+#if defined(DEBUG)
pmapdebug = opmapdebug;
#endif
printf("avail mem = %ld\n", (long)ptoa(cnt.v_free_count));
@@ -720,17 +790,24 @@ cpu_startup()
#endif
}
configure();
+
+ /*
+ * Note that bootstrapping is finished, and set the HWRPB up
+ * to do restarts.
+ */
+ hwrbp_restart_setup();
}
+void
identifycpu()
{
/*
* print out CPU identification information.
*/
- printf("%s, %dMHz\n", cpu_model,
+ printf("%s, %ldMHz\n", cpu_model,
hwrpb->rpb_cc_freq / 1000000); /* XXX true for 21164? */
- printf("%d byte page size, %d processor%s.\n",
+ printf("%ld byte page size, %d processor%s.\n",
hwrpb->rpb_page_size, ncpus, ncpus == 1 ? "" : "s");
#if 0
/* this isn't defined for any systems that we run on? */
@@ -747,8 +824,9 @@ int waittime = -1;
struct pcb dumppcb;
void
-boot(howto)
+boot(howto /* , bootstr */)
int howto;
+ /* char *bootstr; */
{
extern int cold;
@@ -758,8 +836,18 @@ boot(howto)
goto haltsys;
}
+ /* If "always halt" was specified as a boot flag, obey. */
+ if ((boothowto & RB_HALT) != 0)
+ howto |= RB_HALT;
+
boothowto = howto;
if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
+ extern struct proc proc0;
+
+ /* protect against curproc->p_stats.foo refs in sync XXX */
+ if (curproc == NULL)
+ curproc = &proc0;
+
waittime = 0;
vfs_shutdown();
/*
@@ -773,10 +861,12 @@ boot(howto)
splhigh();
/* If rebooting and a dump is requested do it. */
- if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) {
- savectx(&dumppcb, 0);
+#if 0
+ if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
+#else
+ if (howto & RB_DUMP)
+#endif
dumpsys();
- }
haltsys:
@@ -803,6 +893,55 @@ int dumpsize = 0; /* pages */
long dumplo = 0; /* blocks */
/*
+ * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
+ */
+int
+cpu_dumpsize()
+{
+ int size;
+
+ size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
+ if (roundup(size, dbtob(1)) != dbtob(1))
+ return -1;
+
+ return (1);
+}
+
+/*
+ * cpu_dump: dump machine-dependent kernel core dump headers.
+ */
+int
+cpu_dump()
+{
+ int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
+ long buf[dbtob(1) / sizeof (long)];
+ kcore_seg_t *segp;
+ cpu_kcore_hdr_t *cpuhdrp;
+
+ dump = bdevsw[major(dumpdev)].d_dump;
+
+ segp = (kcore_seg_t *)buf;
+ cpuhdrp =
+ (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp)) / sizeof (long)];
+
+ /*
+ * Generate a segment header.
+ */
+ CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
+ segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
+
+ /*
+ * Add the machine-dependent header info
+ */
+ cpuhdrp->lev1map_pa = ALPHA_K0SEG_TO_PHYS((vm_offset_t)Lev1map);
+ cpuhdrp->page_size = PAGE_SIZE;
+ cpuhdrp->core_seg.start = ctob(firstusablepage);
+ cpuhdrp->core_seg.size = ctob(physmem);
+
+ return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
+}
+
+/*
* This is called by configure to set dumplo and dumpsize.
* Dumps always skip the first CLBYTES of disk space
* in case there might be a disk label stored there.
@@ -812,55 +951,114 @@ long dumplo = 0; /* blocks */
void
dumpconf()
{
- int nblks; /* size of dump area */
+ int nblks, dumpblks; /* size of dump area */
int maj;
if (dumpdev == NODEV)
- return;
+ goto bad;
maj = major(dumpdev);
if (maj < 0 || maj >= nblkdev)
panic("dumpconf: bad dumpdev=0x%x", dumpdev);
if (bdevsw[maj].d_psize == NULL)
- return;
+ goto bad;
nblks = (*bdevsw[maj].d_psize)(dumpdev);
if (nblks <= ctod(1))
- return;
+ goto bad;
- /* XXX XXX XXX STARTING MEMORY LOCATION */
- dumpsize = physmem;
+ dumpblks = cpu_dumpsize();
+ if (dumpblks < 0)
+ goto bad;
+ dumpblks += ctod(physmem);
- /* Always skip the first CLBYTES, in case there is a label there. */
- if (dumplo < ctod(1))
- dumplo = ctod(1);
+ /* If dump won't fit (incl. room for possible label), punt. */
+ if (dumpblks > (nblks - ctod(1)))
+ goto bad;
- /* Put dump at end of partition, and make it fit. */
- if (dumpsize > dtoc(nblks - dumplo))
- dumpsize = dtoc(nblks - dumplo);
- if (dumplo < nblks - ctod(dumpsize))
- dumplo = nblks - ctod(dumpsize);
+ /* Put dump at end of partition */
+ dumplo = nblks - dumpblks;
+
+ /* dumpsize is in page units, and doesn't include headers. */
+ dumpsize = physmem;
+ return;
+
+bad:
+ dumpsize = 0;
+ return;
}
/*
- * Doadump comes here after turning off memory management and
- * getting on the dump stack, either when called above, or by
- * the auto-restart code.
+ * Dump the kernel's image to the swap partition.
*/
+#define BYTES_PER_DUMP NBPG
+
void
dumpsys()
{
+ unsigned bytes, i, n;
+ int maddr, psize;
+ daddr_t blkno;
+ int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
+ int error;
- msgbufmapped = 0;
+ /* Save registers. */
+ savectx(&dumppcb);
+
+ msgbufmapped = 0; /* don't record dump msgs in msgbuf */
if (dumpdev == NODEV)
return;
- if (dumpsize == 0) {
+
+ /*
+ * For dumps during autoconfiguration,
+ * if dump device has already configured...
+ */
+ if (dumpsize == 0)
dumpconf();
- if (dumpsize == 0)
- return;
+ if (dumplo <= 0) {
+ printf("\ndump to dev %x not possible\n", dumpdev);
+ return;
}
- printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
+ printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
+ psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
printf("dump ");
- switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
+ if (psize == -1) {
+ printf("area unavailable\n");
+ return;
+ }
+
+ /* XXX should purge all outstanding keystrokes. */
+
+ if ((error = cpu_dump()) != 0)
+ goto err;
+
+ bytes = ctob(physmem);
+ maddr = ctob(firstusablepage);
+ blkno = dumplo + cpu_dumpsize();
+ dump = bdevsw[major(dumpdev)].d_dump;
+ error = 0;
+ for (i = 0; i < bytes; i += n) {
+
+ /* Print out how many MBs we to go. */
+ n = bytes - i;
+ if (n && (n % (1024*1024)) == 0)
+ printf("%d ", n / (1024 * 1024));
+
+ /* Limit size for next transfer. */
+ if (n > BYTES_PER_DUMP)
+ n = BYTES_PER_DUMP;
+
+ error = (*dump)(dumpdev, blkno,
+ (caddr_t)ALPHA_PHYS_TO_K0SEG(maddr), n);
+ if (error)
+ break;
+ maddr += n;
+ blkno += btodb(n); /* XXX? */
+
+ /* XXX should look for keystrokes, to cancel. */
+ }
+
+err:
+ switch (error) {
case ENXIO:
printf("device bad\n");
@@ -882,9 +1080,13 @@ dumpsys()
printf("aborted from console\n");
break;
- default:
+ case 0:
printf("succeeded\n");
break;
+
+ default:
+ printf("error %d\n", error);
+ break;
}
printf("\n\n");
delay(1000);
@@ -912,9 +1114,9 @@ frametoreg(framep, regp)
regp->r_regs[R_S4] = framep->tf_regs[FRAME_S4];
regp->r_regs[R_S5] = framep->tf_regs[FRAME_S5];
regp->r_regs[R_S6] = framep->tf_regs[FRAME_S6];
- regp->r_regs[R_A0] = framep->tf_a0;
- regp->r_regs[R_A1] = framep->tf_a1;
- regp->r_regs[R_A2] = framep->tf_a2;
+ regp->r_regs[R_A0] = framep->tf_regs[FRAME_A0];
+ regp->r_regs[R_A1] = framep->tf_regs[FRAME_A1];
+ regp->r_regs[R_A2] = framep->tf_regs[FRAME_A2];
regp->r_regs[R_A3] = framep->tf_regs[FRAME_A3];
regp->r_regs[R_A4] = framep->tf_regs[FRAME_A4];
regp->r_regs[R_A5] = framep->tf_regs[FRAME_A5];
@@ -925,8 +1127,8 @@ frametoreg(framep, regp)
regp->r_regs[R_RA] = framep->tf_regs[FRAME_RA];
regp->r_regs[R_T12] = framep->tf_regs[FRAME_T12];
regp->r_regs[R_AT] = framep->tf_regs[FRAME_AT];
- regp->r_regs[R_GP] = framep->tf_gp;
- regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP];
+ regp->r_regs[R_GP] = framep->tf_regs[FRAME_GP];
+ /* regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP]; XXX */
regp->r_regs[R_ZERO] = 0;
}
@@ -952,9 +1154,9 @@ regtoframe(regp, framep)
framep->tf_regs[FRAME_S4] = regp->r_regs[R_S4];
framep->tf_regs[FRAME_S5] = regp->r_regs[R_S5];
framep->tf_regs[FRAME_S6] = regp->r_regs[R_S6];
- framep->tf_a0 = regp->r_regs[R_A0];
- framep->tf_a1 = regp->r_regs[R_A1];
- framep->tf_a2 = regp->r_regs[R_A2];
+ framep->tf_regs[FRAME_A0] = regp->r_regs[R_A0];
+ framep->tf_regs[FRAME_A1] = regp->r_regs[R_A1];
+ framep->tf_regs[FRAME_A2] = regp->r_regs[R_A2];
framep->tf_regs[FRAME_A3] = regp->r_regs[R_A3];
framep->tf_regs[FRAME_A4] = regp->r_regs[R_A4];
framep->tf_regs[FRAME_A5] = regp->r_regs[R_A5];
@@ -965,8 +1167,8 @@ regtoframe(regp, framep)
framep->tf_regs[FRAME_RA] = regp->r_regs[R_RA];
framep->tf_regs[FRAME_T12] = regp->r_regs[R_T12];
framep->tf_regs[FRAME_AT] = regp->r_regs[R_AT];
- framep->tf_gp = regp->r_regs[R_GP];
- framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP];
+ framep->tf_regs[FRAME_GP] = regp->r_regs[R_GP];
+ /* framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP]; XXX */
/* ??? = regp->r_regs[R_ZERO]; */
}
@@ -988,6 +1190,8 @@ regdump(framep)
struct reg reg;
frametoreg(framep, &reg);
+ reg.r_regs[R_SP] = alpha_pal_rdusp();
+
printf("REGISTERS:\n");
printregs(&reg);
}
@@ -1033,13 +1237,12 @@ sendsig(catcher, sig, mask, code)
psp->ps_sigstk.ss_size - rndfsize);
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
} else
- scp = (struct sigcontext *)(frame->tf_regs[FRAME_SP] -
- rndfsize);
+ scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize);
if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
(void)grow(p, (u_long)scp);
#ifdef DEBUG
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig(%d): sig %d ssp %lx usp %lx\n", p->p_pid,
+ printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
sig, &oonstack, scp);
#endif
if (useracc((caddr_t)scp, fsize, B_WRITE) == 0) {
@@ -1066,18 +1269,19 @@ sendsig(catcher, sig, mask, code)
*/
ksc.sc_onstack = oonstack;
ksc.sc_mask = mask;
- ksc.sc_pc = frame->tf_pc;
- ksc.sc_ps = frame->tf_ps;
+ ksc.sc_pc = frame->tf_regs[FRAME_PC];
+ ksc.sc_ps = frame->tf_regs[FRAME_PS];
/* copy the registers. */
frametoreg(frame, (struct reg *)ksc.sc_regs);
ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
+ ksc.sc_regs[R_SP] = alpha_pal_rdusp();
/* save the floating-point state, if necessary, then copy it. */
if (p == fpcurproc) {
- pal_wrfen(1);
+ alpha_pal_wrfen(1);
savefpstate(&p->p_addr->u_pcb.pcb_fp);
- pal_wrfen(0);
+ alpha_pal_wrfen(0);
fpcurproc = NULL;
}
ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED;
@@ -1100,24 +1304,25 @@ sendsig(catcher, sig, mask, code)
(void) copyout((caddr_t)&ksc, (caddr_t)scp, fsize);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
- printf("sendsig(%d): sig %d scp %lx code %lx\n", p->p_pid, sig,
+ printf("sendsig(%d): sig %d scp %p code %lx\n", p->p_pid, sig,
scp, code);
#endif
/*
* Set up the registers to return to sigcode.
*/
- frame->tf_pc = (u_int64_t)PS_STRINGS - (esigcode - sigcode);
- frame->tf_regs[FRAME_SP] = (u_int64_t)scp;
- frame->tf_a0 = sig;
- frame->tf_a1 = code;
- frame->tf_a2 = (u_int64_t)scp;
+ frame->tf_regs[FRAME_PC] =
+ (u_int64_t)PS_STRINGS - (esigcode - sigcode);
+ frame->tf_regs[FRAME_A0] = sig;
+ frame->tf_regs[FRAME_A1] = code;
+ frame->tf_regs[FRAME_A2] = (u_int64_t)scp;
frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */
+ alpha_pal_wrusp((unsigned long)scp);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid,
- frame->tf_pc, frame->tf_regs[FRAME_A3]);
+ frame->tf_regs[FRAME_PC], frame->tf_regs[FRAME_A3]);
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): sig %d returns\n",
p->p_pid, sig);
@@ -1150,7 +1355,7 @@ sys_sigreturn(p, v, retval)
scp = SCARG(uap, sigcntxp);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
- printf("sigreturn: pid %d, scp %lx\n", p->p_pid, scp);
+ printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
#endif
if (ALIGN(scp) != (u_int64_t)scp)
@@ -1175,10 +1380,12 @@ sys_sigreturn(p, v, retval)
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ksc.sc_mask &~ sigcantmask;
- p->p_md.md_tf->tf_pc = ksc.sc_pc;
- p->p_md.md_tf->tf_ps = (ksc.sc_ps | PSL_USERSET) & ~PSL_USERCLR;
+ p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
+ p->p_md.md_tf->tf_regs[FRAME_PS] =
+ (ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR;
regtoframe((struct reg *)ksc.sc_regs, p->p_md.md_tf);
+ alpha_pal_wrusp(ksc.sc_regs[R_SP]);
/* XXX ksc.sc_ownedfp ? */
if (p == fpcurproc)
@@ -1197,6 +1404,7 @@ sys_sigreturn(p, v, retval)
/*
* machine dependent system variables.
*/
+int
cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
int *name;
u_int namelen;
@@ -1224,6 +1432,18 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
case CPU_ROOT_DEVICE:
return (sysctl_rdstring(oldp, oldlenp, newp, root_device));
+ case CPU_UNALIGNED_PRINT:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &alpha_unaligned_print));
+
+ case CPU_UNALIGNED_FIX:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &alpha_unaligned_fix));
+
+ case CPU_UNALIGNED_SIGBUS:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &alpha_unaligned_sigbus));
+
default:
return (EOPNOTSUPP);
}
@@ -1245,27 +1465,31 @@ setregs(p, pack, stack, retval)
extern struct proc *fpcurproc;
#ifdef DEBUG
- for (i = 0; i < FRAME_NSAVEREGS; i++)
+ /*
+ * Crash and dump, if the user requested it.
+ */
+ if (boothowto & RB_DUMP)
+ panic("crash requested by boot flags");
+#endif
+
+#ifdef DEBUG
+ for (i = 0; i < FRAME_SIZE; i++)
tfp->tf_regs[i] = 0xbabefacedeadbeef;
- tfp->tf_gp = 0xbabefacedeadbeef;
- tfp->tf_a0 = 0xbabefacedeadbeef;
- tfp->tf_a1 = 0xbabefacedeadbeef;
- tfp->tf_a2 = 0xbabefacedeadbeef;
#else
- bzero(tfp->tf_regs, FRAME_NSAVEREGS * sizeof tfp->tf_regs[0]);
- tfp->tf_gp = 0;
- tfp->tf_a0 = 0;
- tfp->tf_a1 = 0;
- tfp->tf_a2 = 0;
+ bzero(tfp->tf_regs, FRAME_SIZE * sizeof tfp->tf_regs[0]);
#endif
bzero(&p->p_addr->u_pcb.pcb_fp, sizeof p->p_addr->u_pcb.pcb_fp);
#define FP_RN 2 /* XXX */
p->p_addr->u_pcb.pcb_fp.fpr_cr = (long)FP_RN << 58;
- tfp->tf_regs[FRAME_SP] = stack; /* restored to usp in trap return */
- tfp->tf_ps = PSL_USERSET;
- tfp->tf_pc = pack->ep_entry & ~3;
+ alpha_pal_wrusp(stack);
+ tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET;
+ tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3;
+
+ tfp->tf_regs[FRAME_A0] = stack;
+ /* a1 and a2 already zeroed */
+ tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */
- p->p_md.md_flags & ~MDP_FPUSED;
+ p->p_md.md_flags &= ~MDP_FPUSED;
if (fpcurproc == p)
fpcurproc = NULL;
@@ -1275,42 +1499,40 @@ setregs(p, pack, stack, retval)
void
netintr()
{
+ int n, s;
+
+ s = splhigh();
+ n = netisr;
+ netisr = 0;
+ splx(s);
+
+#define DONETISR(bit, fn) \
+ do { \
+ if (n & (1 << (bit))) \
+ fn; \
+ } while (0)
+
#ifdef INET
-#if NETHER > 0
- if (netisr & (1 << NETISR_ARP)) {
- netisr &= ~(1 << NETISR_ARP);
- arpintr();
- }
-#endif
- if (netisr & (1 << NETISR_IP)) {
- netisr &= ~(1 << NETISR_IP);
- ipintr();
- }
+ DONETISR(NETISR_ARP, arpintr());
+ DONETISR(NETISR_IP, ipintr());
#endif
#ifdef NS
- if (netisr & (1 << NETISR_NS)) {
- netisr &= ~(1 << NETISR_NS);
- nsintr();
- }
+ DONETISR(NETISR_NS, nsintr());
#endif
#ifdef ISO
- if (netisr & (1 << NETISR_ISO)) {
- netisr &= ~(1 << NETISR_ISO);
- clnlintr();
- }
+ DONETISR(NETISR_ISO, clnlintr());
#endif
#ifdef CCITT
- if (netisr & (1 << NETISR_CCITT)) {
- netisr &= ~(1 << NETISR_CCITT);
- ccittintr();
- }
+ DONETISR(NETISR_CCITT, ccittintr());
#endif
-#ifdef PPP
- if (netisr & (1 << NETISR_PPP)) {
- netisr &= ~(1 << NETISR_PPP);
- pppintr();
- }
+#ifdef NATM
+ DONETISR(NETISR_NATM, natmintr());
+#endif
+#if NPPP > 1
+ DONETISR(NETISR_PPP, pppintr());
#endif
+
+#undef DONETISR
}
void
@@ -1338,7 +1560,7 @@ spl0()
do_sir();
}
- return (pal_swpipl(PSL_IPL_0));
+ return (alpha_pal_swpipl(ALPHA_PSL_IPL_0));
}
/*
@@ -1431,9 +1653,9 @@ microtime(tvp)
/*
* Wait "n" microseconds.
*/
-int
+void
delay(n)
- int n;
+ unsigned long n;
{
long N = cycles_per_usec * (n);
@@ -1452,7 +1674,7 @@ cpu_exec_ecoff_setregs(p, epp, stack, retval)
struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
setregs(p, epp, stack, retval);
- p->p_md.md_tf->tf_gp = execp->a.gp_value;
+ p->p_md.md_tf->tf_regs[FRAME_GP] = execp->a.gp_value;
}
/*
@@ -1480,7 +1702,7 @@ cpu_exec_ecoff_hook(p, epp)
break;
#endif
- case ECOFF_MAGIC_NETBSD_ALPHA:
+ case ECOFF_MAGIC_NATIVE_ALPHA:
epp->ep_emul = &emul_native;
break;
@@ -1490,24 +1712,3 @@ cpu_exec_ecoff_hook(p, epp)
return 0;
}
#endif
-
-vm_offset_t
-vtophys(vaddr)
- vm_offset_t vaddr;
-{
- vm_offset_t paddr;
-
- if (vaddr < K0SEG_BEGIN) {
- printf("vtophys: invalid vaddr 0x%lx", vaddr);
- paddr = vaddr;
- } else if (vaddr < K0SEG_END)
- paddr = k0segtophys(vaddr);
- else
- paddr = vatopa(vaddr);
-
-#if 0
- printf("vtophys(0x%lx) -> %lx\n", vaddr, paddr);
-#endif
-
- return (paddr);
-}
diff --git a/sys/arch/alpha/alpha/mainbus.c b/sys/arch/alpha/alpha/mainbus.c
index 13aff1bbbad..e610c2b7f49 100644
--- a/sys/arch/alpha/alpha/mainbus.c
+++ b/sys/arch/alpha/alpha/mainbus.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: mainbus.c,v 1.5 1996/07/29 22:57:45 niklas Exp $ */
-/* $NetBSD: mainbus.c,v 1.9 1996/04/12 06:07:35 cgd Exp $ */
+/* $OpenBSD: mainbus.c,v 1.6 1996/10/30 22:38:15 niklas Exp $ */
+/* $NetBSD: mainbus.c,v 1.12 1996/10/13 02:59:40 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -44,7 +44,7 @@ struct mainbus_softc {
/* Definition of the mainbus driver. */
static int mbmatch __P((struct device *, void *, void *));
static void mbattach __P((struct device *, struct device *, void *));
-static int mbprint __P((void *, char *));
+static int mbprint __P((void *, /* const */ char *));
struct cfattach mainbus_ca = {
sizeof(struct mainbus_softc), mbmatch, mbattach
@@ -87,9 +87,8 @@ mbattach(parent, self, aux)
{
struct mainbus_softc *sc = (struct mainbus_softc *)self;
struct confargs nca;
- struct pcs *pcsp;
int i, cpuattachcnt;
- extern int cputype, ncpus;
+ extern int ncpus;
extern char *cpu_iobus;
printf("\n");
@@ -136,7 +135,7 @@ mbattach(parent, self, aux)
static int
mbprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
struct confargs *ca = aux;
diff --git a/sys/arch/alpha/alpha/mcclock.c b/sys/arch/alpha/alpha/mcclock.c
index 6bec1b29f85..6c4b457f586 100644
--- a/sys/arch/alpha/alpha/mcclock.c
+++ b/sys/arch/alpha/alpha/mcclock.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: mcclock.c,v 1.2 1996/07/29 22:57:47 niklas Exp $ */
-/* $NetBSD: mcclock.c,v 1.2 1996/04/17 22:22:32 cgd Exp $ */
+/* $OpenBSD: mcclock.c,v 1.3 1996/10/30 22:38:16 niklas Exp $ */
+/* $NetBSD: mcclock.c,v 1.4 1996/10/13 02:59:41 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/alpha/mcclockvar.h b/sys/arch/alpha/alpha/mcclockvar.h
index 73cd23ed7ce..f1064251092 100644
--- a/sys/arch/alpha/alpha/mcclockvar.h
+++ b/sys/arch/alpha/alpha/mcclockvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mcclockvar.h,v 1.2 1996/07/29 22:57:48 niklas Exp $ */
+/* $OpenBSD: mcclockvar.h,v 1.3 1996/10/30 22:38:17 niklas Exp $ */
/* $NetBSD: mcclockvar.h,v 1.2 1996/04/17 22:22:38 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/alpha/mem.c b/sys/arch/alpha/alpha/mem.c
index 747e36b50aa..46e0a555cd4 100644
--- a/sys/arch/alpha/alpha/mem.c
+++ b/sys/arch/alpha/alpha/mem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: mem.c,v 1.4 1996/07/29 22:57:49 niklas Exp $ */
-/* $NetBSD: mem.c,v 1.6 1996/04/12 02:06:21 cgd Exp $ */
+/* $OpenBSD: mem.c,v 1.5 1996/10/30 22:38:17 niklas Exp $ */
+/* $NetBSD: mem.c,v 1.9 1996/08/20 23:00:25 cgd Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -59,11 +59,17 @@
caddr_t zeropage;
extern int firstusablepage, lastusablepage;
+int mmopen __P((dev_t, int, int, struct proc *));
+int mmclose __P((dev_t, int, int, struct proc *));
+int mmrw __P((dev_t, struct uio *, int));
+int mmmmap __P((dev_t, vm_offset_t, int));
+
/*ARGSUSED*/
int
-mmopen(dev, flag, mode)
+mmopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
+ struct proc *p;
{
return (0);
@@ -71,15 +77,17 @@ mmopen(dev, flag, mode)
/*ARGSUSED*/
int
-mmclose(dev, flag, mode)
+mmclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
+ struct proc *p;
{
return (0);
}
/*ARGSUSED*/
+int
mmrw(dev, uio, flags)
dev_t dev;
struct uio *uio;
@@ -113,15 +121,16 @@ kmemphys:
#endif
o = uio->uio_offset & PGOFSET;
c = min(uio->uio_resid, (int)(NBPG - o));
- error = uiomove((caddr_t)phystok0seg(v), c, uio);
+ error =
+ uiomove((caddr_t)ALPHA_PHYS_TO_K0SEG(v), c, uio);
continue;
/* minor device 1 is kernel memory */
case 1:
v = uio->uio_offset;
- if (v >= K0SEG_BEGIN && v < K0SEG_END) {
- v = k0segtophys(v);
+ if (v >= ALPHA_K0SEG_BASE && v <= ALPHA_K0SEG_END) {
+ v = ALPHA_K0SEG_TO_PHYS(v);
goto kmemphys;
}
@@ -152,7 +161,7 @@ kmemphys:
* is a global zeroed page, the null segment table.
*/
if (zeropage == NULL) {
-#if CLBYTES == NBPG
+#if (CLBYTES == NBPG) && !defined(NEW_PMAP)
extern caddr_t Segtabzero;
zeropage = Segtabzero;
#else
diff --git a/sys/arch/alpha/alpha/pal.s b/sys/arch/alpha/alpha/pal.s
index 1dc00e428d9..4be046c27af 100644
--- a/sys/arch/alpha/alpha/pal.s
+++ b/sys/arch/alpha/alpha/pal.s
@@ -1,5 +1,5 @@
-/* $OpenBSD: pal.s,v 1.3 1996/07/29 22:57:51 niklas Exp $ */
-/* $NetBSD: pal.s,v 1.2 1995/11/23 02:34:23 cgd Exp $ */
+/* $OpenBSD: pal.s,v 1.4 1996/10/30 22:38:18 niklas Exp $ */
+/* $NetBSD: pal.s,v 1.5 1996/07/14 04:21:53 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -37,166 +37,89 @@
*/
/*
- * pal_bpt: Breakpoint trap [UNPRIVILEGED]
+ * alpha_rpcc: read process cycle counter (XXX INSTRUCTION, NOT PALcode OP)
*/
- .text
-LEAF(pal_bpt,0)
- call_pal PAL_bpt
- RET
- END(pal_bpt)
-
-/*
- * pal_bugchk: Bugcheck trap [UNPRIVILEGED]
- */
- .text
-LEAF(pal_bugchk,0)
- call_pal PAL_bugchk
- RET
- END(pal_bugchk)
+ .text
+LEAF(alpha_rpcc,1)
+ rpcc v0
+ RET
+ END(alpha_rpcc)
-#ifdef ILLEGAL /* ILLEGAL FROM KERNEL MODE */
/*
- * pal_callsys: System call [UNPRIVILEGED]
+ * alpha_mb: memory barrier (XXX INSTRUCTION, NOT PALcode OP)
*/
.text
-LEAF(pal_callsys,0)
- call_pal PAL_OSF1_callsys
+LEAF(alpha_mb,0)
+ mb
RET
- END(pal_callsys)
-#endif /* ILLEGAL */
+ END(alpha_mb)
/*
- * pal_gentrap: Generate trap [UNPRIVILEGED]
+ * alpha_wmb: write memory barrier (XXX INSTRUCTION, NOT PALcode OP)
*/
.text
-LEAF(pal_gentrap,0)
- call_pal PAL_gentrap
+LEAF(alpha_wmb,0)
+ /* wmb XXX */
+ mb /* XXX */
RET
- END(pal_gentrap)
+ END(alpha_wmb)
/*
- * pal_imb: I-Stream memory barrier. [UNPRIVILEGED]
+ * alpha_pal_imb: I-Stream memory barrier. [UNPRIVILEGED]
* (Makes instruction stream coherent with data stream.)
*/
.text
-LEAF(pal_imb,0)
+LEAF(alpha_pal_imb,0)
call_pal PAL_imb
RET
- END(pal_imb)
-
-/*
- * pal_rdunique: Read process unique value. [UNPRIVILEGED]
- *
- * Return:
- * v0 current process unique value
- */
- .text
-LEAF(pal_rdunique,0)
- call_pal PAL_rdunique
- RET
- END(pal_rdunique)
-
-/*
- * pal_wrunique: Write process unique value. [UNPRIVILEGED]
- * Arguments:
- * a0 new process unique value
- */
- .text
-LEAF(pal_wrunique,1)
- call_pal PAL_wrunique
- RET
- END(pal_wrunique)
+ END(alpha_pal_imb)
/*
- * pal_draina: Drain aborts. [PRIVILEGED]
+ * alpha_pal_draina: Drain aborts. [PRIVILEGED]
*/
.text
-LEAF(pal_draina,0)
+LEAF(alpha_pal_draina,0)
call_pal PAL_draina
RET
- END(pal_draina)
+ END(alpha_pal_draina)
/*
- * pal_halt: Halt the processor. [PRIVILEGED]
+ * alpha_pal_halt: Halt the processor. [PRIVILEGED]
*/
.text
-LEAF(pal_halt,0)
+LEAF(alpha_pal_halt,0)
call_pal PAL_halt
- br zero,pal_halt /* Just in case */
+ br zero,alpha_pal_halt /* Just in case */
RET
- END(pal_halt)
+ END(alpha_pal_halt)
/*
- * pal_rdps: Read processor status. [PRIVILEGED]
+ * alpha_pal_rdmces: Read MCES processor register. [PRIVILEGED]
*
* Return:
- * v0 current processor status
+ * v0 current MCES value
*/
.text
-LEAF(pal_rdps,0)
- call_pal PAL_OSF1_rdps
+LEAF(alpha_pal_rdmces,1)
+ call_pal PAL_OSF1_rdmces
RET
- END(pal_rdps)
+ END(alpha_pal_rdmces)
/*
- * pal_rdusp: Read user stack pointer. [PRIVILEGED]
+ * alpha_pal_rdusp: Read user stack pointer. [PRIVILEGED]
*
* Return:
* v0 current user stack pointer
*/
.text
-LEAF(pal_rdusp,0)
+LEAF(alpha_pal_rdusp,0)
call_pal PAL_OSF1_rdusp
RET
- END(pal_rdusp)
-
-/*
- * pal_rdval: Read system value. [PRIVILEGED]
- *
- * Return:
- * v0 current system value
- */
- .text
-LEAF(pal_rdval,0)
- call_pal PAL_OSF1_rdval
- RET
- END(pal_rdval)
-
-/*
- * pal_retsys: Return from system call. [PRIVILEGED]
- */
- .text
-LEAF(pal_retsys,0)
- call_pal PAL_OSF1_retsys
- RET
- END(pal_retsys)
-
-/*
- * pal_rti: Return from trap, fault, or interrupt. [PRIVILEGED]
- */
- .text
-LEAF(pal_rti,0)
- call_pal PAL_OSF1_rti
- RET
- END(pal_rti)
-
-/*
- * pal_swpctx: Swap process context. [PRIVILEGED]
- *
- * Arguments:
- * a0 new PCB
- *
- * Return:
- * v0 old PCB
- */
- .text
-LEAF(pal_swpctx,1)
- call_pal PAL_OSF1_swpctx
- RET
- END(pal_swpctx)
+ END(alpha_pal_rdusp)
/*
- * pal_swpipl: Swap Interrupt priority level. [PRIVILEGED]
+ * alpha_pal_swpipl: Swap Interrupt priority level. [PRIVILEGED]
+ * _alpha_pal_swpipl: Same, from profiling code. [PRIVILEGED]
*
* Arguments:
* a0 new IPL
@@ -205,122 +128,98 @@ LEAF(pal_swpctx,1)
* v0 old IPL
*/
.text
-LEAF(pal_swpipl,1)
+LEAF(alpha_pal_swpipl,1)
call_pal PAL_OSF1_swpipl
RET
- END(pal_swpipl)
+ END(alpha_pal_swpipl)
-LEAF_NOPROFILE(profile_swpipl,1)
+LEAF_NOPROFILE(_alpha_pal_swpipl,1)
call_pal PAL_OSF1_swpipl
RET
- END(profile_swpipl)
+ END(_alpha_pal_swpipl)
/*
- * pal_tbi: Translation buffer invalidate. [PRIVILEGED]
+ * alpha_pal_tbi: Translation buffer invalidate. [PRIVILEGED]
*
* Arguments:
* a0 operation selector
* a1 address to operate on (if necessary)
*/
.text
-LEAF(pal_tbi,2)
+LEAF(alpha_pal_tbi,2)
call_pal PAL_OSF1_tbi
RET
- END(pal_tbi)
+ END(alpha_pal_tbi)
/*
- * pal_whami: Who am I? [PRIVILEGED]
+ * alpha_pal_whami: Who am I? [PRIVILEGED]
*
* Return:
* v0 processor number
*/
.text
-LEAF(pal_whami,0)
+LEAF(alpha_pal_whami,0)
call_pal PAL_OSF1_whami
RET
- END(pal_whami)
+ END(alpha_pal_whami)
/*
- * pal_wrent: Write system entry address. [PRIVILEGED]
+ * alpha_pal_wrent: Write system entry address. [PRIVILEGED]
*
* Arguments:
* a0 new vector
* a1 vector selector
*/
.text
-LEAF(pal_wrent,2)
+LEAF(alpha_pal_wrent,2)
call_pal PAL_OSF1_wrent
RET
- END(pal_wrent)
+ END(alpha_pal_wrent)
/*
- * pal_wrfen: Write floating-point enable. [PRIVILEGED]
+ * alpha_pal_wrfen: Write floating-point enable. [PRIVILEGED]
*
* Arguments:
* a0 new enable value (val & 0x1 -> enable).
*/
.text
-LEAF(pal_wrfen,1)
+LEAF(alpha_pal_wrfen,1)
call_pal PAL_OSF1_wrfen
RET
- END(pal_wrfen)
-
-/*
- * pal_wrkgp: Write kernel global pointer. [PRIVILEGED]
- *
- * Arguments:
- * a0 new kernel global pointer
- */
- .text
-LEAF(pal_wrkgp,1)
- call_pal PAL_OSF1_wrkgp
- RET
- END(pal_wrkgp)
+ END(alpha_pal_wrfen)
/*
- * pal_wrusp: Write user stack pointer. [PRIVILEGED]
+ * alpha_pal_wrusp: Write user stack pointer. [PRIVILEGED]
*
* Arguments:
* a0 new user stack pointer
*/
.text
-LEAF(pal_wrusp,1)
+LEAF(alpha_pal_wrusp,1)
call_pal PAL_OSF1_wrusp
RET
- END(pal_wrusp)
-
-/*
- * pal_wrval: Write system value. [PRIVILEGED]
- *
- * Arguments:
- * a0 new system value
- */
- .text
-LEAF(pal_wrval,1)
- call_pal PAL_OSF1_wrval
- RET
- END(pal_wrval)
+ END(alpha_pal_wrusp)
/*
- * pal_wrvptptr: Write virtual page table pointer. [PRIVILEGED]
+ * alpha_pal_wrvptptr: Write virtual page table pointer. [PRIVILEGED]
*
* Arguments:
* a0 new virtual page table pointer
*/
.text
-LEAF(pal_wrvptptr,1)
+LEAF(alpha_pal_wrvptptr,1)
call_pal PAL_OSF1_wrvptptr
RET
- END(pal_wrvptptr)
+ END(alpha_pal_wrvptptr)
/*
- * pal_mtpr_mces: Write MCES processor register. [PRIVILEGED, VMS, XXX!]
+ * alpha_pal_wrmces: Write MCES processor register. [PRIVILEGED]
*
* Arguments:
* a0 value to write to MCES
*/
.text
-LEAF(pal_mtpr_mces,1)
- call_pal PAL_VMS_mtpr_mces
+LEAF(alpha_pal_wrmces,1)
+ call_pal PAL_OSF1_wrmces
RET
- END(pal_mtpr_mces)
+ END(alpha_pal_wrmces)
diff --git a/sys/arch/alpha/alpha/pmap.c b/sys/arch/alpha/alpha/pmap.c
index dfd75311e7e..2357e853826 100644
--- a/sys/arch/alpha/alpha/pmap.c
+++ b/sys/arch/alpha/alpha/pmap.c
@@ -1,79 +1,51 @@
-/* $OpenBSD: pmap.c,v 1.4 1996/07/29 22:57:53 niklas Exp $ */
-/* $NetBSD: pmap.c,v 1.8 1996/04/12 02:09:24 cgd Exp $ */
+/* $OpenBSD: pmap.c,v 1.5 1996/10/30 22:38:20 niklas Exp $ */
+/* $NetBSD: pmap.c,v 1.17 1996/10/13 02:59:42 christos Exp $ */
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department.
- *
- * 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.
- *
- * @(#)pmap.c 8.6 (Berkeley) 5/27/94
+/*
+ * Copyright (c) 1992, 1996 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
*/
-#ifdef XXX
/*
- * HP9000/300 series physical map management code.
- *
- * Supports:
- * 68020 with HP MMU models 320, 350
- * 68020 with 68551 MMU models 318, 319, 330 (all untested)
- * 68030 with on-chip MMU models 340, 360, 370, 345, 375, 400
- * 68040 with on-chip MMU models 380, 425, 433
+ * File: pmap.c
*
- * Notes:
- * Don't even pay lip service to multiprocessor support.
+ * Author list
+ * vax: Avadis Tevanian, Jr., Michael Wayne Young
+ * i386: Lance Berc, Mike Kupfer, Bob Baron, David Golub, Richard Draves
+ * alpha: Alessandro Forin
+ * {Net,Open}BSD/Alpha: Chris Demetriou
*
- * We assume TLB entries don't have process tags (except for the
- * supervisor/user distinction) so we only invalidate TLB entries
- * when changing mappings for the current (or kernel) pmap. This is
- * technically not true for the 68551 but we flush the TLB on every
- * context switch, so it effectively winds up that way.
+ * Physical Map management code for DEC Alpha
*
- * Bitwise and/or operations are significantly faster than bitfield
- * references so we use them when accessing STE/PTEs in the pmap_pte_*
- * macros. Note also that the two are not always equivalent; e.g.:
- * (*(int *)pte & PG_PROT) [4] != pte->pg_prot [1]
- * and a couple of routines that deal with protection and wiring take
- * some shortcuts that assume the and/or definitions.
+ * Manages physical address maps.
*
- * This implementation will only work for PAGE_SIZE == NBPG
- * (i.e. 4096 bytes).
+ * This code was derived exclusively from information available in
+ * "Alpha Architecture Reference Manual", Richard L. Sites ed.
+ * Digital Press, Burlington, MA 01803
+ * ISBN 1-55558-098-X, Order no. EY-L520E-DP
*/
-#endif
/*
- * Manages physical address maps.
- *
* In addition to hardware address maps, this
* module is called upon to provide software-use-only
* maps which may or may not be stored in the same
@@ -110,359 +82,782 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
#include <machine/cpu.h>
+#include <machine/alpha_cpu.h>
+
+
+#define VM_OBJECT_NULL NULL
+#define VM_PAGE_NULL NULL
+#define BYTE_SIZE NBBY
+#define page_size PAGE_SIZE
+#define ALPHA_PTE_GLOBAL ALPHA_PTE_ASM
+#define MACRO_BEGIN do {
+#define MACRO_END } while (0)
+#define K2SEG_BASE ALPHA_K1SEG_BASE
+#define integer_t long
+#define spl_t int
+#define vm_page_fictitious_addr 0
+#define aligned_block_copy(src, dest, size) bcopy((void *)src, (void *)dest, size)
+#define db_printf printf
+#define tbia ALPHA_TBIA
+#define alphacache_Iflush alpha_pal_imb
+#define cpu_number() 0
+#define check_simple_locks()
+#define K0SEG_TO_PHYS ALPHA_K0SEG_TO_PHYS
+#define ISA_K0SEG(v) (v >= ALPHA_K0SEG_BASE && v <= ALPHA_K0SEG_END)
+#ifndef assert
+#define assert(x)
+#endif
+
+vm_offset_t avail_start; /* PA of first available physical page */
+vm_offset_t avail_end; /* PA of last available physical page */
+vm_offset_t mem_size; /* memory size in bytes */
+vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/
+vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
-#ifdef PMAPSTATS
-struct {
- int collectscans;
- int collectpages;
- int kpttotal;
- int kptinuse;
- int kptmaxuse;
-} kpt_stats;
-struct {
- int kernel; /* entering kernel mapping */
- int user; /* entering user mapping */
- int ptpneeded; /* needed to allocate a PT page */
- int nochange; /* no change at all */
- int pwchange; /* no mapping change, just wiring or protection */
- int wchange; /* no mapping change, just wiring */
- int pchange; /* no mapping change, just protection */
- int mchange; /* was mapped but mapping to different page */
- int managed; /* a managed page */
- int firstpv; /* first mapping for this PA */
- int secondpv; /* second mapping for this PA */
- int ci; /* cache inhibited */
- int unmanaged; /* not a managed page */
- int flushes; /* cache flushes */
-} enter_stats;
-struct {
- int calls;
- int removes;
- int pvfirst;
- int pvsearch;
- int ptinvalid;
- int uflushes;
- int sflushes;
-} remove_stats;
-struct {
- int calls;
- int changed;
- int alreadyro;
- int alreadyrw;
-} protect_stats;
-struct chgstats {
- int setcalls;
- int sethits;
- int setmiss;
- int clrcalls;
- int clrhits;
- int clrmiss;
-} changebit_stats[16];
-#endif
+/* XXX */
+struct pv_entry *pmap_alloc_pv __P((void));
+void pmap_free_pv __P((struct pv_entry *pv));
+vm_page_t vm_page_grab __P((void));
+
+vm_offset_t pmap_resident_extract __P((pmap_t, vm_offset_t));
+
+/* For external use... */
+vm_offset_t kvtophys(vm_offset_t virt)
+{
+
+ return pmap_resident_extract(kernel_pmap, virt);
+}
+
+/* ..but for internal use... */
+#define phystokv(a) ALPHA_PHYS_TO_K0SEG(a)
+#define kvtophys(p) ALPHA_K0SEG_TO_PHYS((vm_offset_t)p)
+
+
+/*
+ * Private data structures.
+ */
+/*
+ * Map from MI protection codes to MD codes.
+ * Assume that there are three MI protection codes, all using low bits.
+ */
+pt_entry_t user_protection_codes[8];
+pt_entry_t kernel_protection_codes[8];
+
+alpha_protection_init()
+{
+ register pt_entry_t *kp, *up, prot;
+
+ kp = kernel_protection_codes;
+ up = user_protection_codes;
+ for (prot = 0; prot < 8; prot++) {
+ switch (prot) {
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
+ *kp++ = 0;
+ *up++ = 0;
+ break;
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
+ *kp++ = ALPHA_PTE_KR;
+ *up++ = ALPHA_PTE_UR|ALPHA_PTE_KR;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
+ *kp++ = ALPHA_PTE_KW;
+ *up++ = ALPHA_PTE_UW|ALPHA_PTE_KW;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ *kp++ = ALPHA_PTE_KW|ALPHA_PTE_KR;
+ *up++ = ALPHA_PTE_UW|ALPHA_PTE_UR|ALPHA_PTE_KW|ALPHA_PTE_KR;
+ break;
+ }
+ }
+}
+
+/*
+ * Given a map and a machine independent protection code,
+ * convert to a alpha protection code.
+ */
+
+#define alpha_protection(map, prot) \
+ (((map) == kernel_pmap) ? kernel_protection_codes[prot] : \
+ user_protection_codes[prot])
+
+/* Build the typical kernel pte */
+#define pte_ktemplate(t,pa,pr) \
+MACRO_BEGIN \
+ (t) = pa_to_pte(pa) | ALPHA_PTE_VALID | ALPHA_PTE_GLOBAL | \
+ (alpha_protection(kernel_pmap,pr)); \
+MACRO_END
+
+/* build the typical pte */
+#define pte_template(m,t,pa,pr) \
+MACRO_BEGIN \
+ (t) = pa_to_pte(pa) | ALPHA_PTE_VALID | \
+ (alpha_protection(m,pr)); \
+MACRO_END
+
+/*
+ * For each vm_page_t, there is a list of all currently
+ * valid virtual mappings of that page. An entry is
+ * a pv_entry_t; the list is the pv_table.
+ */
+
+typedef struct pv_entry {
+ struct pv_entry *next; /* next pv_entry */
+ pmap_t pmap; /* pmap where mapping lies */
+ vm_offset_t va; /* virtual address for mapping */
+} *pv_entry_t;
+
+#define PV_ENTRY_NULL ((pv_entry_t) 0)
+
+pv_entry_t pv_head_table; /* array of entries, one per page */
+
+/*
+ * pv_list entries are kept on a list that can only be accessed
+ * with the pmap system locked (at SPLVM, not in the cpus_active set).
+ * The list is refilled from the pv_list_zone if it becomes empty.
+ */
+pv_entry_t pv_free_list; /* free list at SPLVM */
+decl_simple_lock_data(, pv_free_list_lock)
+
+#define PV_ALLOC(pv_e) { \
+ simple_lock(&pv_free_list_lock); \
+ if ((pv_e = pv_free_list) != 0) { \
+ pv_free_list = pv_e->next; \
+ } \
+ simple_unlock(&pv_free_list_lock); \
+}
+
+#define PV_FREE(pv_e) { \
+ simple_lock(&pv_free_list_lock); \
+ pv_e->next = pv_free_list; \
+ pv_free_list = pv_e; \
+ simple_unlock(&pv_free_list_lock); \
+}
-#ifdef DEBUG
-#define PDB_FOLLOW 0x0001
-#define PDB_INIT 0x0002
-#define PDB_ENTER 0x0004
-#define PDB_REMOVE 0x0008
-#define PDB_CREATE 0x0010
-#define PDB_PTPAGE 0x0020
-#define PDB_CACHE 0x0040
-#define PDB_BITS 0x0080
-#define PDB_COLLECT 0x0100
-#define PDB_PROTECT 0x0200
-#define PDB_SEGTAB 0x0400
-#define PDB_MULTIMAP 0x0800
-#define PDB_BOOTSTRAP 0x1000
-#define PDB_PARANOIA 0x2000
-#define PDB_WIRING 0x4000
-#define PDB_PVDUMP 0x8000
-
-int debugmap = 0;
-int pmapdebug = PDB_PARANOIA;
-extern vm_offset_t pager_sva, pager_eva;
+#if 0
+zone_t pv_list_zone; /* zone of pv_entry structures */
#endif
/*
- * Get STEs and PTEs for user/kernel address space
+ * Each entry in the pv_head_table is locked by a bit in the
+ * pv_lock_table. The lock bits are accessed by the physical
+ * address of the page they lock.
*/
-#define pmap_ste(m, v) (&((m)->pm_stab[vatoste((vm_offset_t)(v))]))
-#define pmap_ste_v(m, v) (*pmap_ste(m, v) & PG_V)
-#define pmap_pte(m, v) \
- (&((m)->pm_ptab[NPTEPG * vatoste((vm_offset_t)(v)) + \
- vatopte((vm_offset_t)(v))]))
-#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT)
-#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
-#define pmap_pte_w(pte) (*(pte) & PG_WIRED)
-#define pmap_pte_v(pte) (*(pte) & PG_V)
+char *pv_lock_table; /* pointer to array of bits */
+#define pv_lock_table_size(n) (((n)+BYTE_SIZE-1)/BYTE_SIZE)
+
+/*
+ * First and last physical addresses that we maintain any information
+ * for. Initialized to zero so that pmap operations done before
+ * pmap_init won't touch any non-existent structures.
+ */
+vm_offset_t vm_first_phys = (vm_offset_t) 0;
+vm_offset_t vm_last_phys = (vm_offset_t) 0;
+boolean_t pmap_initialized = FALSE;/* Has pmap_init completed? */
-#define pmap_pte_set_w(pte, v) \
- if (v) *(u_long *)(pte) |= PG_WIRED; else *(u_long *)(pte) &= ~PG_WIRED
-#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
+/*
+ * Index into pv_head table, its lock bits, and the modify/reference
+ * bits starting at vm_first_phys.
+ */
-#define pmap_pte_set_prot(pte, np) { *(pte) &= ~PG_PROT ; *(pte) |= (np); }
-#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
-
+#define pa_index(pa) (atop(pa - vm_first_phys))
+
+#define pai_to_pvh(pai) (&pv_head_table[pai])
+#define lock_pvh_pai(pai) (bit_lock(pai, pv_lock_table))
+#define unlock_pvh_pai(pai) (bit_unlock(pai, pv_lock_table))
/*
- * Given a map and a machine independent protection code,
- * convert to an hp300 protection code.
+ * Array of physical page attributes for managed pages.
+ * One byte per physical page.
*/
-#define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p])
-int protection_codes[2][8];
+char *pmap_phys_attributes;
/*
- * Kernel page table page management.
+ * Physical page attributes. Copy bits from PTE.
+ */
+#define PHYS_MODIFIED (ALPHA_PTE_MOD>>16) /* page modified */
+#define PHYS_REFERENCED (ALPHA_PTE_REF>>16) /* page referenced */
+
+#define pte_get_attributes(p) ((*p & (ALPHA_PTE_MOD|ALPHA_PTE_REF)) >> 16)
+
+/*
+ * Amount of virtual memory mapped by one
+ * page-directory entry.
+ */
+#define PDE_MAPPED_SIZE (pdetova(1))
+#define PDE2_MAPPED_SIZE (pde2tova(1))
+#define PDE3_MAPPED_SIZE (pde3tova(1))
+
+/*
+ * We allocate page table pages directly from the VM system
+ * through this object. It maps physical memory.
+ */
+vm_object_t pmap_object = VM_OBJECT_NULL;
+
+/*
+ * Locking and TLB invalidation
+ */
+
+/*
+ * Locking Protocols:
+ *
+ * There are two structures in the pmap module that need locking:
+ * the pmaps themselves, and the per-page pv_lists (which are locked
+ * by locking the pv_lock_table entry that corresponds to the pv_head
+ * for the list in question.) Most routines want to lock a pmap and
+ * then do operations in it that require pv_list locking -- however
+ * pmap_remove_all and pmap_copy_on_write operate on a physical page
+ * basis and want to do the locking in the reverse order, i.e. lock
+ * a pv_list and then go through all the pmaps referenced by that list.
+ * To protect against deadlock between these two cases, the pmap_lock
+ * is used. There are three different locking protocols as a result:
+ *
+ * 1. pmap operations only (pmap_extract, pmap_access, ...) Lock only
+ * the pmap.
+ *
+ * 2. pmap-based operations (pmap_enter, pmap_remove, ...) Get a read
+ * lock on the pmap_lock (shared read), then lock the pmap
+ * and finally the pv_lists as needed [i.e. pmap lock before
+ * pv_list lock.]
+ *
+ * 3. pv_list-based operations (pmap_remove_all, pmap_copy_on_write, ...)
+ * Get a write lock on the pmap_lock (exclusive write); this
+ * also guaranteees exclusive access to the pv_lists. Lock the
+ * pmaps as needed.
+ *
+ * At no time may any routine hold more than one pmap lock or more than
+ * one pv_list lock. Because interrupt level routines can allocate
+ * mbufs and cause pmap_enter's, the pmap_lock and the lock on the
+ * kernel_pmap can only be held at splvm.
+ */
+
+#if NCPUS > 1
+/*
+ * We raise the interrupt level to splvm, to block interprocessor
+ * interrupts during pmap operations. We must take the CPU out of
+ * the cpus_active set while interrupts are blocked.
+ */
+#define SPLVM(spl) { \
+ spl = splvm(); \
+ i_bit_clear(cpu_number(), &cpus_active); \
+}
+
+#define SPLX(spl) { \
+ i_bit_set(cpu_number(), &cpus_active); \
+ splx(spl); \
+}
+
+/*
+ * Lock on pmap system
+ */
+lock_data_t pmap_system_lock;
+
+volatile boolean_t cpu_update_needed[NCPUS];
+
+#define PMAP_READ_LOCK(pmap, spl) { \
+ SPLVM(spl); \
+ lock_read(&pmap_system_lock); \
+ simple_lock(&(pmap)->lock); \
+}
+
+#define PMAP_WRITE_LOCK(spl) { \
+ SPLVM(spl); \
+ lock_write(&pmap_system_lock); \
+}
+
+#define PMAP_READ_UNLOCK(pmap, spl) { \
+ simple_unlock(&(pmap)->lock); \
+ lock_read_done(&pmap_system_lock); \
+ SPLX(spl); \
+}
+
+#define PMAP_WRITE_UNLOCK(spl) { \
+ lock_write_done(&pmap_system_lock); \
+ SPLX(spl); \
+}
+
+#define PMAP_WRITE_TO_READ_LOCK(pmap) { \
+ simple_lock(&(pmap)->lock); \
+ lock_write_to_read(&pmap_system_lock); \
+}
+
+#define LOCK_PVH(index) (lock_pvh_pai(index))
+
+#define UNLOCK_PVH(index) (unlock_pvh_pai(index))
+
+#define PMAP_UPDATE_TLBS(pmap, s, e) \
+{ \
+ cpu_set cpu_mask = 1 << cpu_number(); \
+ cpu_set users; \
+ \
+ /* Since the pmap is locked, other updates are locked */ \
+ /* out, and any pmap_activate has finished. */ \
+ \
+ /* find other cpus using the pmap */ \
+ users = (pmap)->cpus_using & ~cpu_mask; \
+ if (users) { \
+ /* signal them, and wait for them to finish */ \
+ /* using the pmap */ \
+ signal_cpus(users, (pmap), (s), (e)); \
+ while ((pmap)->cpus_using & cpus_active & ~cpu_mask) \
+ continue; \
+ } \
+ \
+ /* invalidate our own TLB if pmap is in use */ \
+ if ((pmap)->cpus_using & cpu_mask) { \
+ INVALIDATE_TLB((s), (e)); \
+ } \
+}
+
+#else NCPUS > 1
+
+#define SPLVM(spl)
+#define SPLX(spl)
+
+#define PMAP_READ_LOCK(pmap, spl) SPLVM(spl)
+#define PMAP_WRITE_LOCK(spl) SPLVM(spl)
+#define PMAP_READ_UNLOCK(pmap, spl) SPLX(spl)
+#define PMAP_WRITE_UNLOCK(spl) SPLX(spl)
+#define PMAP_WRITE_TO_READ_LOCK(pmap)
+
+#define LOCK_PVH(index)
+#define UNLOCK_PVH(index)
+
+#if 0 /*fix bug later */
+#define PMAP_UPDATE_TLBS(pmap, s, e) { \
+ /* invalidate our own TLB if pmap is in use */ \
+ if ((pmap)->cpus_using) { \
+ INVALIDATE_TLB((s), (e)); \
+ } \
+}
+#else
+#define PMAP_UPDATE_TLBS(pmap, s, e) { \
+ INVALIDATE_TLB((s), (e)); \
+}
+#endif
+
+#endif /* NCPUS > 1 */
+
+#if 0
+#define INVALIDATE_TLB(s, e) { \
+ register vm_offset_t v = s, ve = e; \
+ while (v < ve) { \
+ tbis(v); v += ALPHA_PGBYTES; \
+ } \
+}
+#else
+#define INVALIDATE_TLB(s, e) { \
+ tbia(); \
+}
+#endif
+
+
+#if NCPUS > 1
+
+void pmap_update_interrupt();
+
+/*
+ * Structures to keep track of pending TLB invalidations
*/
-struct kpt_page {
- struct kpt_page *kpt_next; /* link on either used or free list */
- vm_offset_t kpt_va; /* always valid kernel VA */
- vm_offset_t kpt_pa; /* PA of this page (for speed) */
-};
-struct kpt_page *kpt_free_list, *kpt_used_list;
-struct kpt_page *kpt_pages;
+
+#define UPDATE_LIST_SIZE 4
+
+struct pmap_update_item {
+ pmap_t pmap; /* pmap to invalidate */
+ vm_offset_t start; /* start address to invalidate */
+ vm_offset_t end; /* end address to invalidate */
+} ;
+
+typedef struct pmap_update_item *pmap_update_item_t;
/*
- * The Alpha's level-1 page table.
+ * List of pmap updates. If the list overflows,
+ * the last entry is changed to invalidate all.
*/
-pt_entry_t *Lev1map;
+struct pmap_update_list {
+ decl_simple_lock_data(, lock)
+ int count;
+ struct pmap_update_item item[UPDATE_LIST_SIZE];
+} ;
+typedef struct pmap_update_list *pmap_update_list_t;
+
+struct pmap_update_list cpu_update_list[NCPUS];
+
+#endif /* NCPUS > 1 */
/*
- * Kernel segment/page table and page table map.
- * The page table map gives us a level of indirection we need to dynamically
- * expand the page table. It is essentially a copy of the segment table
- * with PTEs instead of STEs. All are initialized in locore at boot time.
- * Segtabzero is an empty segment table which all processes share til they
- * reference something.
+ * Other useful macros.
*/
-pt_entry_t *Sysptmap;
-pt_entry_t *Sysmap;
-vm_size_t Sysptmapsize, Sysmapsize;
-pt_entry_t *Segtabzero, Segtabzeropte;
+#define current_pmap() (vm_map_pmap(current_thread()->task->map))
+#define pmap_in_use(pmap, cpu) (((pmap)->cpus_using & (1 << (cpu))) != 0)
struct pmap kernel_pmap_store;
-vm_map_t st_map, pt_map;
+pmap_t kernel_pmap;
-vm_offset_t avail_start; /* PA of first available physical page */
-vm_offset_t avail_end; /* PA of last available physical page */
-vm_size_t mem_size; /* memory size in bytes */
-vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/
-vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
-vm_offset_t vm_first_phys; /* PA of first managed page */
-vm_offset_t vm_last_phys; /* PA just past last managed page */
-boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
-char *pmap_attributes; /* reference and modify bits */
+struct zone *pmap_zone; /* zone of pmap structures */
+
+int pmap_debug = 0; /* flag for debugging prints */
+int ptes_per_vm_page; /* number of hardware ptes needed
+ to map one VM page. */
+unsigned int inuse_ptepages_count = 0; /* debugging */
+extern char end;
/*
- * Internal routines
+ * Page directory for kernel.
*/
-void alpha_protection_init __P((void));
-void pmap_remove_mapping __P((pmap_t, vm_offset_t, pt_entry_t *, int));
-void pmap_changebit __P((vm_offset_t, u_long, boolean_t));
-void pmap_enter_ptpage __P((pmap_t, vm_offset_t));
-#ifdef DEBUG
-void pmap_pvdump __P((vm_offset_t));
-void pmap_check_wiring __P((char *, vm_offset_t));
+pt_entry_t *root_kpdes;
+
+void pmap_remove_range(); /* forward */
+#if NCPUS > 1
+void signal_cpus(); /* forward */
+#endif /* NCPUS > 1 */
+
+int pmap_max_asn;
+void pmap_expand __P((pmap_t, vm_offset_t));
+
+/* XXX */
+#define PDB_BOOTSTRAP 0x00000001
+#define PDB_BOOTSTRAP_ALLOC 0x00000002
+#define PDB_UNMAP_PROM 0x00000004
+#define PDB_ACTIVATE 0x00000008
+#define PDB_DEACTIVATE 0x00000010
+#define PDB_TLBPID_INIT 0x00000020
+#define PDB_TLBPID_ASSIGN 0x00000040
+#define PDB_TLBPID_DESTROY 0x00000080
+#define PDB_ENTER 0x00000100
+#define PDB_CREATE 0x00000200
+#define PDB_PINIT 0x00000400
+#define PDB_EXPAND 0x00000800
+#define PDB_EXTRACT 0x00001000
+#define PDB_PTE 0x00002000
+#define PDB_RELEASE 0x00004000
+#define PDB_DESTROY 0x00008000
+#define PDB_COPY_PAGE 0x00010000
+#define PDB_ZERO_PAGE 0x00020000
+
+#define PDB_ANOMALOUS 0x20000000
+#define PDB_FOLLOW 0x40000000
+#define PDB_VERBOSE 0x80000000
+
+int pmapdebug = PDB_ANOMALOUS |-1 /* -1 */;
+
+#if defined(DEBUG) || 1
+#define DOPDB(x) ((pmapdebug & (x)) != 0)
+#else
+#define DOPDB(x) 0
#endif
+#define DOVPDB(x) (DOPDB(x) && DOPDB(PDB_VERBOSE))
+
+/*
+ * Given an offset and a map, compute the address of the
+ * pte. If the address is invalid with respect to the map
+ * then PT_ENTRY_NULL is returned (and the map may need to grow).
+ *
+ * This is only used internally.
+ */
+#define pmap_pde(pmap, addr) (&(pmap)->dirbase[pdenum(addr)])
+
+pt_entry_t *pmap_pte(pmap, addr)
+ register pmap_t pmap;
+ register vm_offset_t addr;
+{
+ register pt_entry_t *ptp, *ptep;
+ register pt_entry_t pte;
+
+ if (DOPDB(PDB_FOLLOW|PDB_PTE))
+ printf("pmap_pte(%p, 0x%lx)\n", pmap, addr);
+
+ if (pmap->dirbase == 0) {
+ if (DOVPDB(PDB_FOLLOW|PDB_PTE))
+ printf("pmap_pte: dirbase == 0\n");
+ ptep = PT_ENTRY_NULL;
+ goto out;
+ }
+
+ /* seg1 */
+ pte = *pmap_pde(pmap,addr);
+ if ((pte & ALPHA_PTE_VALID) == 0) {
+ if (DOVPDB(PDB_FOLLOW|PDB_PTE))
+ printf("pmap_pte: l1 not valid\n");
+ ptep = PT_ENTRY_NULL;
+ goto out;
+ }
+
+ /* seg2 */
+ ptp = (pt_entry_t *)ptetokv(pte);
+ pte = ptp[pte2num(addr)];
+ if ((pte & ALPHA_PTE_VALID) == 0) {
+ if (DOVPDB(PDB_FOLLOW|PDB_PTE))
+ printf("pmap_pte: l2 not valid\n");
+ ptep = PT_ENTRY_NULL;
+ goto out;
+ }
+
+ /* seg3 */
+ ptp = (pt_entry_t *)ptetokv(pte);
+ ptep = &ptp[pte3num(addr)];
+
+out:
+ if (DOPDB(PDB_FOLLOW|PDB_PTE))
+ printf("pmap_pte: returns %p\n", ptep);
+ return (ptep);
+}
-#define PAGE_IS_MANAGED(pa) ((pa) >= vm_first_phys && (pa) < vm_last_phys)
+#define DEBUG_PTE_PAGE 1
-/* pmap_remove_mapping flags */
-#define PRM_TFLUSH 1
-#define PRM_CFLUSH 2
+extern vm_offset_t virtual_avail, virtual_end;
+extern vm_offset_t avail_start, avail_end;
/*
- * pmap_bootstrap:
- * Bootstrap the system to run with virtual memory.
- * firstaddr is the first unused kseg0 address (not page aligned).
+ * Bootstrap the system enough to run with virtual memory.
+ * Map the kernel's code and data, and allocate the system page table.
+ * Called with mapping OFF. Page_size must already be set.
+ *
+ * Parameters:
+ * avail_start PA of first available physical page
+ * avail_end PA of last available physical page
+ * virtual_avail VA of first available page
+ * virtual_end VA of last available page
+ *
*/
+vm_size_t pmap_kernel_vm = 5; /* each one 8 meg worth */
+
+unsigned int
+pmap_free_pages()
+{
+ return atop(avail_end - avail_start);
+}
+
void
-pmap_bootstrap(firstaddr, ptaddr)
- vm_offset_t firstaddr;
- vm_offset_t ptaddr;
+pmap_bootstrap(firstaddr, ptaddr, maxasn)
+ vm_offset_t firstaddr, ptaddr;
+ int maxasn;
{
- register int i;
+ vm_offset_t pa;
+ pt_entry_t template;
+ pt_entry_t *pde, *pte;
vm_offset_t start;
- pt_entry_t pte;
- extern int firstusablepage, lastusablepage;
+ extern int firstusablepage, lastusablepage;
+ int i;
+ long npages;
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
- printf("pmap_bootstrap(0x%lx, 0x%lx)\n", firstaddr, ptaddr);
-#endif
+ if (DOPDB(PDB_FOLLOW|PDB_BOOTSTRAP))
+ printf("pmap_bootstrap(0x%lx, 0x%lx, %d)\n", firstaddr, ptaddr,
+ maxasn);
/* must be page aligned */
start = firstaddr = alpha_round_page(firstaddr);
-#define valloc(name, type, num) \
- (name) = (type *)firstaddr; \
+#define valloc(name, type, num) \
+ (name) = (type *)firstaddr; \
firstaddr = ALIGN((vm_offset_t)((name)+(num)))
+#define vallocsz(name, cast, size) \
+ (name) = (cast)firstaddr; \
+ firstaddr = ALIGN(firstaddr + size)
/*
- * Allocate an empty prototype segment map for processes.
- * This will be used until processes get their own.
+ * Initialize protection array.
*/
- valloc(Segtabzero, pt_entry_t, NPTEPG);
- Segtabzeropte = (k0segtophys(Segtabzero) >> PGSHIFT) << PG_SHIFT;
- Segtabzeropte |= PG_V | PG_KRE | PG_KWE | PG_WIRED;
+ alpha_protection_init();
/*
- * Figure out how many PTE's are necessary to map the kernel.
- * The '512' comes from PAGER_MAP_SIZE in vm_pager_init().
- * This should be kept in sync.
- * We also reserve space for kmem_alloc_pageable() for vm_fork().
+ * Set ptes_per_vm_page for general use.
*/
- Sysmapsize = (VM_KMEM_SIZE + VM_MBUF_SIZE + VM_PHYS_SIZE +
- nbuf * MAXBSIZE + 16 * NCARGS) / NBPG + 512 + 256;
- Sysmapsize += maxproc * (btoc(ALPHA_STSIZE) + btoc(ALPHA_MAX_PTSIZE));
-
-#ifdef SYSVSHM
- Sysmapsize += shminfo.shmall;
-#endif
- Sysmapsize = roundup(Sysmapsize, NPTEPG);
+ ptes_per_vm_page = page_size / ALPHA_PGBYTES;
/*
- * Allocate a level 1 PTE table for the kernel.
- * This is always one page long.
- * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.
+ * The kernel's pmap is statically allocated so we don't
+ * have to use pmap_create, which is unlikely to work
+ * correctly at this part of the boot sequence.
*/
- valloc(Lev1map, pt_entry_t, NPTEPG);
+
+ kernel_pmap = &kernel_pmap_store;
+
+#if NCPUS > 1
+ lock_init(&pmap_system_lock, FALSE); /* NOT a sleep lock */
+#endif /* NCPUS > 1 */
+
+ simple_lock_init(&kernel_pmap->lock);
+
+ kernel_pmap->ref_count = 1;
/*
- * Allocate a level 2 PTE table for the kernel.
- * These must map all of the level3 PTEs.
- * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.
+ * Allocate the kernel page directory, and put its
+ * virtual address in root_kpdes.
+ *
+ * No other physical memory has been allocated.
*/
- Sysptmapsize = roundup(howmany(Sysmapsize, NPTEPG), NPTEPG);
- valloc(Sysptmap, pt_entry_t, Sysptmapsize);
- pmap_kernel()->pm_stab = Sysptmap;
+
+ vallocsz(root_kpdes, pt_entry_t *, PAGE_SIZE);
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: root_kpdes = %p\n", root_kpdes);
+ kernel_pmap->dirbase = root_kpdes;
+ kernel_pmap->dirpfn = alpha_btop(kvtophys((vm_offset_t)root_kpdes));
+
+ /* First, copy mappings for things below VM_MIN_KERNEL_ADDRESS */
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: setting up root_kpdes (copy 0x%lx)\n",
+ pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
+ bzero(root_kpdes, PAGE_SIZE);
+ bcopy((caddr_t)ptaddr, root_kpdes,
+ pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
/*
- * Allocate a level 3 PTE table for the kernel.
- * Contains Sysmapsize PTEs.
+ * Set up the virtual page table.
*/
- valloc(Sysmap, pt_entry_t, Sysmapsize);
- pmap_kernel()->pm_ptab = Sysmap;
+ pte_ktemplate(template, kvtophys(root_kpdes),
+ VM_PROT_READ | VM_PROT_WRITE);
+ template &= ~ALPHA_PTE_GLOBAL;
+ root_kpdes[pdenum(VPTBASE)] = template;
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: VPT PTE 0x%lx at 0x%lx)\n",
+ root_kpdes[pdenum(VPTBASE)], &root_kpdes[pdenum(VPTBASE)]);
+#if 0
/*
- * Allocate memory for page attributes.
- * allocates a few more entries than we need, but that's safe.
+ * Rid of console's default mappings
*/
- valloc(pmap_attributes, char, 1 + lastusablepage - firstusablepage);
+ for (pde = pmap_pde(kernel_pmap,0);
+ pde < pmap_pde(kernel_pmap,VM_MIN_KERNEL_ADDRESS);)
+ *pde++ = 0;
+#endif
/*
- * Allocate memory for pv_table.
- * This will allocate more entries than we really need.
- * We could do this in pmap_init when we know the actual
- * phys_start and phys_end but its better to use kseg0 addresses
- * rather than kernel virtual addresses mapped through the TLB.
+ * Allocate the seg2 kernel page table entries from the front
+ * of available physical memory. Take enough to cover all of
+ * the K2SEG range. But of course one page is enough for 8Gb,
+ * and more in future chips ...
*/
- i = 1 + lastusablepage - alpha_btop(k0segtophys(firstaddr));
- valloc(pv_table, struct pv_entry, i);
+#define enough_kseg2() (PAGE_SIZE)
+
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: allocating kvseg segment pages\n");
+ vallocsz(pte, pt_entry_t *, enough_kseg2()); /* virtual */
+ pa = kvtophys(pte); /* physical */
+ bzero(pte, enough_kseg2());
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: kvseg segment pages at %p\n", pte);
+
+#undef enough_kseg2
/*
- * Clear allocated memory.
+ * Make a note of it in the seg1 table
*/
- firstaddr = alpha_round_page(firstaddr);
- bzero((caddr_t)start, firstaddr - start);
+
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: inserting segment pages into root\n");
+ tbia();
+ pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
+ pde = pmap_pde(kernel_pmap,K2SEG_BASE);
+ i = ptes_per_vm_page;
+ do {
+ *pde++ = template;
+ pte_increment_pa(template);
+ i--;
+ } while (i > 0);
/*
- * Set up level 1 page table
+ * The kernel runs unmapped and cached (k0seg),
+ * only dynamic data are mapped in k1seg.
+ * ==> No need to map it.
*/
- /* First, copy mappings for things below VM_MIN_KERNEL_ADDRESS */
- bcopy((caddr_t)ptaddr, Lev1map,
- kvtol1pte(VM_MIN_KERNEL_ADDRESS) * sizeof Lev1map[0]);
-
- /* Second, map all of the level 2 pte pages */
- for (i = 0; i < howmany(Sysptmapsize, NPTEPG); i++) {
- pte = (k0segtophys(Sysptmap + (i*PAGE_SIZE)) >> PGSHIFT)
- << PG_SHIFT;
- pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
- Lev1map[kvtol1pte(VM_MIN_KERNEL_ADDRESS +
- (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
- }
-
- /* Finally, map the virtual page table */
- pte = (k0segtophys(Lev1map) >> PGSHIFT) << PG_SHIFT;
- pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
- Lev1map[kvtol1pte(VPTBASE)] = pte;
-
/*
- * Set up level 2 page table.
+ * But don't we need some seg2 pagetables to start with ?
*/
- /* Map all of the level 3 pte pages */
- for (i = 0; i < howmany(Sysmapsize, NPTEPG); i++) {
- pte = (k0segtophys(((caddr_t)Sysmap)+(i*PAGE_SIZE)) >> PGSHIFT)
- << PG_SHIFT;
- pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
- Sysptmap[vatoste(VM_MIN_KERNEL_ADDRESS+
- (i*PAGE_SIZE*NPTEPG))] = pte;
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: allocating kvseg page table pages\n");
+ pde = &pte[pte2num(K2SEG_BASE)];
+ for (i = pmap_kernel_vm; i > 0; i--) {
+ register int j;
+
+ vallocsz(pte, pt_entry_t *, PAGE_SIZE); /* virtual */
+ pa = kvtophys(pte); /* physical */
+ pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
+ bzero(pte, PAGE_SIZE);
+ j = ptes_per_vm_page;
+ do {
+ *pde++ = template;
+ pte_increment_pa(template);
+ } while (--j > 0);
}
/*
- * Set up level three page table (Sysmap)
+ * Fix up managed physical memory information.
*/
- /* Nothing to do; it's already zero'd */
-
- avail_start = k0segtophys(firstaddr);
-#if 1
+ avail_start = ALPHA_K0SEG_TO_PHYS(firstaddr);
avail_end = alpha_ptob(lastusablepage + 1);
mem_size = avail_end - avail_start;
-#else
- /* XXX why not lastusablepage + 1, & not include NBPG in mem_size? */
- avail_end = alpha_ptob(lastusablepage);
- mem_size = NBPG + avail_end - avail_start;
-#endif
-#if 0
- printf("avail_start = 0x%lx\n", avail_start);
- printf("avail_end = 0x%lx\n", avail_end);
- printf("mem_size = 0x%lx\n", mem_size);
-#endif
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n",
+ avail_start, avail_end, mem_size);
+
+ /*
+ * Allocate memory for the pv_head_table and its
+ * lock bits, and the reference/modify byte array.
+ */
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: allocating page management data\n");
+
+ npages = ((BYTE_SIZE * mem_size) /
+ (BYTE_SIZE * (PAGE_SIZE + sizeof (struct pv_entry) + 1) + 1));
+
+ valloc(pv_head_table, struct pv_entry, npages);
+ bzero(pv_head_table, sizeof (struct pv_entry) * npages);
- virtual_avail = VM_MIN_KERNEL_ADDRESS;
- virtual_end = VM_MIN_KERNEL_ADDRESS + Sysmapsize * NBPG;
+ valloc(pv_lock_table, char, pv_lock_table_size(npages));
+ bzero(pv_lock_table, pv_lock_table_size(npages));
- simple_lock_init(&pmap_kernel()->pm_lock);
- pmap_kernel()->pm_count = 1;
+ valloc(pmap_phys_attributes, char, npages);
+ bzero(pmap_phys_attributes, sizeof (char) * npages);
+
+ avail_start = alpha_round_page(ALPHA_K0SEG_TO_PHYS(firstaddr));
+ if (npages > pmap_free_pages())
+ panic("pmap_bootstrap");
+ mem_size = avail_end - avail_start;
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n",
+ avail_start, avail_end, mem_size);
/*
- * Set up curproc's (i.e. proc 0's) PCB such that the ptbr
- * points to the right place.
+ * Assert kernel limits (because of pmap_expand).
*/
- curproc->p_addr->u_pcb.pcb_ptbr = k0segtophys(Lev1map) >> PGSHIFT;
-}
-/*
- * Unmap the PROM mappings. PROM mappings are kept around
- * by pmap_bootstrap, so we can still use the prom's printf.
- * Basically, blow away all mappings in the level one PTE
- * table below VM_MIN_KERNEL_ADDRESS. The Virtual Page Table
- * Is at the end of virtual space, so it's safe.
- */
-void
-pmap_unmap_prom()
-{
- int i;
- extern int prom_mapped;
- extern pt_entry_t *rom_ptep, rom_pte;
+ virtual_avail = alpha_round_page(K2SEG_BASE);
+ virtual_end = trunc_page(K2SEG_BASE + pde2tova(pmap_kernel_vm));
+ if (DOVPDB(PDB_BOOTSTRAP)) {
+ printf("pmap_bootstrap: virtual_avail = %p\n", virtual_avail);
+ printf("pmap_bootstrap: virtual_end = %p\n", virtual_end);
+ }
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
- printf("pmap_unmap_prom\n");
-#endif
+ /*
+ * The distinguished tlbpid value of 0 is reserved for
+ * the kernel pmap. Initialize the tlbpid allocator,
+ * who knows about this.
+ */
+ kernel_pmap->pid = 0;
+ pmap_tlbpid_init(maxasn);
- /* XXX save old pte so that we can remap prom if necessary */
- rom_ptep = &Lev1map[0]; /* XXX */
- rom_pte = *rom_ptep & ~PG_ASM; /* XXX */
+ if (DOVPDB(PDB_BOOTSTRAP))
+ printf("pmap_bootstrap: leaving\n");
+}
- /* Mark all mappings before VM_MIN_KERNEL_ADDRESS as invalid. */
- bzero(Lev1map, kvtol1pte(VM_MIN_KERNEL_ADDRESS) * sizeof Lev1map[0]);
- prom_mapped = 0;
- TBIA();
+pmap_rid_of_console()
+{
+ pt_entry_t *pde;
+ /*
+ * Rid of console's default mappings
+ */
+ for (pde = pmap_pde(kernel_pmap,0L);
+ pde < pmap_pde(kernel_pmap,VM_MIN_KERNEL_ADDRESS);)
+ *pde++ = 0;
}
/*
@@ -470,13 +865,14 @@ pmap_unmap_prom()
* memory allocation until the virtual memory system has been bootstrapped.
* After that point, either kmem_alloc or malloc should be used. This
* function works by stealing pages from the (to be) managed page pool,
- * stealing virtual address space, then implicitly mapping the pages
- * (by using their k0seg addresses) and zeroing them.
+ * implicitly mapping them (by using their k0seg addresses),
+ * and zeroing them.
*
* It should be used from pmap_bootstrap till vm_page_startup, afterwards
* it cannot be used, and will generate a panic if tried. Note that this
* memory will never be freed, and in essence it is wired down.
*/
+
void *
pmap_bootstrap_alloc(size)
int size;
@@ -484,22 +880,58 @@ pmap_bootstrap_alloc(size)
vm_offset_t val;
extern boolean_t vm_page_startup_initialized;
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
+ if (DOPDB(PDB_FOLLOW|PDB_BOOTSTRAP_ALLOC))
printf("pmap_bootstrap_alloc(%lx)\n", size);
-#endif
if (vm_page_startup_initialized)
panic("pmap_bootstrap_alloc: called after startup initialized");
- val = phystok0seg(avail_start);
- size = round_page(size);
+ val = ALPHA_PHYS_TO_K0SEG(avail_start);
+ size = alpha_round_page(size);
avail_start += size;
+ if (avail_start > avail_end) /* sanity */
+ panic("pmap_bootstrap_alloc");
bzero((caddr_t)val, size);
+
+ if (DOVPDB(PDB_BOOTSTRAP_ALLOC))
+ printf("pmap_bootstrap_alloc: returns %p\n", val);
return ((void *)val);
}
/*
+ * Unmap the PROM mappings. PROM mappings are kept around
+ * by pmap_bootstrap, so we can still use the prom's printf.
+ * Basically, blow away all mappings in the level one PTE
+ * table below VM_MIN_KERNEL_ADDRESS. The Virtual Page Table
+ * Is at the end of virtual space, so it's safe.
+ */
+void
+pmap_unmap_prom()
+{
+ int i;
+ extern int prom_mapped;
+ extern pt_entry_t *rom_ptep, rom_pte;
+
+ if (DOPDB(PDB_FOLLOW|PDB_UNMAP_PROM))
+ printf("pmap_unmap_prom\n");
+
+ /* XXX save old pte so that we can remap prom if necessary */
+ rom_ptep = &root_kpdes[0]; /* XXX */
+ rom_pte = *rom_ptep & ~ALPHA_PTE_ASM; /* XXX */
+
+ if (DOVPDB(PDB_UNMAP_PROM))
+ printf("pmap_unmap_prom: zero 0x%lx, rom_pte was 0x%lx\n",
+ pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0],
+ rom_pte);
+ /* Mark all mappings before VM_MIN_KERNEL_ADDRESS as invalid. */
+ bzero(root_kpdes, pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
+ prom_mapped = 0;
+ ALPHA_TBIA();
+ if (DOVPDB(PDB_UNMAP_PROM))
+ printf("pmap_unmap_prom: leaving\n");
+}
+
+/*
* Initialize the pmap module.
* Called by vm_init, to initialize any structures that the pmap
* system needs to map virtual memory.
@@ -508,65 +940,121 @@ void
pmap_init(phys_start, phys_end)
vm_offset_t phys_start, phys_end;
{
- vm_offset_t addr, addr2;
- vm_size_t s;
-
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_init(%x, %x)\n", phys_start, phys_end);
-#endif
-
- /* initialize protection array */
- alpha_protection_init();
+ vm_size_t s;
+ int i;
/*
- * Allocate the segment table map
+ * Create the zone of physical maps,
+ * and of the physical-to-virtual entries.
*/
- s = maxproc * ALPHA_STSIZE;
- st_map = kmem_suballoc(kernel_map, &addr, &addr2, s, TRUE);
+#if 0
+ s = (vm_size_t) sizeof(struct pmap);
+ pmap_zone = zinit(s, 400*s, 4096, FALSE, "pmap"); /* XXX */
+ s = (vm_size_t) sizeof(struct pv_entry);
+ pv_list_zone = zinit(s, 10000*s, 4096, FALSE, "pv_list"); /* XXX */
+#endif
+#if NCPUS > 1
/*
- * Allocate the page table map
+ * Set up the pmap request lists
*/
- s = maxproc * ALPHA_MAX_PTSIZE; /* XXX limit it */
- pt_map = kmem_suballoc(kernel_map, &addr, &addr2, s, TRUE);
-
+ for (i = 0; i < NCPUS; i++) {
+ pmap_update_list_t up = &cpu_update_list[i];
+
+ simple_lock_init(&up->lock);
+ up->count = 0;
+ }
+
+ alpha_set_scb_entry( SCB_INTERPROC, pmap_update_interrupt);
+
+#endif /* NCPUS > 1 */
+
/*
- * Now it is safe to enable pv_table recording.
+ * Only now, when all of the data structures are allocated,
+ * can we set vm_first_phys and vm_last_phys. If we set them
+ * too soon, the kmem_alloc_wired above will try to use these
+ * data structures and blow up.
*/
+
vm_first_phys = phys_start;
vm_last_phys = phys_end;
-#if 0
- printf("vm_first_phys = 0x%lx\n", vm_first_phys);
- printf("vm_last_phys = 0x%lx\n", vm_last_phys);
-#endif
pmap_initialized = TRUE;
}
+#define pmap_valid_page(x) ((avail_start <= x) && (x < avail_end))
+#define valid_page(x) (pmap_initialized && pmap_valid_page(x))
+
/*
- * Used to map a range of physical addresses into kernel
- * virtual address space.
+ * Routine: pmap_page_table_page_alloc
+ *
+ * Allocates a new physical page to be used as a page-table page.
*
- * For now, VM is already on, we only need to map the
- * specified memory.
+ * Must be called with the pmap system and the pmap unlocked,
+ * since these must be unlocked to use vm_page_grab.
*/
vm_offset_t
-pmap_map(virt, start, end, prot)
- vm_offset_t virt;
- vm_offset_t start;
- vm_offset_t end;
- int prot;
+pmap_page_table_page_alloc()
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_map(%lx, %lx, %lx, %lx)\n", virt, start, end, prot);
-#endif
- while (start < end) {
- pmap_enter(pmap_kernel(), virt, start, prot, FALSE);
- virt += PAGE_SIZE;
- start += PAGE_SIZE;
- }
- return(virt);
+ register vm_page_t m;
+ register vm_offset_t pa;
+
+ check_simple_locks();
+
+ /*
+ * We cannot allocate the pmap_object in pmap_init,
+ * because it is called before the zone package is up.
+ * Allocate it now if it is missing.
+ */
+ if (pmap_object == VM_OBJECT_NULL)
+ pmap_object = vm_object_allocate(mem_size);
+
+ /*
+ * Allocate a VM page
+ */
+ while ((m = vm_page_grab()) == VM_PAGE_NULL)
+ vm_page_wait();
+
+ /*
+ * Map the page to its physical address so that it
+ * can be found later.
+ */
+ pa = m->phys_addr;
+ vm_object_lock(pmap_object);
+ vm_page_insert(m, pmap_object, pa);
+ vm_page_lock_queues();
+ vm_page_wire(m);
+ inuse_ptepages_count++;
+ vm_page_unlock_queues();
+ vm_object_unlock(pmap_object);
+
+ /*
+ * Zero the page.
+ */
+ bzero((void *)phystokv(pa), PAGE_SIZE);
+
+ return pa;
+}
+
+/*
+ * Deallocate a page-table page.
+ * The page-table page must have all mappings removed,
+ * and be removed from its page directory.
+ */
+void
+pmap_page_table_page_dealloc(pa)
+ vm_offset_t pa;
+{
+ vm_page_t m;
+
+ vm_object_lock(pmap_object);
+ m = vm_page_lookup(pmap_object, pa);
+ if (m == VM_PAGE_NULL)
+ panic("pmap_page_table_page_dealloc: page %#X not in object", pa);
+ vm_page_lock_queues();
+ vm_page_free(m);
+ inuse_ptepages_count--;
+ vm_page_unlock_queues();
+ vm_object_unlock(pmap_object);
}
/*
@@ -583,55 +1071,91 @@ pmap_map(virt, start, end, prot)
*/
pmap_t
pmap_create(size)
- vm_size_t size;
+ vm_size_t size;
{
- register pmap_t pmap;
+ register pmap_t p;
+
+ if (DOPDB(PDB_FOLLOW|PDB_CREATE))
+ printf("pmap_create(%d)\n", size);
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
- printf("pmap_create(%lx)\n", size);
-#endif
/*
- * Software use map does not need a pmap
+ * A software use-only map doesn't even need a map.
*/
- if (size)
- return(NULL);
+
+ if (size != 0) {
+ p = PMAP_NULL;
+ goto out;
+ }
/* XXX: is it ok to wait here? */
- pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK);
-#ifdef notifwewait
- if (pmap == NULL)
+ p = (pmap_t) malloc(sizeof *p, M_VMPMAP, M_WAITOK);
+ if (p == NULL)
panic("pmap_create: cannot allocate a pmap");
-#endif
- bzero(pmap, sizeof(*pmap));
- pmap_pinit(pmap);
- return (pmap);
+
+ bzero(p, sizeof (*p));
+ pmap_pinit(p);
+
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_CREATE))
+ printf("pmap_create: returning %p\n", p);
+ return (p);
}
-/*
- * Initialize a preallocated and zeroed pmap structure,
- * such as one in a vmspace structure.
- */
void
-pmap_pinit(pmap)
- register struct pmap *pmap;
+pmap_pinit(p)
+ struct pmap *p;
{
+ register pmap_statistics_t stats;
+ extern struct vmspace vmspace0;
+
+ if (DOPDB(PDB_FOLLOW|PDB_PINIT))
+ printf("pmap_init(%p)\n", p);
+
+#if 0
+ /* XXX cgd WHY NOT pmap_page_table_page_alloc()? */
+ p->dirbase = (void *)kmem_alloc(kernel_map, ALPHA_PGBYTES);
+#else
+ p->dirbase = (void *)phystokv(pmap_page_table_page_alloc());
+#endif
+ if (p->dirbase == NULL)
+ panic("pmap_create");
+ p->dirpfn = alpha_btop(pmap_resident_extract(kernel_pmap,
+ (vm_offset_t)p->dirbase));
+
+ if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
+ printf("pmap_init(%p): dirbase = %p, dirpfn = 0x%x\n", p,
+ p->dirbase, p->dirpfn);
+ aligned_block_copy(root_kpdes, p->dirbase, ALPHA_PGBYTES);
+ p->ref_count = 1;
+ p->pid = -1;
+ if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
+ printf("pmap_init(%p): first pde = 0x%lx\n", p->dirbase[0]);
+
+ {
+ pt_entry_t template;
+
+ pte_ktemplate(template, kvtophys(p->dirbase),
+ VM_PROT_READ | VM_PROT_WRITE);
+ template &= ~ALPHA_PTE_GLOBAL;
+ p->dirbase[pdenum(VPTBASE)] = template;
+ }
+printf("PMAP_PINIT: FIRST ENT = 0x%lx\n", p->dirbase[0]);
+
+ simple_lock_init(&p->lock);
+ p->cpus_using = 0;
+ p->hacking = 0;
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
- printf("pmap_pinit(%lx)\n", pmap);
-#endif
/*
- * No need to allocate page table space yet but we do need a
- * valid segment table. Initially, we point everyone at the
- * "null" segment table. On the first pmap_enter, a real
- * segment table will be allocated.
+ * Initialize statistics.
*/
- pmap->pm_stab = Segtabzero;
- pmap->pm_stpte = Segtabzeropte;
- pmap->pm_stchanged = TRUE;
- pmap->pm_count = 1;
- simple_lock_init(&pmap->pm_lock);
+
+ stats = &p->stats;
+ stats->resident_count = 0;
+ stats->wired_count = 0;
+
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
+ printf("pmap_init: leaving\n", p);
}
/*
@@ -639,270 +1163,550 @@ pmap_pinit(pmap)
* Should only be called if the map contains
* no valid mappings.
*/
-void
-pmap_destroy(pmap)
- register pmap_t pmap;
+
+void pmap_destroy(p)
+ register pmap_t p;
{
- int count;
+ register int c;
+ register spl_t s;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_destroy(%lx)\n", pmap);
-#endif
- if (pmap == NULL)
- return;
+ if (DOPDB(PDB_FOLLOW|PDB_DESTROY))
+ printf("pmap_destroy(%p)\n", p);
+
+ if (p == PMAP_NULL)
+ goto out;
- simple_lock(&pmap->pm_lock);
- count = --pmap->pm_count;
- simple_unlock(&pmap->pm_lock);
- if (count == 0) {
- pmap_release(pmap);
- free((caddr_t)pmap, M_VMPMAP);
+ SPLVM(s);
+ simple_lock(&p->lock);
+ c = --p->ref_count;
+ simple_unlock(&p->lock);
+ SPLX(s);
+
+ if (c == 0) {
+ pmap_release(p);
+ free(p, M_VMPMAP);
}
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_DESTROY))
+ printf("pmap_destroy: leaving\n");
}
-/*
- * Release any resources held by the given physical map.
- * Called when a pmap initialized by pmap_pinit is being released.
- * Should only be called if the map contains no valid mappings.
- */
void
-pmap_release(pmap)
- register struct pmap *pmap;
+pmap_release(p)
+ pmap_t p;
{
+ register pt_entry_t *pdep, *ptep, *eptep;
+ register vm_offset_t pa;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_release(%lx)\n", pmap);
-#endif
-#ifdef notdef /* DIAGNOSTIC */
- /* count would be 0 from pmap_destroy... */
- simple_lock(&pmap->pm_lock);
- if (pmap->pm_count != 1)
- panic("pmap_release count");
+ if (DOPDB(PDB_FOLLOW|PDB_RELEASE))
+ printf("pmap_release(%p)\n", p);
+
+ if (p->dirbase == NULL) {
+ if (DOPDB(PDB_FOLLOW|PDB_ANOMALOUS|PDB_RELEASE))
+ printf("pmap_release: already reclaimed\n");
+ /* resources already reclaimed */
+ goto out;
+ }
+
+ /*
+ * Free the memory maps, then the
+ * pmap structure.
+ */
+ for (pdep = p->dirbase;
+ pdep < pmap_pde(p,VM_MIN_KERNEL_ADDRESS);
+ pdep += ptes_per_vm_page) {
+ if (*pdep & ALPHA_PTE_VALID) {
+ pa = pte_to_pa(*pdep);
+
+ ptep = (pt_entry_t *)phystokv(pa);
+ eptep = ptep + NPTES;
+ for (; ptep < eptep; ptep += ptes_per_vm_page ) {
+ if (*ptep & ALPHA_PTE_VALID)
+ pmap_page_table_page_dealloc(pte_to_pa(*ptep));
+ }
+ pmap_page_table_page_dealloc(pa);
+ }
+ }
+ pmap_tlbpid_destroy(p->pid, FALSE);
+
+#if 0
+ kmem_free(kernel_map, (vm_offset_t)p->dirbase, ALPHA_PGBYTES);
+#else
+ pmap_page_table_page_dealloc(kvtophys(p->dirbase));
#endif
- if (pmap->pm_ptab)
- kmem_free_wakeup(pt_map, (vm_offset_t)pmap->pm_ptab,
- ALPHA_MAX_PTSIZE);
- if (pmap->pm_stab != Segtabzero)
- kmem_free_wakeup(st_map, (vm_offset_t)pmap->pm_stab,
- ALPHA_STSIZE);
+ p->dirbase = NULL;
+
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_RELEASE))
+ printf("pmap_release: leaving\n");
}
/*
* Add a reference to the specified pmap.
*/
-void
-pmap_reference(pmap)
- pmap_t pmap;
+
+void pmap_reference(p)
+ register pmap_t p;
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_reference(%lx)\n", pmap);
-#endif
- if (pmap != NULL) {
- simple_lock(&pmap->pm_lock);
- pmap->pm_count++;
- simple_unlock(&pmap->pm_lock);
+ spl_t s;
+ if (p != PMAP_NULL) {
+ SPLVM(s);
+ simple_lock(&p->lock);
+ p->ref_count++;
+ simple_unlock(&p->lock);
+ SPLX(s);
}
}
/*
- * Remove the given range of addresses from the specified map.
+ * Remove a range of hardware page-table entries.
+ * The entries given are the first (inclusive)
+ * and last (exclusive) entries for the VM pages.
+ * The virtual address is the va for the first pte.
*
- * It is assumed that the start and end are properly
- * rounded to the page size.
+ * The pmap must be locked.
+ * If the pmap is not the kernel pmap, the range must lie
+ * entirely within one pte-page. This is NOT checked.
+ * Assumes that the pte-page exists.
*/
-void
-pmap_remove(pmap, sva, eva)
- register pmap_t pmap;
- register vm_offset_t sva, eva;
+
+/* static */
+void pmap_remove_range(pmap, va, spte, epte)
+ pmap_t pmap;
+ vm_offset_t va;
+ pt_entry_t *spte;
+ pt_entry_t *epte;
{
- register vm_offset_t nssva;
- register pt_entry_t *pte;
- boolean_t firstpage, needcflush;
- int flags;
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
- printf("pmap_remove(%lx, %lx, %lx)\n", pmap, sva, eva);
-#endif
+ register pt_entry_t *cpte;
+ int num_removed, num_unwired;
+ int pai;
+ vm_offset_t pa;
- if (pmap == NULL)
- return;
+ num_removed = 0;
+ num_unwired = 0;
+
+ for (cpte = spte; cpte < epte;
+ cpte += ptes_per_vm_page, va += PAGE_SIZE) {
+
+ if (*cpte == 0)
+ continue;
+ pa = pte_to_pa(*cpte);
+
+ num_removed++;
+ if (*cpte & ALPHA_PTE_WIRED)
+ num_unwired++;
+
+ if (!valid_page(pa)) {
-#ifdef PMAPSTATS
- remove_stats.calls++;
-#endif
- firstpage = TRUE;
- needcflush = FALSE;
- flags = active_pmap(pmap) ? PRM_TFLUSH : 0;
- while (sva < eva) {
- nssva = alpha_trunc_seg(sva) + ALPHA_SEG_SIZE;
- if (nssva == 0 || nssva > eva)
- nssva = eva;
/*
- * If VA belongs to an unallocated segment,
- * skip to the next segment boundary.
+ * Outside range of managed physical memory.
+ * Just remove the mappings.
*/
- if (!pmap_ste_v(pmap, sva)) {
- sva = nssva;
- continue;
+ register int i = ptes_per_vm_page;
+ register pt_entry_t *lpte = cpte;
+ do {
+ *lpte = 0;
+ lpte++;
+ } while (--i > 0);
+ continue;
+ }
+
+ pai = pa_index(pa);
+ LOCK_PVH(pai);
+
+ /*
+ * Get the modify and reference bits.
+ */
+ {
+ register int i;
+ register pt_entry_t *lpte;
+
+ i = ptes_per_vm_page;
+ lpte = cpte;
+ do {
+ pmap_phys_attributes[pai] |= pte_get_attributes(lpte);
+ *lpte = 0;
+ lpte++;
+ } while (--i > 0);
+ }
+
+ /*
+ * Remove the mapping from the pvlist for
+ * this physical page.
+ */
+ {
+ register pv_entry_t pv_h, prev, cur;
+
+ pv_h = pai_to_pvh(pai);
+ if (pv_h->pmap == PMAP_NULL) {
+ panic("pmap_remove: null pv_list!");
}
- /*
- * Invalidate every valid mapping within this segment.
- */
- pte = pmap_pte(pmap, sva);
- while (sva < nssva) {
- if (pmap_pte_v(pte)) {
- pmap_remove_mapping(pmap, sva, pte, flags);
- firstpage = FALSE;
+ if (pv_h->va == va && pv_h->pmap == pmap) {
+ /*
+ * Header is the pv_entry. Copy the next one
+ * to header and free the next one (we cannot
+ * free the header)
+ */
+ cur = pv_h->next;
+ if (cur != PV_ENTRY_NULL) {
+ *pv_h = *cur;
+ PV_FREE(cur);
+ }
+ else {
+ pv_h->pmap = PMAP_NULL;
+ }
+ }
+ else {
+ cur = pv_h;
+ do {
+ prev = cur;
+ if ((cur = prev->next) == PV_ENTRY_NULL) {
+ panic("pmap-remove: mapping not in pv_list!");
}
- pte++;
- sva += PAGE_SIZE;
+ } while (cur->va != va || cur->pmap != pmap);
+ prev->next = cur->next;
+ PV_FREE(cur);
}
+ UNLOCK_PVH(pai);
+ }
}
+
/*
- * Didn't do anything, no need for cache flushes
+ * Update the counts
*/
- if (firstpage)
- return;
+ pmap->stats.resident_count -= num_removed;
+ pmap->stats.wired_count -= num_unwired;
}
/*
- * pmap_page_protect:
- *
- * Lower the permission for all mappings to a given page.
+ * One level up, iterate an operation on the
+ * virtual range va..eva, mapped by the 1st
+ * level pte spte.
*/
+
+/* static */
+void pmap_iterate_lev2(pmap, s, e, spte, operation)
+ pmap_t pmap;
+ vm_offset_t s, e;
+ pt_entry_t *spte;
+ void (*operation)();
+{
+ vm_offset_t l;
+ pt_entry_t *epte;
+ pt_entry_t *cpte;
+
+if (pmap_debug > 1) db_printf("iterate2(%x,%x,%x)", s, e, spte);
+ while (s < e) {
+ /* at most 1 << 23 virtuals per iteration */
+ l = roundup(s+1,PDE2_MAPPED_SIZE);
+ if (l > e)
+ l = e;
+ if (*spte & ALPHA_PTE_VALID) {
+ register int n;
+ cpte = (pt_entry_t *) ptetokv(*spte);
+ n = pte3num(l);
+ if (n == 0) n = SEG_MASK + 1;/* l == next segment up */
+ epte = &cpte[n];
+ cpte = &cpte[pte3num(s)];
+ assert(epte >= cpte);
+if (pmap_debug > 1) db_printf(" [%x %x, %x %x]", s, l, cpte, epte);
+ operation(pmap, s, cpte, epte);
+ }
+ s = l;
+ spte++;
+ }
+if (pmap_debug > 1) db_printf("\n");
+}
+
void
-pmap_page_protect(pa, prot)
- vm_offset_t pa;
- vm_prot_t prot;
+pmap_make_readonly(pmap, va, spte, epte)
+ pmap_t pmap;
+ vm_offset_t va;
+ pt_entry_t *spte;
+ pt_entry_t *epte;
{
- register pv_entry_t pv;
- int s;
+ while (spte < epte) {
+ if (*spte & ALPHA_PTE_VALID)
+ *spte &= ~ALPHA_PTE_WRITE;
+ spte++;
+ }
+}
-#ifdef DEBUG
- if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
- prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))
- printf("pmap_page_protect(%lx, %lx)\n", pa, prot);
-#endif
- if (!PAGE_IS_MANAGED(pa))
+/*
+ * Remove the given range of addresses
+ * from the specified map.
+ *
+ * It is assumed that the start and end are properly
+ * rounded to the hardware page size.
+ */
+vm_offset_t pmap_suspect_vs, pmap_suspect_ve;
+
+
+void pmap_remove(map, s, e)
+ pmap_t map;
+ vm_offset_t s, e;
+{
+ spl_t spl;
+ register pt_entry_t *pde;
+ register pt_entry_t *spte;
+ vm_offset_t l;
+
+ if (map == PMAP_NULL)
return;
+if (pmap_debug || ((s > pmap_suspect_vs) && (s < pmap_suspect_ve)))
+db_printf("[%d]pmap_remove(%x,%x,%x)\n", cpu_number(), map, s, e);
+ PMAP_READ_LOCK(map, spl);
+
+ /*
+ * Invalidate the translation buffer first
+ */
+ PMAP_UPDATE_TLBS(map, s, e);
+
+ pde = pmap_pde(map, s);
+ while (s < e) {
+ /* at most (1 << 33) virtuals per iteration */
+ l = roundup(s+1, PDE_MAPPED_SIZE);
+ if (l > e)
+ l = e;
+ if (*pde & ALPHA_PTE_VALID) {
+ spte = (pt_entry_t *)ptetokv(*pde);
+ spte = &spte[pte2num(s)];
+ pmap_iterate_lev2(map, s, l, spte, pmap_remove_range);
+ }
+ s = l;
+ pde++;
+ }
+
+ PMAP_READ_UNLOCK(map, spl);
+}
+
+/*
+ * Routine: pmap_page_protect
+ *
+ * Function:
+ * Lower the permission for all mappings to a given
+ * page.
+ */
+vm_offset_t pmap_suspect_phys;
+
+void pmap_page_protect(phys, prot)
+ vm_offset_t phys;
+ vm_prot_t prot;
+{
+ pv_entry_t pv_h, prev;
+ register pv_entry_t pv_e;
+ register pt_entry_t *pte;
+ int pai;
+ register pmap_t pmap;
+ spl_t spl;
+ boolean_t remove;
+
+if (pmap_debug || (phys == pmap_suspect_phys)) db_printf("pmap_page_protect(%x,%x)\n", phys, prot);
+
+ assert(phys != vm_page_fictitious_addr);
+ if (!valid_page(phys)) {
+ /*
+ * Not a managed page.
+ */
+ return;
+ }
+
+ /*
+ * Determine the new protection.
+ */
switch (prot) {
- case VM_PROT_READ|VM_PROT_WRITE:
- case VM_PROT_ALL:
- return;
- /* copy_on_write */
- case VM_PROT_READ:
- case VM_PROT_READ|VM_PROT_EXECUTE:
-/* XXX */ pmap_changebit(pa, PG_KWE | PG_UWE, FALSE);
- return;
- /* remove_all */
- default:
+ case VM_PROT_READ:
+ case VM_PROT_READ|VM_PROT_EXECUTE:
+ remove = FALSE;
+ break;
+ case VM_PROT_ALL:
+ return; /* nothing to do */
+ default:
+ remove = TRUE;
break;
}
- pv = pa_to_pvh(pa);
- s = splimp();
- while (pv->pv_pmap != NULL) {
- register pt_entry_t *pte;
-
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
-#ifdef DEBUG
- if (!pmap_ste_v(pv->pv_pmap, pv->pv_va) ||
- pmap_pte_pa(pte) != pa)
- panic("pmap_page_protect: bad mapping");
-#endif
- if (!pmap_pte_w(pte))
- pmap_remove_mapping(pv->pv_pmap, pv->pv_va,
- pte, PRM_TFLUSH|PRM_CFLUSH);
+
+ /*
+ * Lock the pmap system first, since we will be changing
+ * several pmaps.
+ */
+
+ PMAP_WRITE_LOCK(spl);
+
+ pai = pa_index(phys);
+ pv_h = pai_to_pvh(pai);
+
+ /*
+ * Walk down PV list, changing or removing all mappings.
+ * We do not have to lock the pv_list because we have
+ * the entire pmap system locked.
+ */
+ if (pv_h->pmap != PMAP_NULL) {
+
+ prev = pv_e = pv_h;
+ do {
+ pmap = pv_e->pmap;
+ /*
+ * Lock the pmap to block pmap_extract and similar routines.
+ */
+ simple_lock(&pmap->lock);
+
+ {
+ register vm_offset_t va;
+
+ va = pv_e->va;
+ pte = pmap_pte(pmap, va);
+
+ /*
+ * Consistency checks.
+ */
+ /* assert(*pte & ALPHA_PTE_VALID); XXX */
+ /* assert(pte_to_phys(*pte) == phys); */
+
+ /*
+ * Invalidate TLBs for all CPUs using this mapping.
+ */
+ PMAP_UPDATE_TLBS(pmap, va, va + PAGE_SIZE);
+ }
+
+ /*
+ * Remove the mapping if new protection is NONE
+ * or if write-protecting a kernel mapping.
+ */
+ if (remove || pmap == kernel_pmap) {
+ /*
+ * Remove the mapping, collecting any modify bits.
+ */
+ if (*pte & ALPHA_PTE_WIRED)
+ panic("pmap_remove_all removing a wired page");
+
+ {
+ register int i = ptes_per_vm_page;
+
+ do {
+ pmap_phys_attributes[pai] |= pte_get_attributes(pte);
+ *pte++ = 0;
+ } while (--i > 0);
+ }
+
+ pmap->stats.resident_count--;
+
+ /*
+ * Remove the pv_entry.
+ */
+ if (pv_e == pv_h) {
+ /*
+ * Fix up head later.
+ */
+ pv_h->pmap = PMAP_NULL;
+ }
+ else {
+ /*
+ * Delete this entry.
+ */
+ prev->next = pv_e->next;
+ PV_FREE(pv_e);
+ }
+ }
else {
- pv = pv->pv_next;
-#ifdef DEBUG
- if (pmapdebug & PDB_PARANOIA)
- printf("%s wired mapping for %lx not removed\n",
- "pmap_page_protect:", pa);
-#endif
+ /*
+ * Write-protect.
+ */
+ register int i = ptes_per_vm_page;
+
+ do {
+ *pte &= ~ALPHA_PTE_WRITE;
+ pte++;
+ } while (--i > 0);
+
+ /*
+ * Advance prev.
+ */
+ prev = pv_e;
}
+
+ simple_unlock(&pmap->lock);
+
+ } while ((pv_e = prev->next) != PV_ENTRY_NULL);
+
+ /*
+ * If pv_head mapping was removed, fix it up.
+ */
+ if (pv_h->pmap == PMAP_NULL) {
+ pv_e = pv_h->next;
+ if (pv_e != PV_ENTRY_NULL) {
+ *pv_h = *pv_e;
+ PV_FREE(pv_e);
+ }
+ }
}
- splx(s);
+
+ PMAP_WRITE_UNLOCK(spl);
}
/*
* Set the physical protection on the
* specified range of this map as requested.
+ * Will not increase permissions.
*/
-void
-pmap_protect(pmap, sva, eva, prot)
- register pmap_t pmap;
- register vm_offset_t sva, eva;
- vm_prot_t prot;
+void pmap_protect(map, s, e, prot)
+ pmap_t map;
+ vm_offset_t s, e;
+ vm_prot_t prot;
{
- register vm_offset_t nssva;
- register pt_entry_t *pte, bits;
- boolean_t firstpage, needtflush;
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
- printf("pmap_protect(%lx, %lx, %lx, %lx)\n", pmap, sva, eva, prot);
-#endif
+ register pt_entry_t *pde;
+ register pt_entry_t *spte, *epte;
+ vm_offset_t l;
+ spl_t spl;
- if (pmap == NULL)
+ if (map == PMAP_NULL)
return;
-#ifdef PMAPSTATS
- protect_stats.calls++;
-#endif
- if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
- pmap_remove(pmap, sva, eva);
+if (pmap_debug || ((s > pmap_suspect_vs) && (s < pmap_suspect_ve)))
+db_printf("[%d]pmap_protect(%x,%x,%x,%x)\n", cpu_number(), map, s, e, prot);
+ /*
+ * Determine the new protection.
+ */
+ switch (prot) {
+ case VM_PROT_READ|VM_PROT_EXECUTE:
+ alphacache_Iflush();
+ case VM_PROT_READ:
+ break;
+ case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
+ alphacache_Iflush();
+ case VM_PROT_READ|VM_PROT_WRITE:
+ return; /* nothing to do */
+ default:
+ pmap_remove(map, s, e);
return;
}
- if (prot & VM_PROT_WRITE)
- return;
- bits = pte_prot(pmap, prot);
- needtflush = active_pmap(pmap);
- firstpage = TRUE;
- while (sva < eva) {
- nssva = alpha_trunc_seg(sva) + ALPHA_SEG_SIZE;
- if (nssva == 0 || nssva > eva)
- nssva = eva;
- /*
- * If VA belongs to an unallocated segment,
- * skip to the next segment boundary.
- */
- if (!pmap_ste_v(pmap, sva)) {
- sva = nssva;
- continue;
- }
- /*
- * Change protection on mapping if it is valid and doesn't
- * already have the correct protection.
- */
- pte = pmap_pte(pmap, sva);
- while (sva < nssva) {
- if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, bits)) {
- pmap_pte_set_prot(pte, bits);
- if (needtflush)
- TBIS((caddr_t)sva);
-#ifdef PMAPSTATS
- protect_stats.changed++;
-#endif
- firstpage = FALSE;
- }
-#ifdef PMAPSTATS
- else if (pmap_pte_v(pte)) {
- if (isro)
- protect_stats.alreadyro++;
- else
- protect_stats.alreadyrw++;
- }
-#endif
- pte++;
- sva += PAGE_SIZE;
- }
+ SPLVM(spl);
+ simple_lock(&map->lock);
+
+ /*
+ * Invalidate the translation buffer first
+ */
+ PMAP_UPDATE_TLBS(map, s, e);
+
+ pde = pmap_pde(map, s);
+ while (s < e) {
+ /* at most (1 << 33) virtuals per iteration */
+ l = roundup(s+1, PDE_MAPPED_SIZE);
+ if (l > e)
+ l = e;
+ if (*pde & ALPHA_PTE_VALID) {
+ spte = (pt_entry_t *)ptetokv(*pde);
+ spte = &spte[pte2num(s)];
+ pmap_iterate_lev2(map, s, l, spte, pmap_make_readonly);
+ }
+ s = l;
+ pde++;
}
+
+ simple_unlock(&map->lock);
+ SPLX(spl);
}
/*
@@ -918,222 +1722,225 @@ pmap_protect(pmap, sva, eva, prot)
* insert this page into the given map NOW.
*/
void
-pmap_enter(pmap, va, pa, prot, wired)
- register pmap_t pmap;
- vm_offset_t va;
- register vm_offset_t pa;
- vm_prot_t prot;
- boolean_t wired;
+pmap_enter(pmap, v, pa, prot, wired)
+ register pmap_t pmap;
+ vm_offset_t v;
+ register vm_offset_t pa;
+ vm_prot_t prot;
+ boolean_t wired;
{
- register pt_entry_t *pte;
- register pt_entry_t npte;
- vm_offset_t opa;
- boolean_t checkpv = TRUE;
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
- printf("pmap_enter(%lx, %lx, %lx, %lx, %lx)\n",
- pmap, va, pa, prot, wired);
-#endif
- if (pmap == NULL)
- return;
+ register pt_entry_t *pte;
+ register pv_entry_t pv_h;
+ register int i, pai;
+ pv_entry_t pv_e;
+ pt_entry_t template;
+ spl_t spl;
+ vm_offset_t old_pa;
+
+ if (DOPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, %d)\n",
+ pmap, v, pa, prot, wired);
+
+ assert(pa != vm_page_fictitious_addr);
+if (pmap_debug || ((v > pmap_suspect_vs) && (v < pmap_suspect_ve)))
+db_printf("[%d]pmap_enter(%x(%d), %x, %x, %x, %x)\n", cpu_number(), pmap, pmap->pid, v, pa, prot, wired);
+ if (pmap == PMAP_NULL)
+ goto out;
+ assert(!pmap_max_asn || pmap->pid >= 0);
-#ifdef PMAPSTATS
- if (pmap == pmap_kernel())
- enter_stats.kernel++;
- else
- enter_stats.user++;
-#endif
/*
- * For user mapping, allocate kernel VM resources if necessary.
+ * Must allocate a new pvlist entry while we're unlocked;
+ * zalloc may cause pageout (which will lock the pmap system).
+ * If we determine we need a pvlist entry, we will unlock
+ * and allocate one. Then we will retry, throwing away
+ * the allocated entry later (if we no longer need it).
*/
- if (pmap->pm_ptab == NULL)
- pmap->pm_ptab = (pt_entry_t *)
- kmem_alloc_wait(pt_map, ALPHA_MAX_PTSIZE);
- /*
- * Segment table entry not valid, we need a new PT page
- */
- if (!pmap_ste_v(pmap, va))
- pmap_enter_ptpage(pmap, va);
-
- pa = alpha_trunc_page(pa);
- pte = pmap_pte(pmap, va);
- opa = pmap_pte_pa(pte);
-#ifdef DEBUG
- if (pmapdebug & PDB_ENTER)
- printf("enter: pte %lx, *pte %lx\n", pte, *pte);
-#endif
+ pv_e = PV_ENTRY_NULL;
+Retry:
+ PMAP_READ_LOCK(pmap, spl);
/*
- * Mapping has not changed, must be protection or wiring change.
+ * Expand pmap to include this pte. Assume that
+ * pmap is always expanded to include enough hardware
+ * pages to map one VM page.
*/
- if (opa == pa) {
-#ifdef PMAPSTATS
- enter_stats.pwchange++;
-#endif
- /*
- * Wiring change, just update stats.
- * We don't worry about wiring PT pages as they remain
- * resident as long as there are valid mappings in them.
- * Hence, if a user page is wired, the PT page will be also.
- */
- if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
-#ifdef DEBUG
- if (pmapdebug & PDB_ENTER)
- printf("enter: wiring change -> %lx\n", wired);
-#endif
- if (wired)
- pmap->pm_stats.wired_count++;
- else
- pmap->pm_stats.wired_count--;
-#ifdef PMAPSTATS
- if (pmap_pte_prot(pte) == pte_prot(pmap, prot))
- enter_stats.wchange++;
-#endif
- }
-#ifdef PMAPSTATS
- else if (pmap_pte_prot(pte) != pte_prot(pmap, prot))
- enter_stats.pchange++;
- else
- enter_stats.nochange++;
-#endif
+
+ while ((pte = pmap_pte(pmap, v)) == PT_ENTRY_NULL) {
/*
- * Retain cache inhibition status
+ * Must unlock to expand the pmap.
*/
- checkpv = FALSE;
- goto validate;
+ PMAP_READ_UNLOCK(pmap, spl);
+
+ pmap_expand(pmap, v);
+
+ PMAP_READ_LOCK(pmap, spl);
}
/*
- * Mapping has changed, invalidate old range and fall through to
- * handle validating new mapping.
+ * Special case if the physical page is already mapped
+ * at this address.
*/
- if (opa) {
-#ifdef DEBUG
- if (pmapdebug & PDB_ENTER)
- printf("enter: removing old mapping %lx\n", va);
-#endif
- pmap_remove_mapping(pmap, va, pte, PRM_TFLUSH|PRM_CFLUSH);
-#ifdef PMAPSTATS
- enter_stats.mchange++;
-#endif
+ old_pa = pte_to_pa(*pte);
+ if (*pte && old_pa == pa) {
+ /*
+ * May be changing its wired attribute or protection
+ */
+
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: same PA already mapped there (0x%lx)\n",
+ *pte);
+
+ if (wired && !(*pte & ALPHA_PTE_WIRED))
+ pmap->stats.wired_count++;
+ else if (!wired && (*pte & ALPHA_PTE_WIRED))
+ pmap->stats.wired_count--;
+
+ pte_template(pmap,template,pa,prot);
+ if (pmap == kernel_pmap)
+ template |= ALPHA_PTE_GLOBAL;
+ if (wired)
+ template |= ALPHA_PTE_WIRED;
+ PMAP_UPDATE_TLBS(pmap, v, v + PAGE_SIZE);
+ i = ptes_per_vm_page;
+ do {
+ template |= (*pte & ALPHA_PTE_MOD);
+ *pte = template;
+ pte++;
+ pte_increment_pa(template);
+ } while (--i > 0);
}
+ else {
- /*
- * If this is a new user mapping, increment the wiring count
- * on this PT page. PT pages are wired down as long as there
- * is a valid mapping in the page.
- */
- if (pmap != pmap_kernel())
- (void) vm_map_pageable(pt_map, trunc_page(pte),
- round_page(pte+1), FALSE);
+ /*
+ * Remove old mapping from the PV list if necessary.
+ */
+ if (*pte) {
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: removing old PTE (0x%lx)\n", *pte);
- /*
- * Enter on the PV list if part of our managed memory
- * Note that we raise IPL while manipulating pv_table
- * since pmap_enter can be called at interrupt time.
- */
- if (PAGE_IS_MANAGED(pa)) {
- register pv_entry_t pv, npv;
- int s;
+ /*
+ * Invalidate the translation buffer,
+ * then remove the mapping.
+ */
+ PMAP_UPDATE_TLBS(pmap, v, v + PAGE_SIZE);
-#ifdef PMAPSTATS
- enter_stats.managed++;
-#endif
- pv = pa_to_pvh(pa);
- s = splimp();
-#ifdef DEBUG
- if (pmapdebug & PDB_ENTER)
- printf("enter: pv at %lx: %lx/%lx/%lx\n",
- pv, pv->pv_va, pv->pv_pmap, pv->pv_next);
-#endif
/*
- * No entries yet, use header as the first entry
+ * Don't free the pte page if removing last
+ * mapping - we will immediately replace it.
*/
- if (pv->pv_pmap == NULL) {
-#ifdef PMAPSTATS
- enter_stats.firstpv++;
-#endif
- pv->pv_va = va;
- pv->pv_pmap = pmap;
- pv->pv_next = NULL;
- pv->pv_ptpte = NULL;
- pv->pv_ptpmap = NULL;
- pv->pv_flags = 0;
- }
+ pmap_remove_range(pmap, v, pte,
+ pte + ptes_per_vm_page);
+ }
+
+ if (valid_page(pa)) {
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: valid page\n");
+
/*
- * There is at least one other VA mapping this page.
- * Place this entry after the header.
+ * Enter the mapping in the PV list for this
+ * physical page.
*/
+
+ pai = pa_index(pa);
+ LOCK_PVH(pai);
+ pv_h = pai_to_pvh(pai);
+
+ if (pv_h->pmap == PMAP_NULL) {
+ /*
+ * No mappings yet
+ */
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: first mapping\n");
+ pv_h->va = v;
+ pv_h->pmap = pmap;
+ pv_h->next = PV_ENTRY_NULL;
+ if (prot & VM_PROT_EXECUTE)
+ alphacache_Iflush();
+ }
else {
-#ifdef DEBUG
- for (npv = pv; npv; npv = npv->pv_next)
- if (pmap == npv->pv_pmap && va == npv->pv_va)
- panic("pmap_enter: already in pv_tab");
-#endif
- npv = (pv_entry_t)
- malloc(sizeof *npv, M_VMPVENT, M_NOWAIT);
- npv->pv_va = va;
- npv->pv_pmap = pmap;
- npv->pv_next = pv->pv_next;
- npv->pv_ptpte = NULL;
- npv->pv_ptpmap = NULL;
- npv->pv_flags = 0;
- pv->pv_next = npv;
-#ifdef PMAPSTATS
- if (!npv->pv_next)
- enter_stats.secondpv++;
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: second+ mapping\n");
+
+#if DEBUG
+ {
+ /* check that this mapping is not already there */
+ pv_entry_t e = pv_h;
+ while (e != PV_ENTRY_NULL) {
+ if (e->pmap == pmap && e->va == v)
+ panic("pmap_enter: already in pv_list");
+ e = e->next;
+ }
+ }
+#endif /* DEBUG */
+
+ /*
+ * Add new pv_entry after header.
+ */
+ if (pv_e == PV_ENTRY_NULL) {
+ pv_e = pmap_alloc_pv();
+#if 0
+ PV_ALLOC(pv_e);
+ if (pv_e == PV_ENTRY_NULL) {
+ UNLOCK_PVH(pai);
+ PMAP_READ_UNLOCK(pmap, spl);
+
+ /*
+ * Refill from zone.
+ */
+ pv_e = (pv_entry_t) zalloc(pv_list_zone);
+ goto Retry;
+ }
#endif
+ }
+ pv_e->va = v;
+ pv_e->pmap = pmap;
+ pv_e->next = pv_h->next;
+ pv_h->next = pv_e;
+ /*
+ * Remember that we used the pvlist entry.
+ */
+ pv_e = PV_ENTRY_NULL;
}
- splx(s);
- }
- /*
- * Assumption: if it is not part of our managed memory
- * then it must be device memory which may be volitile.
- */
- else if (pmap_initialized) {
- checkpv = FALSE;
-#ifdef PMAPSTATS
- enter_stats.unmanaged++;
-#endif
+ UNLOCK_PVH(pai);
+ }
+
+ /*
+ * And count the mapping.
+ */
+
+ pmap->stats.resident_count++;
+ if (wired)
+ pmap->stats.wired_count++;
+
+ /*
+ * Build a template to speed up entering -
+ * only the pfn changes.
+ */
+ pte_template(pmap,template,pa,prot);
+ if (pmap == kernel_pmap)
+ template |= ALPHA_PTE_GLOBAL;
+ if (wired)
+ template |= ALPHA_PTE_WIRED;
+ i = ptes_per_vm_page;
+ do {
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: entering PTE 0x%lx at %p\n",
+ template, pte);
+ *pte = template;
+ pte++;
+ pte_increment_pa(template);
+ } while (--i > 0);
+ ALPHA_TBIA();
}
- /*
- * Increment counters
- */
- pmap->pm_stats.resident_count++;
- if (wired)
- pmap->pm_stats.wired_count++;
-
-validate:
- /*
- * Build the new PTE.
- */
- npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
- if (PAGE_IS_MANAGED(pa)) {
- if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) == 0)
- npte |= PG_FOR | PG_FOW | PG_FOE;
- else if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) == 0)
- npte |= PG_FOW;
+ if (pv_e != PV_ENTRY_NULL) {
+ PV_FREE(pv_e);
}
- if (wired)
- npte |= PG_WIRED;
-#ifdef DEBUG
- if (pmapdebug & PDB_ENTER)
- printf("enter: new pte value %lx\n", npte);
-#endif
- /*
- * Remember if this was a wiring-only change.
- * If so, we need not flush the TLB and caches.
- */
- wired = ((*pte ^ npte) == PG_WIRED);
- *pte = npte;
- if (!wired && active_pmap(pmap))
- TBIS((caddr_t)va);
-#ifdef DEBUG
- if ((pmapdebug & PDB_WIRING) && pmap != pmap_kernel())
- pmap_check_wiring("enter", trunc_page(pmap_pte(pmap, va)));
-#endif
+
+ PMAP_READ_UNLOCK(pmap, spl);
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter: done\n");
}
/*
@@ -1143,54 +1950,47 @@ validate:
* In/out conditions:
* The mapping must already exist in the pmap.
*/
-void
-pmap_change_wiring(pmap, va, wired)
- register pmap_t pmap;
- vm_offset_t va;
+void pmap_change_wiring(map, v, wired)
+ register pmap_t map;
+ vm_offset_t v;
boolean_t wired;
{
- register pt_entry_t *pte;
-
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_change_wiring(%lx, %lx, %lx)\n", pmap, va, wired);
-#endif
- if (pmap == NULL)
- return;
+ register pt_entry_t *pte;
+ register int i;
+ spl_t spl;
- pte = pmap_pte(pmap, va);
-#ifdef DEBUG
- /*
- * Page table page is not allocated.
- * Should this ever happen? Ignore it for now,
- * we don't want to force allocation of unnecessary PTE pages.
- */
- if (!pmap_ste_v(pmap, va)) {
- if (pmapdebug & PDB_PARANOIA)
- printf("pmap_change_wiring: invalid STE for %lx\n", va);
- return;
- }
+if (pmap_debug) db_printf("pmap_change_wiring(%x,%x,%x)\n", map, v, wired);
/*
- * Page not valid. Should this ever happen?
- * Just continue and change wiring anyway.
+ * We must grab the pmap system lock because we may
+ * change a pte_page queue.
*/
- if (!pmap_pte_v(pte)) {
- if (pmapdebug & PDB_PARANOIA)
- printf("pmap_change_wiring: invalid PTE for %lx\n", va);
+ PMAP_READ_LOCK(map, spl);
+
+ if ((pte = pmap_pte(map, v)) == PT_ENTRY_NULL)
+ panic("pmap_change_wiring: pte missing");
+
+ if (wired && !(*pte & ALPHA_PTE_WIRED)) {
+ /*
+ * wiring down mapping
+ */
+ map->stats.wired_count++;
+ i = ptes_per_vm_page;
+ do {
+ *pte++ |= ALPHA_PTE_WIRED;
+ } while (--i > 0);
}
-#endif
- /*
- * If wiring actually changed (always?) set the wire bit and
- * update the wire count. Note that wiring is not a hardware
- * characteristic so there is no need to invalidate the TLB.
- */
- if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
- pmap_pte_set_w(pte, wired);
- if (wired)
- pmap->pm_stats.wired_count++;
- else
- pmap->pm_stats.wired_count--;
+ else if (!wired && (*pte & ALPHA_PTE_WIRED)) {
+ /*
+ * unwiring mapping
+ */
+ map->stats.wired_count--;
+ i = ptes_per_vm_page;
+ do {
+ *pte &= ~ALPHA_PTE_WIRED;
+ } while (--i > 0);
}
+
+ PMAP_READ_UNLOCK(map, spl);
}
/*
@@ -1203,36 +2003,207 @@ pmap_change_wiring(pmap, va, wired)
vm_offset_t
pmap_extract(pmap, va)
register pmap_t pmap;
- vm_offset_t va;
+ vm_offset_t va;
{
- pt_entry_t pte;
- register vm_offset_t pa;
+ register pt_entry_t *pte;
+ register vm_offset_t pa;
+ spl_t spl;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_extract(%lx, %lx) -> ", pmap, va);
-#endif
- pa = 0;
- if (pmap && pmap_ste_v(pmap, va)) {
- pte = *pmap_pte(pmap, va);
- if (pte & PG_V)
- pa = ctob(PG_PFNUM(pte)) | (va & PGOFSET);
+ if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
+ printf("pmap_extract(%p, 0x%lx)\n", pmap, va);
+
+ /*
+ * Special translation for kernel addresses in
+ * K0 space (directly mapped to physical addresses).
+ */
+ if (ISA_K0SEG(va)) {
+ pa = K0SEG_TO_PHYS(va);
+ if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
+ printf("pmap_extract: returns 0x%lx\n", pa);
+ goto out;
}
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("%lx\n", pa);
-#endif
+ SPLVM(spl);
+ simple_lock(&pmap->lock);
+ if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
+ pa = (vm_offset_t) 0;
+ else if (!(*pte & ALPHA_PTE_VALID))
+ pa = (vm_offset_t) 0;
+ else
+ pa = pte_to_pa(*pte) + (va & ALPHA_OFFMASK);
+ simple_unlock(&pmap->lock);
+
+ /*
+ * Beware: this puts back this thread in the cpus_active set
+ */
+ SPLX(spl);
+
+out:
+ if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
+ printf("pmap_extract: returns 0x%lx\n", pa);
+ return(pa);
+}
+
+vm_offset_t
+pmap_resident_extract(pmap, va)
+ register pmap_t pmap;
+ vm_offset_t va;
+{
+ register pt_entry_t *pte;
+ register vm_offset_t pa;
+
+ /*
+ * Special translation for kernel addresses in
+ * K0 space (directly mapped to physical addresses).
+ */
+ if (ISA_K0SEG(va)) {
+ pa = K0SEG_TO_PHYS(va);
+ goto out;
+ }
+
+ if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
+ pa = (vm_offset_t) 0;
+ else if (!(*pte & ALPHA_PTE_VALID))
+ pa = (vm_offset_t) 0;
+ else
+ pa = pte_to_pa(*pte) + (va & ALPHA_OFFMASK);
+
+out:
return(pa);
}
/*
+ * Routine: pmap_expand
+ *
+ * Expands a pmap to be able to map the specified virtual address.
+ *
+ * Must be called with the pmap system and the pmap unlocked,
+ * since these must be unlocked to use vm_page_grab.
+ * Thus it must be called in a loop that checks whether the map
+ * has been expanded enough.
+ */
+void
+pmap_expand(map, v)
+ register pmap_t map;
+ register vm_offset_t v;
+{
+ pt_entry_t template;
+ pt_entry_t *pdp;
+ register vm_page_t m;
+ register vm_offset_t pa;
+ register int i;
+ spl_t spl;
+
+ if (DOPDB(PDB_FOLLOW|PDB_EXPAND))
+ printf("pmap_expand(%p, 0x%lx)\n", map, v);
+
+ /* Would have to go through all maps to add this page */
+ if (map == kernel_pmap)
+ panic("pmap_expand");
+
+ /*
+ * Allocate a VM page for the level 2 page table entries,
+ * if not already there.
+ */
+ pdp = pmap_pde(map,v);
+ if ((*pdp & ALPHA_PTE_VALID) == 0) {
+ pt_entry_t *pte;
+
+ if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
+ printf("pmap_expand: needs pde\n");
+
+ pa = pmap_page_table_page_alloc();
+
+ /*
+ * Re-lock the pmap and check that another thread has
+ * not already allocated the page-table page. If it
+ * has, discard the new page-table page (and try
+ * again to make sure).
+ */
+ PMAP_READ_LOCK(map, spl);
+
+ if (*pdp & ALPHA_PTE_VALID) {
+ /*
+ * Oops...
+ */
+ PMAP_READ_UNLOCK(map, spl);
+ pmap_page_table_page_dealloc(pa);
+ return;
+ }
+
+ /*
+ * Map the page.
+ */
+ i = ptes_per_vm_page;
+ pte = pdp;
+ pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
+ if (map != kernel_pmap)
+ template &= ~ALPHA_PTE_ASM;
+ do {
+ *pte = template;
+ if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
+ printf("pmap_expand: inserted l1 pte (0x%lx) at %p\n",
+ template, pte);
+ pte++;
+ pte_increment_pa(template);
+ } while (--i > 0);
+ PMAP_READ_UNLOCK(map, spl);
+ }
+
+ /*
+ * Allocate a level 3 page table.
+ */
+
+ pa = pmap_page_table_page_alloc();
+
+ /*
+ * Re-lock the pmap and check that another thread has
+ * not already allocated the page-table page. If it
+ * has, we are done.
+ */
+ PMAP_READ_LOCK(map, spl);
+
+ if (pmap_pte(map, v) != PT_ENTRY_NULL) {
+ PMAP_READ_UNLOCK(map, spl);
+ pmap_page_table_page_dealloc(pa);
+ return;
+ }
+
+ /*
+ * Set the page directory entry for this page table.
+ * If we have allocated more than one hardware page,
+ * set several page directory entries.
+ */
+ i = ptes_per_vm_page;
+ pdp = (pt_entry_t *)ptetokv(*pdp);
+ pdp = &pdp[pte2num(v)];
+ pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
+ if (map != kernel_pmap)
+ template &= ~ALPHA_PTE_ASM;
+ do {
+ *pdp = template;
+ if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
+ printf("pmap_expand: inserted l2 pte (0x%lx) at %p\n",
+ template, pdp);
+ pdp++;
+ pte_increment_pa(template);
+ } while (--i > 0);
+ PMAP_READ_UNLOCK(map, spl);
+
+out:
+ if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
+ printf("pmap_expand: leaving\n");
+ return;
+}
+
+/*
* Copy the range specified by src_addr/len
* from the source map to the range dst_addr/len
* in the destination map.
*
* This routine is only advisory and need not do anything.
*/
+#if 0
void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
pmap_t dst_pmap;
pmap_t src_pmap;
@@ -1240,29 +2211,11 @@ void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
vm_size_t len;
vm_offset_t src_addr;
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_copy(%lx, %lx, %lx, %lx, %lx)\n",
- dst_pmap, src_pmap, dst_addr, len, src_addr);
-#endif
+#ifdef lint
+ dst_pmap++; src_pmap++; dst_addr++; len++; src_addr++;
+#endif /* lint */
}
-
-/*
- * Require that all active physical maps contain no
- * incorrect entries NOW. [This update includes
- * forcing updates of any address map caching.]
- *
- * Generally used to insure that a thread about
- * to run will see a semantically correct world.
- */
-void pmap_update()
-{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_update()\n");
#endif
- TBIA();
-}
/*
* Routine: pmap_collect
@@ -1275,176 +2228,216 @@ void pmap_update()
* Usage:
* Called by the pageout daemon when pages are scarce.
*/
-void
-pmap_collect(pmap)
- pmap_t pmap;
+void pmap_collect(p)
+ pmap_t p;
{
- register vm_offset_t pa;
- register pv_entry_t pv;
- register pt_entry_t *pte;
- vm_offset_t kpa;
- int s;
-
-#ifdef DEBUG
- pt_entry_t *ste;
- int opmapdebug;
-#endif
- if (pmap != pmap_kernel())
+#if notyet
+
+ register pt_entry_t *pdp, *ptp;
+ pt_entry_t *eptp;
+ vm_offset_t pa;
+ spl_t spl;
+ int wired;
+
+ if (p == PMAP_NULL)
return;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_collect(%lx)\n", pmap);
-#endif
-#ifdef PMAPSTATS
- kpt_stats.collectscans++;
-#endif
- s = splimp();
- for (pa = vm_first_phys; pa < vm_last_phys; pa += PAGE_SIZE) {
- register struct kpt_page *kpt, **pkpt;
+ if (p == kernel_pmap)
+ return;
- /*
- * Locate physical pages which are being used as kernel
- * page table pages.
- */
- pv = pa_to_pvh(pa);
- if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
- continue;
- do {
- if (pv->pv_ptpte && pv->pv_ptpmap == pmap_kernel())
- break;
- } while (pv = pv->pv_next);
- if (pv == NULL)
- continue;
-#ifdef DEBUG
- if (pv->pv_va < (vm_offset_t)Sysmap ||
- pv->pv_va >= (vm_offset_t)Sysmap + ALPHA_MAX_PTSIZE)
- printf("collect: kernel PT VA out of range\n");
- else
- goto ok;
- pmap_pvdump(pa);
- continue;
-ok:
-#endif
- pte = (pt_entry_t *)(pv->pv_va + ALPHA_PAGE_SIZE);
- while (--pte >= (pt_entry_t *)pv->pv_va && *pte == PG_NV)
- ;
- if (pte >= (pt_entry_t *)pv->pv_va)
- continue;
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) {
- printf("collect: freeing KPT page at %lx (ste %lx@%lx)\n",
- pv->pv_va, *pv->pv_ptpte, pv->pv_ptpte);
- opmapdebug = pmapdebug;
- pmapdebug |= PDB_PTPAGE;
- }
+ /*
+ * Garbage collect map.
+ */
+ PMAP_READ_LOCK(p, spl);
+ PMAP_UPDATE_TLBS(p, VM_MIN_ADDRESS, VM_MAX_ADDRESS);
+ pmap_tlbpid_destroy(p->pid, FALSE);
+
+ for (pdp = p->dirbase;
+ pdp < pmap_pde(p,VM_MIN_KERNEL_ADDRESS);
+ pdp += ptes_per_vm_page)
+ {
+ if (*pdp & ALPHA_PTE_VALID) {
+
+ pa = pte_to_pa(*pdp);
+ ptp = (pt_entry_t *)phystokv(pa);
+ eptp = ptp + NPTES*ptes_per_vm_page;
- ste = pv->pv_ptpte;
-#endif
- /*
- * If all entries were invalid we can remove the page.
- * We call pmap_remove_entry to take care of invalidating
- * ST and Sysptmap entries.
- */
- kpa = pmap_extract(pmap, pv->pv_va);
- pmap_remove_mapping(pmap, pv->pv_va, PT_ENTRY_NULL,
- PRM_TFLUSH|PRM_CFLUSH);
/*
- * Use the physical address to locate the original
- * (kmem_alloc assigned) address for the page and put
- * that page back on the free list.
+ * If the pte page has any wired mappings, we cannot
+ * free it.
*/
- for (pkpt = &kpt_used_list, kpt = *pkpt;
- kpt != (struct kpt_page *)0;
- pkpt = &kpt->kpt_next, kpt = *pkpt)
- if (kpt->kpt_pa == kpa)
- break;
-#ifdef DEBUG
- if (kpt == (struct kpt_page *)0)
- panic("pmap_collect: lost a KPT page");
- if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
- printf("collect: %lx (%lx) to free list\n",
- kpt->kpt_va, kpa);
-#endif
- *pkpt = kpt->kpt_next;
- kpt->kpt_next = kpt_free_list;
- kpt_free_list = kpt;
-#ifdef PMAPSTATS
- kpt_stats.kptinuse--;
- kpt_stats.collectpages++;
+ wired = 0;
+ {
+ register pt_entry_t *ptep;
+ for (ptep = ptp; ptep < eptp; ptep++) {
+ if (*ptep & ALPHA_PTE_WIRED) {
+ wired = 1;
+ break;
+ }
+ }
+ }
+ if (!wired) {
+ /*
+ * Remove the virtual addresses mapped by this pte page.
+ */
+..... pmap_remove_range_2(p,
+ pdetova(pdp - p->dirbase),
+ ptp,
+ eptp);
+
+ /*
+ * Invalidate the page directory pointer.
+ */
+ {
+ register int i = ptes_per_vm_page;
+ register pt_entry_t *pdep = pdp;
+ do {
+ *pdep++ = 0;
+ } while (--i > 0);
+ }
+
+ PMAP_READ_UNLOCK(p, spl);
+
+ /*
+ * And free the pte page itself.
+ */
+ {
+ register vm_page_t m;
+
+ vm_object_lock(pmap_object);
+ m = vm_page_lookup(pmap_object, pa);
+ if (m == VM_PAGE_NULL)
+ panic("pmap_collect: pte page not in object");
+ vm_page_lock_queues();
+ vm_page_free(m);
+ inuse_ptepages_count--;
+ vm_page_unlock_queues();
+ vm_object_unlock(pmap_object);
+ }
+
+ PMAP_READ_LOCK(p, spl);
+ }
+ }
+ }
+ PMAP_READ_UNLOCK(p, spl);
+ return;
#endif
-#ifdef DEBUG
- if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
- pmapdebug = opmapdebug;
-
- if (*ste)
- printf("collect: kernel STE at %lx still valid (%lx)\n",
- ste, *ste);
- ste = &Sysptmap[(pt_entry_t *)ste-pmap_ste(pmap_kernel(), 0)];
- if (*ste)
- printf("collect: kernel PTmap at %lx still valid (%lx)\n",
- ste, *ste);
+}
+
+/*
+ * Routine: pmap_activate
+ * Function:
+ * Binds the given physical map to the given
+ * processor, and returns a hardware map description.
+ */
+void
+pmap_activate(pmap, hwpcb, cpu)
+ register pmap_t pmap;
+ struct alpha_pcb *hwpcb;
+ int cpu;
+{
+
+ if (DOPDB(PDB_FOLLOW|PDB_ACTIVATE))
+ printf("pmap_activate(%p, %p, %d)\n", pmap, hwpcb, cpu);
+
+#if 0
+ PMAP_ACTIVATE(my_pmap, th, my_cpu);
+#else
+ if (DOVPDB(PDB_ACTIVATE))
+ printf("pmap_activate: old pid = %d\n", pmap->pid);
+ if (pmap->pid < 0) pmap_tlbpid_assign(pmap);
+ hwpcb->apcb_asn = pmap->pid;
+ hwpcb->apcb_ptbr = pmap->dirpfn;
+ if (pmap != kernel_pmap)
+ pmap->cpus_using = TRUE;
+ if (DOVPDB(PDB_ACTIVATE))
+ printf("pmap_activate: new pid = %d, new ptbr = 0x%lx\n",
+ pmap->pid, pmap->dirpfn);
#endif
- }
- splx(s);
}
+/*
+ * Routine: pmap_deactivate
+ * Function:
+ * Indicates that the given physical map is no longer
+ * in use on the specified processor. (This is a macro
+ * in pmap.h)
+ */
void
-pmap_activate(pmap)
- register pmap_t pmap;
+pmap_deactivate(pmap, hwpcb, cpu)
+ register pmap_t pmap;
+ struct alpha_pcb *hwpcb;
+ int cpu;
{
- int iscurproc;
+ if (DOPDB(PDB_FOLLOW|PDB_DEACTIVATE))
+ printf("pmap_deactivate(%p, %p, %d)\n", pmap, hwpcb, cpu);
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_SEGTAB))
- printf("pmap_activate(%lx)\n", pmap);
+#if 0
+ PMAP_DEACTIVATE(pmap, th, which_cpu);
+#else
+ if (DOVPDB(PDB_DEACTIVATE))
+ printf("pmap_deactivate: pid = %d, ptbr = 0x%lx\n",
+ pmap->pid, pmap->dirpfn);
+ pmap->cpus_using = FALSE;
#endif
+}
- iscurproc = curproc != NULL && pmap == curproc->p_vmspace->vm_map.pmap;
- PMAP_ACTIVATE(pmap, iscurproc);
+/*
+ * Routine: pmap_kernel
+ * Function:
+ * Returns the physical map handle for the kernel.
+ */
+#if 0
+pmap_t pmap_kernel()
+{
+ return (kernel_pmap);
}
+#endif
/*
- * pmap_zero_page zeros the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bzero to clear its contents, one machine dependent page
- * at a time.
+ * pmap_zero_page zeros the specified (machine independent) page.
+ * See machine/phys.c or machine/phys.s for implementation.
*/
+#if 1
void
pmap_zero_page(phys)
- vm_offset_t phys;
+ register vm_offset_t phys;
{
- caddr_t p;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_zero_page(%lx)\n", phys);
-#endif
- p = (caddr_t)phystok0seg(phys);
- bzero(p, PAGE_SIZE);
+ if (DOPDB(PDB_FOLLOW|PDB_ZERO_PAGE))
+ printf("pmap_zero_page(0x%lx)\n", phys);
+
+ assert(phys != vm_page_fictitious_addr);
+
+ bzero((void *)phystokv(phys), PAGE_SIZE);
+
+ if (DOVPDB(PDB_FOLLOW|PDB_ZERO_PAGE))
+ printf("pmap_zero_page: leaving\n");
}
+#endif
/*
- * pmap_copy_page copies the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bcopy to copy the page, one machine dependent page at a
- * time.
+ * pmap_copy_page copies the specified (machine independent) page.
+ * See machine/phys.c or machine/phys.s for implementation.
*/
+#if 1 /* fornow */
void
pmap_copy_page(src, dst)
- vm_offset_t src, dst;
+ vm_offset_t src, dst;
{
- caddr_t s, d;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_copy_page(%lx, %lx)\n", src, dst);
-#endif
- s = (caddr_t)phystok0seg(src);
- d = (caddr_t)phystok0seg(dst);
- bcopy(s, d, PAGE_SIZE);
+ if (DOPDB(PDB_FOLLOW|PDB_COPY_PAGE))
+ printf("pmap_copy_page(0x%lx, 0x%lx)\n", src, dst);
+
+ assert(src != vm_page_fictitious_addr);
+ assert(dst != vm_page_fictitious_addr);
+
+ aligned_block_copy(phystokv(src), phystokv(dst), PAGE_SIZE);
+
+ if (DOVPDB(PDB_FOLLOW|PDB_COPY_PAGE))
+ printf("pmap_copy_page: leaving\n");
}
+#endif
/*
* Routine: pmap_pageable
@@ -1461,130 +2454,247 @@ pmap_copy_page(src, dst)
* down (or not) as appropriate.
*/
void
-pmap_pageable(pmap, sva, eva, pageable)
+pmap_pageable(pmap, start, end, pageable)
pmap_t pmap;
- vm_offset_t sva, eva;
+ vm_offset_t start;
+ vm_offset_t end;
boolean_t pageable;
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_pageable(%lx, %lx, %lx, %lx)\n",
- pmap, sva, eva, pageable);
+#ifdef lint
+ pmap++; start++; end++; pageable++;
#endif
+}
+
+/*
+ * Clear specified attribute bits.
+ */
+void
+phys_attribute_clear(phys, bits)
+ vm_offset_t phys;
+ int bits;
+{
+ pv_entry_t pv_h;
+ register pv_entry_t pv_e;
+ register pt_entry_t *pte;
+ int pai;
+ register pmap_t pmap;
+ spl_t spl;
+
+ assert(phys != vm_page_fictitious_addr);
+ if (!valid_page(phys)) {
+ /*
+ * Not a managed page.
+ */
+ return;
+ }
+
+ /*
+ * Lock the pmap system first, since we will be changing
+ * several pmaps.
+ */
+
+ PMAP_WRITE_LOCK(spl);
+
+ pai = pa_index(phys);
+ pv_h = pai_to_pvh(pai);
+
/*
- * If we are making a PT page pageable then all valid
- * mappings must be gone from that page. Hence it should
- * be all zeros and there is no need to clean it.
- * Assumptions:
- * - we are called with only one page at a time
- * - PT pages have only one pv_table entry
+ * Walk down PV list, clearing all modify or reference bits.
+ * We do not have to lock the pv_list because we have
+ * the entire pmap system locked.
*/
- if (pmap == pmap_kernel() && pageable && sva + PAGE_SIZE == eva) {
- register pv_entry_t pv;
- register vm_offset_t pa;
-
-#ifdef DEBUG
- if ((pmapdebug & (PDB_FOLLOW|PDB_PTPAGE)) == PDB_PTPAGE)
- printf("pmap_pageable(%lx, %lx, %lx, %lx)\n",
- pmap, sva, eva, pageable);
+ if (pv_h->pmap != PMAP_NULL) {
+ /*
+ * There are some mappings.
+ */
+ for (pv_e = pv_h; pv_e != PV_ENTRY_NULL; pv_e = pv_e->next) {
+
+ pmap = pv_e->pmap;
+ /*
+ * Lock the pmap to block pmap_extract and similar routines.
+ */
+ simple_lock(&pmap->lock);
+
+ {
+ register vm_offset_t va;
+
+ va = pv_e->va;
+ pte = pmap_pte(pmap, va);
+
+#if 0
+ /*
+ * Consistency checks.
+ */
+ assert(*pte & ALPHA_PTE_VALID);
+ /* assert(pte_to_phys(*pte) == phys); */
#endif
- if (!pmap_ste_v(pmap, sva))
- return;
- pa = pmap_pte_pa(pmap_pte(pmap, sva));
- if (!PAGE_IS_MANAGED(pa))
- return;
- pv = pa_to_pvh(pa);
- if (pv->pv_ptpte == NULL)
- return;
-#ifdef DEBUG
- if (pv->pv_va != sva || pv->pv_next) {
- printf("pmap_pageable: bad PT page va %lx next %lx\n",
- pv->pv_va, pv->pv_next);
- return;
+
+ /*
+ * Invalidate TLBs for all CPUs using this mapping.
+ */
+ PMAP_UPDATE_TLBS(pmap, va, va + PAGE_SIZE);
}
-#endif
+
/*
- * Mark it unmodified to avoid pageout
+ * Clear modify or reference bits.
*/
- pmap_clear_modify(pa);
-#ifdef DEBUG
- if ((PHYS_TO_VM_PAGE(pa)->flags & PG_CLEAN) == 0) {
- printf("pa %lx: flags=%lx: not clean\n",
- pa, PHYS_TO_VM_PAGE(pa)->flags);
- PHYS_TO_VM_PAGE(pa)->flags |= PG_CLEAN;
+ {
+ register int i = ptes_per_vm_page;
+ do {
+ *pte &= ~bits;
+ } while (--i > 0);
}
- if (pmapdebug & PDB_PTPAGE)
- printf("pmap_pageable: PT page %lx(%lx) unmodified\n",
- sva, *pmap_pte(pmap, sva));
- if (pmapdebug & PDB_WIRING)
- pmap_check_wiring("pageable", sva);
-#endif
+ simple_unlock(&pmap->lock);
+ }
}
+
+ pmap_phys_attributes[pai] &= ~ (bits >> 16);
+
+ PMAP_WRITE_UNLOCK(spl);
}
/*
- * Clear the modify bits on the specified physical page.
+ * Check specified attribute bits.
*/
+boolean_t
+phys_attribute_test(phys, bits)
+ vm_offset_t phys;
+ int bits;
+{
+ pv_entry_t pv_h;
+ register pv_entry_t pv_e;
+ register pt_entry_t *pte;
+ int pai;
+ register pmap_t pmap;
+ spl_t spl;
+
+ assert(phys != vm_page_fictitious_addr);
+ if (!valid_page(phys)) {
+ /*
+ * Not a managed page.
+ */
+ return (FALSE);
+ }
+
+ /*
+ * Lock the pmap system first, since we will be checking
+ * several pmaps.
+ */
+
+ PMAP_WRITE_LOCK(spl);
+
+ pai = pa_index(phys);
+ pv_h = pai_to_pvh(pai);
+
+ if (pmap_phys_attributes[pai] & (bits >> 16)) {
+ PMAP_WRITE_UNLOCK(spl);
+ return (TRUE);
+ }
+
+ /*
+ * Walk down PV list, checking all mappings.
+ * We do not have to lock the pv_list because we have
+ * the entire pmap system locked.
+ */
+ if (pv_h->pmap != PMAP_NULL) {
+ /*
+ * There are some mappings.
+ */
+ for (pv_e = pv_h; pv_e != PV_ENTRY_NULL; pv_e = pv_e->next) {
+
+ pmap = pv_e->pmap;
+ /*
+ * Lock the pmap to block pmap_extract and similar routines.
+ */
+ simple_lock(&pmap->lock);
+
+ {
+ register vm_offset_t va;
+
+ va = pv_e->va;
+ pte = pmap_pte(pmap, va);
+
+#if 0
+ /*
+ * Consistency checks.
+ */
+ assert(*pte & ALPHA_PTE_VALID);
+ /* assert(pte_to_phys(*pte) == phys); */
+#endif
+ }
+ /*
+ * Check modify or reference bits.
+ */
+ {
+ register int i = ptes_per_vm_page;
+
+ do {
+ if (*pte & bits) {
+ simple_unlock(&pmap->lock);
+ PMAP_WRITE_UNLOCK(spl);
+ return (TRUE);
+ }
+ } while (--i > 0);
+ }
+ simple_unlock(&pmap->lock);
+ }
+ }
+ PMAP_WRITE_UNLOCK(spl);
+ return (FALSE);
+}
+
+/*
+ * Set specified attribute bits. <ugly>
+ */
void
-pmap_clear_modify(pa)
- vm_offset_t pa;
+phys_attribute_set(phys, bits)
+ vm_offset_t phys;
+ int bits;
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_clear_modify(%lx)\n", pa);
-#endif
- if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
- return;
- if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) != 0) {
- pmap_changebit(pa, PG_FOW, TRUE);
- pmap_attributes[pa_index(pa)] &= ~PMAP_ATTR_MOD;
+ int pai;
+ spl_t spl;
+
+ assert(phys != vm_page_fictitious_addr);
+ if (!valid_page(phys)) {
+ /*
+ * Not a managed page.
+ */
+ return;
}
+
+ /*
+ * Lock the pmap system.
+ */
+
+ PMAP_WRITE_LOCK(spl);
+
+ pai = pa_index(phys);
+ pmap_phys_attributes[pai] |= (bits >> 16);
+
+ PMAP_WRITE_UNLOCK(spl);
}
/*
- * pmap_clear_reference:
- *
- * Clear the reference bit on the specified physical page.
+ * Clear the modify bits on the specified physical page.
*/
-void pmap_clear_reference(pa)
- vm_offset_t pa;
+void pmap_clear_modify(phys)
+ register vm_offset_t phys;
{
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_clear_reference(%lx)\n", pa);
-#endif
- if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
- return;
- if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) != 0) {
- pmap_changebit(pa, PG_FOR | PG_FOW | PG_FOE, TRUE);
- pmap_attributes[pa_index(pa)] &= ~PMAP_ATTR_REF;
- }
+if (pmap_debug) db_printf("pmap_clear_mod(%x)\n", phys);
+ phys_attribute_clear(phys, ALPHA_PTE_MOD);
}
/*
- * pmap_is_referenced:
- *
- * Return whether or not the specified physical page is referenced
- * by any physical maps.
+ * Set the modify bits on the specified physical page.
*/
-boolean_t
-pmap_is_referenced(pa)
- vm_offset_t pa;
+void pmap_set_modify(phys)
+ register vm_offset_t phys;
{
- boolean_t rv;
-
- if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
- return 0;
- rv = (pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) != 0;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW) {
- printf("pmap_is_referenced(%lx) -> %c\n", pa, "FT"[rv]);
- }
-#endif
- return rv;
+if (pmap_debug) db_printf("pmap_set_mod(%x)\n", phys);
+ phys_attribute_set(phys, ALPHA_PTE_MOD);
}
/*
@@ -1594,524 +2704,496 @@ pmap_is_referenced(pa)
* by any physical maps.
*/
-boolean_t
-pmap_is_modified(pa)
- vm_offset_t pa;
+boolean_t pmap_is_modified(phys)
+ register vm_offset_t phys;
{
- boolean_t rv;
-
- if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
- return 0;
- rv = (pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) != 0;
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW) {
- printf("pmap_is_modified(%lx) -> %c\n", pa, "FT"[rv]);
- }
-#endif
- return rv;
+if (pmap_debug) db_printf("pmap_is_mod(%x)\n", phys);
+ return (phys_attribute_test(phys, ALPHA_PTE_MOD));
}
-vm_offset_t
-pmap_phys_address(ppn)
- int ppn;
+/*
+ * pmap_clear_reference:
+ *
+ * Clear the reference bit on the specified physical page.
+ */
+
+void pmap_clear_reference(phys)
+ vm_offset_t phys;
{
- return(alpha_ptob(ppn));
+if (pmap_debug) db_printf("pmap_clear_ref(%x)\n", phys);
+ phys_attribute_clear(phys, ALPHA_PTE_REF);
}
/*
- * Miscellaneous support routines follow
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page is referenced
+ * by any physical maps.
*/
+boolean_t pmap_is_referenced(phys)
+ vm_offset_t phys;
+{
+if (pmap_debug) db_printf("pmap_is_ref(%x)\n", phys);
+ return (phys_attribute_test(phys, ALPHA_PTE_REF));
+}
+
+#if NCPUS > 1
+/*
+* TLB Coherence Code (TLB "shootdown" code)
+*
+* Threads that belong to the same task share the same address space and
+* hence share a pmap. However, they may run on distinct cpus and thus
+* have distinct TLBs that cache page table entries. In order to guarantee
+* the TLBs are consistent, whenever a pmap is changed, all threads that
+* are active in that pmap must have their TLB updated. To keep track of
+* this information, the set of cpus that are currently using a pmap is
+* maintained within each pmap structure (cpus_using). Pmap_activate() and
+* pmap_deactivate add and remove, respectively, a cpu from this set.
+* Since the TLBs are not addressable over the bus, each processor must
+* flush its own TLB; a processor that needs to invalidate another TLB
+* needs to interrupt the processor that owns that TLB to signal the
+* update.
+*
+* Whenever a pmap is updated, the lock on that pmap is locked, and all
+* cpus using the pmap are signaled to invalidate. All threads that need
+* to activate a pmap must wait for the lock to clear to await any updates
+* in progress before using the pmap. They must ACQUIRE the lock to add
+* their cpu to the cpus_using set. An implicit assumption made
+* throughout the TLB code is that all kernel code that runs at or higher
+* than splvm blocks out update interrupts, and that such code does not
+* touch pageable pages.
+*
+* A shootdown interrupt serves another function besides signaling a
+* processor to invalidate. The interrupt routine (pmap_update_interrupt)
+* waits for the both the pmap lock (and the kernel pmap lock) to clear,
+* preventing user code from making implicit pmap updates while the
+* sending processor is performing its update. (This could happen via a
+* user data write reference that turns on the modify bit in the page
+* table). It must wait for any kernel updates that may have started
+* concurrently with a user pmap update because the IPC code
+* changes mappings.
+* Spinning on the VALUES of the locks is sufficient (rather than
+* having to acquire the locks) because any updates that occur subsequent
+* to finding the lock unlocked will be signaled via another interrupt.
+* (This assumes the interrupt is cleared before the low level interrupt code
+* calls pmap_update_interrupt()).
+*
+* The signaling processor must wait for any implicit updates in progress
+* to terminate before continuing with its update. Thus it must wait for an
+* acknowledgement of the interrupt from each processor for which such
+* references could be made. For maintaining this information, a set
+* cpus_active is used. A cpu is in this set if and only if it can
+* use a pmap. When pmap_update_interrupt() is entered, a cpu is removed from
+* this set; when all such cpus are removed, it is safe to update.
+*
+* Before attempting to acquire the update lock on a pmap, a cpu (A) must
+* be at least at the priority of the interprocessor interrupt
+* (splip<=splvm). Otherwise, A could grab a lock and be interrupted by a
+* kernel update; it would spin forever in pmap_update_interrupt() trying
+* to acquire the user pmap lock it had already acquired. Furthermore A
+* must remove itself from cpus_active. Otherwise, another cpu holding
+* the lock (B) could be in the process of sending an update signal to A,
+* and thus be waiting for A to remove itself from cpus_active. If A is
+* spinning on the lock at priority this will never happen and a deadlock
+* will result.
+*/
+
/*
- * Initialize Alpha protection code array.
+ * Signal another CPU that it must flush its TLB
*/
-/* static */
-void
-alpha_protection_init()
+void signal_cpus(use_list, pmap, start, end)
+ cpu_set use_list;
+ pmap_t pmap;
+ vm_offset_t start, end;
{
- int prot, *kp, *up;
+ register int which_cpu, j;
+ register pmap_update_list_t update_list_p;
- kp = protection_codes[0];
- up = protection_codes[1];
+ while ((which_cpu = ffs(use_list)) != 0) {
+ which_cpu -= 1; /* convert to 0 origin */
- for (prot = 0; prot < 8; prot++) {
- switch (prot) {
- case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
- *kp++ = PG_ASM;
- *up++ = 0;
- break;
- case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
- case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
- case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
- *kp++ = PG_ASM | PG_KRE;
- *up++ = PG_URE | PG_KRE;
- break;
- case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
- *kp++ = PG_ASM | PG_KWE;
- *up++ = PG_UWE | PG_KWE;
- break;
- case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
- case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
- case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
- *kp++ = PG_ASM | PG_KWE | PG_KRE;
- *up++ = PG_UWE | PG_URE | PG_KWE | PG_KRE;
- break;
- }
+ update_list_p = &cpu_update_list[which_cpu];
+ simple_lock(&update_list_p->lock);
+
+ j = update_list_p->count;
+ if (j >= UPDATE_LIST_SIZE) {
+ /*
+ * list overflowed. Change last item to
+ * indicate overflow.
+ */
+ update_list_p->item[UPDATE_LIST_SIZE-1].pmap = kernel_pmap;
+ update_list_p->item[UPDATE_LIST_SIZE-1].start = VM_MIN_ADDRESS;
+ update_list_p->item[UPDATE_LIST_SIZE-1].end = VM_MAX_KERNEL_ADDRESS;
+ }
+ else {
+ update_list_p->item[j].pmap = pmap;
+ update_list_p->item[j].start = start;
+ update_list_p->item[j].end = end;
+ update_list_p->count = j+1;
+ }
+ cpu_update_needed[which_cpu] = TRUE;
+ simple_unlock(&update_list_p->lock);
+
+ if ((cpus_idle & (1 << which_cpu)) == 0)
+ interrupt_processor(which_cpu);
+ use_list &= ~(1 << which_cpu);
}
}
-/*
- * Invalidate a single page denoted by pmap/va.
- * If (pte != NULL), it is the already computed PTE for the page.
- * If (flags & PRM_TFLUSH), we must invalidate any TLB information.
- * If (flags & PRM_CFLUSH), we must flush/invalidate any cache information.
- */
-/* static */
-void
-pmap_remove_mapping(pmap, va, pte, flags)
- register pmap_t pmap;
- register vm_offset_t va;
- register pt_entry_t *pte;
- int flags;
+void process_pmap_updates(my_pmap)
+ register pmap_t my_pmap;
+{
+ register int my_cpu = cpu_number();
+ register pmap_update_list_t update_list_p;
+ register int j;
+ register pmap_t pmap;
+
+ update_list_p = &cpu_update_list[my_cpu];
+ simple_lock(&update_list_p->lock);
+
+ for (j = 0; j < update_list_p->count; j++) {
+ pmap = update_list_p->item[j].pmap;
+ if (pmap == my_pmap ||
+ pmap == kernel_pmap) {
+
+ INVALIDATE_TLB(update_list_p->item[j].start,
+ update_list_p->item[j].end);
+ }
+ }
+ update_list_p->count = 0;
+ cpu_update_needed[my_cpu] = FALSE;
+ simple_unlock(&update_list_p->lock);
+}
+
+#if MACH_KDB
+
+static boolean_t db_interp_int[NCPUS];
+int db_inside_pmap_update[NCPUS];
+int suicide_cpu;
+
+cpu_interrupt_to_db(i)
+ int i;
{
- register vm_offset_t pa;
- register pv_entry_t pv, npv;
- pmap_t ptpmap;
- pt_entry_t *ste;
- int s;
-#ifdef DEBUG
- pt_entry_t opte;
-
- if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
- printf("pmap_remove_mapping(%lx, %lx, %lx, %lx)\n",
- pmap, va, pte, flags);
+ db_interp_int[i] = TRUE;
+ interrupt_processor(i);
+}
#endif
- /*
- * PTE not provided, compute it from pmap and va.
- */
- if (pte == PT_ENTRY_NULL) {
- pte = pmap_pte(pmap, va);
- if (*pte == PG_NV)
- return;
+/*
+ * Interrupt routine for TBIA requested from other processor.
+ */
+void pmap_update_interrupt()
+{
+ register int my_cpu;
+ register pmap_t my_pmap;
+ spl_t s;
+
+ my_cpu = cpu_number();
+
+ db_inside_pmap_update[my_cpu]++;
+#if MACH_KDB
+ if (db_interp_int[my_cpu]) {
+ db_interp_int[my_cpu] = FALSE;
+ remote_db_enter();
+ /* In case another processor modified text */
+ alphacache_Iflush();
+if (cpu_number() == suicide_cpu) halt();
+ goto out; /* uhmmm, maybe should do updates just in case */
}
- pa = pmap_pte_pa(pte);
-#ifdef DEBUG
- opte = *pte;
-#endif
-#ifdef PMAPSTATS
- remove_stats.removes++;
#endif
/*
- * Update statistics
+ * Exit now if we're idle. We'll pick up the update request
+ * when we go active, and we must not put ourselves back in
+ * the active set because we'll never process the interrupt
+ * while we're idle (thus hanging the system).
*/
- if (pmap_pte_w(pte))
- pmap->pm_stats.wired_count--;
- pmap->pm_stats.resident_count--;
+ if (cpus_idle & (1 << my_cpu))
+ goto out;
- /*
- * Invalidate the PTE after saving the reference modify info.
- */
-#ifdef DEBUG
- if (pmapdebug & PDB_REMOVE)
- printf("remove: invalidating pte at %lx\n", pte);
-#endif
- *pte = PG_NV;
- if ((flags & PRM_TFLUSH) && active_pmap(pmap))
- TBIS((caddr_t)va);
- /*
- * For user mappings decrement the wiring count on
- * the PT page. We do this after the PTE has been
- * invalidated because vm_map_pageable winds up in
- * pmap_pageable which clears the modify bit for the
- * PT page.
- */
- if (pmap != pmap_kernel()) {
- (void) vm_map_pageable(pt_map, trunc_page(pte),
- round_page(pte+1), TRUE);
-#ifdef DEBUG
- if (pmapdebug & PDB_WIRING)
- pmap_check_wiring("remove", trunc_page(pte));
-#endif
- }
- /*
- * If this isn't a managed page, we are all done.
- */
- if (!PAGE_IS_MANAGED(pa))
- return;
- /*
- * Otherwise remove it from the PV table
- * (raise IPL since we may be called at interrupt time).
- */
- pv = pa_to_pvh(pa);
- ste = NULL;
- s = splimp();
- /*
- * If it is the first entry on the list, it is actually
- * in the header and we must copy the following entry up
- * to the header. Otherwise we must search the list for
- * the entry. In either case we free the now unused entry.
- */
- if (pmap == pv->pv_pmap && va == pv->pv_va) {
- ste = pv->pv_ptpte;
- ptpmap = pv->pv_ptpmap;
- npv = pv->pv_next;
- if (npv) {
- npv->pv_flags = pv->pv_flags;
- *pv = *npv;
- free((caddr_t)npv, M_VMPVENT);
- } else
- pv->pv_pmap = NULL;
-#ifdef PMAPSTATS
- remove_stats.pvfirst++;
-#endif
- } else {
- for (npv = pv->pv_next; npv; npv = npv->pv_next) {
-#ifdef PMAPSTATS
- remove_stats.pvsearch++;
-#endif
- if (pmap == npv->pv_pmap && va == npv->pv_va)
- break;
- pv = npv;
- }
-#ifdef DEBUG
- if (npv == NULL)
- panic("pmap_remove: PA not in pv_tab");
-#endif
- ste = npv->pv_ptpte;
- ptpmap = npv->pv_ptpmap;
- pv->pv_next = npv->pv_next;
- free((caddr_t)npv, M_VMPVENT);
- pv = pa_to_pvh(pa);
+ if (current_thread() == THREAD_NULL)
+ my_pmap = kernel_pmap;
+ else {
+ my_pmap = current_pmap();
+ if (!pmap_in_use(my_pmap, my_cpu))
+ my_pmap = kernel_pmap;
}
+
/*
- * If this was a PT page we must also remove the
- * mapping from the associated segment table.
+ * Raise spl to splvm (above splip) to block out pmap_extract
+ * from IO code (which would put this cpu back in the active
+ * set).
*/
- if (ste) {
-#ifdef PMAPSTATS
- remove_stats.ptinvalid++;
-#endif
-#ifdef DEBUG
- if (pmapdebug & (PDB_REMOVE|PDB_PTPAGE))
- printf("remove: ste was %lx@%lx pte was %lx@%lx\n",
- *ste, ste, opte, pmap_pte(pmap, va));
-#endif
- *ste = PG_NV;
- /*
- * If it was a user PT page, we decrement the
- * reference count on the segment table as well,
- * freeing it if it is now empty.
- */
- if (ptpmap != pmap_kernel()) {
-#ifdef DEBUG
- if (pmapdebug & (PDB_REMOVE|PDB_SEGTAB))
- printf("remove: stab %lx, refcnt %d\n",
- ptpmap->pm_stab, ptpmap->pm_sref - 1);
- if ((pmapdebug & PDB_PARANOIA) &&
- ptpmap->pm_stab != (pt_entry_t *)trunc_page(ste))
- panic("remove: bogus ste");
-#endif
- if (--(ptpmap->pm_sref) == 0) {
-#ifdef DEBUG
- if (pmapdebug&(PDB_REMOVE|PDB_SEGTAB))
- printf("remove: free stab %lx\n",
- ptpmap->pm_stab);
-#endif
- kmem_free_wakeup(st_map,
- (vm_offset_t)ptpmap->pm_stab,
- ALPHA_STSIZE);
- ptpmap->pm_stab = Segtabzero;
- ptpmap->pm_stpte = Segtabzeropte;
- ptpmap->pm_stchanged = TRUE;
- /*
- * XXX may have changed segment table
- * pointer for current process so
- * update now to reload hardware.
- * (curproc may be NULL if exiting.)
- */
- if (curproc != NULL &&
- ptpmap == curproc->p_vmspace->vm_map.pmap)
- PMAP_ACTIVATE(ptpmap, 1);
- }
-#ifdef DEBUG
- else if (ptpmap->pm_sref < 0)
- panic("remove: sref < 0");
-#endif
- }
-#if 0
- /*
- * XXX this should be unnecessary as we have been
- * flushing individual mappings as we go.
- */
- if (ptpmap == pmap_kernel())
- TBIAS();
- else
- TBIAU();
-#endif
- pv->pv_flags &= ~PV_PTPAGE;
- ptpmap->pm_ptpages--;
- }
+ s = splvm();
+
+ do {
+
+ /*
+ * Indicate that we're not using either user or kernel
+ * pmap.
+ */
+ i_bit_clear(my_cpu, &cpus_active);
+
+ /*
+ * Wait for any pmap updates in progress, on either user
+ * or kernel pmap.
+ */
+ while (*(volatile int *)&my_pmap->lock.lock_data ||
+ *(volatile int *)&kernel_pmap->lock.lock_data)
+ continue;
+
+ process_pmap_updates(my_pmap);
+
+ i_bit_set(my_cpu, &cpus_active);
+
+ } while (cpu_update_needed[my_cpu]);
+
splx(s);
+out:
+ db_inside_pmap_update[my_cpu]--;
+}
+#else NCPUS > 1
+/*
+ * Dummy routine to satisfy external reference.
+ */
+void pmap_update_interrupt()
+{
+ /* should never be called. */
}
+#endif /* NCPUS > 1 */
-/* static */
void
-pmap_changebit(pa, bit, setem)
- register vm_offset_t pa;
- u_long bit;
- boolean_t setem;
+set_ptbr(pmap_t map, pcb_t pcb, boolean_t switchit)
{
- register pv_entry_t pv;
- register pt_entry_t *pte, npte;
- vm_offset_t va;
- int s;
- boolean_t firstpage = TRUE;
-#ifdef PMAPSTATS
- struct chgstats *chgp;
-#endif
+ /* optimize later */
+ vm_offset_t pa;
-#ifdef DEBUG
- if (pmapdebug & PDB_BITS)
- printf("pmap_changebit(%lx, %lx, %s)\n",
- pa, bit, setem ? "set" : "clear");
+ pa = pmap_resident_extract(kernel_pmap, (vm_offset_t)map->dirbase);
+printf("set_ptbr (switch = %d): dirbase = 0x%lx, pa = 0x%lx\n", switchit, map->dirbase, pa);
+ if (pa == 0)
+ panic("set_ptbr");
+#if 0
+ pcb->mss.hw_pcb.ptbr = alpha_btop(pa);
+ if (switchit) {
+ pcb->mss.hw_pcb.asn = map->pid;
+ swpctxt(kvtophys((vm_offset_t) pcb), &(pcb)->mss.hw_pcb.ksp);
+ }
+#else
+ pcb->pcb_hw.apcb_ptbr = alpha_btop(pa);
+ if (switchit) {
+ pcb->pcb_hw.apcb_asn = map->pid;
+ swpctxt(kvtophys((vm_offset_t) pcb), &(pcb)->pcb_hw.apcb_ksp);
+ }
#endif
- if (!PAGE_IS_MANAGED(pa))
- return;
+}
-#ifdef PMAPSTATS
- chgp = &changebit_stats[(bit>>2)-1];
- if (setem)
- chgp->setcalls++;
- else
- chgp->clrcalls++;
-#endif
- pv = pa_to_pvh(pa);
- s = splimp();
- /*
- * Loop over all current mappings setting/clearing as appropos
- * If setting RO do we need to clear the VAC?
- */
- if (pv->pv_pmap != NULL) {
-#ifdef DEBUG
- int toflush = 0;
-#endif
- for (; pv; pv = pv->pv_next) {
-#ifdef DEBUG
- toflush |= (pv->pv_pmap == pmap_kernel()) ? 2 : 1;
+/***************************************************************************
+ *
+ * TLBPID Management
+ *
+ * This is basically a unique number generator, with the twist
+ * that numbers are in a given range (dynamically defined).
+ * All things considered, I did it right in the MIPS case.
+ */
+
+#if 0
+/* above */
+int pmap_max_asn;
#endif
- va = pv->pv_va;
- /*
- * XXX don't write protect pager mappings
- */
-/* XXX */ if (bit == (PG_UWE | PG_KWE)) {
- extern vm_offset_t pager_sva, pager_eva;
+decl_simple_lock_data(static, tlbpid_lock)
+static struct pmap **pids_in_use;
+static int pmap_next_pid;
- if (va >= pager_sva && va < pager_eva)
- continue;
- }
+pmap_tlbpid_init(maxasn)
+ int maxasn;
+{
+ simple_lock_init(&tlbpid_lock);
- pte = pmap_pte(pv->pv_pmap, va);
- if (setem)
- npte = *pte | bit;
- else
- npte = *pte & ~bit;
- if (*pte != npte) {
- *pte = npte;
- if (active_pmap(pv->pv_pmap))
- TBIS((caddr_t)va);
-#ifdef PMAPSTATS
- if (setem)
- chgp->sethits++;
- else
- chgp->clrhits++;
-#endif
- }
-#ifdef PMAPSTATS
- else {
- if (setem)
- chgp->setmiss++;
- else
- chgp->clrmiss++;
+ if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_INIT))
+ printf("pmap_tlbpid_init: maxasn = %d\n", maxasn);
+
+ pmap_max_asn = maxasn;
+ if (maxasn == 0) {
+ /* ASNs not implemented... Is this the right way to check? */
+ return;
+ }
+
+ pids_in_use = (struct pmap **)
+ pmap_bootstrap_alloc((maxasn + 1) * sizeof(struct pmap *));
+ bzero(pids_in_use, (maxasn + 1) * sizeof(struct pmap *));
+
+ pmap_next_pid = 1;
+}
+
+/*
+ * Axioms:
+ * - pmap_next_pid always points to a free one, unless the table is full;
+ * in that case it points to a likely candidate for recycling.
+ * - pmap.pid prevents from making duplicates: if -1 there is no
+ * pid for it, otherwise there is one and only one entry at that index.
+ *
+ * pmap_tlbpid_assign provides a tlbpid for the given pmap, creating
+ * a new one if necessary
+ * pmap_tlbpid_destroy returns a tlbpid to the pool of available ones
+ */
+
+pmap_tlbpid_assign(map)
+ struct pmap *map;
+{
+ register int pid, next_pid;
+
+ if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_ASSIGN))
+ printf("pmap_tlbpid_assign: pmap %p had %d\n", map, map->pid);
+
+ if (pmap_max_asn && map->pid < 0) {
+
+ simple_lock(&tlbpid_lock);
+
+ next_pid = pmap_next_pid;
+ if (pids_in_use[next_pid]) {
+ /* are we _really_ sure it's full ? */
+ for (pid = 1; pid < pmap_max_asn; pid++)
+ if (pids_in_use[pid] == PMAP_NULL) {
+ /* aha! */
+ next_pid = pid;
+ goto got_a_free_one;
+ }
+ /* Table full */
+ while (pids_in_use[next_pid]->cpus_using) {
+ if (++next_pid == pmap_max_asn)
+ next_pid = 1;
}
-#endif
+ pmap_tlbpid_destroy(next_pid, TRUE);
}
+got_a_free_one:
+ pids_in_use[next_pid] = map;
+ map->pid = next_pid;
+ if (++next_pid == pmap_max_asn)
+ next_pid = 1;
+ pmap_next_pid = next_pid;
+
+ simple_unlock(&tlbpid_lock);
}
- splx(s);
+ if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_ASSIGN))
+ printf("pmap_tlbpid_assign: pmap %p got %d\n", map, map->pid);
}
-/* static */
-void
-pmap_enter_ptpage(pmap, va)
- register pmap_t pmap;
- register vm_offset_t va;
+pmap_tlbpid_destroy(pid, locked)
+ int pid;
+ boolean_t locked;
{
- register vm_offset_t ptpa;
- register pv_entry_t pv;
- pt_entry_t *ste;
- int s;
-
-#ifdef DEBUG
- if (pmapdebug & (PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE))
- printf("pmap_enter_ptpage: pmap %lx, va %lx\n", pmap, va);
-#endif
-#ifdef PMAPSTATS
- enter_stats.ptpneeded++;
-#endif
- /*
- * Allocate a segment table if necessary. Note that it is allocated
- * from a private map and not pt_map. This keeps user page tables
- * aligned on segment boundaries in the kernel address space.
- * The segment table is wired down. It will be freed whenever the
- * reference count drops to zero.
- */
- if (pmap->pm_stab == Segtabzero) {
- pmap->pm_stab = (pt_entry_t *)
- kmem_alloc(st_map, ALPHA_STSIZE);
- pmap->pm_stpte = *kvtopte(pmap->pm_stab);
- pmap->pm_stchanged = TRUE;
- /*
- * XXX may have changed segment table pointer for current
- * process so update now to reload hardware.
- */
- if (pmap == curproc->p_vmspace->vm_map.pmap)
- PMAP_ACTIVATE(pmap, 1);
-#ifdef DEBUG
- if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
- printf("enter: pmap %lx stab %lx(%lx)\n",
- pmap, pmap->pm_stab, pmap->pm_stpte);
-#endif
- }
+ struct pmap *map;
- ste = pmap_ste(pmap, va);
- va = trunc_page((vm_offset_t)pmap_pte(pmap, va));
+ if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_DESTROY))
+ printf("pmap_tlbpid_destroy(%d, %d)\n", pid, locked);
- /*
- * In the kernel we allocate a page from the kernel PT page
- * free list and map it into the kernel page table map (via
- * pmap_enter).
- */
- if (pmap == pmap_kernel()) {
- register struct kpt_page *kpt;
+ if (pid < 0) /* no longer in use */
+ return;
+
+ assert(pmap_max_asn);
+
+ if (!locked) simple_lock(&tlbpid_lock);
- s = splimp();
- if ((kpt = kpt_free_list) == (struct kpt_page *)0) {
- /*
- * No PT pages available.
- * Try once to free up unused ones.
- */
-#ifdef DEBUG
- if (pmapdebug & PDB_COLLECT)
- printf("enter: no KPT pages, collecting...\n");
-#endif
- pmap_collect(pmap_kernel());
- if ((kpt = kpt_free_list) == (struct kpt_page *)0)
- panic("pmap_enter_ptpage: can't get KPT page");
- }
-#ifdef PMAPSTATS
- if (++kpt_stats.kptinuse > kpt_stats.kptmaxuse)
- kpt_stats.kptmaxuse = kpt_stats.kptinuse;
-#endif
- kpt_free_list = kpt->kpt_next;
- kpt->kpt_next = kpt_used_list;
- kpt_used_list = kpt;
- ptpa = kpt->kpt_pa;
- bzero((caddr_t)kpt->kpt_va, ALPHA_PAGE_SIZE);
- pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT, TRUE);
-#ifdef DEBUG
- if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) {
- int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0);
-
- printf("enter: add &Sysptmap[%d]: %lx (KPT page %lx)\n",
- ix, Sysptmap[ix], kpt->kpt_va);
- }
-#endif
- splx(s);
- }
/*
- * For user processes we just simulate a fault on that location
- * letting the VM system allocate a zero-filled page.
+ * Make the pid available, and the map unassigned.
*/
- else {
- /*
- * Count the segment table reference now so that we won't
- * lose the segment table when low on memory.
- */
- pmap->pm_sref++;
-#ifdef DEBUG
- if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
- printf("enter: about to fault UPT pg at %lx\n", va);
-#endif
- s = vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE);
- if (s != KERN_SUCCESS) {
- printf("vm_fault(pt_map, %lx, RW, 0) -> %d\n", va, s);
- panic("pmap_enter: vm_fault failed");
+ map = pids_in_use[pid];
+ assert(map != NULL);
+ pids_in_use[pid] = PMAP_NULL;
+ map->pid = -1;
+
+ if (!locked) simple_unlock(&tlbpid_lock);
+}
+
+#if 1 /* DEBUG */
+
+print_pv_list()
+{
+ pv_entry_t p;
+ vm_offset_t phys;
+
+ db_printf("phys pages %x < p < %x\n", vm_first_phys, vm_last_phys);
+ for (phys = vm_first_phys; phys < vm_last_phys; phys += PAGE_SIZE) {
+ p = pai_to_pvh(pa_index(phys));
+ if (p->pmap != PMAP_NULL) {
+ db_printf("%x: %x %x\n", phys, p->pmap, p->va);
+ while (p = p->next)
+ db_printf("\t\t%x %x\n", p->pmap, p->va);
}
- ptpa = pmap_extract(pmap_kernel(), va);
- /*
- * Mark the page clean now to avoid its pageout (and
- * hence creation of a pager) between now and when it
- * is wired; i.e. while it is on a paging queue.
- */
- PHYS_TO_VM_PAGE(ptpa)->flags |= PG_CLEAN;
-#ifdef DEBUG
- PHYS_TO_VM_PAGE(ptpa)->flags |= PG_PTPAGE;
-#endif
- }
- /*
- * Locate the PV entry in the kernel for this PT page and
- * record the STE address. This is so that we can invalidate
- * the STE when we remove the mapping for the page.
- */
- pv = pa_to_pvh(ptpa);
- s = splimp();
- if (pv) {
- pv->pv_flags |= PV_PTPAGE;
- do {
- if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
- break;
- } while (pv = pv->pv_next);
}
-#ifdef DEBUG
- if (pv == NULL)
- panic("pmap_enter_ptpage: PT page not entered");
-#endif
- pv->pv_ptpte = ste;
- pv->pv_ptpmap = pmap;
-#ifdef DEBUG
- if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
- printf("enter: new PT page at PA %lx, ste at %lx\n", ptpa, ste);
-#endif
+}
- /*
- * Map the new PT page into the segment table.
- * Reference count on the user segment tables incremented above
- * to prevent race conditions. Note that we don't use vm_map_pageable
- * to keep the count like we do for PT pages, this is mostly because
- * it would be difficult to identify ST pages in pmap_pageable to
- * release them. We also avoid the overhead of vm_map_pageable.
- */
- *ste = ((ptpa >> PGSHIFT) << PG_SHIFT) | PG_KRE | PG_KWE | PG_V |
- (pmap == pmap_kernel() ? PG_ASM : 0);
- if (pmap != pmap_kernel()) {
-#ifdef DEBUG
- if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
- printf("enter: stab %lx refcnt %d\n",
- pmap->pm_stab, pmap->pm_sref);
#endif
- }
-#if 0
- /*
- * Flush stale TLB info.
- */
- if (pmap == pmap_kernel())
- TBIAS();
- else
- TBIAU();
-#endif
- pmap->pm_ptpages++;
- splx(s);
+
+vm_offset_t
+pmap_phys_address(ppn)
+ int ppn;
+{
+ return(alpha_ptob(ppn));
+}
+
+void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
+ pmap_t dst_pmap;
+ pmap_t src_pmap;
+ vm_offset_t dst_addr;
+ vm_size_t len;
+ vm_offset_t src_addr;
+{
+}
+
+void pmap_update()
+{
+}
+
+vm_page_t
+vm_page_grab()
+{
+ register vm_page_t mem;
+ int spl;
+
+ spl = splimp(); /* XXX */
+ simple_lock(&vm_page_queue_free_lock);
+ if (vm_page_queue_free.tqh_first == NULL) {
+ simple_unlock(&vm_page_queue_free_lock);
+ splx(spl);
+ return (NULL);
+ }
+
+ mem = vm_page_queue_free.tqh_first;
+ TAILQ_REMOVE(&vm_page_queue_free, mem, pageq);
+
+ cnt.v_free_count--;
+ simple_unlock(&vm_page_queue_free_lock);
+ splx(spl);
+
+ mem->flags = PG_BUSY | PG_CLEAN | PG_FAKE;
+ mem->wire_count = 0;
+
+ /*
+ * Decide if we should poke the pageout daemon.
+ * We do this if the free count is less than the low
+ * water mark, or if the free count is less than the high
+ * water mark (but above the low water mark) and the inactive
+ * count is less than its target.
+ *
+ * We don't have the counts locked ... if they change a little,
+ * it doesn't really matter.
+ */
+
+ if (cnt.v_free_count < cnt.v_free_min ||
+ (cnt.v_free_count < cnt.v_free_target &&
+ cnt.v_inactive_count < cnt.v_inactive_target))
+ thread_wakeup((void *)&vm_pages_needed);
+ return (mem);
+}
+
+int
+vm_page_wait()
+{
+
+ assert_wait(&cnt.v_free_count, 0);
+ thread_block();
}
/*
@@ -2119,146 +3201,120 @@ pmap_enter_ptpage(pmap, va)
*/
void
pmap_emulate_reference(p, v, user, write)
- struct proc *p;
- vm_offset_t v;
- int user;
- int write;
+ struct proc *p;
+ vm_offset_t v;
+ int user;
+ int write;
{
- pt_entry_t faultoff, *pte;
- vm_offset_t pa;
- char attr;
-
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("pmap_emulate_reference: 0x%lx, 0x%lx, %d, %d\n",
- p, v, user, write);
-#endif
+ /* XXX */
+}
- /*
- * Convert process and virtual address to physical address.
- */
- if (v >= VM_MIN_KERNEL_ADDRESS) {
- if (user)
- panic("pmap_emulate_reference: user ref to kernel");
- pte = kvtopte(v);
- } else {
-#ifdef DIAGNOSTIC
- if (p == NULL)
- panic("pmap_emulate_reference: bad proc");
- if (p->p_vmspace == NULL)
- panic("pmap_emulate_reference: bad p_vmspace");
-#endif
- pte = pmap_pte(&p->p_vmspace->vm_pmap, v);
- }
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW) {
- printf("\tpte = 0x%lx, ", pte);
- printf("*pte = 0x%lx\n", *pte);
- }
-#endif
-#ifdef DEBUG /* These checks are more expensive */
- if (!pmap_pte_v(pte))
- panic("pmap_emulate_reference: invalid pte");
-#if 0
- /*
- * Can't do these, because cpu_fork and cpu_swapin call
- * pmap_emulate_reference(), and the bits aren't guaranteed,
- * for them...
- */
- if (write) {
- if (!(*pte & (user ? PG_UWE : PG_UWE | PG_KWE)))
- panic("pmap_emulate_reference: write but unwritable");
- if (!(*pte & PG_FOW))
- panic("pmap_emulate_reference: write but not FOW");
+struct pv_page;
+
+struct pv_page_info {
+ TAILQ_ENTRY(pv_page) pgi_list;
+ struct pv_entry *pgi_freelist;
+ int pgi_nfree;
+};
+
+#define NPVPPG ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
+
+struct pv_page {
+ struct pv_page_info pvp_pgi;
+ struct pv_entry pvp_pv[NPVPPG];
+};
+
+TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist;
+int pv_nfree;
+
+#define pv_next next
+
+struct pv_entry *
+pmap_alloc_pv()
+{
+ struct pv_page *pvp;
+ struct pv_entry *pv;
+ int i;
+
+ if (pv_nfree == 0) {
+ pvp = (struct pv_page *)kmem_alloc(kernel_map, NBPG);
+ if (pvp == 0)
+ panic("pmap_alloc_pv: kmem_alloc() failed");
+ pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1];
+ for (i = NPVPPG - 2; i; i--, pv++)
+ pv->pv_next = pv + 1;
+ pv->pv_next = 0;
+ pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1;
+ TAILQ_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ pv = &pvp->pvp_pv[0];
} else {
- if (!(*pte & (user ? PG_URE : PG_URE | PG_KRE)))
- panic("pmap_emulate_reference: !write but unreadable");
- if (!(*pte & (PG_FOR | PG_FOE)))
- panic("pmap_emulate_reference: !write but not FOR|FOE");
- }
-#endif
- /* Other diagnostics? */
-#endif
- pa = pmap_pte_pa(pte);
-#ifdef DEBUG
- if (pmapdebug & PDB_FOLLOW)
- printf("\tpa = 0x%lx\n", pa);
-#endif
+ --pv_nfree;
+ pvp = pv_page_freelist.tqh_first;
+ if (--pvp->pvp_pgi.pgi_nfree == 0) {
+ TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ }
+ pv = pvp->pvp_pgi.pgi_freelist;
#ifdef DIAGNOSTIC
- if (!PAGE_IS_MANAGED(pa))
- printf("WARNING: pmap_emulate_reference(0x%lx, 0x%lx, %d, %d): pa 0x%lx not managed\n", p, v, user, write, pa);
-#endif
-
- /*
- * Twiddle the appropriate bits to reflect the reference
- * and/or modification..
- *
- * The rules:
- * (1) always mark page as used, and
- * (2) if it was a write fault, mark page as modified.
- */
- attr = PMAP_ATTR_REF;
- faultoff = PG_FOR | PG_FOE;
- if (write) {
- attr |= PMAP_ATTR_MOD;
- faultoff |= PG_FOW;
- }
- pmap_attributes[pa_index(pa)] |= attr;
- pmap_changebit(pa, faultoff, FALSE);
- if ((*pte & faultoff) != 0) {
-#if 0
- /*
- * This is apparently normal. Why? -- cgd
- * XXX because was being called on unmanaged pages?
- */
- printf("warning: pmap_changebit didn't.");
+ if (pv == 0)
+ panic("pmap_alloc_pv: pgi_nfree inconsistent");
#endif
- *pte &= ~faultoff;
- TBIS((caddr_t)v);
+ pvp->pvp_pgi.pgi_freelist = pv->pv_next;
}
+ return pv;
}
-#ifdef DEBUG
-/* static */
void
-pmap_pvdump(pa)
- vm_offset_t pa;
+pmap_free_pv(pv)
+ struct pv_entry *pv;
{
- register pv_entry_t pv;
+ register struct pv_page *pvp;
+ register int i;
- printf("pa %lx", pa);
- for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
- printf(" -> pmap %lx, va %lx, stpte %lx, ptpmap %lx, flags %lx",
- pv->pv_pmap, pv->pv_va, pv->pv_ptpte, pv->pv_ptpmap,
- pv->pv_flags);
- printf("\n");
+ pvp = (struct pv_page *) trunc_page(pv);
+ switch (++pvp->pvp_pgi.pgi_nfree) {
+ case 1:
+ TAILQ_INSERT_TAIL(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ default:
+ pv->pv_next = pvp->pvp_pgi.pgi_freelist;
+ pvp->pvp_pgi.pgi_freelist = pv;
+ ++pv_nfree;
+ break;
+ case NPVPPG:
+ pv_nfree -= NPVPPG - 1;
+ TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);
+ kmem_free(kernel_map, (vm_offset_t)pvp, NBPG);
+ break;
+ }
}
-/* static */
-void
-pmap_check_wiring(str, va)
- char *str;
- vm_offset_t va;
+#if 0
+sanity(pmap, addr)
+ register pmap_t pmap;
+ register vm_offset_t addr;
{
- vm_map_entry_t entry;
- pt_entry_t *pte;
- register int count;
+ register pt_entry_t *ptp;
+ register pt_entry_t pte;
+
+ printf("checking dirbase...\n");
+ assert(pmap->dirbase != 0);
+ printf("checking dirpfn...\n");
+ assert(pmap->dirpfn == curproc->p_addr->u_pcb.pcb_hw.apcb_ptbr);
+ printf("checking pid...\n");
+ assert(pmap->pid == curproc->p_addr->u_pcb.pcb_hw.apcb_asn);
- va = trunc_page(va);
- if (!pmap_ste_v(pmap_kernel(), va) ||
- !pmap_pte_v(pmap_pte(pmap_kernel(), va)))
- return;
+
+ /* seg1 */
+ pte = *pmap_pde(pmap,addr);
+ if ((pte & ALPHA_PTE_VALID) == 0)
+ return(PT_ENTRY_NULL);
+ /* seg2 */
+ ptp = (pt_entry_t *)ptetokv(pte);
+ pte = ptp[pte2num(addr)];
+ if ((pte & ALPHA_PTE_VALID) == 0)
+ return(PT_ENTRY_NULL);
+ /* seg3 */
+ ptp = (pt_entry_t *)ptetokv(pte);
+ return(&ptp[pte3num(addr)]);
- if (!vm_map_lookup_entry(pt_map, va, &entry)) {
- printf("wired_check: entry for %lx not found\n", va);
- return;
- }
- count = 0;
- for (pte = (pt_entry_t *)va; pte < (pt_entry_t *)(va+PAGE_SIZE); pte++)
- if (*pte)
- count++;
- if (entry->wired_count != count)
- printf("*%s*: %lx: w%d/a%d\n",
- str, va, entry->wired_count, count);
}
#endif
diff --git a/sys/arch/alpha/alpha/pmap.old.c b/sys/arch/alpha/alpha/pmap.old.c
new file mode 100644
index 00000000000..28335634806
--- /dev/null
+++ b/sys/arch/alpha/alpha/pmap.old.c
@@ -0,0 +1,2283 @@
+/* $OpenBSD: pmap.old.c,v 1.1 1996/10/30 22:38:22 niklas Exp $ */
+/* $NetBSD: pmap.old.c,v 1.13 1996/10/13 02:59:44 christos Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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.
+ *
+ * @(#)pmap.c 8.6 (Berkeley) 5/27/94
+ */
+
+#ifdef XXX
+/*
+ * HP9000/300 series physical map management code.
+ *
+ * Supports:
+ * 68020 with HP MMU models 320, 350
+ * 68020 with 68551 MMU models 318, 319, 330 (all untested)
+ * 68030 with on-chip MMU models 340, 360, 370, 345, 375, 400
+ * 68040 with on-chip MMU models 380, 425, 433
+ *
+ * Notes:
+ * Don't even pay lip service to multiprocessor support.
+ *
+ * We assume TLB entries don't have process tags (except for the
+ * supervisor/user distinction) so we only invalidate TLB entries
+ * when changing mappings for the current (or kernel) pmap. This is
+ * technically not true for the 68551 but we flush the TLB on every
+ * context switch, so it effectively winds up that way.
+ *
+ * Bitwise and/or operations are significantly faster than bitfield
+ * references so we use them when accessing STE/PTEs in the pmap_pte_*
+ * macros. Note also that the two are not always equivalent; e.g.:
+ * (*(int *)pte & PG_PROT) [4] != pte->pg_prot [1]
+ * and a couple of routines that deal with protection and wiring take
+ * some shortcuts that assume the and/or definitions.
+ *
+ * This implementation will only work for PAGE_SIZE == NBPG
+ * (i.e. 4096 bytes).
+ */
+#endif
+
+/*
+ * Manages physical address maps.
+ *
+ * In addition to hardware address maps, this
+ * module is called upon to provide software-use-only
+ * maps which may or may not be stored in the same
+ * form as hardware maps. These pseudo-maps are
+ * used to store intermediate results from copy
+ * operations to and from address spaces.
+ *
+ * Since the information managed by this module is
+ * also stored by the logical address mapping module,
+ * this module may throw away valid virtual-to-physical
+ * mappings at almost any time. However, invalidations
+ * of virtual-to-physical mappings must be done as
+ * requested.
+ *
+ * In order to cope with hardware architectures which
+ * make virtual-to-physical map invalidates expensive,
+ * this module may delay invalidate or reduced protection
+ * operations until such time as they are actually
+ * necessary. This module is given full information as
+ * to which processors are currently using which maps,
+ * and to when physical maps must be made correct.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/user.h>
+#include <sys/buf.h>
+#ifdef SYSVSHM
+#include <sys/shm.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+
+#include <machine/cpu.h>
+
+#ifdef PMAPSTATS
+struct {
+ int collectscans;
+ int collectpages;
+ int kpttotal;
+ int kptinuse;
+ int kptmaxuse;
+} kpt_stats;
+struct {
+ int kernel; /* entering kernel mapping */
+ int user; /* entering user mapping */
+ int ptpneeded; /* needed to allocate a PT page */
+ int nochange; /* no change at all */
+ int pwchange; /* no mapping change, just wiring or protection */
+ int wchange; /* no mapping change, just wiring */
+ int pchange; /* no mapping change, just protection */
+ int mchange; /* was mapped but mapping to different page */
+ int managed; /* a managed page */
+ int firstpv; /* first mapping for this PA */
+ int secondpv; /* second mapping for this PA */
+ int ci; /* cache inhibited */
+ int unmanaged; /* not a managed page */
+ int flushes; /* cache flushes */
+} enter_stats;
+struct {
+ int calls;
+ int removes;
+ int pvfirst;
+ int pvsearch;
+ int ptinvalid;
+ int uflushes;
+ int sflushes;
+} remove_stats;
+struct {
+ int calls;
+ int changed;
+ int alreadyro;
+ int alreadyrw;
+} protect_stats;
+struct chgstats {
+ int setcalls;
+ int sethits;
+ int setmiss;
+ int clrcalls;
+ int clrhits;
+ int clrmiss;
+} changebit_stats[16];
+#endif
+
+#ifdef DEBUG
+#define PDB_FOLLOW 0x0001
+#define PDB_INIT 0x0002
+#define PDB_ENTER 0x0004
+#define PDB_REMOVE 0x0008
+#define PDB_CREATE 0x0010
+#define PDB_PTPAGE 0x0020
+#define PDB_CACHE 0x0040
+#define PDB_BITS 0x0080
+#define PDB_COLLECT 0x0100
+#define PDB_PROTECT 0x0200
+#define PDB_SEGTAB 0x0400
+#define PDB_MULTIMAP 0x0800
+#define PDB_BOOTSTRAP 0x1000
+#define PDB_PARANOIA 0x2000
+#define PDB_WIRING 0x4000
+#define PDB_PVDUMP 0x8000
+
+int debugmap = 0;
+int pmapdebug = PDB_PARANOIA;
+extern vm_offset_t pager_sva, pager_eva;
+#endif
+
+/*
+ * Get STEs and PTEs for user/kernel address space
+ */
+#define pmap_ste(m, v) (&((m)->pm_stab[vatoste((vm_offset_t)(v))]))
+#define pmap_ste_v(m, v) (*pmap_ste(m, v) & PG_V)
+
+#define pmap_pte(m, v) \
+ (&((m)->pm_ptab[NPTEPG * vatoste((vm_offset_t)(v)) + \
+ vatopte((vm_offset_t)(v))]))
+#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT)
+#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
+#define pmap_pte_w(pte) (*(pte) & PG_WIRED)
+#define pmap_pte_v(pte) (*(pte) & PG_V)
+
+#define pmap_pte_set_w(pte, v) \
+ if (v) *(u_long *)(pte) |= PG_WIRED; else *(u_long *)(pte) &= ~PG_WIRED
+#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
+
+#define pmap_pte_set_prot(pte, np) { *(pte) &= ~PG_PROT ; *(pte) |= (np); }
+#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
+
+
+/*
+ * Given a map and a machine independent protection code,
+ * convert to an hp300 protection code.
+ */
+#define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p])
+int protection_codes[2][8];
+
+/*
+ * Kernel page table page management.
+ */
+struct kpt_page {
+ struct kpt_page *kpt_next; /* link on either used or free list */
+ vm_offset_t kpt_va; /* always valid kernel VA */
+ vm_offset_t kpt_pa; /* PA of this page (for speed) */
+};
+struct kpt_page *kpt_free_list, *kpt_used_list;
+struct kpt_page *kpt_pages;
+
+/*
+ * The Alpha's level-1 page table.
+ */
+pt_entry_t *Lev1map;
+
+/*
+ * Kernel segment/page table and page table map.
+ * The page table map gives us a level of indirection we need to dynamically
+ * expand the page table. It is essentially a copy of the segment table
+ * with PTEs instead of STEs. All are initialized in locore at boot time.
+ * Segtabzero is an empty segment table which all processes share til they
+ * reference something.
+ */
+pt_entry_t *Sysptmap;
+pt_entry_t *Sysmap;
+vm_size_t Sysptmapsize, Sysmapsize;
+pt_entry_t *Segtabzero, Segtabzeropte;
+
+struct pmap kernel_pmap_store;
+vm_map_t st_map, pt_map;
+
+vm_offset_t avail_start; /* PA of first available physical page */
+vm_offset_t avail_end; /* PA of last available physical page */
+vm_size_t mem_size; /* memory size in bytes */
+vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/
+vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
+vm_offset_t vm_first_phys; /* PA of first managed page */
+vm_offset_t vm_last_phys; /* PA just past last managed page */
+boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
+char *pmap_attributes; /* reference and modify bits */
+
+/*
+ * Internal routines
+ */
+void alpha_protection_init __P((void));
+void pmap_remove_mapping __P((pmap_t, vm_offset_t, pt_entry_t *, int));
+void pmap_changebit __P((vm_offset_t, u_long, boolean_t));
+void pmap_enter_ptpage __P((pmap_t, vm_offset_t));
+#ifdef DEBUG
+void pmap_pvdump __P((vm_offset_t));
+void pmap_check_wiring __P((char *, vm_offset_t));
+#endif
+
+#define PAGE_IS_MANAGED(pa) ((pa) >= vm_first_phys && (pa) < vm_last_phys)
+
+/* pmap_remove_mapping flags */
+#define PRM_TFLUSH 1
+#define PRM_CFLUSH 2
+
+/*
+ * pmap_bootstrap:
+ * Bootstrap the system to run with virtual memory.
+ * firstaddr is the first unused kseg0 address (not page aligned).
+ */
+void
+pmap_bootstrap(firstaddr, ptaddr)
+ vm_offset_t firstaddr;
+ vm_offset_t ptaddr;
+{
+ register int i;
+ vm_offset_t start;
+ pt_entry_t pte;
+ extern int firstusablepage, lastusablepage;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
+ printf("pmap_bootstrap(0x%lx, 0x%lx)\n", firstaddr, ptaddr);
+#endif
+
+ /* must be page aligned */
+ start = firstaddr = alpha_round_page(firstaddr);
+
+#define valloc(name, type, num) \
+ (name) = (type *)firstaddr; \
+ firstaddr = ALIGN((vm_offset_t)((name)+(num)))
+
+ /*
+ * Allocate an empty prototype segment map for processes.
+ * This will be used until processes get their own.
+ */
+ valloc(Segtabzero, pt_entry_t, NPTEPG);
+ Segtabzeropte = (ALPHA_K0SEG_TO_PHYS((vm_offset_t)Segtabzero) >> PGSHIFT) << PG_SHIFT;
+ Segtabzeropte |= PG_V | PG_KRE | PG_KWE | PG_WIRED;
+
+ /*
+ * Figure out how many PTE's are necessary to map the kernel.
+ * The '512' comes from PAGER_MAP_SIZE in vm_pager_init().
+ * This should be kept in sync.
+ * We also reserve space for kmem_alloc_pageable() for vm_fork().
+ */
+ Sysmapsize = (VM_KMEM_SIZE + VM_MBUF_SIZE + VM_PHYS_SIZE +
+ nbuf * MAXBSIZE + 16 * NCARGS) / NBPG + 512 + 256;
+ Sysmapsize += maxproc * (btoc(ALPHA_STSIZE) + btoc(ALPHA_MAX_PTSIZE));
+
+#ifdef SYSVSHM
+ Sysmapsize += shminfo.shmall;
+#endif
+ Sysmapsize = roundup(Sysmapsize, NPTEPG);
+
+ /*
+ * Allocate a level 1 PTE table for the kernel.
+ * This is always one page long.
+ * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.
+ */
+ valloc(Lev1map, pt_entry_t, NPTEPG);
+
+ /*
+ * Allocate a level 2 PTE table for the kernel.
+ * These must map all of the level3 PTEs.
+ * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.
+ */
+ Sysptmapsize = roundup(howmany(Sysmapsize, NPTEPG), NPTEPG);
+ valloc(Sysptmap, pt_entry_t, Sysptmapsize);
+ pmap_kernel()->pm_stab = Sysptmap;
+
+ /*
+ * Allocate a level 3 PTE table for the kernel.
+ * Contains Sysmapsize PTEs.
+ */
+ valloc(Sysmap, pt_entry_t, Sysmapsize);
+ pmap_kernel()->pm_ptab = Sysmap;
+
+ /*
+ * Allocate memory for page attributes.
+ * allocates a few more entries than we need, but that's safe.
+ */
+ valloc(pmap_attributes, char, 1 + lastusablepage - firstusablepage);
+
+ /*
+ * Allocate memory for pv_table.
+ * This will allocate more entries than we really need.
+ * We could do this in pmap_init when we know the actual
+ * phys_start and phys_end but its better to use kseg0 addresses
+ * rather than kernel virtual addresses mapped through the TLB.
+ */
+ i = 1 + lastusablepage - alpha_btop(ALPHA_K0SEG_TO_PHYS(firstaddr));
+ valloc(pv_table, struct pv_entry, i);
+
+ /*
+ * Clear allocated memory.
+ */
+ firstaddr = alpha_round_page(firstaddr);
+ bzero((caddr_t)start, firstaddr - start);
+
+ /*
+ * Set up level 1 page table
+ */
+
+ /* First, copy mappings for things below VM_MIN_KERNEL_ADDRESS */
+ bcopy((caddr_t)ptaddr, Lev1map,
+ kvtol1pte(VM_MIN_KERNEL_ADDRESS) * sizeof Lev1map[0]);
+
+ /* Second, map all of the level 2 pte pages */
+ for (i = 0; i < howmany(Sysptmapsize, NPTEPG); i++) {
+ pte = (ALPHA_K0SEG_TO_PHYS(((vm_offset_t)Sysptmap) + (i*PAGE_SIZE)) >> PGSHIFT)
+ << PG_SHIFT;
+ pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
+ Lev1map[kvtol1pte(VM_MIN_KERNEL_ADDRESS +
+ (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
+ }
+
+ /* Finally, map the virtual page table */
+ pte = (ALPHA_K0SEG_TO_PHYS((vm_offset_t)Lev1map) >> PGSHIFT) << PG_SHIFT;
+ pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
+ Lev1map[kvtol1pte(VPTBASE)] = pte;
+
+ /*
+ * Set up level 2 page table.
+ */
+ /* Map all of the level 3 pte pages */
+ for (i = 0; i < howmany(Sysmapsize, NPTEPG); i++) {
+ pte = (ALPHA_K0SEG_TO_PHYS(((vm_offset_t)Sysmap)+(i*PAGE_SIZE)) >> PGSHIFT)
+ << PG_SHIFT;
+ pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
+ Sysptmap[vatoste(VM_MIN_KERNEL_ADDRESS+
+ (i*PAGE_SIZE*NPTEPG))] = pte;
+ }
+
+ /*
+ * Set up level three page table (Sysmap)
+ */
+ /* Nothing to do; it's already zero'd */
+
+ avail_start = ALPHA_K0SEG_TO_PHYS(firstaddr);
+#if 1
+ avail_end = alpha_ptob(lastusablepage + 1);
+ mem_size = avail_end - avail_start;
+#else
+ /* XXX why not lastusablepage + 1, & not include NBPG in mem_size? */
+ avail_end = alpha_ptob(lastusablepage);
+ mem_size = NBPG + avail_end - avail_start;
+#endif
+#if 0
+ printf("avail_start = 0x%lx\n", avail_start);
+ printf("avail_end = 0x%lx\n", avail_end);
+ printf("mem_size = 0x%lx\n", mem_size);
+#endif
+
+ virtual_avail = VM_MIN_KERNEL_ADDRESS;
+ virtual_end = VM_MIN_KERNEL_ADDRESS + Sysmapsize * NBPG;
+
+ simple_lock_init(&pmap_kernel()->pm_lock);
+ pmap_kernel()->pm_count = 1;
+
+ /*
+ * Set up curproc's (i.e. proc 0's) PCB such that the ptbr
+ * points to the right place.
+ */
+ curproc->p_addr->u_pcb.pcb_hw.apcb_ptbr = ALPHA_K0SEG_TO_PHYS((vm_offset_t)Lev1map) >> PGSHIFT;
+}
+
+/*
+ * Unmap the PROM mappings. PROM mappings are kept around
+ * by pmap_bootstrap, so we can still use the prom's printf.
+ * Basically, blow away all mappings in the level one PTE
+ * table below VM_MIN_KERNEL_ADDRESS. The Virtual Page Table
+ * Is at the end of virtual space, so it's safe.
+ */
+void
+pmap_unmap_prom()
+{
+ extern int prom_mapped;
+ extern pt_entry_t *rom_ptep, rom_pte;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
+ printf("pmap_unmap_prom\n");
+#endif
+
+ /* XXX save old pte so that we can remap prom if necessary */
+ rom_ptep = &Lev1map[0]; /* XXX */
+ rom_pte = *rom_ptep & ~PG_ASM; /* XXX */
+
+ /* Mark all mappings before VM_MIN_KERNEL_ADDRESS as invalid. */
+ bzero(Lev1map, kvtol1pte(VM_MIN_KERNEL_ADDRESS) * sizeof Lev1map[0]);
+ prom_mapped = 0;
+ ALPHA_TBIA();
+}
+
+/*
+ * Bootstrap memory allocator. This function allows for early dynamic
+ * memory allocation until the virtual memory system has been bootstrapped.
+ * After that point, either kmem_alloc or malloc should be used. This
+ * function works by stealing pages from the (to be) managed page pool,
+ * stealing virtual address space, then implicitly mapping the pages
+ * (by using their k0seg addresses) and zeroing them.
+ *
+ * It should be used from pmap_bootstrap till vm_page_startup, afterwards
+ * it cannot be used, and will generate a panic if tried. Note that this
+ * memory will never be freed, and in essence it is wired down.
+ */
+void *
+pmap_bootstrap_alloc(size)
+ int size;
+{
+ vm_offset_t val;
+ extern boolean_t vm_page_startup_initialized;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
+ printf("pmap_bootstrap_alloc(%lx)\n", size);
+#endif
+ if (vm_page_startup_initialized)
+ panic("pmap_bootstrap_alloc: called after startup initialized");
+
+ val = ALPHA_PHYS_TO_K0SEG(avail_start);
+ size = round_page(size);
+ avail_start += size;
+
+ bzero((caddr_t)val, size);
+ return ((void *)val);
+}
+
+/*
+ * Initialize the pmap module.
+ * Called by vm_init, to initialize any structures that the pmap
+ * system needs to map virtual memory.
+ */
+void
+pmap_init(phys_start, phys_end)
+ vm_offset_t phys_start, phys_end;
+{
+ vm_offset_t addr, addr2;
+ vm_size_t s;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_init(%x, %x)\n", phys_start, phys_end);
+#endif
+
+ /* initialize protection array */
+ alpha_protection_init();
+
+ /*
+ * Allocate the segment table map
+ */
+ s = maxproc * ALPHA_STSIZE;
+ st_map = kmem_suballoc(kernel_map, &addr, &addr2, s, TRUE);
+
+ /*
+ * Allocate the page table map
+ */
+ s = maxproc * ALPHA_MAX_PTSIZE; /* XXX limit it */
+ pt_map = kmem_suballoc(kernel_map, &addr, &addr2, s, TRUE);
+
+ /*
+ * Now it is safe to enable pv_table recording.
+ */
+ vm_first_phys = phys_start;
+ vm_last_phys = phys_end;
+#if 0
+ printf("vm_first_phys = 0x%lx\n", vm_first_phys);
+ printf("vm_last_phys = 0x%lx\n", vm_last_phys);
+#endif
+ pmap_initialized = TRUE;
+}
+
+/*
+ * Used to map a range of physical addresses into kernel
+ * virtual address space.
+ *
+ * For now, VM is already on, we only need to map the
+ * specified memory.
+ */
+vm_offset_t
+pmap_map(virt, start, end, prot)
+ vm_offset_t virt;
+ vm_offset_t start;
+ vm_offset_t end;
+ int prot;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_map(%lx, %lx, %lx, %lx)\n", virt, start, end, prot);
+#endif
+ while (start < end) {
+ pmap_enter(pmap_kernel(), virt, start, prot, FALSE);
+ virt += PAGE_SIZE;
+ start += PAGE_SIZE;
+ }
+ return(virt);
+}
+
+/*
+ * Create and return a physical map.
+ *
+ * If the size specified for the map
+ * is zero, the map is an actual physical
+ * map, and may be referenced by the
+ * hardware.
+ *
+ * If the size specified is non-zero,
+ * the map will be used in software only, and
+ * is bounded by that size.
+ */
+pmap_t
+pmap_create(size)
+ vm_size_t size;
+{
+ register pmap_t pmap;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
+ printf("pmap_create(%lx)\n", size);
+#endif
+ /*
+ * Software use map does not need a pmap
+ */
+ if (size)
+ return(NULL);
+
+ /* XXX: is it ok to wait here? */
+ pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK);
+#ifdef notifwewait
+ if (pmap == NULL)
+ panic("pmap_create: cannot allocate a pmap");
+#endif
+ bzero(pmap, sizeof(*pmap));
+ pmap_pinit(pmap);
+ return (pmap);
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure,
+ * such as one in a vmspace structure.
+ */
+void
+pmap_pinit(pmap)
+ register struct pmap *pmap;
+{
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
+ printf("pmap_pinit(%lx)\n", pmap);
+#endif
+ /*
+ * No need to allocate page table space yet but we do need a
+ * valid segment table. Initially, we point everyone at the
+ * "null" segment table. On the first pmap_enter, a real
+ * segment table will be allocated.
+ */
+ pmap->pm_stab = Segtabzero;
+ pmap->pm_stpte = Segtabzeropte;
+ pmap->pm_stchanged = TRUE;
+ pmap->pm_count = 1;
+ simple_lock_init(&pmap->pm_lock);
+}
+
+/*
+ * Retire the given physical map from service.
+ * Should only be called if the map contains
+ * no valid mappings.
+ */
+void
+pmap_destroy(pmap)
+ register pmap_t pmap;
+{
+ int count;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_destroy(%lx)\n", pmap);
+#endif
+ if (pmap == NULL)
+ return;
+
+ simple_lock(&pmap->pm_lock);
+ count = --pmap->pm_count;
+ simple_unlock(&pmap->pm_lock);
+ if (count == 0) {
+ pmap_release(pmap);
+ free((caddr_t)pmap, M_VMPMAP);
+ }
+}
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_release(pmap)
+ register struct pmap *pmap;
+{
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_release(%lx)\n", pmap);
+#endif
+#ifdef notdef /* DIAGNOSTIC */
+ /* count would be 0 from pmap_destroy... */
+ simple_lock(&pmap->pm_lock);
+ if (pmap->pm_count != 1)
+ panic("pmap_release count");
+#endif
+ if (pmap->pm_ptab)
+ kmem_free_wakeup(pt_map, (vm_offset_t)pmap->pm_ptab,
+ ALPHA_MAX_PTSIZE);
+ if (pmap->pm_stab != Segtabzero)
+ kmem_free_wakeup(st_map, (vm_offset_t)pmap->pm_stab,
+ ALPHA_STSIZE);
+}
+
+/*
+ * Add a reference to the specified pmap.
+ */
+void
+pmap_reference(pmap)
+ pmap_t pmap;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_reference(%lx)\n", pmap);
+#endif
+ if (pmap != NULL) {
+ simple_lock(&pmap->pm_lock);
+ pmap->pm_count++;
+ simple_unlock(&pmap->pm_lock);
+ }
+}
+
+/*
+ * Remove the given range of addresses from the specified map.
+ *
+ * It is assumed that the start and end are properly
+ * rounded to the page size.
+ */
+void
+pmap_remove(pmap, sva, eva)
+ register pmap_t pmap;
+ register vm_offset_t sva, eva;
+{
+ register vm_offset_t nssva;
+ register pt_entry_t *pte;
+ boolean_t firstpage, needcflush;
+ int flags;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
+ printf("pmap_remove(%lx, %lx, %lx)\n", pmap, sva, eva);
+#endif
+
+ if (pmap == NULL)
+ return;
+
+#ifdef PMAPSTATS
+ remove_stats.calls++;
+#endif
+ firstpage = TRUE;
+ needcflush = FALSE;
+ flags = active_pmap(pmap) ? PRM_TFLUSH : 0;
+ while (sva < eva) {
+ nssva = alpha_trunc_seg(sva) + ALPHA_SEG_SIZE;
+ if (nssva == 0 || nssva > eva)
+ nssva = eva;
+ /*
+ * If VA belongs to an unallocated segment,
+ * skip to the next segment boundary.
+ */
+ if (!pmap_ste_v(pmap, sva)) {
+ sva = nssva;
+ continue;
+ }
+ /*
+ * Invalidate every valid mapping within this segment.
+ */
+ pte = pmap_pte(pmap, sva);
+ while (sva < nssva) {
+ if (pmap_pte_v(pte)) {
+ pmap_remove_mapping(pmap, sva, pte, flags);
+ firstpage = FALSE;
+ }
+ pte++;
+ sva += PAGE_SIZE;
+ }
+ }
+ /*
+ * Didn't do anything, no need for cache flushes
+ */
+ if (firstpage)
+ return;
+}
+
+/*
+ * pmap_page_protect:
+ *
+ * Lower the permission for all mappings to a given page.
+ */
+void
+pmap_page_protect(pa, prot)
+ vm_offset_t pa;
+ vm_prot_t prot;
+{
+ register pv_entry_t pv;
+ int s;
+
+#ifdef DEBUG
+ if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
+ (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
+ printf("pmap_page_protect(%lx, %lx)\n", pa, prot);
+#endif
+ if (!PAGE_IS_MANAGED(pa))
+ return;
+
+ switch (prot) {
+ case VM_PROT_READ|VM_PROT_WRITE:
+ case VM_PROT_ALL:
+ return;
+ /* copy_on_write */
+ case VM_PROT_READ:
+ case VM_PROT_READ|VM_PROT_EXECUTE:
+/* XXX */ pmap_changebit(pa, PG_KWE | PG_UWE, FALSE);
+ return;
+ /* remove_all */
+ default:
+ break;
+ }
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ while (pv->pv_pmap != NULL) {
+ register pt_entry_t *pte;
+
+ pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+#ifdef DEBUG
+ if (!pmap_ste_v(pv->pv_pmap, pv->pv_va) ||
+ pmap_pte_pa(pte) != pa)
+ panic("pmap_page_protect: bad mapping");
+#endif
+ if (!pmap_pte_w(pte))
+ pmap_remove_mapping(pv->pv_pmap, pv->pv_va,
+ pte, PRM_TFLUSH|PRM_CFLUSH);
+ else {
+ pv = pv->pv_next;
+#ifdef DEBUG
+ if (pmapdebug & PDB_PARANOIA)
+ printf("%s wired mapping for %lx not removed\n",
+ "pmap_page_protect:", pa);
+#endif
+ }
+ }
+ splx(s);
+}
+
+/*
+ * Set the physical protection on the
+ * specified range of this map as requested.
+ */
+void
+pmap_protect(pmap, sva, eva, prot)
+ register pmap_t pmap;
+ register vm_offset_t sva, eva;
+ vm_prot_t prot;
+{
+ register vm_offset_t nssva;
+ register pt_entry_t *pte, bits;
+ boolean_t firstpage, needtflush;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
+ printf("pmap_protect(%lx, %lx, %lx, %lx)\n", pmap, sva, eva, prot);
+#endif
+
+ if (pmap == NULL)
+ return;
+
+#ifdef PMAPSTATS
+ protect_stats.calls++;
+#endif
+ if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
+ pmap_remove(pmap, sva, eva);
+ return;
+ }
+ if (prot & VM_PROT_WRITE)
+ return;
+
+ bits = pte_prot(pmap, prot);
+ needtflush = active_pmap(pmap);
+ firstpage = TRUE;
+ while (sva < eva) {
+ nssva = alpha_trunc_seg(sva) + ALPHA_SEG_SIZE;
+ if (nssva == 0 || nssva > eva)
+ nssva = eva;
+ /*
+ * If VA belongs to an unallocated segment,
+ * skip to the next segment boundary.
+ */
+ if (!pmap_ste_v(pmap, sva)) {
+ sva = nssva;
+ continue;
+ }
+ /*
+ * Change protection on mapping if it is valid and doesn't
+ * already have the correct protection.
+ */
+ pte = pmap_pte(pmap, sva);
+ while (sva < nssva) {
+ if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, bits)) {
+ pmap_pte_set_prot(pte, bits);
+ if (needtflush)
+ ALPHA_TBIS(sva);
+#ifdef PMAPSTATS
+ protect_stats.changed++;
+#endif
+ firstpage = FALSE;
+ }
+#ifdef PMAPSTATS
+ else if (pmap_pte_v(pte)) {
+ if (isro)
+ protect_stats.alreadyro++;
+ else
+ protect_stats.alreadyrw++;
+ }
+#endif
+ pte++;
+ sva += PAGE_SIZE;
+ }
+ }
+}
+
+/*
+ * Insert the given physical page (p) at
+ * the specified virtual address (v) in the
+ * target physical map with the protection requested.
+ *
+ * If specified, the page will be wired down, meaning
+ * that the related pte can not be reclaimed.
+ *
+ * NB: This is the only routine which MAY NOT lazy-evaluate
+ * or lose information. That is, this routine must actually
+ * insert this page into the given map NOW.
+ */
+void
+pmap_enter(pmap, va, pa, prot, wired)
+ register pmap_t pmap;
+ vm_offset_t va;
+ register vm_offset_t pa;
+ vm_prot_t prot;
+ boolean_t wired;
+{
+ register pt_entry_t *pte;
+ register pt_entry_t npte;
+ vm_offset_t opa;
+ boolean_t checkpv = TRUE;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
+ printf("pmap_enter(%lx, %lx, %lx, %lx, %lx)\n",
+ pmap, va, pa, prot, wired);
+#endif
+ if (pmap == NULL)
+ return;
+
+#ifdef PMAPSTATS
+ if (pmap == pmap_kernel())
+ enter_stats.kernel++;
+ else
+ enter_stats.user++;
+#endif
+ /*
+ * For user mapping, allocate kernel VM resources if necessary.
+ */
+ if (pmap->pm_ptab == NULL)
+ pmap->pm_ptab = (pt_entry_t *)
+ kmem_alloc_wait(pt_map, ALPHA_MAX_PTSIZE);
+ /*
+ * Segment table entry not valid, we need a new PT page
+ */
+ if (!pmap_ste_v(pmap, va))
+ pmap_enter_ptpage(pmap, va);
+
+ pa = alpha_trunc_page(pa);
+ pte = pmap_pte(pmap, va);
+ opa = pmap_pte_pa(pte);
+#ifdef DEBUG
+ if (pmapdebug & PDB_ENTER)
+ printf("enter: pte %lx, *pte %lx\n", pte, *pte);
+#endif
+
+ /*
+ * Mapping has not changed, must be protection or wiring change.
+ */
+ if (opa == pa) {
+#ifdef PMAPSTATS
+ enter_stats.pwchange++;
+#endif
+ /*
+ * Wiring change, just update stats.
+ * We don't worry about wiring PT pages as they remain
+ * resident as long as there are valid mappings in them.
+ * Hence, if a user page is wired, the PT page will be also.
+ */
+ if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
+#ifdef DEBUG
+ if (pmapdebug & PDB_ENTER)
+ printf("enter: wiring change -> %lx\n", wired);
+#endif
+ if (wired)
+ pmap->pm_stats.wired_count++;
+ else
+ pmap->pm_stats.wired_count--;
+#ifdef PMAPSTATS
+ if (pmap_pte_prot(pte) == pte_prot(pmap, prot))
+ enter_stats.wchange++;
+#endif
+ }
+#ifdef PMAPSTATS
+ else if (pmap_pte_prot(pte) != pte_prot(pmap, prot))
+ enter_stats.pchange++;
+ else
+ enter_stats.nochange++;
+#endif
+ /*
+ * Retain cache inhibition status
+ */
+ checkpv = FALSE;
+ goto validate;
+ }
+
+ /*
+ * Mapping has changed, invalidate old range and fall through to
+ * handle validating new mapping.
+ */
+ if (opa) {
+#ifdef DEBUG
+ if (pmapdebug & PDB_ENTER)
+ printf("enter: removing old mapping %lx\n", va);
+#endif
+ pmap_remove_mapping(pmap, va, pte, PRM_TFLUSH|PRM_CFLUSH);
+#ifdef PMAPSTATS
+ enter_stats.mchange++;
+#endif
+ }
+
+ /*
+ * If this is a new user mapping, increment the wiring count
+ * on this PT page. PT pages are wired down as long as there
+ * is a valid mapping in the page.
+ */
+ if (pmap != pmap_kernel())
+ (void) vm_map_pageable(pt_map, trunc_page(pte),
+ round_page(pte+1), FALSE);
+
+ /*
+ * Enter on the PV list if part of our managed memory
+ * Note that we raise IPL while manipulating pv_table
+ * since pmap_enter can be called at interrupt time.
+ */
+ if (PAGE_IS_MANAGED(pa)) {
+ register pv_entry_t pv, npv;
+ int s;
+
+#ifdef PMAPSTATS
+ enter_stats.managed++;
+#endif
+ pv = pa_to_pvh(pa);
+ s = splimp();
+#ifdef DEBUG
+ if (pmapdebug & PDB_ENTER)
+ printf("enter: pv at %lx: %lx/%lx/%lx\n",
+ pv, pv->pv_va, pv->pv_pmap, pv->pv_next);
+#endif
+ /*
+ * No entries yet, use header as the first entry
+ */
+ if (pv->pv_pmap == NULL) {
+#ifdef PMAPSTATS
+ enter_stats.firstpv++;
+#endif
+ pv->pv_va = va;
+ pv->pv_pmap = pmap;
+ pv->pv_next = NULL;
+ pv->pv_ptpte = NULL;
+ pv->pv_ptpmap = NULL;
+ pv->pv_flags = 0;
+ }
+ /*
+ * There is at least one other VA mapping this page.
+ * Place this entry after the header.
+ */
+ else {
+#ifdef DEBUG
+ for (npv = pv; npv; npv = npv->pv_next)
+ if (pmap == npv->pv_pmap && va == npv->pv_va)
+ panic("pmap_enter: already in pv_tab");
+#endif
+ npv = (pv_entry_t)
+ malloc(sizeof *npv, M_VMPVENT, M_NOWAIT);
+ npv->pv_va = va;
+ npv->pv_pmap = pmap;
+ npv->pv_next = pv->pv_next;
+ npv->pv_ptpte = NULL;
+ npv->pv_ptpmap = NULL;
+ npv->pv_flags = 0;
+ pv->pv_next = npv;
+#ifdef PMAPSTATS
+ if (!npv->pv_next)
+ enter_stats.secondpv++;
+#endif
+ }
+ splx(s);
+ }
+ /*
+ * Assumption: if it is not part of our managed memory
+ * then it must be device memory which may be volitile.
+ */
+ else if (pmap_initialized) {
+ checkpv = FALSE;
+#ifdef PMAPSTATS
+ enter_stats.unmanaged++;
+#endif
+ }
+
+ /*
+ * Increment counters
+ */
+ pmap->pm_stats.resident_count++;
+ if (wired)
+ pmap->pm_stats.wired_count++;
+
+validate:
+ /*
+ * Build the new PTE.
+ */
+ npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
+ if (PAGE_IS_MANAGED(pa)) {
+ if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) == 0)
+ npte |= PG_FOR | PG_FOW | PG_FOE;
+ else if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) == 0)
+ npte |= PG_FOW;
+ }
+ if (wired)
+ npte |= PG_WIRED;
+#ifdef DEBUG
+ if (pmapdebug & PDB_ENTER)
+ printf("enter: new pte value %lx\n", npte);
+#endif
+ /*
+ * Remember if this was a wiring-only change.
+ * If so, we need not flush the TLB and caches.
+ */
+ wired = ((*pte ^ npte) == PG_WIRED);
+ *pte = npte;
+ if (!wired && active_pmap(pmap))
+ ALPHA_TBIS(va);
+#ifdef DEBUG
+ if ((pmapdebug & PDB_WIRING) && pmap != pmap_kernel())
+ pmap_check_wiring("enter", trunc_page(pmap_pte(pmap, va)));
+#endif
+}
+
+/*
+ * Routine: pmap_change_wiring
+ * Function: Change the wiring attribute for a map/virtual-address
+ * pair.
+ * In/out conditions:
+ * The mapping must already exist in the pmap.
+ */
+void
+pmap_change_wiring(pmap, va, wired)
+ register pmap_t pmap;
+ vm_offset_t va;
+ boolean_t wired;
+{
+ register pt_entry_t *pte;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_change_wiring(%lx, %lx, %lx)\n", pmap, va, wired);
+#endif
+ if (pmap == NULL)
+ return;
+
+ pte = pmap_pte(pmap, va);
+#ifdef DEBUG
+ /*
+ * Page table page is not allocated.
+ * Should this ever happen? Ignore it for now,
+ * we don't want to force allocation of unnecessary PTE pages.
+ */
+ if (!pmap_ste_v(pmap, va)) {
+ if (pmapdebug & PDB_PARANOIA)
+ printf("pmap_change_wiring: invalid STE for %lx\n", va);
+ return;
+ }
+ /*
+ * Page not valid. Should this ever happen?
+ * Just continue and change wiring anyway.
+ */
+ if (!pmap_pte_v(pte)) {
+ if (pmapdebug & PDB_PARANOIA)
+ printf("pmap_change_wiring: invalid PTE for %lx\n", va);
+ }
+#endif
+ /*
+ * If wiring actually changed (always?) set the wire bit and
+ * update the wire count. Note that wiring is not a hardware
+ * characteristic so there is no need to invalidate the TLB.
+ */
+ if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
+ pmap_pte_set_w(pte, wired);
+ if (wired)
+ pmap->pm_stats.wired_count++;
+ else
+ pmap->pm_stats.wired_count--;
+ }
+}
+
+/*
+ * Routine: pmap_extract
+ * Function:
+ * Extract the physical page address associated
+ * with the given map/virtual_address pair.
+ */
+
+vm_offset_t
+pmap_extract(pmap, va)
+ register pmap_t pmap;
+ vm_offset_t va;
+{
+ pt_entry_t pte;
+ register vm_offset_t pa;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_extract(%lx, %lx) -> ", pmap, va);
+#endif
+ pa = 0;
+ if (pmap && pmap_ste_v(pmap, va)) {
+ pte = *pmap_pte(pmap, va);
+ if (pte & PG_V)
+ pa = ctob(PG_PFNUM(pte)) | (va & PGOFSET);
+ }
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("%lx\n", pa);
+#endif
+ return(pa);
+}
+
+/*
+ * Copy the range specified by src_addr/len
+ * from the source map to the range dst_addr/len
+ * in the destination map.
+ *
+ * This routine is only advisory and need not do anything.
+ */
+void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
+ pmap_t dst_pmap;
+ pmap_t src_pmap;
+ vm_offset_t dst_addr;
+ vm_size_t len;
+ vm_offset_t src_addr;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_copy(%lx, %lx, %lx, %lx, %lx)\n",
+ dst_pmap, src_pmap, dst_addr, len, src_addr);
+#endif
+}
+
+/*
+ * Require that all active physical maps contain no
+ * incorrect entries NOW. [This update includes
+ * forcing updates of any address map caching.]
+ *
+ * Generally used to insure that a thread about
+ * to run will see a semantically correct world.
+ */
+void pmap_update()
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_update()\n");
+#endif
+ ALPHA_TBIA();
+}
+
+/*
+ * Routine: pmap_collect
+ * Function:
+ * Garbage collects the physical map system for
+ * pages which are no longer used.
+ * Success need not be guaranteed -- that is, there
+ * may well be pages which are not referenced, but
+ * others may be collected.
+ * Usage:
+ * Called by the pageout daemon when pages are scarce.
+ */
+void
+pmap_collect(pmap)
+ pmap_t pmap;
+{
+ register vm_offset_t pa;
+ register pv_entry_t pv;
+ register pt_entry_t *pte;
+ vm_offset_t kpa;
+ int s;
+
+#ifdef DEBUG
+ pt_entry_t *ste;
+ int opmapdebug;
+#endif
+ if (pmap != pmap_kernel())
+ return;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_collect(%lx)\n", pmap);
+#endif
+#ifdef PMAPSTATS
+ kpt_stats.collectscans++;
+#endif
+ s = splimp();
+ for (pa = vm_first_phys; pa < vm_last_phys; pa += PAGE_SIZE) {
+ register struct kpt_page *kpt, **pkpt;
+
+ /*
+ * Locate physical pages which are being used as kernel
+ * page table pages.
+ */
+ pv = pa_to_pvh(pa);
+ if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE))
+ continue;
+ do {
+ if (pv->pv_ptpte && pv->pv_ptpmap == pmap_kernel())
+ break;
+ } while ((pv = pv->pv_next) != NULL);
+ if (pv == NULL)
+ continue;
+#ifdef DEBUG
+ if (pv->pv_va < (vm_offset_t)Sysmap ||
+ pv->pv_va >= (vm_offset_t)Sysmap + ALPHA_MAX_PTSIZE)
+ printf("collect: kernel PT VA out of range\n");
+ else
+ goto ok;
+ pmap_pvdump(pa);
+ continue;
+ok:
+#endif
+ pte = (pt_entry_t *)(pv->pv_va + ALPHA_PAGE_SIZE);
+ while (--pte >= (pt_entry_t *)pv->pv_va && *pte == PG_NV)
+ ;
+ if (pte >= (pt_entry_t *)pv->pv_va)
+ continue;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) {
+ printf("collect: freeing KPT page at %lx (ste %lx@%lx)\n",
+ pv->pv_va, *pv->pv_ptpte, pv->pv_ptpte);
+ opmapdebug = pmapdebug;
+ pmapdebug |= PDB_PTPAGE;
+ }
+
+ ste = pv->pv_ptpte;
+#endif
+ /*
+ * If all entries were invalid we can remove the page.
+ * We call pmap_remove_entry to take care of invalidating
+ * ST and Sysptmap entries.
+ */
+ kpa = pmap_extract(pmap, pv->pv_va);
+ pmap_remove_mapping(pmap, pv->pv_va, PT_ENTRY_NULL,
+ PRM_TFLUSH|PRM_CFLUSH);
+ /*
+ * Use the physical address to locate the original
+ * (kmem_alloc assigned) address for the page and put
+ * that page back on the free list.
+ */
+ for (pkpt = &kpt_used_list, kpt = *pkpt;
+ kpt != (struct kpt_page *)0;
+ pkpt = &kpt->kpt_next, kpt = *pkpt)
+ if (kpt->kpt_pa == kpa)
+ break;
+#ifdef DEBUG
+ if (kpt == (struct kpt_page *)0)
+ panic("pmap_collect: lost a KPT page");
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
+ printf("collect: %lx (%lx) to free list\n",
+ kpt->kpt_va, kpa);
+#endif
+ *pkpt = kpt->kpt_next;
+ kpt->kpt_next = kpt_free_list;
+ kpt_free_list = kpt;
+#ifdef PMAPSTATS
+ kpt_stats.kptinuse--;
+ kpt_stats.collectpages++;
+#endif
+#ifdef DEBUG
+ if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
+ pmapdebug = opmapdebug;
+
+ if (*ste)
+ printf("collect: kernel STE at %lx still valid (%lx)\n",
+ ste, *ste);
+ ste = &Sysptmap[(pt_entry_t *)ste-pmap_ste(pmap_kernel(), 0)];
+ if (*ste)
+ printf("collect: kernel PTmap at %lx still valid (%lx)\n",
+ ste, *ste);
+#endif
+ }
+ splx(s);
+}
+
+void
+pmap_activate(pmap)
+ register pmap_t pmap;
+{
+ int iscurproc;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_SEGTAB))
+ printf("pmap_activate(%lx)\n", pmap);
+#endif
+
+ iscurproc = curproc != NULL && pmap == curproc->p_vmspace->vm_map.pmap;
+ PMAP_ACTIVATE(pmap, iscurproc);
+}
+
+/*
+ * pmap_zero_page zeros the specified (machine independent)
+ * page by mapping the page into virtual memory and using
+ * bzero to clear its contents, one machine dependent page
+ * at a time.
+ */
+void
+pmap_zero_page(phys)
+ vm_offset_t phys;
+{
+ caddr_t p;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_zero_page(%lx)\n", phys);
+#endif
+ p = (caddr_t)ALPHA_PHYS_TO_K0SEG(phys);
+ bzero(p, PAGE_SIZE);
+}
+
+/*
+ * pmap_copy_page copies the specified (machine independent)
+ * page by mapping the page into virtual memory and using
+ * bcopy to copy the page, one machine dependent page at a
+ * time.
+ */
+void
+pmap_copy_page(src, dst)
+ vm_offset_t src, dst;
+{
+ caddr_t s, d;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_copy_page(%lx, %lx)\n", src, dst);
+#endif
+ s = (caddr_t)ALPHA_PHYS_TO_K0SEG(src);
+ d = (caddr_t)ALPHA_PHYS_TO_K0SEG(dst);
+ bcopy(s, d, PAGE_SIZE);
+}
+
+/*
+ * Routine: pmap_pageable
+ * Function:
+ * Make the specified pages (by pmap, offset)
+ * pageable (or not) as requested.
+ *
+ * A page which is not pageable may not take
+ * a fault; therefore, its page table entry
+ * must remain valid for the duration.
+ *
+ * This routine is merely advisory; pmap_enter
+ * will specify that these pages are to be wired
+ * down (or not) as appropriate.
+ */
+void
+pmap_pageable(pmap, sva, eva, pageable)
+ pmap_t pmap;
+ vm_offset_t sva, eva;
+ boolean_t pageable;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_pageable(%lx, %lx, %lx, %lx)\n",
+ pmap, sva, eva, pageable);
+#endif
+ /*
+ * If we are making a PT page pageable then all valid
+ * mappings must be gone from that page. Hence it should
+ * be all zeros and there is no need to clean it.
+ * Assumptions:
+ * - we are called with only one page at a time
+ * - PT pages have only one pv_table entry
+ */
+ if (pmap == pmap_kernel() && pageable && sva + PAGE_SIZE == eva) {
+ register pv_entry_t pv;
+ register vm_offset_t pa;
+
+#ifdef DEBUG
+ if ((pmapdebug & (PDB_FOLLOW|PDB_PTPAGE)) == PDB_PTPAGE)
+ printf("pmap_pageable(%lx, %lx, %lx, %lx)\n",
+ pmap, sva, eva, pageable);
+#endif
+ if (!pmap_ste_v(pmap, sva))
+ return;
+ pa = pmap_pte_pa(pmap_pte(pmap, sva));
+ if (!PAGE_IS_MANAGED(pa))
+ return;
+ pv = pa_to_pvh(pa);
+ if (pv->pv_ptpte == NULL)
+ return;
+#ifdef DEBUG
+ if (pv->pv_va != sva || pv->pv_next) {
+ printf("pmap_pageable: bad PT page va %lx next %lx\n",
+ pv->pv_va, pv->pv_next);
+ return;
+ }
+#endif
+ /*
+ * Mark it unmodified to avoid pageout
+ */
+ pmap_clear_modify(pa);
+#ifdef DEBUG
+ if ((PHYS_TO_VM_PAGE(pa)->flags & PG_CLEAN) == 0) {
+ printf("pa %lx: flags=%lx: not clean\n",
+ pa, PHYS_TO_VM_PAGE(pa)->flags);
+ PHYS_TO_VM_PAGE(pa)->flags |= PG_CLEAN;
+ }
+ if (pmapdebug & PDB_PTPAGE)
+ printf("pmap_pageable: PT page %lx(%lx) unmodified\n",
+ sva, *pmap_pte(pmap, sva));
+ if (pmapdebug & PDB_WIRING)
+ pmap_check_wiring("pageable", sva);
+#endif
+ }
+}
+
+/*
+ * Clear the modify bits on the specified physical page.
+ */
+
+void
+pmap_clear_modify(pa)
+ vm_offset_t pa;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_clear_modify(%lx)\n", pa);
+#endif
+ if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
+ return;
+ if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) != 0) {
+ pmap_changebit(pa, PG_FOW, TRUE);
+ pmap_attributes[pa_index(pa)] &= ~PMAP_ATTR_MOD;
+ }
+}
+
+/*
+ * pmap_clear_reference:
+ *
+ * Clear the reference bit on the specified physical page.
+ */
+
+void pmap_clear_reference(pa)
+ vm_offset_t pa;
+{
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_clear_reference(%lx)\n", pa);
+#endif
+ if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
+ return;
+ if ((pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) != 0) {
+ pmap_changebit(pa, PG_FOR | PG_FOW | PG_FOE, TRUE);
+ pmap_attributes[pa_index(pa)] &= ~PMAP_ATTR_REF;
+ }
+}
+
+/*
+ * pmap_is_referenced:
+ *
+ * Return whether or not the specified physical page is referenced
+ * by any physical maps.
+ */
+
+boolean_t
+pmap_is_referenced(pa)
+ vm_offset_t pa;
+{
+ boolean_t rv;
+
+ if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
+ return 0;
+ rv = (pmap_attributes[pa_index(pa)] & PMAP_ATTR_REF) != 0;
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ printf("pmap_is_referenced(%lx) -> %c\n", pa, "FT"[rv]);
+ }
+#endif
+ return rv;
+}
+
+/*
+ * pmap_is_modified:
+ *
+ * Return whether or not the specified physical page is modified
+ * by any physical maps.
+ */
+
+boolean_t
+pmap_is_modified(pa)
+ vm_offset_t pa;
+{
+ boolean_t rv;
+
+ if (!PAGE_IS_MANAGED(pa)) /* XXX why not panic? */
+ return 0;
+ rv = (pmap_attributes[pa_index(pa)] & PMAP_ATTR_MOD) != 0;
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ printf("pmap_is_modified(%lx) -> %c\n", pa, "FT"[rv]);
+ }
+#endif
+ return rv;
+}
+
+vm_offset_t
+pmap_phys_address(ppn)
+ int ppn;
+{
+ return(alpha_ptob(ppn));
+}
+
+/*
+ * Miscellaneous support routines follow
+ */
+
+/*
+ * Initialize Alpha protection code array.
+ */
+/* static */
+void
+alpha_protection_init()
+{
+ int prot, *kp, *up;
+
+ kp = protection_codes[0];
+ up = protection_codes[1];
+
+ for (prot = 0; prot < 8; prot++) {
+ switch (prot) {
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
+ *kp++ = PG_ASM;
+ *up++ = 0;
+ break;
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
+ *kp++ = PG_ASM | PG_KRE;
+ *up++ = PG_URE | PG_KRE;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
+ *kp++ = PG_ASM | PG_KWE;
+ *up++ = PG_UWE | PG_KWE;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ *kp++ = PG_ASM | PG_KWE | PG_KRE;
+ *up++ = PG_UWE | PG_URE | PG_KWE | PG_KRE;
+ break;
+ }
+ }
+}
+
+/*
+ * Invalidate a single page denoted by pmap/va.
+ * If (pte != NULL), it is the already computed PTE for the page.
+ * If (flags & PRM_TFLUSH), we must invalidate any TLB information.
+ * If (flags & PRM_CFLUSH), we must flush/invalidate any cache information.
+ */
+/* static */
+void
+pmap_remove_mapping(pmap, va, pte, flags)
+ register pmap_t pmap;
+ register vm_offset_t va;
+ register pt_entry_t *pte;
+ int flags;
+{
+ register vm_offset_t pa;
+ register pv_entry_t pv, npv;
+ pmap_t ptpmap;
+ pt_entry_t *ste;
+ int s;
+#ifdef DEBUG
+ pt_entry_t opte;
+
+ if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
+ printf("pmap_remove_mapping(%lx, %lx, %lx, %lx)\n",
+ pmap, va, pte, flags);
+#endif
+
+ /*
+ * PTE not provided, compute it from pmap and va.
+ */
+ if (pte == PT_ENTRY_NULL) {
+ pte = pmap_pte(pmap, va);
+ if (*pte == PG_NV)
+ return;
+ }
+ pa = pmap_pte_pa(pte);
+#ifdef DEBUG
+ opte = *pte;
+#endif
+#ifdef PMAPSTATS
+ remove_stats.removes++;
+#endif
+ /*
+ * Update statistics
+ */
+ if (pmap_pte_w(pte))
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+
+ /*
+ * Invalidate the PTE after saving the reference modify info.
+ */
+#ifdef DEBUG
+ if (pmapdebug & PDB_REMOVE)
+ printf("remove: invalidating pte at %lx\n", pte);
+#endif
+ *pte = PG_NV;
+ if ((flags & PRM_TFLUSH) && active_pmap(pmap))
+ ALPHA_TBIS(va);
+ /*
+ * For user mappings decrement the wiring count on
+ * the PT page. We do this after the PTE has been
+ * invalidated because vm_map_pageable winds up in
+ * pmap_pageable which clears the modify bit for the
+ * PT page.
+ */
+ if (pmap != pmap_kernel()) {
+ (void) vm_map_pageable(pt_map, trunc_page(pte),
+ round_page(pte+1), TRUE);
+#ifdef DEBUG
+ if (pmapdebug & PDB_WIRING)
+ pmap_check_wiring("remove", trunc_page(pte));
+#endif
+ }
+ /*
+ * If this isn't a managed page, we are all done.
+ */
+ if (!PAGE_IS_MANAGED(pa))
+ return;
+ /*
+ * Otherwise remove it from the PV table
+ * (raise IPL since we may be called at interrupt time).
+ */
+ pv = pa_to_pvh(pa);
+ ste = NULL;
+ s = splimp();
+ /*
+ * If it is the first entry on the list, it is actually
+ * in the header and we must copy the following entry up
+ * to the header. Otherwise we must search the list for
+ * the entry. In either case we free the now unused entry.
+ */
+ if (pmap == pv->pv_pmap && va == pv->pv_va) {
+ ste = pv->pv_ptpte;
+ ptpmap = pv->pv_ptpmap;
+ npv = pv->pv_next;
+ if (npv) {
+ npv->pv_flags = pv->pv_flags;
+ *pv = *npv;
+ free((caddr_t)npv, M_VMPVENT);
+ } else
+ pv->pv_pmap = NULL;
+#ifdef PMAPSTATS
+ remove_stats.pvfirst++;
+#endif
+ } else {
+ for (npv = pv->pv_next; npv; npv = npv->pv_next) {
+#ifdef PMAPSTATS
+ remove_stats.pvsearch++;
+#endif
+ if (pmap == npv->pv_pmap && va == npv->pv_va)
+ break;
+ pv = npv;
+ }
+#ifdef DEBUG
+ if (npv == NULL)
+ panic("pmap_remove: PA not in pv_tab");
+#endif
+ ste = npv->pv_ptpte;
+ ptpmap = npv->pv_ptpmap;
+ pv->pv_next = npv->pv_next;
+ free((caddr_t)npv, M_VMPVENT);
+ pv = pa_to_pvh(pa);
+ }
+ /*
+ * If this was a PT page we must also remove the
+ * mapping from the associated segment table.
+ */
+ if (ste) {
+#ifdef PMAPSTATS
+ remove_stats.ptinvalid++;
+#endif
+#ifdef DEBUG
+ if (pmapdebug & (PDB_REMOVE|PDB_PTPAGE))
+ printf("remove: ste was %lx@%lx pte was %lx@%lx\n",
+ *ste, ste, opte, pmap_pte(pmap, va));
+#endif
+ *ste = PG_NV;
+ /*
+ * If it was a user PT page, we decrement the
+ * reference count on the segment table as well,
+ * freeing it if it is now empty.
+ */
+ if (ptpmap != pmap_kernel()) {
+#ifdef DEBUG
+ if (pmapdebug & (PDB_REMOVE|PDB_SEGTAB))
+ printf("remove: stab %lx, refcnt %d\n",
+ ptpmap->pm_stab, ptpmap->pm_sref - 1);
+ if ((pmapdebug & PDB_PARANOIA) &&
+ ptpmap->pm_stab != (pt_entry_t *)trunc_page(ste))
+ panic("remove: bogus ste");
+#endif
+ if (--(ptpmap->pm_sref) == 0) {
+#ifdef DEBUG
+ if (pmapdebug&(PDB_REMOVE|PDB_SEGTAB))
+ printf("remove: free stab %lx\n",
+ ptpmap->pm_stab);
+#endif
+ kmem_free_wakeup(st_map,
+ (vm_offset_t)ptpmap->pm_stab,
+ ALPHA_STSIZE);
+ ptpmap->pm_stab = Segtabzero;
+ ptpmap->pm_stpte = Segtabzeropte;
+ ptpmap->pm_stchanged = TRUE;
+ /*
+ * XXX may have changed segment table
+ * pointer for current process so
+ * update now to reload hardware.
+ * (curproc may be NULL if exiting.)
+ */
+ if (curproc != NULL &&
+ ptpmap == curproc->p_vmspace->vm_map.pmap)
+ PMAP_ACTIVATE(ptpmap, 1);
+ }
+#ifdef DEBUG
+ else if (ptpmap->pm_sref < 0)
+ panic("remove: sref < 0");
+#endif
+ }
+#if 0
+ /*
+ * XXX this should be unnecessary as we have been
+ * flushing individual mappings as we go.
+ */
+ if (ptpmap == pmap_kernel())
+ ALPHA_TBIAS();
+ else
+ ALPHA_TBIAU();
+#endif
+ pv->pv_flags &= ~PV_PTPAGE;
+ ptpmap->pm_ptpages--;
+ }
+ splx(s);
+}
+
+/* static */
+void
+pmap_changebit(pa, bit, setem)
+ register vm_offset_t pa;
+ u_long bit;
+ boolean_t setem;
+{
+ register pv_entry_t pv;
+ register pt_entry_t *pte, npte;
+ vm_offset_t va;
+ int s;
+#ifdef PMAPSTATS
+ struct chgstats *chgp;
+#endif
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_BITS)
+ printf("pmap_changebit(%lx, %lx, %s)\n",
+ pa, bit, setem ? "set" : "clear");
+#endif
+ if (!PAGE_IS_MANAGED(pa))
+ return;
+
+#ifdef PMAPSTATS
+ chgp = &changebit_stats[(bit>>2)-1];
+ if (setem)
+ chgp->setcalls++;
+ else
+ chgp->clrcalls++;
+#endif
+ pv = pa_to_pvh(pa);
+ s = splimp();
+ /*
+ * Loop over all current mappings setting/clearing as appropos
+ * If setting RO do we need to clear the VAC?
+ */
+ if (pv->pv_pmap != NULL) {
+#ifdef DEBUG
+ int toflush = 0;
+#endif
+ for (; pv; pv = pv->pv_next) {
+#ifdef DEBUG
+ toflush |= (pv->pv_pmap == pmap_kernel()) ? 2 : 1;
+#endif
+ va = pv->pv_va;
+
+ /*
+ * XXX don't write protect pager mappings
+ */
+/* XXX */ if (bit == (PG_UWE | PG_KWE)) {
+ extern vm_offset_t pager_sva, pager_eva;
+
+ if (va >= pager_sva && va < pager_eva)
+ continue;
+ }
+
+ pte = pmap_pte(pv->pv_pmap, va);
+ if (setem)
+ npte = *pte | bit;
+ else
+ npte = *pte & ~bit;
+ if (*pte != npte) {
+ *pte = npte;
+ if (active_pmap(pv->pv_pmap))
+ ALPHA_TBIS(va);
+#ifdef PMAPSTATS
+ if (setem)
+ chgp->sethits++;
+ else
+ chgp->clrhits++;
+#endif
+ }
+#ifdef PMAPSTATS
+ else {
+ if (setem)
+ chgp->setmiss++;
+ else
+ chgp->clrmiss++;
+ }
+#endif
+ }
+ }
+ splx(s);
+}
+
+/* static */
+void
+pmap_enter_ptpage(pmap, va)
+ register pmap_t pmap;
+ register vm_offset_t va;
+{
+ register vm_offset_t ptpa;
+ register pv_entry_t pv;
+ pt_entry_t *ste;
+ int s;
+
+#ifdef DEBUG
+ if (pmapdebug & (PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE))
+ printf("pmap_enter_ptpage: pmap %lx, va %lx\n", pmap, va);
+#endif
+#ifdef PMAPSTATS
+ enter_stats.ptpneeded++;
+#endif
+ /*
+ * Allocate a segment table if necessary. Note that it is allocated
+ * from a private map and not pt_map. This keeps user page tables
+ * aligned on segment boundaries in the kernel address space.
+ * The segment table is wired down. It will be freed whenever the
+ * reference count drops to zero.
+ */
+ if (pmap->pm_stab == Segtabzero) {
+ pmap->pm_stab = (pt_entry_t *)
+ kmem_alloc(st_map, ALPHA_STSIZE);
+ pmap->pm_stpte = *kvtopte(pmap->pm_stab);
+ pmap->pm_stchanged = TRUE;
+ /*
+ * XXX may have changed segment table pointer for current
+ * process so update now to reload hardware.
+ */
+ if (pmap == curproc->p_vmspace->vm_map.pmap)
+ PMAP_ACTIVATE(pmap, 1);
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
+ printf("enter: pmap %lx stab %lx(%lx)\n",
+ pmap, pmap->pm_stab, pmap->pm_stpte);
+#endif
+ }
+
+ ste = pmap_ste(pmap, va);
+ va = trunc_page((vm_offset_t)pmap_pte(pmap, va));
+
+ /*
+ * In the kernel we allocate a page from the kernel PT page
+ * free list and map it into the kernel page table map (via
+ * pmap_enter).
+ */
+ if (pmap == pmap_kernel()) {
+ register struct kpt_page *kpt;
+
+ s = splimp();
+ if ((kpt = kpt_free_list) == (struct kpt_page *)0) {
+ /*
+ * No PT pages available.
+ * Try once to free up unused ones.
+ */
+#ifdef DEBUG
+ if (pmapdebug & PDB_COLLECT)
+ printf("enter: no KPT pages, collecting...\n");
+#endif
+ pmap_collect(pmap_kernel());
+ if ((kpt = kpt_free_list) == (struct kpt_page *)0)
+ panic("pmap_enter_ptpage: can't get KPT page");
+ }
+#ifdef PMAPSTATS
+ if (++kpt_stats.kptinuse > kpt_stats.kptmaxuse)
+ kpt_stats.kptmaxuse = kpt_stats.kptinuse;
+#endif
+ kpt_free_list = kpt->kpt_next;
+ kpt->kpt_next = kpt_used_list;
+ kpt_used_list = kpt;
+ ptpa = kpt->kpt_pa;
+ bzero((caddr_t)kpt->kpt_va, ALPHA_PAGE_SIZE);
+ pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT, TRUE);
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) {
+ int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0);
+
+ printf("enter: add &Sysptmap[%d]: %lx (KPT page %lx)\n",
+ ix, Sysptmap[ix], kpt->kpt_va);
+ }
+#endif
+ splx(s);
+ }
+ /*
+ * For user processes we just simulate a fault on that location
+ * letting the VM system allocate a zero-filled page.
+ */
+ else {
+ /*
+ * Count the segment table reference now so that we won't
+ * lose the segment table when low on memory.
+ */
+ pmap->pm_sref++;
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
+ printf("enter: about to fault UPT pg at %lx\n", va);
+#endif
+ s = vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE);
+ if (s != KERN_SUCCESS) {
+ printf("vm_fault(pt_map, %lx, RW, 0) -> %d\n", va, s);
+ panic("pmap_enter: vm_fault failed");
+ }
+ ptpa = pmap_extract(pmap_kernel(), va);
+ /*
+ * Mark the page clean now to avoid its pageout (and
+ * hence creation of a pager) between now and when it
+ * is wired; i.e. while it is on a paging queue.
+ */
+ PHYS_TO_VM_PAGE(ptpa)->flags |= PG_CLEAN;
+#ifdef DEBUG
+ PHYS_TO_VM_PAGE(ptpa)->flags |= PG_PTPAGE;
+#endif
+ }
+ /*
+ * Locate the PV entry in the kernel for this PT page and
+ * record the STE address. This is so that we can invalidate
+ * the STE when we remove the mapping for the page.
+ */
+ pv = pa_to_pvh(ptpa);
+ s = splimp();
+ if (pv) {
+ pv->pv_flags |= PV_PTPAGE;
+ do {
+ if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va)
+ break;
+ } while ((pv = pv->pv_next) != NULL);
+ }
+#ifdef DEBUG
+ if (pv == NULL)
+ panic("pmap_enter_ptpage: PT page not entered");
+#endif
+ pv->pv_ptpte = ste;
+ pv->pv_ptpmap = pmap;
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
+ printf("enter: new PT page at PA %lx, ste at %lx\n", ptpa, ste);
+#endif
+
+ /*
+ * Map the new PT page into the segment table.
+ * Reference count on the user segment tables incremented above
+ * to prevent race conditions. Note that we don't use vm_map_pageable
+ * to keep the count like we do for PT pages, this is mostly because
+ * it would be difficult to identify ST pages in pmap_pageable to
+ * release them. We also avoid the overhead of vm_map_pageable.
+ */
+ *ste = ((ptpa >> PGSHIFT) << PG_SHIFT) | PG_KRE | PG_KWE | PG_V |
+ (pmap == pmap_kernel() ? PG_ASM : 0);
+ if (pmap != pmap_kernel()) {
+#ifdef DEBUG
+ if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
+ printf("enter: stab %lx refcnt %d\n",
+ pmap->pm_stab, pmap->pm_sref);
+#endif
+ }
+#if 0
+ /*
+ * Flush stale TLB info.
+ */
+ if (pmap == pmap_kernel())
+ ALPHA_TBIAS();
+ else
+ ALPHA_TBIAU();
+#endif
+ pmap->pm_ptpages++;
+ splx(s);
+}
+
+/*
+ * Emulate reference and/or modified bit hits.
+ */
+void
+pmap_emulate_reference(p, v, user, write)
+ struct proc *p;
+ vm_offset_t v;
+ int user;
+ int write;
+{
+ pt_entry_t faultoff, *pte;
+ vm_offset_t pa;
+ char attr;
+
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("pmap_emulate_reference: 0x%lx, 0x%lx, %d, %d\n",
+ p, v, user, write);
+#endif
+
+ /*
+ * Convert process and virtual address to physical address.
+ */
+ if (v >= VM_MIN_KERNEL_ADDRESS) {
+ if (user)
+ panic("pmap_emulate_reference: user ref to kernel");
+ pte = kvtopte(v);
+ } else {
+#ifdef DIAGNOSTIC
+ if (p == NULL)
+ panic("pmap_emulate_reference: bad proc");
+ if (p->p_vmspace == NULL)
+ panic("pmap_emulate_reference: bad p_vmspace");
+#endif
+ pte = pmap_pte(&p->p_vmspace->vm_pmap, v);
+ }
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW) {
+ printf("\tpte = 0x%lx, ", pte);
+ printf("*pte = 0x%lx\n", *pte);
+ }
+#endif
+#ifdef DEBUG /* These checks are more expensive */
+ if (!pmap_pte_v(pte))
+ panic("pmap_emulate_reference: invalid pte");
+#if 0
+ /*
+ * Can't do these, because cpu_fork and cpu_swapin call
+ * pmap_emulate_reference(), and the bits aren't guaranteed,
+ * for them...
+ */
+ if (write) {
+ if (!(*pte & (user ? PG_UWE : PG_UWE | PG_KWE)))
+ panic("pmap_emulate_reference: write but unwritable");
+ if (!(*pte & PG_FOW))
+ panic("pmap_emulate_reference: write but not FOW");
+ } else {
+ if (!(*pte & (user ? PG_URE : PG_URE | PG_KRE)))
+ panic("pmap_emulate_reference: !write but unreadable");
+ if (!(*pte & (PG_FOR | PG_FOE)))
+ panic("pmap_emulate_reference: !write but not FOR|FOE");
+ }
+#endif
+ /* Other diagnostics? */
+#endif
+ pa = pmap_pte_pa(pte);
+#ifdef DEBUG
+ if (pmapdebug & PDB_FOLLOW)
+ printf("\tpa = 0x%lx\n", pa);
+#endif
+#ifdef DIAGNOSTIC
+ if (!PAGE_IS_MANAGED(pa))
+ printf("WARNING: pmap_emulate_reference(0x%lx, 0x%lx, %d, %d): pa 0x%lx not managed\n", p, v, user, write, pa);
+#endif
+
+ /*
+ * Twiddle the appropriate bits to reflect the reference
+ * and/or modification..
+ *
+ * The rules:
+ * (1) always mark page as used, and
+ * (2) if it was a write fault, mark page as modified.
+ */
+ attr = PMAP_ATTR_REF;
+ faultoff = PG_FOR | PG_FOE;
+ if (write) {
+ attr |= PMAP_ATTR_MOD;
+ faultoff |= PG_FOW;
+ }
+ pmap_attributes[pa_index(pa)] |= attr;
+ pmap_changebit(pa, faultoff, FALSE);
+ if ((*pte & faultoff) != 0) {
+#if 0
+ /*
+ * This is apparently normal. Why? -- cgd
+ * XXX because was being called on unmanaged pages?
+ */
+ printf("warning: pmap_changebit didn't.");
+#endif
+ *pte &= ~faultoff;
+ ALPHA_TBIS(v);
+ }
+}
+
+#ifdef DEBUG
+/* static */
+void
+pmap_pvdump(pa)
+ vm_offset_t pa;
+{
+ register pv_entry_t pv;
+
+ printf("pa %lx", pa);
+ for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
+ printf(" -> pmap %lx, va %lx, stpte %lx, ptpmap %lx, flags %lx",
+ pv->pv_pmap, pv->pv_va, pv->pv_ptpte, pv->pv_ptpmap,
+ pv->pv_flags);
+ printf("\n");
+}
+
+/* static */
+void
+pmap_check_wiring(str, va)
+ char *str;
+ vm_offset_t va;
+{
+ vm_map_entry_t entry;
+ pt_entry_t *pte;
+ register int count;
+
+ va = trunc_page(va);
+ if (!pmap_ste_v(pmap_kernel(), va) ||
+ !pmap_pte_v(pmap_pte(pmap_kernel(), va)))
+ return;
+
+ if (!vm_map_lookup_entry(pt_map, va, &entry)) {
+ printf("wired_check: entry for %lx not found\n", va);
+ return;
+ }
+ count = 0;
+ for (pte = (pt_entry_t *)va; pte < (pt_entry_t *)(va+PAGE_SIZE); pte++)
+ if (*pte)
+ count++;
+ if (entry->wired_count != count)
+ printf("*%s*: %lx: w%d/a%d\n",
+ str, va, entry->wired_count, count);
+}
+#endif
+
+vm_offset_t
+vtophys(vaddr)
+ vm_offset_t vaddr;
+{
+ vm_offset_t paddr;
+
+ if (vaddr < ALPHA_K0SEG_BASE) {
+ printf("vtophys: invalid vaddr 0x%lx", vaddr);
+ paddr = vaddr;
+ } else if (vaddr <= ALPHA_K0SEG_END)
+ paddr = ALPHA_K0SEG_TO_PHYS(vaddr);
+ else
+ paddr = vatopa(vaddr);
+
+#if 0
+ printf("vtophys(0x%lx) -> %lx\n", vaddr, paddr);
+#endif
+
+ return (paddr);
+}
diff --git a/sys/arch/alpha/alpha/process_machdep.c b/sys/arch/alpha/alpha/process_machdep.c
index c9f6b8af9d9..be249eec38c 100644
--- a/sys/arch/alpha/alpha/process_machdep.c
+++ b/sys/arch/alpha/alpha/process_machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: process_machdep.c,v 1.3 1996/07/29 22:57:56 niklas Exp $ */
-/* $NetBSD: process_machdep.c,v 1.3 1995/11/23 02:34:29 cgd Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.4 1996/10/30 22:38:23 niklas Exp $ */
+/* $NetBSD: process_machdep.c,v 1.7 1996/07/11 20:14:21 cgd Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -64,7 +64,8 @@
#include <machine/frame.h>
#define process_frame(p) ((p)->p_md.md_tf)
-#define process_fpframe(p) (&(p)->p_addr->u_pcb.pcb_fp)
+#define process_pcb(p) (&(p)->p_addr->u_pcb)
+#define process_fpframe(p) (&(process_pcb(p)->pcb_fp))
int
process_read_regs(p, regs)
@@ -73,7 +74,8 @@ process_read_regs(p, regs)
{
frametoreg(process_frame(p), regs);
- regs->r_regs[R_ZERO] = process_frame(p)->tf_pc;
+ regs->r_regs[R_ZERO] = process_frame(p)->tf_regs[FRAME_PC];
+ regs->r_regs[R_SP] = process_pcb(p)->pcb_hw.apcb_usp;
return (0);
}
@@ -83,8 +85,9 @@ process_write_regs(p, regs)
struct reg *regs;
{
- process_frame(p)->tf_pc = regs->r_regs[R_ZERO];
regtoframe(regs, process_frame(p));
+ process_frame(p)->tf_regs[FRAME_PC] = regs->r_regs[R_ZERO];
+ process_pcb(p)->pcb_hw.apcb_usp = regs->r_regs[R_SP];
return (0);
}
@@ -107,7 +110,7 @@ process_set_pc(p, addr)
{
struct trapframe *frame = process_frame(p);
- frame->tf_pc = (u_int64_t)addr;
+ frame->tf_regs[FRAME_PC] = (u_int64_t)addr;
return (0);
}
@@ -119,9 +122,9 @@ process_read_fpregs(p, regs)
extern struct proc *fpcurproc;
if (p == fpcurproc) {
- pal_wrfen(1);
+ alpha_pal_wrfen(1);
savefpstate(process_fpframe(p));
- pal_wrfen(0);
+ alpha_pal_wrfen(0);
}
bcopy(process_fpframe(p), regs, sizeof(struct fpreg));
diff --git a/sys/arch/alpha/alpha/prom.c b/sys/arch/alpha/alpha/prom.c
index 8678f12be04..f3df0cb78a7 100644
--- a/sys/arch/alpha/alpha/prom.c
+++ b/sys/arch/alpha/alpha/prom.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: prom.c,v 1.3 1996/07/29 22:57:57 niklas Exp $ */
-/* $NetBSD: prom.c,v 1.5.4.2 1996/06/13 18:35:21 cgd Exp $ */
+/* $OpenBSD: prom.c,v 1.4 1996/10/30 22:38:23 niklas Exp $ */
+/* $NetBSD: prom.c,v 1.11 1996/10/16 00:00:40 cgd Exp $ */
/*
* Copyright (c) 1992, 1994, 1995, 1996 Carnegie Mellon University
@@ -27,16 +27,25 @@
*/
#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/systm.h>
#include <machine/rpb.h>
#include <machine/prom.h>
-#include <machine/pte.h>
+#ifdef NEW_PMAP
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#endif
#include <dev/cons.h>
/* XXX this is to fake out the console routines, while booting. */
void promcnputc __P((dev_t, int));
int promcngetc __P((dev_t));
+u_int64_t hwrpb_checksum __P((void));
+long console_restart __P((u_int64_t, u_int64_t, u_int64_t));
+
struct consdev promcons = { NULL, NULL, promcngetc, promcnputc,
nullcnpollc, makedev(23,0), 1 };
@@ -48,6 +57,10 @@ extern struct prom_vec prom_dispatch_v;
pt_entry_t *rom_ptep, rom_pte, saved_pte; /* XXX */
+#ifdef NEW_PMAP
+#define rom_ptep (curproc ? &curproc->p_vmspace->vm_pmap.dir[0] : rom_ptep)
+#endif
+
void
init_prom_interface()
{
@@ -82,7 +95,7 @@ promcnputc(dev, c)
int c;
{
prom_return_t ret;
- unsigned char *to = (unsigned char *)0x20000000;
+ u_char *to = (u_char *)0x20000000;
int s;
#ifdef notdef /* XXX */
@@ -94,7 +107,7 @@ promcnputc(dev, c)
if (!prom_mapped) { /* XXX */
saved_pte = *rom_ptep; /* XXX */
*rom_ptep = rom_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
*to = c;
@@ -104,7 +117,7 @@ promcnputc(dev, c)
if (!prom_mapped) { /* XXX */
*rom_ptep = saved_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
splx(s);
}
@@ -131,12 +144,12 @@ promcngetc(dev)
if (!prom_mapped) { /* XXX */
saved_pte = *rom_ptep; /* XXX */
*rom_ptep = rom_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
- ret.bits = prom_dispatch(PROM_R_GETC, alpha_console);
+ ret.bits = prom_dispatch(PROM_R_GETC, alpha_console, 0, 0);
if (!prom_mapped) { /* XXX */
*rom_ptep = saved_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
splx(s);
if (ret.u.status == 0 || ret.u.status == 1)
@@ -166,12 +179,12 @@ promcnlookc(dev, cp)
if (!prom_mapped) { /* XXX */
saved_pte = *rom_ptep; /* XXX */
*rom_ptep = rom_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
- ret.bits = prom_dispatch(PROM_R_GETC, alpha_console);
+ ret.bits = prom_dispatch(PROM_R_GETC, alpha_console, 0, 0);
if (!prom_mapped) { /* XXX */
*rom_ptep = saved_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
}
splx(s);
if (ret.u.status == 0 || ret.u.status == 1) {
@@ -199,13 +212,13 @@ prom_getenv(id, buf, len)
if (!prom_mapped) { /* XXX */
saved_pte = *rom_ptep; /* XXX */
*rom_ptep = rom_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
ret.bits = prom_dispatch(PROM_R_GETENV, id, to, len);
bcopy(to, buf, len);
if (!prom_mapped) { /* XXX */
*rom_ptep = saved_pte; /* XXX */
- TBIA(); /* XXX */
+ ALPHA_TBIA(); /* XXX */
} /* XXX */
splx(s);
@@ -232,8 +245,7 @@ prom_halt(halt)
* we want to happen when we halt.
*/
p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
- /* XXX BIP should have been cleared long ago. */
- p->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ | PCS_BIP);
+ p->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ);
if (halt)
p->pcs_flags |= PCS_HALT_STAY_HALTED;
else
@@ -242,5 +254,66 @@ prom_halt(halt)
/*
* Halt the machine.
*/
- pal_halt();
+ alpha_pal_halt();
+}
+
+u_int64_t
+hwrpb_checksum()
+{
+ u_int64_t *p, sum;
+ int i;
+
+#define offsetof(type, member) ((size_t)(&((type *)0)->member)) /* XXX */
+
+ for (i = 0, p = (u_int64_t *)hwrpb, sum = 0;
+ i < (offsetof(struct rpb, rpb_checksum) / sizeof (u_int64_t));
+ i++, p++)
+ sum += *p;
+
+ return (sum);
+}
+
+void XentRestart __P((void));
+
+void
+hwrbp_restart_setup()
+{
+ struct pcs *p;
+
+ /* Clear bootstrap-in-progress flag since we're done bootstrapping */
+ p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
+ p->pcs_flags &= ~PCS_BIP;
+
+ bcopy(&proc0.p_addr->u_pcb.pcb_hw, p->pcs_hwpcb,
+ sizeof proc0.p_addr->u_pcb.pcb_hw);
+ hwrpb->rpb_vptb = VPTBASE;
+
+ /* when 'c'ontinuing from console halt, do a dump */
+ hwrpb->rpb_rest_term = (long (*) __P((long)))&XentRestart;
+ hwrpb->rpb_rest_term_val = 0x1;
+
+#if 0
+ /* don't know what this is really used by, so don't mess with it. */
+ hwrpb->rpb_restart = (long (*) __P((long)))&XentRestart;
+ hwrpb->rpb_restart_val = 0x2;
+#endif
+
+ hwrpb->rpb_checksum = hwrpb_checksum();
+
+ p->pcs_flags |= (PCS_RC | PCS_CV);
+}
+
+long
+console_restart(ra, ai, pv)
+ u_int64_t ra, ai, pv;
+{
+ struct pcs *p;
+
+ /* Clear restart-capable flag, since we can no longer restart. */
+ p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
+ p->pcs_flags &= ~PCS_RC;
+
+ panic("user requested console halt");
+
+ return (1);
}
diff --git a/sys/arch/alpha/alpha/prom_disp.s b/sys/arch/alpha/alpha/prom_disp.s
index 68b176394b1..73ac11d8348 100644
--- a/sys/arch/alpha/alpha/prom_disp.s
+++ b/sys/arch/alpha/alpha/prom_disp.s
@@ -1,5 +1,5 @@
-/* $OpenBSD: prom_disp.s,v 1.3 1996/07/29 22:57:59 niklas Exp $ */
-/* $NetBSD: prom_disp.s,v 1.4 1996/04/12 06:07:38 cgd Exp $ */
+/* $OpenBSD: prom_disp.s,v 1.4 1996/10/30 22:38:24 niklas Exp $ */
+/* $NetBSD: prom_disp.s,v 1.5 1996/09/17 21:17:14 cgd Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -30,12 +30,10 @@
#ifndef _LOCORE
#include <machine/asm.h>
-#include <machine/prom.h>
-#include <machine/rpb.h>
#endif
.globl prom_dispatch_v
- .comm prom_dispatch_v 16
+ .comm prom_dispatch_v,16
.text
.align 4
diff --git a/sys/arch/alpha/alpha/promcons.c b/sys/arch/alpha/alpha/promcons.c
index cafa9a8e8c0..60382a24814 100644
--- a/sys/arch/alpha/alpha/promcons.c
+++ b/sys/arch/alpha/alpha/promcons.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: promcons.c,v 1.3 1996/07/29 22:58:00 niklas Exp $ */
-/* $NetBSD: promcons.c,v 1.2.6.1 1996/06/03 18:54:31 cgd Exp $ */
+/* $OpenBSD: promcons.c,v 1.4 1996/10/30 22:38:25 niklas Exp $ */
+/* $NetBSD: promcons.c,v 1.3 1996/05/30 18:44:30 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -43,10 +43,18 @@
#include <sys/types.h>
#include <sys/device.h>
+#include <dev/cons.h>
+
+#include <machine/rpb.h>
+#include <machine/prom.h>
+
static struct tty *prom_tty[1];
-void promstart(), promtimeout();
-int promparam();
+void promstart __P((struct tty *));
+void promtimeout __P((void *));
+int promparam __P((struct tty *, struct termios *));
+cdev_decl(prom);
+cons_decl(prom);
int
promopen(dev, flag, mode, p)
@@ -55,7 +63,6 @@ promopen(dev, flag, mode, p)
struct proc *p;
{
int unit = minor(dev);
- u_short iobase;
struct tty *tp;
int s;
int error = 0, setuptimeout = 0;
@@ -193,9 +200,10 @@ out:
/*
* Stop output on a line.
*/
-void
+int
promstop(tp, flag)
struct tty *tp;
+ int flag;
{
int s;
@@ -204,12 +212,14 @@ promstop(tp, flag)
if ((tp->t_state & TS_TTSTOP) == 0)
tp->t_state |= TS_FLUSH;
splx(s);
+ return 0;
}
void
-promtimeout(tp)
- struct tty *tp;
+promtimeout(v)
+ void *v;
{
+ struct tty *tp = v;
u_char c;
while (promcnlookc(tp->t_dev, &c)) {
diff --git a/sys/arch/alpha/alpha/rd_root.c b/sys/arch/alpha/alpha/rd_root.c
new file mode 100644
index 00000000000..ac46e33d9ee
--- /dev/null
+++ b/sys/arch/alpha/alpha/rd_root.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: rd_root.c,v 1.1 1996/10/30 22:38:26 niklas Exp $ */
+/* $NetBSD: rd_root.c,v 1.5 1996/10/13 02:59:47 christos Exp $ */
+
+/*
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+
+#include <dev/ramdisk.h>
+
+extern int boothowto;
+
+#ifndef MINIROOTSIZE
+#define MINIROOTSIZE 512
+#endif
+
+#define ROOTBYTES (MINIROOTSIZE << DEV_BSHIFT)
+
+/*
+ * This array will be patched to contain a file-system image.
+ */
+u_int32_t rd_root_size = ROOTBYTES;
+char rd_root_image[ROOTBYTES] = "|This is the root ramdisk!\n";
+
+/*
+ * This is called during autoconfig.
+ */
+void
+rd_attach_hook(unit, rd)
+ int unit;
+ struct rd_conf *rd;
+{
+
+ if (unit == 0) {
+ /* Setup root ramdisk */
+ rd->rd_addr = (caddr_t)rd_root_image;
+ rd->rd_size = (size_t)rd_root_size;
+ rd->rd_type = RD_KMEM_FIXED;
+ printf("rd%d: internal %dK image area\n", unit,
+ ROOTBYTES / 1024);
+ }
+}
+
+/*
+ * This is called during open (i.e. mountroot)
+ */
+void
+rd_open_hook(unit, rd)
+ int unit;
+ struct rd_conf *rd;
+{
+
+ if (unit == 0) {
+ /* The root ramdisk only works single-user. */
+ boothowto |= RB_SINGLE;
+ }
+}
diff --git a/sys/arch/alpha/alpha/support.c b/sys/arch/alpha/alpha/support.c
index 48c7010794e..51a0cae1ce1 100644
--- a/sys/arch/alpha/alpha/support.c
+++ b/sys/arch/alpha/alpha/support.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: support.c,v 1.3 1996/07/29 22:58:02 niklas Exp $ */
+/* $OpenBSD: support.c,v 1.4 1996/10/30 22:38:27 niklas Exp $ */
/* $NetBSD: support.c,v 1.2 1995/11/23 02:34:32 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/alpha/swapgeneric.c b/sys/arch/alpha/alpha/swapgeneric.c
index 9d0c3d51ae0..66648a92192 100644
--- a/sys/arch/alpha/alpha/swapgeneric.c
+++ b/sys/arch/alpha/alpha/swapgeneric.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: swapgeneric.c,v 1.3 1996/07/29 22:58:03 niklas Exp $ */
-/* $NetBSD: swapgeneric.c,v 1.4.4.1 1996/06/13 18:02:37 cgd Exp $ */
+/* $OpenBSD: swapgeneric.c,v 1.4 1996/10/30 22:38:27 niklas Exp $ */
+/* $NetBSD: swapgeneric.c,v 1.5 1996/06/12 01:26:37 cgd Exp $ */
/*-
* Copyright (c) 1994
diff --git a/sys/arch/alpha/alpha/sys_machdep.c b/sys/arch/alpha/alpha/sys_machdep.c
index f1bdce6a8c5..eabe550b2ec 100644
--- a/sys/arch/alpha/alpha/sys_machdep.c
+++ b/sys/arch/alpha/alpha/sys_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_machdep.c,v 1.3 1996/07/29 22:58:05 niklas Exp $ */
+/* $OpenBSD: sys_machdep.c,v 1.4 1996/10/30 22:38:28 niklas Exp $ */
/* $NetBSD: sys_machdep.c,v 1.3 1995/11/23 02:34:35 cgd Exp $ */
/*
@@ -40,10 +40,12 @@ sys_sysarch(p, v, retval)
void *v;
register_t *retval;
{
+#if 0
struct sys_sysarch_args /* {
syscallarg(int) op;
syscallarg(char *) parms;
} */ *uap = v;
+#endif
return (ENOSYS);
}
diff --git a/sys/arch/alpha/alpha/trap.c b/sys/arch/alpha/alpha/trap.c
index c489c7162fd..ce38dec1827 100644
--- a/sys/arch/alpha/alpha/trap.c
+++ b/sys/arch/alpha/alpha/trap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: trap.c,v 1.4 1996/07/29 22:58:06 niklas Exp $ */
-/* $NetBSD: trap.c,v 1.5 1995/11/23 02:34:37 cgd Exp $ */
+/* $OpenBSD: trap.c,v 1.5 1996/10/30 22:38:29 niklas Exp $ */
+/* $NetBSD: trap.c,v 1.16 1996/10/13 02:59:48 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -33,18 +33,29 @@
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/syscall.h>
+#include <sys/buf.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <machine/cpu.h>
#include <machine/reg.h>
-#include <machine/trap.h>
#ifdef COMPAT_OSF1
#include <compat/osf1/osf1_syscall.h>
#endif
+static __inline void userret __P((struct proc *, u_int64_t, u_quad_t));
+void trap __P((const u_long, const u_long, const u_long, const u_long,
+ struct trapframe *));
+int unaligned_fixup __P((u_long, u_long, u_long, struct proc *));
+void syscall __P((u_int64_t, struct trapframe *));
+void child_return __P((struct proc *));
+void ast __P((struct trapframe *));
+u_long Sfloat_to_reg __P((u_int));
+u_int reg_to_Sfloat __P((u_long));
+u_long Tfloat_reg_cvt __P((u_long));
+
struct proc *fpcurproc; /* current user of the FPU */
/*
@@ -94,230 +105,314 @@ userret(p, pc, oticks)
}
/*
- * Trap is called from locore to handle most types of processor traps,
- * including events such as simulated software interrupts/AST's.
- * System calls are broken out for efficiency.
+ * Trap is called from locore to handle most types of processor traps.
+ * System calls are broken out for efficiency and ASTs are broken out
+ * to make the code a bit cleaner and more representative of the
+ * Alpha architecture.
*/
/*ARGSUSED*/
-trap(type, code, v, framep)
- unsigned long type;
- unsigned long code;
- register unsigned long v;
+void
+trap(a0, a1, a2, entry, framep)
+ const unsigned long a0, a1, a2, entry;
struct trapframe *framep;
{
- extern char fswintr[];
register struct proc *p;
register int i;
u_int64_t ucode;
u_quad_t sticks;
+ int user;
cnt.v_trap++;
p = curproc;
ucode = 0;
- if (USERMODE(framep->tf_ps)) {
- type |= T_USER;
+ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0) {
+ user = 1;
sticks = p->p_sticks;
p->p_md.md_tf = framep;
- }
-#ifdef DDB
- if (type == T_BPT) {
- if (kdb_trap(type, framep))
- return;
- }
-#endif
- switch (type) {
+ } else
+ user = 0;
- default:
-dopanic:
- printf("trap type %ld, code = 0x%lx, v = 0x%lx\n", type,
- code, v);
- printf("pc = 0x%lx\n", framep->tf_pc);
- printf("curproc = 0x%lx\n", curproc);
- if (curproc != NULL)
- printf("curproc->p_pid = 0x%d\n", curproc->p_pid);
-
-#ifdef DDB
- if (kdb_trap(type, framep))
- return;
-#endif
- regdump(framep);
- type &= ~T_USER;
-#ifdef XXX
- if ((unsigned)type < trap_types)
- panic(trap_type[type]);
-#endif
- panic("trap");
-
- case T_ASTFLT:
- /* oops. this can't happen. */
- goto dopanic;
+ switch (entry) {
+ case ALPHA_KENTRY_UNA:
+ /*
+ * If user-land, do whatever fixups, printing, and
+ * signalling is appropriate (based on system-wide
+ * and per-process unaligned-access-handling flags).
+ */
+ if (user) {
+ if ((i = unaligned_fixup(a0, a1, a2, p)) == 0)
+ goto out;
- case T_ASTFLT|T_USER:
- astpending = 0;
- cnt.v_soft++;
- if (p->p_flag & P_OWEUPC) {
- p->p_flag &= ~P_OWEUPC;
- ADDUPROF(p);
+ ucode = a0; /* VA */
+ break;
}
- goto out;
- case T_UNAFLT: /* Always an error of some kind. */
- if (p == NULL || p->p_addr->u_pcb.pcb_onfault == NULL)
- goto dopanic;
- else {
- framep->tf_pc = (u_int64_t)p->p_addr->u_pcb.pcb_onfault;
- p->p_addr->u_pcb.pcb_onfault = NULL;
- }
- goto out;
+ /*
+ * Unaligned access from kernel mode is always an error,
+ * EVEN IF A COPY FAULT HANDLER IS SET!
+ *
+ * It's an error if a copy fault handler is set because
+ * the various routines which do user-initiated copies
+ * do so in a bcopy-like manner. In other words, the
+ * kernel never assumes that pointers provided by the
+ * user are properly aligned, and so if the kernel
+ * does cause an unaligned access it's a kernel bug.
+ */
+ goto dopanic;
- case T_UNAFLT|T_USER: /* "Here, have a SIGBUS instead!" */
- i = SIGBUS;
- ucode = v;
- break;
+ case ALPHA_KENTRY_ARITH:
+ /*
+ * If user-land, just give a SIGFPE. Should do
+ * software completion and IEEE handling, if the
+ * user has requested that.
+ */
+ if (user) {
+sigfpe: i = SIGFPE;
+ ucode = a0; /* exception summary */
+ break;
+ }
- case T_ARITHFLT|T_USER:
-sigfpe: i = SIGFPE;
- ucode = v;
- break;
+ /* Always fatal in kernel. Should never happen. */
+ goto dopanic;
- case T_FPDISABLED|T_USER:
+ case ALPHA_KENTRY_IF:
/*
- * on exit from the kernel, if proc == fpcurproc, FP is
- * enabled.
+ * These are always fatal in kernel, and should never
+ * happen.
*/
- if (fpcurproc == p)
- panic("fp disabled for fpcurproc == %lx", p);
+ if (!user)
+ goto dopanic;
- pal_wrfen(1);
- if (fpcurproc)
- savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
- fpcurproc = p;
- restorefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
- pal_wrfen(0);
+ switch (a0) {
+ case ALPHA_IF_CODE_GENTRAP:
+ if (framep->tf_regs[FRAME_A0] == -2) /* weird! */
+ goto sigfpe;
+ case ALPHA_IF_CODE_BPT:
+ case ALPHA_IF_CODE_BUGCHK:
+ ucode = a0; /* trap type */
+ i = SIGTRAP;
+ break;
- p->p_md.md_flags |= MDP_FPUSED;
- goto out;
+ case ALPHA_IF_CODE_OPDEC:
+ ucode = a0; /* trap type */
+#ifdef NEW_PMAP
+{
+int instr;
+printf("REAL SIGILL: PC = 0x%lx, RA = 0x%lx\n", framep->tf_regs[FRAME_PC], framep->tf_regs[FRAME_RA]);
+printf("INSTRUCTION (%d) = 0x%lx\n", copyin((void*)framep->tf_regs[FRAME_PC] - 4, &instr, 4), instr);
+regdump(framep);
+panic("foo");
+}
+#endif
+ i = SIGILL;
+ break;
- case T_GENTRAP|T_USER:
- if (framep->tf_a0 == -2) /* weird! */
- goto sigfpe;
- case T_BPT|T_USER:
- case T_BUGCHK|T_USER:
- ucode = code;
- i = SIGTRAP;
- break;
+ case ALPHA_IF_CODE_FEN:
+ /*
+ * on exit from the kernel, if proc == fpcurproc,
+ * FP is enabled.
+ */
+ if (fpcurproc == p) {
+ printf("trap: fp disabled for fpcurproc == %p",
+ p);
+ goto dopanic;
+ }
+
+ alpha_pal_wrfen(1);
+ if (fpcurproc)
+ savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ fpcurproc = p;
+ restorefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+
+ p->p_md.md_flags |= MDP_FPUSED;
+ goto out;
- case T_OPDEC|T_USER:
- ucode = code;
- i = SIGILL;
+ default:
+ printf("trap: unknown IF type 0x%lx\n", a0);
+ goto dopanic;
+ }
break;
- case T_INVALTRANS:
- case T_INVALTRANS|T_USER:
- case T_ACCESS:
- case T_ACCESS|T_USER:
- {
- register vm_offset_t va;
- register struct vmspace *vm;
- register vm_map_t map;
- vm_prot_t ftype;
- int rv;
- extern int fswintrberr();
- extern vm_map_t kernel_map;
-
- /* if it was caused by fuswintr or suswintr, just punt. */
- if ((type & T_USER) == 0 && p != NULL &&
- p->p_addr->u_pcb.pcb_onfault == (caddr_t)fswintrberr) {
- framep->tf_pc = (u_int64_t)p->p_addr->u_pcb.pcb_onfault;
- p->p_addr->u_pcb.pcb_onfault = NULL;
+ case ALPHA_KENTRY_MM:
+#ifdef NEW_PMAP
+ printf("mmfault: 0x%lx, 0x%lx, %d\n", a0, a1, a2);
+#endif
+ switch (a1) {
+ case ALPHA_MMCSR_FOR:
+ case ALPHA_MMCSR_FOE:
+#ifdef NEW_PMAP
+ printf("mmfault for/foe in\n");
+#endif
+ pmap_emulate_reference(p, a0, user, 0);
+#ifdef NEW_PMAP
+ printf("mmfault for/foe out\n");
+#endif
goto out;
- }
- /*
- * It is only a kernel address space fault iff:
- * 1. (type & T_USER) == 0 and
- * 2. pcb_onfault not set or
- * 3. pcb_onfault set but kernel space data fault
- * The last can occur during an exec() copyin where the
- * argument space is lazy-allocated.
- */
- if ((type & T_USER) == 0 && (v >= VM_MIN_KERNEL_ADDRESS ||
- p == NULL || p->p_addr->u_pcb.pcb_onfault == NULL))
- map = kernel_map;
- else {
- vm = p->p_vmspace;
- map = &vm->vm_map;
- }
+ case ALPHA_MMCSR_FOW:
+#ifdef NEW_PMAP
+ printf("mmfault fow in\n");
+#endif
+ pmap_emulate_reference(p, a0, user, 1);
+#ifdef NEW_PMAP
+ printf("mmfault fow out\n");
+#endif
+ goto out;
- switch (code) {
- case -1: /* instruction fetch fault */
- case 0: /* load instruction */
- ftype = VM_PROT_READ;
- break;
- case 1: /* store instruction */
- ftype = VM_PROT_WRITE;
- break;
- }
+ case ALPHA_MMCSR_INVALTRANS:
+ case ALPHA_MMCSR_ACCESS:
+ {
+ register vm_offset_t va;
+ register struct vmspace *vm;
+ register vm_map_t map;
+ vm_prot_t ftype;
+ int rv;
+ extern int fswintrberr __P((void));
+ extern vm_map_t kernel_map;
+
+#ifdef NEW_PMAP
+ printf("mmfault invaltrans/access in\n");
+#endif
+ /*
+ * If it was caused by fuswintr or suswintr,
+ * just punt. Note that we check the faulting
+ * address against the address accessed by
+ * [fs]uswintr, in case another fault happens
+ * when they are running.
+ */
+ if (!user &&
+ p != NULL &&
+ p->p_addr->u_pcb.pcb_onfault ==
+ (unsigned long)fswintrberr &&
+ p->p_addr->u_pcb.pcb_accessaddr == a0) {
+#ifdef NEW_PMAP
+ printf("mmfault nfintr in\n");
+#endif
+ framep->tf_regs[FRAME_PC] =
+ p->p_addr->u_pcb.pcb_onfault;
+ p->p_addr->u_pcb.pcb_onfault = 0;
+#ifdef NEW_PMAP
+ printf("mmfault nfintr out\n");
+#endif
+ goto out;
+ }
- va = trunc_page((vm_offset_t)v);
- rv = vm_fault(map, va, ftype, FALSE);
-#ifdef VMFAULT_TRACE
- printf("vm_fault(0x%lx (pmap 0x%lx), 0x%lx (0x%lx), 0x%lx, %d) -> 0x%lx at pc 0x%lx\n",
- map, map == kernel_map ? pmap_kernel() : &vm->vm_pmap,
- va, v, ftype, FALSE, rv, framep->tf_pc);
+ /*
+ * It is only a kernel address space fault iff:
+ * 1. !user and
+ * 2. pcb_onfault not set or
+ * 3. pcb_onfault set but kernel space data fault
+ * The last can occur during an exec() copyin where the
+ * argument space is lazy-allocated.
+ */
+ if (!user && (a0 >= VM_MIN_KERNEL_ADDRESS ||
+ p == NULL || p->p_addr->u_pcb.pcb_onfault == 0))
+ map = kernel_map;
+ else {
+ vm = p->p_vmspace;
+ map = &vm->vm_map;
+ }
+
+ switch (a2) {
+ case -1: /* instruction fetch fault */
+ case 0: /* load instruction */
+ ftype = VM_PROT_READ;
+ break;
+ case 1: /* store instruction */
+ ftype = VM_PROT_WRITE;
+ break;
+ }
+
+ va = trunc_page((vm_offset_t)a0);
+#ifdef NEW_PMAP
+ printf("mmfault going to vm_fault\n");
#endif
- /*
- * If this was a stack access we keep track of the maximum
- * accessed stack size. Also, if vm_fault gets a protection
- * failure it is due to accessing the stack region outside
- * the current limit and we need to reflect that as an access
- * error.
- */
- if (map != kernel_map && (caddr_t)va >= vm->vm_maxsaddr) {
+ rv = vm_fault(map, va, ftype, FALSE);
+#ifdef NEW_PMAP
+ printf("mmfault back from vm_fault\n");
+#endif
+ /*
+ * If this was a stack access we keep track of the
+ * maximum accessed stack size. Also, if vm_fault
+ * gets a protection failure it is due to accessing
+ * the stack region outside the current limit and
+ * we need to reflect that as an access error.
+ */
+ if (map != kernel_map &&
+ (caddr_t)va >= vm->vm_maxsaddr) {
+ if (rv == KERN_SUCCESS) {
+ unsigned nss;
+
+ nss = clrnd(btoc(USRSTACK -
+ (unsigned long)va));
+ if (nss > vm->vm_ssize)
+ vm->vm_ssize = nss;
+ } else if (rv == KERN_PROTECTION_FAILURE)
+ rv = KERN_INVALID_ADDRESS;
+ }
if (rv == KERN_SUCCESS) {
- unsigned nss;
-
- nss = clrnd(btoc(USRSTACK-(unsigned)va));
- if (nss > vm->vm_ssize)
- vm->vm_ssize = nss;
- } else if (rv == KERN_PROTECTION_FAILURE)
- rv = KERN_INVALID_ADDRESS;
- }
- if (rv == KERN_SUCCESS)
- goto out;
- if (!USERMODE(framep->tf_ps)) {
- if (p != NULL &&
- p->p_addr->u_pcb.pcb_onfault != NULL) {
- framep->tf_pc =
- (u_int64_t)p->p_addr->u_pcb.pcb_onfault;
- p->p_addr->u_pcb.pcb_onfault = NULL;
+#ifdef NEW_PMAP
+ printf("mmfault vm_fault success\n");
+#endif
goto out;
}
+
+ if (!user) {
+#ifdef NEW_PMAP
+ printf("mmfault check copyfault\n");
+#endif
+ /* Check for copyin/copyout fault */
+ if (p != NULL &&
+ p->p_addr->u_pcb.pcb_onfault != 0) {
+ framep->tf_regs[FRAME_PC] =
+ p->p_addr->u_pcb.pcb_onfault;
+ p->p_addr->u_pcb.pcb_onfault = 0;
+ goto out;
+ }
+ goto dopanic;
+ }
+ ucode = a0;
+ i = SIGSEGV;
+ break;
+ }
+
+ default:
+ printf("trap: unknown MMCSR value 0x%lx\n", a1);
goto dopanic;
}
- ucode = v;
- i = SIGSEGV;
break;
- }
-
- case T_FOR:
- case T_FOR|T_USER:
- case T_FOE:
- case T_FOE|T_USER:
- pmap_emulate_reference(p, v, (type & T_USER) != 0, 0);
- goto out;
- case T_FOW:
- case T_FOW|T_USER:
- pmap_emulate_reference(p, v, (type & T_USER) != 0, 1);
- goto out;
+ default:
+ goto dopanic;
}
trapsignal(p, i, ucode);
out:
- if ((type & T_USER) == 0)
- return;
- userret(p, framep->tf_pc, sticks);
+ if (user)
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
+ return;
+
+dopanic:
+ printf("\n");
+ printf("fatal %s trap:\n", user ? "user" : "kernel");
+ printf("\n");
+ printf(" trap entry = 0x%lx\n", entry);
+ printf(" a0 = 0x%lx\n", a0);
+ printf(" a1 = 0x%lx\n", a1);
+ printf(" a2 = 0x%lx\n", a2);
+ printf(" pc = 0x%lx\n", framep->tf_regs[FRAME_PC]);
+ printf(" ra = 0x%lx\n", framep->tf_regs[FRAME_RA]);
+ printf(" curproc = %p\n", curproc);
+ if (curproc != NULL)
+ printf(" pid = %d, comm = %s\n", curproc->p_pid,
+ curproc->p_comm);
+ printf("\n");
+
+ /* XXX dump registers */
+ /* XXX kernel debugger */
+
+ panic("trap");
}
/*
@@ -351,25 +446,24 @@ syscall(code, framep)
#endif
#if notdef /* can't happen, ever. */
- if (!USERMODE(framep->tf_ps))
+ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0) {
panic("syscall");
#endif
cnt.v_syscall++;
p = curproc;
p->p_md.md_tf = framep;
- opc = framep->tf_pc - 4;
+ opc = framep->tf_regs[FRAME_PC] - 4;
sticks = p->p_sticks;
callp = p->p_emul->e_sysent;
numsys = p->p_emul->e_nsysent;
-
#ifdef COMPAT_OSF1
if (p->p_emul == &emul_osf1)
switch (code) {
case OSF1_SYS_syscall:
/* OSF/1 syscall() */
- code = framep->tf_a0;
+ code = framep->tf_regs[FRAME_A0];
hidden = 1;
break;
default:
@@ -384,7 +478,7 @@ syscall(code, framep)
* syscall() and __syscall() are handled the same on
* the alpha, as everything is 64-bit aligned, anyway.
*/
- code = framep->tf_a0;
+ code = framep->tf_regs[FRAME_A0];
hidden = 1;
break;
default:
@@ -402,7 +496,7 @@ syscall(code, framep)
default:
if (nargs > 10) /* XXX */
panic("syscall: too many args (%d)", nargs);
- error = copyin((caddr_t)(framep->tf_regs[FRAME_SP]), &args[6],
+ error = copyin((caddr_t)(alpha_pal_rdusp()), &args[6],
(nargs - 6) * sizeof(u_int64_t));
case 6:
args[5] = framep->tf_regs[FRAME_A5];
@@ -411,11 +505,11 @@ syscall(code, framep)
case 4:
args[3] = framep->tf_regs[FRAME_A3];
case 3:
- args[2] = framep->tf_a2;
+ args[2] = framep->tf_regs[FRAME_A2];
case 2:
- args[1] = framep->tf_a1;
+ args[1] = framep->tf_regs[FRAME_A1];
case 1:
- args[0] = framep->tf_a0;
+ args[0] = framep->tf_regs[FRAME_A0];
case 0:
break;
}
@@ -425,6 +519,9 @@ syscall(code, framep)
#endif
#ifdef SYSCALL_DEBUG
scdebug_call(p, code, args + hidden);
+#ifdef NEW_PMAP
+ printf("called from 0x%lx, ra 0x%lx\n", framep->tf_regs[FRAME_PC], framep->tf_regs[FRAME_RA]);
+#endif
#endif
if (error == 0) {
rval[0] = 0;
@@ -439,7 +536,7 @@ syscall(code, framep)
framep->tf_regs[FRAME_A3] = 0;
break;
case ERESTART:
- framep->tf_pc = opc;
+ framep->tf_regs[FRAME_PC] = opc;
break;
case EJUSTRETURN:
break;
@@ -456,9 +553,12 @@ syscall(code, framep)
p = curproc;
#ifdef SYSCALL_DEBUG
scdebug_ret(p, code, error, rval);
+#ifdef NEW_PMAP
+ printf("outgoing pc 0x%lx, ra 0x%lx\n", framep->tf_regs[FRAME_PC], framep->tf_regs[FRAME_RA]);
+#endif
#endif
- userret(p, framep->tf_pc, sticks);
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, code, error, rval[0]);
@@ -477,9 +577,375 @@ child_return(p)
* Return values in the frame set by cpu_fork().
*/
- userret(p, p->p_md.md_tf->tf_pc, 0);
+ userret(p, p->p_md.md_tf->tf_regs[FRAME_PC], 0);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, SYS_fork, 0, 0);
#endif
}
+
+/*
+ * Process an asynchronous software trap.
+ * This is relatively easy.
+ */
+void
+ast(framep)
+ struct trapframe *framep;
+{
+ register struct proc *p;
+ u_quad_t sticks;
+
+ p = curproc;
+ sticks = p->p_sticks;
+ p->p_md.md_tf = framep;
+
+ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0)
+ panic("ast and not user");
+
+ cnt.v_soft++;
+
+ astpending = 0;
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ ADDUPROF(p);
+ }
+
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
+}
+
+/*
+ * Unaligned access handler. It's not clear that this can get much slower...
+ *
+ */
+const static int reg_to_framereg[32] = {
+ FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2,
+ FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6,
+ FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2,
+ FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6,
+ FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3,
+ FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9,
+ FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12,
+ FRAME_AT, FRAME_GP, FRAME_SP, -1,
+};
+
+#define irp(p, reg) \
+ ((reg_to_framereg[(reg)] == -1) ? NULL : \
+ &(p)->p_md.md_tf->tf_regs[reg_to_framereg[(reg)]])
+
+#define frp(p, reg) \
+ (&(p)->p_addr->u_pcb.pcb_fp.fpr_regs[(reg)])
+
+#define dump_fp_regs() \
+ if (p == fpcurproc) { \
+ alpha_pal_wrfen(1); \
+ savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp); \
+ alpha_pal_wrfen(0); \
+ fpcurproc = NULL; \
+ }
+
+#define unaligned_load(storage, ptrf, mod) \
+ if (copyin((caddr_t)va, &(storage), sizeof (storage)) == 0 && \
+ (regptr = ptrf(p, reg)) != NULL) \
+ signal = 0; \
+ else \
+ break; \
+ *regptr = mod (storage);
+
+#define unaligned_store(storage, ptrf, mod) \
+ if ((regptr = ptrf(p, reg)) == NULL) \
+ break; \
+ (storage) = mod (*regptr); \
+ if (copyout(&(storage), (caddr_t)va, sizeof (storage)) == 0) \
+ signal = 0; \
+ else \
+ break;
+
+#define unaligned_load_integer(storage) \
+ unaligned_load(storage, irp, )
+
+#define unaligned_store_integer(storage) \
+ unaligned_store(storage, irp, )
+
+#define unaligned_load_floating(storage, mod) \
+ dump_fp_regs(); \
+ unaligned_load(storage, frp, mod)
+
+#define unaligned_store_floating(storage, mod) \
+ dump_fp_regs(); \
+ unaligned_store(storage, frp, mod)
+
+unsigned long
+Sfloat_to_reg(s)
+ unsigned int s;
+{
+ unsigned long sign, expn, frac;
+ unsigned long result;
+
+ sign = (s & 0x80000000) >> 31;
+ expn = (s & 0x7f800000) >> 23;
+ frac = (s & 0x007fffff) >> 0;
+
+ /* map exponent part, as appropriate. */
+ if (expn == 0xff)
+ expn = 0x7ff;
+ else if ((expn & 0x80) != 0)
+ expn = (0x400 | (expn & ~0x80));
+ else if ((expn & 0x80) == 0 && expn != 0)
+ expn = (0x380 | (expn & ~0x80));
+
+ result = (sign << 63) | (expn << 52) | (frac << 29);
+ return (result);
+}
+
+unsigned int
+reg_to_Sfloat(r)
+ unsigned long r;
+{
+ unsigned long sign, expn, frac;
+ unsigned int result;
+
+ sign = (r & 0x8000000000000000) >> 63;
+ expn = (r & 0x7ff0000000000000) >> 52;
+ frac = (r & 0x000fffffe0000000) >> 29;
+
+ /* map exponent part, as appropriate. */
+ expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
+
+ result = (sign << 31) | (expn << 23) | (frac << 0);
+ return (result);
+}
+
+/*
+ * Conversion of T floating datums to and from register format
+ * requires no bit reordering whatsoever.
+ */
+unsigned long
+Tfloat_reg_cvt(input)
+ unsigned long input;
+{
+
+ return (input);
+}
+
+#ifdef FIX_UNALIGNED_VAX_FP
+unsigned long
+Ffloat_to_reg(f)
+ unsigned int f;
+{
+ unsigned long sign, expn, frlo, frhi;
+ unsigned long result;
+
+ sign = (f & 0x00008000) >> 15;
+ expn = (f & 0x00007f80) >> 7;
+ frhi = (f & 0x0000007f) >> 0;
+ frlo = (f & 0xffff0000) >> 16;
+
+ /* map exponent part, as appropriate. */
+ if ((expn & 0x80) != 0)
+ expn = (0x400 | (expn & ~0x80));
+ else if ((expn & 0x80) == 0 && expn != 0)
+ expn = (0x380 | (expn & ~0x80));
+
+ result = (sign << 63) | (expn << 52) | (frhi << 45) | (frlo << 29);
+ return (result);
+}
+
+unsigned int
+reg_to_Ffloat(r)
+ unsigned long r;
+{
+ unsigned long sign, expn, frhi, frlo;
+ unsigned int result;
+
+ sign = (r & 0x8000000000000000) >> 63;
+ expn = (r & 0x7ff0000000000000) >> 52;
+ frhi = (r & 0x000fe00000000000) >> 45;
+ frlo = (r & 0x00001fffe0000000) >> 29;
+
+ /* map exponent part, as appropriate. */
+ expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
+
+ result = (sign << 15) | (expn << 7) | (frhi << 0) | (frlo << 16);
+ return (result);
+}
+
+/*
+ * Conversion of G floating datums to and from register format is
+ * symmetrical. Just swap shorts in the quad...
+ */
+unsigned long
+Gfloat_reg_cvt(input)
+ unsigned long input;
+{
+ unsigned long a, b, c, d;
+ unsigned long result;
+
+ a = (input & 0x000000000000ffff) >> 0;
+ b = (input & 0x00000000ffff0000) >> 16;
+ c = (input & 0x0000ffff00000000) >> 32;
+ d = (input & 0xffff000000000000) >> 48;
+
+ result = (a << 48) | (b << 32) | (c << 16) | (d << 0);
+ return (result);
+}
+#endif /* FIX_UNALIGNED_VAX_FP */
+
+extern int alpha_unaligned_print, alpha_unaligned_fix;
+extern int alpha_unaligned_sigbus;
+
+int
+unaligned_fixup(va, opcode, reg, p)
+ unsigned long va, opcode, reg;
+ struct proc *p;
+{
+ int doprint, dofix, dosigbus;
+ int signal, size;
+ const char *type;
+ unsigned long *regptr, longdata;
+ int intdata; /* signed to get extension when storing */
+ struct {
+ const char *type; /* opcode name */
+ int size; /* size, 0 if fixup not supported */
+ } tab[0x10] = {
+#ifdef FIX_UNALIGNED_VAX_FP
+ { "ldf", 4 }, { "ldg", 8 },
+#else
+ { "ldf", 0 }, { "ldg", 0 },
+#endif
+ { "lds", 4 }, { "ldt", 8 },
+#ifdef FIX_UNALIGNED_VAX_FP
+ { "stf", 4 }, { "stg", 8 },
+#else
+ { "stf", 0 }, { "stg", 0 },
+#endif
+ { "sts", 4 }, { "stt", 8 },
+ { "ldl", 4 }, { "ldq", 8 },
+ { "ldl_l", 0 }, { "ldq_l", 0 }, /* can't fix */
+ { "stl", 4 }, { "stq", 8 },
+ { "stl_c", 0 }, { "stq_c", 0 }, /* can't fix */
+ };
+
+ /*
+ * Figure out what actions to take.
+ *
+ * XXX In the future, this should have a per-process component
+ * as well.
+ */
+ doprint = alpha_unaligned_print;
+ dofix = alpha_unaligned_fix;
+ dosigbus = alpha_unaligned_sigbus;
+
+ /*
+ * Find out which opcode it is. Arrange to have the opcode
+ * printed if it's an unknown opcode.
+ */
+ if (opcode >= 0x20 && opcode <= 0x2f) {
+ type = tab[opcode - 0x20].type;
+ size = tab[opcode - 0x20].size;
+ } else {
+ type = "0x%lx";
+ size = 0;
+ }
+
+ /*
+ * See if the user can access the memory in question.
+ * Even if it's an unknown opcode, SEGV if the access
+ * should have failed.
+ */
+ if (!useracc((caddr_t)va, size ? size : 1, B_WRITE)) {
+ signal = SIGSEGV;
+ goto out;
+ }
+
+ /*
+ * If we're supposed to be noisy, squawk now.
+ */
+ if (doprint) {
+ uprintf("pid %d (%s): unaligned access: va=0x%lx pc=0x%lx ra=0x%lx op=%:\n",
+ p->p_pid, p->p_comm, va, p->p_md.md_tf->tf_regs[FRAME_PC],
+ p->p_md.md_tf->tf_regs[FRAME_PC], type, opcode);
+ }
+
+ /*
+ * If we should try to fix it and know how, give it a shot.
+ *
+ * We never allow bad data to be unknowingly used by the
+ * user process. That is, if we decide not to fix up an
+ * access we cause a SIGBUS rather than letting the user
+ * process go on without warning.
+ *
+ * If we're trying to do a fixup, we assume that things
+ * will be botched. If everything works out OK,
+ * unaligned_{load,store}_* clears the signal flag.
+ */
+ signal = SIGBUS;
+ if (dofix && size != 0) {
+ switch (opcode) {
+#ifdef FIX_UNALIGNED_VAX_FP
+ case 0x20: /* ldf */
+ unaligned_load_floating(intdata, Ffloat_to_reg);
+ break;
+
+ case 0x21: /* ldg */
+ unaligned_load_floating(longdata, Gfloat_reg_cvt);
+ break;
+#endif
+
+ case 0x22: /* lds */
+ unaligned_load_floating(intdata, Sfloat_to_reg);
+ break;
+
+ case 0x23: /* ldt */
+ unaligned_load_floating(longdata, Tfloat_reg_cvt);
+ break;
+
+#ifdef FIX_UNALIGNED_VAX_FP
+ case 0x24: /* stf */
+ unaligned_store_floating(intdata, reg_to_Ffloat);
+ break;
+
+ case 0x25: /* stg */
+ unaligned_store_floating(longdata, Gfloat_reg_cvt);
+ break;
+#endif
+
+ case 0x26: /* sts */
+ unaligned_store_floating(intdata, reg_to_Sfloat);
+ break;
+
+ case 0x27: /* stt */
+ unaligned_store_floating(longdata, Tfloat_reg_cvt);
+ break;
+
+ case 0x28: /* ldl */
+ unaligned_load_integer(intdata);
+ break;
+
+ case 0x29: /* ldq */
+ unaligned_load_integer(longdata);
+ break;
+
+ case 0x2c: /* stl */
+ unaligned_store_integer(intdata);
+ break;
+
+ case 0x2d: /* stq */
+ unaligned_store_integer(longdata);
+ break;
+
+#ifdef DIAGNOSTIC
+ default:
+ panic("unaligned_fixup: can't get here");
+#endif
+ }
+ }
+
+ /*
+ * Force SIGBUS if requested.
+ */
+ if (dosigbus)
+ signal = SIGBUS;
+
+out:
+ return (signal);
+}
diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c
index b49d2dfd39b..2e92985a491 100644
--- a/sys/arch/alpha/alpha/vm_machdep.c
+++ b/sys/arch/alpha/alpha/vm_machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: vm_machdep.c,v 1.4 1996/07/29 22:58:08 niklas Exp $ */
-/* $NetBSD: vm_machdep.c,v 1.9 1996/04/23 15:26:10 cgd Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.5 1996/10/30 22:38:30 niklas Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.20 1996/10/13 02:59:50 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -45,9 +45,13 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
+extern void exception_return __P((void));
+extern void child_return __P((struct proc *));
+
/*
* Dump the machine specific header information at the start of a core dump.
*/
+int
cpu_coredump(p, vp, cred, chdr)
struct proc *p;
struct vnode *vp;
@@ -55,11 +59,7 @@ cpu_coredump(p, vp, cred, chdr)
struct core *chdr;
{
int error;
- register struct user *up = p->p_addr;
- struct cpustate {
- struct trapframe regs;
- struct fpreg fpstate;
- } cpustate;
+ struct md_coredump cpustate;
struct coreseg cseg;
extern struct proc *fpcurproc;
@@ -68,16 +68,17 @@ cpu_coredump(p, vp, cred, chdr)
chdr->c_seghdrsize = ALIGN(sizeof(cseg));
chdr->c_cpusize = sizeof(cpustate);
- cpustate.regs = *p->p_md.md_tf;
+ cpustate.md_tf = *p->p_md.md_tf;
+ cpustate.md_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp(); /* XXX */
if (p->p_md.md_flags & MDP_FPUSED)
if (p == fpcurproc) {
- pal_wrfen(1);
- savefpstate(&cpustate.fpstate);
- pal_wrfen(0);
+ alpha_pal_wrfen(1);
+ savefpstate(&cpustate.md_fpstate);
+ alpha_pal_wrfen(0);
} else
- cpustate.fpstate = p->p_addr->u_pcb.pcb_fp;
+ cpustate.md_fpstate = p->p_addr->u_pcb.pcb_fp;
else
- bzero(&cpustate.fpstate, sizeof(cpustate.fpstate));
+ bzero(&cpustate.md_fpstate, sizeof(cpustate.md_fpstate));
CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ALPHA, CORE_CPU);
cseg.c_addr = 0;
@@ -139,7 +140,6 @@ cpu_fork(p1, p2)
pt_entry_t *ptep;
int i;
extern struct proc *fpcurproc;
- extern void proc_trampoline(), rei(), child_return();
p2->p_md.md_tf = p1->p_md.md_tf;
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
@@ -148,9 +148,15 @@ cpu_fork(p1, p2)
* Cache the physical address of the pcb, so we can
* swap to it easily.
*/
+#ifndef NEW_PMAP
ptep = kvtopte(up);
p2->p_md.md_pcbpaddr =
&((struct user *)(PG_PFNUM(*ptep) << PGSHIFT))->u_pcb;
+#else
+ p2->p_md.md_pcbpaddr = (void *)vtophys((vm_offset_t)&up->u_pcb);
+ printf("process %d pcbpaddr = 0x%lx, pmap = %p\n",
+ p2->p_pid, p2->p_md.md_pcbpaddr, &p2->p_vmspace->vm_pmap);
+#endif
/*
* Simulate a write to the process's U-area pages,
@@ -167,9 +173,9 @@ cpu_fork(p1, p2)
* if this process has state stored there.
*/
if (p1 == fpcurproc) {
- pal_wrfen(1);
+ alpha_pal_wrfen(1);
savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
- pal_wrfen(0);
+ alpha_pal_wrfen(0);
}
/*
@@ -178,7 +184,12 @@ cpu_fork(p1, p2)
* part of the stack. The stack and pcb need to agree;
*/
p2->p_addr->u_pcb = p1->p_addr->u_pcb;
+ p2->p_addr->u_pcb.pcb_hw.apcb_usp = alpha_pal_rdusp();
+#ifndef NEW_PMAP
PMAP_ACTIVATE(&p2->p_vmspace->vm_pmap, 0);
+#else
+printf("NEW PROCESS %d USP = %p\n", p2->p_pid, p2->p_addr->u_pcb.pcb_hw.apcb_usp);
+#endif
/*
* Arrange for a non-local goto when the new process
@@ -187,7 +198,7 @@ cpu_fork(p1, p2)
#ifdef DIAGNOSTIC
if (p1 != curproc)
panic("cpu_fork: curproc");
- if (up->u_pcb.pcb_fen != 0)
+ if ((up->u_pcb.pcb_hw.apcb_flags & ALPHA_PCB_FLAGS_FEN) != 0)
printf("DANGER WILL ROBINSON: FEN SET IN cpu_fork!\n");
#endif
@@ -196,7 +207,6 @@ cpu_fork(p1, p2)
*/
{
struct trapframe *p2tf;
- extern void rei();
/*
* Pick a stack pointer, leaving room for a trapframe;
@@ -208,6 +218,9 @@ cpu_fork(p1, p2)
bcopy(p1->p_md.md_tf, p2->p_md.md_tf,
sizeof(struct trapframe));
+#ifdef NEW_PMAP
+printf("FORK CHILD: pc = %p, ra = %p\n", p2tf->tf_regs[FRAME_PC], p2tf->tf_regs[FRAME_RA]);
+#endif
/*
* Set up return-value registers as fork() libc stub expects.
*/
@@ -217,18 +230,18 @@ cpu_fork(p1, p2)
/*
* Arrange for continuation at child_return(), which
- * will return to rei(). Note that the child process
- * doesn't stay in the kernel for long!
+ * will return to exception_return(). Note that the child
+ * process doesn't stay in the kernel for long!
*
* This is an inlined version of cpu_set_kpc.
*/
- up->u_pcb.pcb_ksp = (u_int64_t)p2tf;
+ up->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)p2tf;
up->u_pcb.pcb_context[0] =
(u_int64_t)child_return; /* s0: pc */
up->u_pcb.pcb_context[1] =
- (u_int64_t)rei; /* s1: ra */
+ (u_int64_t)exception_return; /* s1: ra */
up->u_pcb.pcb_context[7] =
- (u_int64_t)proc_trampoline; /* ra: assembly magic */
+ (u_int64_t)switch_trampoline; /* ra: assembly magic */
}
}
@@ -239,8 +252,8 @@ cpu_fork(p1, p2)
* named pc, as if the code at that address were called as a function
* with argument, the current process's process pointer.
*
- * Note that it's assumed that when the named process returns, rei()
- * should be invoked, to return to user mode.
+ * Note that it's assumed that when the named process returns,
+ * exception_return() should be invoked, to return to user mode.
*
* (Note that cpu_fork(), above, uses an open-coded version of this.)
*/
@@ -250,14 +263,12 @@ cpu_set_kpc(p, pc)
void (*pc) __P((struct proc *));
{
struct pcb *pcbp;
- extern void proc_trampoline();
- extern void rei();
pcbp = &p->p_addr->u_pcb;
pcbp->pcb_context[0] = (u_int64_t)pc; /* s0 - pc to invoke */
- pcbp->pcb_context[1] = (u_int64_t)rei; /* s1 - return address */
+ pcbp->pcb_context[1] = (u_int64_t)exception_return; /* s1 - return address */
pcbp->pcb_context[7] =
- (u_int64_t)proc_trampoline; /* ra - assembly magic */
+ (u_int64_t)switch_trampoline; /* ra - assembly magic */
}
/*
@@ -277,9 +288,13 @@ cpu_swapin(p)
* Cache the physical address of the pcb, so we can swap to
* it easily.
*/
+#ifndef NEW_PMAP
ptep = kvtopte(up);
p->p_md.md_pcbpaddr =
&((struct user *)(PG_PFNUM(*ptep) << PGSHIFT))->u_pcb;
+#else
+ p->p_md.md_pcbpaddr = (void *)vtophys((vm_offset_t)&up->u_pcb);
+#endif
/*
* Simulate a write to the process's U-area pages,
@@ -308,9 +323,9 @@ cpu_swapout(p)
if (p != fpcurproc)
return;
- pal_wrfen(1);
+ alpha_pal_wrfen(1);
savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
- pal_wrfen(0);
+ alpha_pal_wrfen(0);
fpcurproc = NULL;
}
@@ -329,11 +344,16 @@ pagemove(from, to, size)
if (size % CLBYTES)
panic("pagemove");
+#ifndef NEW_PMAP
fpte = kvtopte(from);
tpte = kvtopte(to);
+#else
+ fpte = pmap_pte(kernel_pmap, (vm_offset_t)from);
+ tpte = pmap_pte(kernel_pmap, (vm_offset_t)to);
+#endif
todo = size; /* if testing > 0, need sign... */
while (todo > 0) {
- TBIS(from);
+ ALPHA_TBIS((vm_offset_t)from);
*tpte++ = *fpte;
*fpte = 0;
fpte++;
diff --git a/sys/arch/alpha/compile/.cvsignore b/sys/arch/alpha/compile/.cvsignore
index 7a0b2488b29..d09b918e852 100644
--- a/sys/arch/alpha/compile/.cvsignore
+++ b/sys/arch/alpha/compile/.cvsignore
@@ -10,3 +10,5 @@ NOSY
NOSY.PROF
OPAL
OPAL.PROF
+RAMDISK
+RAMDISK.PROF
diff --git a/sys/arch/alpha/compile/.keep_me b/sys/arch/alpha/compile/.keep_me
index c92516d7ab9..2d357971ff0 100644
--- a/sys/arch/alpha/compile/.keep_me
+++ b/sys/arch/alpha/compile/.keep_me
@@ -1,4 +1,4 @@
-$OpenBSD: .keep_me,v 1.2 1996/07/29 22:58:15 niklas Exp $
+$OpenBSD: .keep_me,v 1.3 1996/10/30 22:38:34 niklas Exp $
$NetBSD: .keep_me,v 1.1 1995/02/13 23:07:19 cgd Exp $
This normally empty directory needs to be kept in the distribution.
diff --git a/sys/arch/alpha/compile/build_all b/sys/arch/alpha/compile/build_all
index b90abb6a68f..3eea2368d0d 100644
--- a/sys/arch/alpha/compile/build_all
+++ b/sys/arch/alpha/compile/build_all
@@ -1,9 +1,9 @@
#!/bin/sh -
#
-# $OpenBSD: build_all,v 1.3 1996/07/29 22:58:17 niklas Exp $
-# $NetBSD: build_all,v 1.4.4.1 1996/06/15 03:46:17 cgd Exp $
+# $OpenBSD: build_all,v 1.4 1996/10/30 22:38:35 niklas Exp $
+# $NetBSD: build_all,v 1.6 1996/08/20 22:28:37 cgd Exp $
-cflist=`cd ../conf ; find . -type f ! -name "*[a-z.]*" ! -name ".*" | \
+cflist=`cd ../conf ; find . -type f ! -name "*[a-z]*" ! -name ".*" | \
sed -e 's,^\./,,'`
docmd()
diff --git a/sys/arch/alpha/compile/rebuild_all b/sys/arch/alpha/compile/rebuild_all
index bff75fac1c6..30eea0f5d8f 100644
--- a/sys/arch/alpha/compile/rebuild_all
+++ b/sys/arch/alpha/compile/rebuild_all
@@ -1,9 +1,9 @@
#!/bin/sh -
#
-# $OpenBSD: rebuild_all,v 1.3 1996/07/29 22:58:18 niklas Exp $
-# $NetBSD: rebuild_all,v 1.4.4.1 1996/06/15 03:46:19 cgd Exp $
+# $OpenBSD: rebuild_all,v 1.4 1996/10/30 22:38:35 niklas Exp $
+# $NetBSD: rebuild_all,v 1.6 1996/08/20 22:28:40 cgd Exp $
-cflist=`cd ../conf ; find . -type f ! -name "*[a-z.]*" ! -name ".*" | \
+cflist=`cd ../conf ; find . -type f ! -name "*[a-z]*" ! -name ".*" | \
sed -e 's,^\./,,'`
docmd()
diff --git a/sys/arch/alpha/conf/ALPHA b/sys/arch/alpha/conf/ALPHA
index 084b89e53c6..c02d1012167 100644
--- a/sys/arch/alpha/conf/ALPHA
+++ b/sys/arch/alpha/conf/ALPHA
@@ -1,9 +1,9 @@
-# $OpenBSD: ALPHA,v 1.7 1996/09/20 06:44:49 deraadt Exp $
-# $NetBSD: ALPHA,v 1.14.4.4 1996/06/13 19:21:59 cgd Exp $
+# $OpenBSD: ALPHA,v 1.8 1996/10/30 22:38:37 niklas Exp $
+# $NetBSD: ALPHA,v 1.24 1996/09/27 17:08:32 cgd Exp $
#
# Alpha kernel with all the options you'd want, and more.
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -60,6 +60,7 @@ options COMPAT_43
#options COMPAT_09
options COMPAT_10
options COMPAT_11
+options COMPAT_12
# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
#options COMPAT_OSF1
@@ -81,7 +82,11 @@ options LKM
#options INSECURE
# Misc. options
-options PCIVERBOSE # recognize "unknown" PCI devices
+options EISAVERBOSE # recognize "unknown" EISA devices
+options FIX_UNALIGNED_VAX_FP # fix unaligned VAX FP loads & stores
+options PCIVERBOSE # recognize "unknown" PCI devices
+options TCVERBOSE # recognize "unknown" TC devices
+options UCONSOLE # users can use TIOCCONS (for xconsole)
config bsd swap generic
#config bsd root on sd0 swap on sd0
@@ -122,15 +127,18 @@ pci* at lca?
pci* at ppb?
# PCI devices
-de* at pci?
-le* at pci?
-ncr* at pci?
-pceb* at pci?
-pcivga* at pci?
-ppb* at pci?
-sio* at pci?
-tga* at pci?
+#ahc* at pci? dev ? function ? # AHA-28xx SCSI (NOT 64-BIT)
+de* at pci? dev ? function ? # 21x4[012]-based Ethernet
+en* at pci? dev ? function ? # ENI PCI ATM (untested)
+ep* at pci? dev ? function ? # 3COM 3c59x (untested)
fpa* at pci? dev ? function ? # DEC DEFPA FDDI cards
+le* at pci? dev ? function ? # PCI LANCE Ethernet (untested)
+ncr* at pci? dev ? function ? # NCR 53c8xx SCSI
+pceb* at pci? dev ? function ? # Intel PCI-EISA brige
+pcivga* at pci? dev ? function ? # PCI VGA graphics
+ppb* at pci? dev ? function ? # PCI-PCI bridges
+sio* at pci? dev ? function ? # Intel PCI-ISA bridge
+tga* at pci? dev ? function ? # DEC ZLXp-E[123] graphics
# ISA/EISA bus support
isa* at pceb?
@@ -172,3 +180,4 @@ pseudo-device sl 4
pseudo-device strip 4
pseudo-device tun 4
pseudo-device vnd 4
+pseudo-device rd 1
diff --git a/sys/arch/alpha/conf/BUNNY b/sys/arch/alpha/conf/BUNNY
index 88803eec57e..1ba7650e2ee 100644
--- a/sys/arch/alpha/conf/BUNNY
+++ b/sys/arch/alpha/conf/BUNNY
@@ -1,12 +1,12 @@
-# $OpenBSD: BUNNY,v 1.6 1996/09/20 06:44:50 deraadt Exp $
-# $NetBSD: BUNNY,v 1.5.4.1 1996/06/13 19:22:03 cgd Exp $
+# $OpenBSD: BUNNY,v 1.7 1996/10/30 22:38:38 niklas Exp $
+# $NetBSD: BUNNY,v 1.9 1996/09/27 17:08:35 cgd Exp $
#
# Kernel for bunnahabhain.pdl.cs.cmu.edu.
#
# Trimmed down kernel for AlphaStation [24]xx systems, with lots
# of buffer cache.
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -42,6 +42,7 @@ options COMPAT_43
#options COMPAT_09
options COMPAT_10
options COMPAT_11
+options COMPAT_12
# Loadable Kernel Modules
options LKM
@@ -50,7 +51,8 @@ options LKM
#options INSECURE
# Misc. options
-options PCIVERBOSE # recognize "unknown" PCI devices
+options PCIVERBOSE # recognize "unknown" PCI devices
+options UCONSOLE # users can use TIOCCONS (for xconsole)
config bsd swap generic
diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC
index 801a4e0fde1..42d0eb2facb 100644
--- a/sys/arch/alpha/conf/GENERIC
+++ b/sys/arch/alpha/conf/GENERIC
@@ -1,9 +1,9 @@
-# $OpenBSD: GENERIC,v 1.8 1996/09/20 06:44:50 deraadt Exp $
-# $NetBSD: GENERIC,v 1.15.4.3 1996/06/13 19:22:07 cgd Exp $
+# $OpenBSD: GENERIC,v 1.9 1996/10/30 22:38:38 niklas Exp $
+# $NetBSD: GENERIC,v 1.24 1996/09/27 17:08:32 cgd Exp $
#
# Generic Alpha kernel. Enough to get booted, etc., but not much more.
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -41,6 +41,7 @@ options COMPAT_43
#options COMPAT_09
options COMPAT_10
options COMPAT_11
+options COMPAT_12
# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
#options COMPAT_OSF1
@@ -52,7 +53,10 @@ options LKM
#options INSECURE
# Misc. options
-options PCIVERBOSE # recognize "unknown" PCI devices
+options EISAVERBOSE # recognize "unknown" EISA devices
+options PCIVERBOSE # recognize "unknown" PCI devices
+options TCVERBOSE # recognize "unknown" TC devices
+options UCONSOLE # users can use TIOCCONS (for xconsole)
config bsd swap generic
#config bsd root on sd0 swap on sd0
@@ -93,15 +97,18 @@ pci* at lca?
pci* at ppb?
# PCI devices
-de* at pci?
-le* at pci?
-ncr* at pci?
-pceb* at pci?
-pcivga* at pci?
-ppb* at pci?
-sio* at pci?
-tga* at pci?
+#ahc* at pci? dev ? function ? # AHA-28xx SCSI (NOT 64-BIT)
+de* at pci? dev ? function ? # 21x4[012]-based Ethernet
+en* at pci? dev ? function ? # ENI PCI ATM (untested)
+ep* at pci? dev ? function ? # 3COM 3c59x (untested)
fpa* at pci? dev ? function ? # DEC DEFPA FDDI cards
+le* at pci? dev ? function ? # PCI LANCE Ethernet (untested)
+ncr* at pci? dev ? function ? # NCR 53c8xx SCSI
+pceb* at pci? dev ? function ? # Intel PCI-EISA brige
+pcivga* at pci? dev ? function ? # PCI VGA graphics
+ppb* at pci? dev ? function ? # PCI-PCI bridges
+sio* at pci? dev ? function ? # Intel PCI-ISA bridge
+tga* at pci? dev ? function ? # DEC ZLXp-E[123] graphics
# ISA/EISA bus support
isa* at pceb?
@@ -140,3 +147,4 @@ pseudo-device loop
pseudo-device pty 64
pseudo-device sl 4
pseudo-device vnd 4
+pseudo-device rd 1
diff --git a/sys/arch/alpha/conf/GENERIC.PROF b/sys/arch/alpha/conf/GENERIC.PROF
new file mode 100644
index 00000000000..5de20fc93c8
--- /dev/null
+++ b/sys/arch/alpha/conf/GENERIC.PROF
@@ -0,0 +1,153 @@
+# $OpenBSD: GENERIC.PROF,v 1.1 1996/10/30 22:38:39 niklas Exp $
+# $NetBSD: GENERIC.PROF,v 1.4 1996/09/27 17:08:33 cgd Exp $
+#
+# Generic Alpha kernel. Enough to get booted, etc., but not much more.
+
+include "arch/alpha/conf/std.alpha"
+
+maxusers 8
+
+# Always include profiling support; does not need 'config -p'.
+makeoptions PROF="-pg"
+options GPROF
+
+# CPU Support
+options DEC_3000_500 # Flamingo etc: 3000/[4-9]00*
+options DEC_3000_300 # Pelican etc: 3000/300*
+options DEC_2100_A50 # Avanti etc: AlphaStation 400, 200, etc.
+options DEC_KN20AA # KN20AA: AlphaStation 600
+options DEC_AXPPCI_33 # NoName: AXPpci33, etc.
+#options DEC_2000_300 # "Jensen": 2000/300 (DECpc AXP 150)
+
+# needs to be set per system
+options TIMEZONE="5*60" # Minutes west of GMT (for param.c)
+options DST=1 # Daylight savings rules (for param.c)
+
+# Standard system options
+options SWAPPAGER, DEVPAGER # Paging (mandatory)
+options DEBUG, DIAGNOSTIC # Extra kernel debugging
+options KTRACE # System call tracing support
+
+# File system options
+options FIFO # POSIX fifo support (in all file systems)
+options FFS # Fast file system
+options MFS # Memory-based file system
+options NFSSERVER # Sun NFS-compatible file system server
+options NFSCLIENT # Sun NFS-compatible file system client
+
+# Networking options
+options INET # Internet protocol suite
+
+# 4.3BSD compatibility. Should be optional, but necessary for now.
+options COMPAT_43
+
+# Binary compatibility with previous versions of NetBSD.
+#options COMPAT_09
+options COMPAT_10
+options COMPAT_11
+options COMPAT_12
+
+# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
+#options COMPAT_OSF1
+
+# Loadable Kernel Modules
+options LKM
+
+# Disable kernel security.
+#options INSECURE
+
+# Misc. options
+options EISAVERBOSE # recognize "unknown" EISA devices
+options PCIVERBOSE # recognize "unknown" PCI devices
+options TCVERBOSE # recognize "unknown" TC devices
+options UCONSOLE # users can use TIOCCONS (for xconsole)
+
+config bsd swap generic
+#config bsd root on sd0 swap on sd0
+#config bsd root nfs swap nfs
+
+mainbus0 at root
+cpu* at mainbus0
+
+# TurboChannel host bus adapter support
+tcasic* at mainbus0
+
+# TurboChannel bus support
+tc* at tcasic?
+
+# TurboChannel devices
+ioasic0 at tc? slot ? offset ?
+mcclock0 at ioasic? offset ?
+le* at ioasic? offset ?
+scc0 at ioasic? offset ?
+scc1 at ioasic? offset ?
+tcds0 at tc? slot ? offset ?
+esp0 at tcds? slot ?
+esp1 at tcds? slot ?
+cfb* at tc? slot ? offset ?
+sfb* at tc? slot ? offset ?
+le* at tc? slot ? offset ?
+fta* at tc? slot ? offset ? # DEC DEFTA FDDI cards
+
+# PCI host bus adapter support
+apecs* at mainbus?
+cia* at mainbus?
+lca* at mainbus?
+
+# PCI bus support
+pci* at apecs?
+pci* at cia?
+pci* at lca?
+pci* at ppb?
+
+# PCI devices
+#ahc* at pci? dev ? function ? # AHA-28xx SCSI (NOT 64-BIT)
+de* at pci? dev ? function ? # 21x4[012]-based Ethernet
+en* at pci? dev ? function ? # ENI PCI ATM (untested)
+ep* at pci? dev ? function ? # 3COM 3c59x (untested)
+fpa* at pci? dev ? function ? # DEC DEFPA FDDI cards
+le* at pci? dev ? function ? # PCI LANCE Ethernet (untested)
+ncr* at pci? dev ? function ? # NCR 53c8xx SCSI
+pceb* at pci? dev ? function ? # Intel PCI-EISA brige
+pcivga* at pci? dev ? function ? # PCI VGA graphics
+ppb* at pci? dev ? function ? # PCI-PCI bridges
+sio* at pci? dev ? function ? # Intel PCI-ISA bridge
+tga* at pci? dev ? function ? # DEC ZLXp-E[123] graphics
+
+# ISA/EISA bus support
+isa* at pceb?
+eisa* at pceb?
+isa* at sio?
+
+# ISA devices
+mcclock0 at isa? port 0x70
+pckbd0 at isa? port 0x60 irq 1 # PC-ish ISA keyboard
+pms0 at isa? port 0x60 irq 12 # PS/2 auxiliary
+com0 at isa? port 0x3f8 irq 4 # standard serial ports
+com1 at isa? port 0x2f8 irq 3
+lpt0 at isa? port 0x3bc irq 7 # standard parallel port
+#wss0 at isa? port 0x530 irq 9 drq 0 # Windows Sound System
+
+# EISA devices
+fea* at eisa? slot ? # DEC DEFEA FDDI cards
+
+# SCSI bus support
+scsibus* at esp?
+scsibus* at ncr?
+
+# SCSI devices
+sd* at scsibus? target ? lun ?
+st* at scsibus? target ? lun ?
+cd* at scsibus? target ? lun ?
+
+# Workstation Console attachments
+wscons* at cfb?
+wscons* at pcivga?
+wscons* at sfb?
+wscons* at tga?
+
+pseudo-device bpfilter 16
+pseudo-device loop
+pseudo-device pty 64
+pseudo-device sl 4
+pseudo-device vnd 4
diff --git a/sys/arch/alpha/conf/JURA b/sys/arch/alpha/conf/JURA
index de3ab57d1e4..fd66de8e82d 100644
--- a/sys/arch/alpha/conf/JURA
+++ b/sys/arch/alpha/conf/JURA
@@ -1,11 +1,11 @@
-# $OpenBSD: JURA,v 1.6 1996/09/20 06:44:51 deraadt Exp $
-# $NetBSD: JURA,v 1.6.4.1 1996/06/13 19:22:10 cgd Exp $
+# $OpenBSD: JURA,v 1.7 1996/10/30 22:38:40 niklas Exp $
+# $NetBSD: JURA,v 1.9 1996/09/27 17:08:34 cgd Exp $
#
# Kernel for jura.pdl.cs.cmu.edu.
#
# THIS KERNEL DOES NOT CURRENTLY WORK, OR EVEN CONFIGURE!
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -39,6 +39,7 @@ options COMPAT_43
#options COMPAT_09
options COMPAT_10
options COMPAT_11
+options COMPAT_12
# Loadable Kernel Modules
options LKM
diff --git a/sys/arch/alpha/conf/Makefile.alpha b/sys/arch/alpha/conf/Makefile.alpha
index 26f39dcae83..68f5a96b5cf 100644
--- a/sys/arch/alpha/conf/Makefile.alpha
+++ b/sys/arch/alpha/conf/Makefile.alpha
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile.alpha,v 1.7 1996/07/29 20:01:25 niklas Exp $
-# $NetBSD: Makefile.alpha,v 1.16 1996/05/19 21:16:51 cgd Exp $
+# $OpenBSD: Makefile.alpha,v 1.8 1996/10/30 22:38:41 niklas Exp $
+# $NetBSD: Makefile.alpha,v 1.25 1996/09/27 17:33:04 cgd Exp $
-# Makefile for NetBSD
+# Makefile for OpenBSD
#
# This makefile is constructed from a machine description:
# config machineid
@@ -22,22 +22,32 @@
# DEBUG is set to -g if debugging.
# PROF is set to -pg if profiling.
-AS?= as
CC?= cc
-CPP?= cpp
LD?= ld
-STRIP?= strip -g -X -x
-TOUCH?= touch -f -c
+MKDEP?= mkdep
+STRIP?= strip
# source tree is located via $S relative to the compilation directory
-S= ../../../..
-ALPHA= ../..
+.ifndef S
+S!= cd ../../../..; pwd
+.endif
+ALPHA= $S/arch/alpha
+
+INCLUDES= -I. -I$S/arch -I$S -nostdinc
+CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -Dalpha
+
+CDIAGFLAGS?= -Werror -Wall -Wstrict-prototypes -Wmissing-prototypes \
+ -Wno-uninitialized -Wno-format
-INCLUDES= -I. -I$S/arch -I$S
-CPPFLAGS= ${INCLUDES} ${IDENT} -D_KERNEL -Dalpha
-CFLAGS= ${DEBUG} -O2 -Werror -mno-fp-regs
-AFLAGS= -x assembler-with-cpp -traditional-cpp -D_LOCORE
+CMACHFLAGS= -mno-fp-regs
+CFLAGS= ${DEBUG} -O2 ${CDIAGFLAGS} ${CMACHFLAGS} ${COPTS}
+AFLAGS= -traditional -D_LOCORE
LINKFLAGS= -N -Ttext fffffc0000230000 -e __start -G 4
+STRIPFLAGS= -g -X -x
+
+HOSTED_CC= ${CC}
+HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}
+HOSTED_CFLAGS= ${CFLAGS}
### find out what to use for libkern
.include "$S/lib/libkern/Makefile.inc"
@@ -55,19 +65,13 @@ LIBCOMPAT= ${COMPATLIB}
LIBCOMPAT= ${COMPATLIB_PROF}
.endif
-# compile rules: rules are named ${TYPE}_${SUFFIX}${CONFIG_DEP}
-# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix,
-# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file
-# is marked as config-dependent.
+# compile rules: rules are named ${TYPE}_${SUFFIX} where TYPE is NORMAL or
+# HOSTED}, and SUFFIX is the file suffix, capitalized (e.g. C for a .c file).
NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
-NORMAL_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $<
-
-DRIVER_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
-DRIVER_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $<
+NORMAL_S= ${CPP} ${AFLAGS} ${CPPFLAGS} $< | sed -e 's,^\#.*,,' | ${AS} -o ${.TARGET}
-NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
-NORMAL_S_C= ${CC} ${AFLAGS} ${CPPFLAGS} ${PARAM} -c $<
+HOSTED_C= ${HOSTED_CC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
%OBJS
@@ -93,9 +97,9 @@ DEBUG?=
LINKFLAGS+= -X
SYSTEM_LD_TAIL+=; \
echo cp $@ $@.gdb; rm -f $@.gdb; cp $@ $@.gdb; \
- echo ${STRIP} $@; ${STRIP} $@
+ echo ${STRIP} ${STRIPFLAGS} $@; ${STRIP} ${STRIPFLAGS} $@
.else
-LINKFLAGS+= -x
+LINKFLAGS+= -S
.endif
%LOAD
@@ -107,14 +111,14 @@ genassym: genassym.o
${CC} -o $@ genassym.o
genassym.o: ${ALPHA}/alpha/genassym.c
- ${NORMAL_C_C}
+ ${HOSTED_C}
param.c: $S/conf/param.c
rm -f param.c
cp $S/conf/param.c .
param.o: param.c Makefile
- ${NORMAL_C_C}
+ ${NORMAL_C}
ioconf.o: ioconf.c
${NORMAL_C}
@@ -125,11 +129,11 @@ newvers: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
clean::
- rm -f eddep *bsd netbsd.gdb tags *.[io] [a-z]*.s \
+ rm -f eddep *bsd bsd.gdb tags *.[io] [a-z]*.s \
[Ee]rrs linterrs makelinks genassym genassym.o assym.h
lint:
- @lint -hbxncez -DGENERIC -Dvolatile= ${CPPFLAGS} ${PARAM} -UKGDB \
+ @lint -hbxncez -DGENERIC -Dvolatile= ${CPPFLAGS} -UKGDB \
${ALPHA}/alpha/Locore.c ${CFILES} ${ALPHA}/alpha/swapgeneric.c \
ioconf.c param.c | \
grep -v 'static function .* unused'
@@ -149,10 +153,11 @@ SRCS= ${ALPHA}/alpha/locore.s \
param.c ioconf.c ${CFILES} ${SFILES}
depend:: .depend
.depend: ${SRCS} assym.h param.c
- mkdep ${AFLAGS} ${CPPFLAGS} ${ALPHA}/alpha/locore.s
- mkdep -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
- mkdep -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
- mkdep -a ${CFLAGS} ${CPPFLAGS} ${PARAM} ${ALPHA}/alpha/genassym.c
+ ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${ALPHA}/alpha/locore.s
+ ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
+ ${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
+ ${MKDEP} -a ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} \
+ ${ALPHA}/alpha/genassym.c
# depend on root or device configuration
diff --git a/sys/arch/alpha/conf/NOSY b/sys/arch/alpha/conf/NOSY
index 5fddc1c81e5..61eddd751eb 100644
--- a/sys/arch/alpha/conf/NOSY
+++ b/sys/arch/alpha/conf/NOSY
@@ -1,10 +1,10 @@
-# $OpenBSD: NOSY,v 1.4 1996/09/20 06:44:51 deraadt Exp $
-# $NetBSD: NOSY,v 1.5.4.2 1996/06/13 19:22:15 cgd Exp $
+# $OpenBSD: NOSY,v 1.5 1996/10/30 22:38:42 niklas Exp $
+# $NetBSD: NOSY,v 1.9 1996/09/27 17:08:34 cgd Exp $
#
# Jason's DEC 3000/400 in the lab...
#
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -38,6 +38,7 @@ options COMPAT_43
#options COMPAT_09
options COMPAT_10
options COMPAT_11
+options COMPAT_12
# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
#options COMPAT_OSF1
diff --git a/sys/arch/alpha/conf/OPAL b/sys/arch/alpha/conf/OPAL
index af1be26d67e..43440918adb 100644
--- a/sys/arch/alpha/conf/OPAL
+++ b/sys/arch/alpha/conf/OPAL
@@ -1,8 +1,8 @@
-# $OpenBSD: OPAL,v 1.3 1996/09/20 06:44:52 deraadt Exp $
+# $OpenBSD: OPAL,v 1.4 1996/10/30 22:38:43 niklas Exp $
#
# OPAL, kernel for a DEC Multia at Applitron
-include "std.alpha"
+include "arch/alpha/conf/std.alpha"
maxusers 8
@@ -25,9 +25,9 @@ option FFS # Fast file system
option MFS # Memory-based file system
option NFSSERVER # Sun NFS-compatible file system server
option NFSCLIENT # Sun NFS-compatible file system client
-option NULLFS # Loopback file system
+#option NULLFS # Loopback file system
#option MSDOSFS # MS-DOS file system
-option UNION # Union file system
+#option UNION # Union file system
option CD9660 # ISO 9660 + Rock Ridge file system
# SVR IPC
@@ -45,6 +45,7 @@ option COMPAT_43
#option COMPAT_09
option COMPAT_10
option COMPAT_11
+option COMPAT_12
# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
option COMPAT_OSF1
@@ -151,3 +152,4 @@ pseudo-device loop
pseudo-device pty 64
pseudo-device sl 4
pseudo-device vnd 4
+pseudo-device rd 1
diff --git a/sys/arch/alpha/conf/RAMDISK b/sys/arch/alpha/conf/RAMDISK
new file mode 100644
index 00000000000..115116e2ad4
--- /dev/null
+++ b/sys/arch/alpha/conf/RAMDISK
@@ -0,0 +1,154 @@
+# $OpenBSD: RAMDISK,v 1.1 1996/10/30 22:38:44 niklas Exp $
+# $NetBSD: RAMDISK,v 1.4 1996/10/03 20:47:19 cgd Exp $
+#
+# Generic Alpha kernel. Enough to get booted, etc., but not much more.
+
+include "arch/alpha/conf/std.alpha"
+
+maxusers 8
+
+# CPU Support
+options DEC_3000_500 # Flamingo etc: 3000/[4-9]00*
+options DEC_3000_300 # Pelican etc: 3000/300*
+options DEC_2100_A50 # Avanti etc: AlphaStation 400, 200, etc.
+options DEC_KN20AA # KN20AA: AlphaStation 600
+options DEC_AXPPCI_33 # NoName: AXPpci33, etc.
+#options DEC_2000_300 # "Jensen": 2000/300 (DECpc AXP 150)
+
+# Enable the hooks used for initializing the ram-disk.
+options RAMDISK_HOOKS
+options MINIROOTSIZE=8192 # 4 Megabytes!
+
+# needs to be set per system
+options TIMEZONE="5*60" # Minutes west of GMT (for param.c)
+options DST=1 # Daylight savings rules (for param.c)
+
+# Standard system options
+options SWAPPAGER, DEVPAGER # Paging (mandatory)
+options DEBUG, DIAGNOSTIC # Extra kernel debugging
+options KTRACE # System call tracing support
+
+# File system options
+options FIFO # POSIX fifo support (in all file systems)
+options FFS # Fast file system
+options MFS # Memory-based file system
+options NFSSERVER # Sun NFS-compatible file system server
+options NFSCLIENT # Sun NFS-compatible file system client
+
+# Networking options
+options INET # Internet protocol suite
+
+# 4.3BSD compatibility. Should be optional, but necessary for now.
+options COMPAT_43
+
+# Binary compatibility with previous versions of NetBSD.
+#options COMPAT_09
+options COMPAT_10
+options COMPAT_11
+options COMPAT_12
+
+# OSF/1 binary compatibility -- CURRENTLY DOES NOT WORK
+#options COMPAT_OSF1
+
+# Loadable Kernel Modules
+options LKM
+
+# Disable kernel security.
+#options INSECURE
+
+# Misc. options
+options EISAVERBOSE # recognize "unknown" EISA devices
+options PCIVERBOSE # recognize "unknown" PCI devices
+options TCVERBOSE # recognize "unknown" TC devices
+options UCONSOLE # users can use TIOCCONS (for xconsole)
+
+config bsd swap generic
+#config bsd root on sd0 swap on sd0
+#config bsd root nfs swap nfs
+
+mainbus0 at root
+cpu* at mainbus0
+
+# TurboChannel host bus adapter support
+tcasic* at mainbus0
+
+# TurboChannel bus support
+tc* at tcasic?
+
+# TurboChannel devices
+ioasic0 at tc? slot ? offset ?
+mcclock0 at ioasic? offset ?
+le* at ioasic? offset ?
+scc0 at ioasic? offset ?
+scc1 at ioasic? offset ?
+tcds0 at tc? slot ? offset ?
+esp0 at tcds? slot ?
+esp1 at tcds? slot ?
+cfb* at tc? slot ? offset ?
+sfb* at tc? slot ? offset ?
+le* at tc? slot ? offset ?
+fta* at tc? slot ? offset ? # DEC DEFTA FDDI cards
+
+# PCI host bus adapter support
+apecs* at mainbus?
+cia* at mainbus?
+lca* at mainbus?
+
+# PCI bus support
+pci* at apecs?
+pci* at cia?
+pci* at lca?
+pci* at ppb?
+
+# PCI devices
+#ahc* at pci? dev ? function ? # AHA-28xx SCSI (NOT 64-BIT)
+de* at pci? dev ? function ? # 21x4[012]-based Ethernet
+en* at pci? dev ? function ? # ENI PCI ATM (untested)
+ep* at pci? dev ? function ? # 3COM 3c59x (untested)
+fpa* at pci? dev ? function ? # DEC DEFPA FDDI cards
+le* at pci? dev ? function ? # PCI LANCE Ethernet (untested)
+ncr* at pci? dev ? function ? # NCR 53c8xx SCSI
+pceb* at pci? dev ? function ? # Intel PCI-EISA brige
+pcivga* at pci? dev ? function ? # PCI VGA graphics
+ppb* at pci? dev ? function ? # PCI-PCI bridges
+sio* at pci? dev ? function ? # Intel PCI-ISA bridge
+tga* at pci? dev ? function ? # DEC ZLXp-E[123] graphics
+
+# ISA/EISA bus support
+isa* at pceb?
+eisa* at pceb?
+isa* at sio?
+
+# ISA devices
+mcclock0 at isa? port 0x70
+pckbd0 at isa? port 0x60 irq 1 # PC-ish ISA keyboard
+pms0 at isa? port 0x60 irq 12 # PS/2 auxiliary
+com0 at isa? port 0x3f8 irq 4 # standard serial ports
+com1 at isa? port 0x2f8 irq 3
+lpt0 at isa? port 0x3bc irq 7 # standard parallel port
+#wss0 at isa? port 0x530 irq 9 drq 0 # Windows Sound System
+
+# EISA devices
+fea* at eisa? slot ? # DEC DEFEA FDDI cards
+
+# SCSI bus support
+scsibus* at esp?
+scsibus* at ncr?
+
+# SCSI devices
+sd* at scsibus? target ? lun ?
+st* at scsibus? target ? lun ?
+cd* at scsibus? target ? lun ?
+
+# Workstation Console attachments
+wscons* at cfb?
+wscons* at pcivga?
+wscons* at sfb?
+wscons* at tga?
+
+pseudo-device bpfilter 16
+pseudo-device loop
+pseudo-device pty 64
+pseudo-device sl 4
+pseudo-device vnd 4
+pseudo-device rd 1
diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha
index e8dc3b51654..8df2ea1b219 100644
--- a/sys/arch/alpha/conf/files.alpha
+++ b/sys/arch/alpha/conf/files.alpha
@@ -1,9 +1,9 @@
-# $OpenBSD: files.alpha,v 1.5 1996/07/29 20:01:27 niklas Exp $
-# $NetBSD: files.alpha,v 1.19.4.2 1996/05/30 23:20:37 cgd Exp $
+# $OpenBSD: files.alpha,v 1.6 1996/10/30 22:38:45 niklas Exp $
+# $NetBSD: files.alpha,v 1.26 1996/09/27 17:14:35 cgd Exp $
#
# alpha-specific configuration info
-# maxpartitions must be first item in files.${ARCH}.newconf
+# maxpartitions must be first item in files.${ARCH}
maxpartitions 8
maxusers 2 8 64
@@ -25,18 +25,23 @@ file arch/alpha/alpha/cpu.c cpu
# Machine-independent SCSI drivers
#
-include "../../../scsi/files.scsi"
+include "scsi/files.scsi"
major { st = 2 }
major { cd = 3 }
major { sd = 8 }
+# RAM Disk
+pseudo-device rd
+file dev/ramdisk.c rd needs-flag
+file arch/alpha/alpha/rd_root.c ramdisk_hooks
+major { rd = 6 }
#
# raster console routines
#
define raster
-include "../../../dev/rcons/files.rcons"
+include "dev/rcons/files.rcons"
file arch/alpha/wscons/wscons_rinit.c raster
file arch/alpha/wscons/wscons_rops.c raster
@@ -59,7 +64,7 @@ file arch/alpha/wscons/ms.c wscons
# TurboChannel Devices
#
-include "../../../dev/tc/files.tc"
+include "dev/tc/files.tc"
device tcasic: tcbus
attach tcasic at mainbus
@@ -114,13 +119,13 @@ file dev/tc/if_le_tc.c le_tc
#
# Machine-independent ATAPI drivers
#
-include "../../../dev/atapi/files.atapi"
+include "dev/atapi/files.atapi"
# XXX Dummy bus needed for some multi-homed devices specified in files.isa
define pcmcia {}
-include "../../../dev/pci/files.pci" # XXX some ISA devs are 'at pci' too.
-include "../../../dev/isa/files.isa"
+include "dev/pci/files.pci" # XXX some ISA devs are 'at pci' too.
+include "dev/isa/files.isa"
#file arch/alpha/isa/isafcns_jensen.c dec_2000_300
@@ -145,14 +150,14 @@ file arch/alpha/isa/pms.c pms needs-flag
# EISA Bus support
#
-include "../../../dev/eisa/files.eisa"
+include "dev/eisa/files.eisa"
#
# PCI Bus support
#
-# include "../../../dev/pci/files.pci" XXX SEE ABOVE
+# include "dev/pci/files.pci" XXX SEE ABOVE
device apecs: pcibus
attach apecs at mainbus
@@ -227,10 +232,11 @@ file arch/alpha/alpha/interrupt.c
file arch/alpha/alpha/machdep.c
file arch/alpha/alpha/mainbus.c
file arch/alpha/alpha/mem.c
-file arch/alpha/alpha/pmap.c
+file arch/alpha/alpha/pmap.c new_pmap
+file arch/alpha/alpha/pmap.old.c !new_pmap
file arch/alpha/alpha/process_machdep.c
file arch/alpha/alpha/prom.c
-file arch/alpha/alpha/support.c
+#file arch/alpha/alpha/support.c
file arch/alpha/alpha/sys_machdep.c
file arch/alpha/alpha/trap.c
file arch/alpha/alpha/vm_machdep.c
@@ -242,7 +248,8 @@ file dev/cons.c
# Optional/miscellaneous files
#
-file arch/alpha/alpha/in_cksum.c inet
+file arch/alpha/alpha/in_cksum.c inet & !generic_in_cksum
+file netinet/in_cksum.c inet & generic_in_cksum
file netns/ns_cksum.c ns
# XXX
@@ -257,4 +264,4 @@ file arch/alpha/alpha/dec_axppci_33.c dec_axppci_33
file arch/alpha/alpha/dec_21000.c dec_21000
# OSF/1 Binary Compatibility (COMPAT_OSF1)
-include "../../../compat/osf1/files.osf1"
+include "compat/osf1/files.osf1"
diff --git a/sys/arch/alpha/conf/std.alpha b/sys/arch/alpha/conf/std.alpha
index a81b37efa17..21d789851c8 100644
--- a/sys/arch/alpha/conf/std.alpha
+++ b/sys/arch/alpha/conf/std.alpha
@@ -1,10 +1,13 @@
-# $OpenBSD: std.alpha,v 1.2 1996/07/29 20:01:27 niklas Exp $
-# $NetBSD: std.alpha,v 1.4 1995/11/25 01:34:38 cgd Exp $
+# $OpenBSD: std.alpha,v 1.3 1996/10/30 22:38:46 niklas Exp $
+# $NetBSD: std.alpha,v 1.8 1996/09/27 17:18:02 cgd Exp $
#
# Standard/required configuration info for OpenBSD/alpha.
machine alpha
makeoptions DEBUG="-g"
+#makeoptions CWARNFLAGS="-Werror"
options EXEC_ECOFF
+options EXEC_ELF64
+options EXEC_SCRIPT
diff --git a/sys/arch/alpha/eisa/eisa_machdep.h b/sys/arch/alpha/eisa/eisa_machdep.h
index ce8ac9e426d..589f705592c 100644
--- a/sys/arch/alpha/eisa/eisa_machdep.h
+++ b/sys/arch/alpha/eisa/eisa_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: eisa_machdep.h,v 1.2 1996/07/29 22:58:21 niklas Exp $ */
+/* $OpenBSD: eisa_machdep.h,v 1.3 1996/10/30 22:38:47 niklas Exp $ */
/* $NetBSD: eisa_machdep.h,v 1.1 1996/04/12 05:39:51 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/alpha_cpu.h b/sys/arch/alpha/include/alpha_cpu.h
new file mode 100644
index 00000000000..0c695e1612f
--- /dev/null
+++ b/sys/arch/alpha/include/alpha_cpu.h
@@ -0,0 +1,281 @@
+/* $OpenBSD: alpha_cpu.h,v 1.1 1996/10/30 22:38:49 niklas Exp $ */
+/* $NetBSD: alpha_cpu.h,v 1.6 1996/08/20 23:02:17 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef __ALPHA_ALPHA_CPU_H__
+#define __ALPHA_ALPHA_CPU_H__
+
+/*
+ * Alpha CPU + OSF/1 PALcode definitions for use by the kernel.
+ *
+ * Definitions for:
+ *
+ * Process Control Block
+ * Interrupt/Exception/Syscall Stack Frame
+ * Processor Status Register
+ * Machine Check Error Summary Register
+ * Machine Check Logout Area
+ * Virtual Memory Management
+ * Kernel Entry Vectors
+ * MMCSR Fault Type Codes
+ * Translation Buffer Invalidation
+ *
+ * and miscellaneous PALcode operations.
+ */
+
+
+/*
+ * Process Control Block definitions [OSF/1 PALcode Specific]
+ */
+
+struct alpha_pcb {
+ unsigned long apcb_ksp; /* kernel stack ptr */
+ unsigned long apcb_usp; /* user stack ptr */
+ unsigned long apcb_ptbr; /* page table base reg */
+ unsigned int apcb_cpc; /* charged process cycles */
+ unsigned int apcb_asn; /* address space number */
+ unsigned long apcb_unique; /* process unique value */
+ unsigned long apcb_flags; /* flags; see below */
+ unsigned long apcb_decrsv0; /* DEC reserved */
+ unsigned long apcb_decrsv1; /* DEC reserved */
+};
+
+#define ALPHA_PCB_FLAGS_FEN 0x0000000000000001
+#define ALPHA_PCB_FLAGS_PME 0x4000000000000000
+
+/*
+ * Interrupt/Exception/Syscall "Hardware" (really PALcode)
+ * Stack Frame definitions
+ *
+ * These are quadword offsets from the sp on kernel entry, i.e.
+ * to get to the value in question you access (sp + (offset * 8)).
+ *
+ * On syscall entry, A0-A2 aren't written to memory but space
+ * _is_ reserved for them.
+ */
+
+#define ALPHA_HWFRAME_PS 0 /* processor status register */
+#define ALPHA_HWFRAME_PC 1 /* program counter */
+#define ALPHA_HWFRAME_GP 2 /* global pointer */
+#define ALPHA_HWFRAME_A0 3 /* a0 */
+#define ALPHA_HWFRAME_A1 4 /* a1 */
+#define ALPHA_HWFRAME_A2 5 /* a2 */
+
+#define ALPHA_HWFRAME_SIZE 6 /* 6 8-byte words */
+
+/*
+ * Processor Status Register [OSF/1 PALcode Specific]
+ *
+ * Includes user/kernel mode bit, interrupt priority levels, etc.
+ */
+
+#define ALPHA_PSL_USERMODE 0x0008 /* set -> user mode */
+#define ALPHA_PSL_IPL_MASK 0x0007 /* interrupt level mask */
+
+#define ALPHA_PSL_IPL_0 0x0000 /* all interrupts enabled */
+#define ALPHA_PSL_IPL_SOFT 0x0001 /* software ints disabled */
+#define ALPHA_PSL_IPL_IO 0x0004 /* I/O dev ints disabled */
+#define ALPHA_PSL_IPL_CLOCK 0x0005 /* clock ints disabled */
+#define ALPHA_PSL_IPL_HIGH 0x0006 /* all but mchecks disabled */
+
+#define ALPHA_PSL_MUST_BE_ZERO 0xfffffffffffffff0
+
+/* Convenience constants: what must be set/clear in user mode */
+#define ALPHA_PSL_USERSET ALPHA_PSL_USERMODE
+#define ALPHA_PSL_USERCLR (ALPHA_PSL_MUST_BE_ZERO | ALPHA_PSL_IPL_MASK)
+
+/*
+ * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
+ *
+ * The following bits are values as read. On write, _PCE, _SCE, and
+ * _MIP are "write 1 to clear."
+ */
+
+#define ALPHA_MCES_IMP \
+ 0xffffffff00000000 /* impl. dependent */
+#define ALPHA_MCES_RSVD \
+ 0x00000000ffffffe0 /* reserved */
+#define ALPHA_MCES_DSC \
+ 0x0000000000000010 /* disable system correctable error reporting */
+#define ALPHA_MCES_DPC \
+ 0x0000000000000008 /* disable processor correctable error reporting */
+#define ALPHA_MCES_PCE \
+ 0x0000000000000004 /* processor correctable error in progress */
+#define ALPHA_MCES_SCE \
+ 0x0000000000000002 /* system correctable error in progress */
+#define ALPHA_MCES_MIP \
+ 0x0000000000000001 /* machine check in progress */
+
+/*
+ * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific]
+ */
+
+struct alpha_logout_area {
+ unsigned int la_frame_size; /* frame size */
+ unsigned int la_flags; /* flags; see below */
+ unsigned int la_cpu_offset; /* offset to cpu area */
+ unsigned int la_system_offset; /* offset to system area */
+};
+
+#define ALPHA_LOGOUT_FLAGS_RETRY 0x80000000 /* OK to continue */
+#define ALPHA_LOGOUT_FLAGS_SE 0x40000000 /* second error */
+#define ALPHA_LOGOUT_FLAGS_SBZ 0x3fffffff /* should be zero */
+
+#define ALPHA_LOGOUT_NOT_BUILT \
+ (struct alpha_logout_area *)0xffffffffffffffff)
+
+#define ALPHA_LOGOUT_PAL_AREA(lap) \
+ (unsigned long *)((unsigned char *)(lap) + 16)
+#define ALPHA_LOGOUT_PAL_SIZE(lap) \
+ ((lap)->la_cpu_offset - 16)
+#define ALPHA_LOGOUT_CPU_AREA(lap) \
+ (unsigned long *)((unsigned char *)(lap) + (lap)->la_cpu_offset)
+#define ALPHA_LOGOUT_CPU_SIZE(lap) \
+ ((lap)->la_system_offset - (lap)->la_cpu_offset)
+#define ALPHA_LOGOUT_SYSTEM_AREA(lap) \
+ (unsigned long *)((unsigned char *)(lap) + (lap)->la_system_offset)
+#define ALPHA_LOGOUT_SYSTEM_SIZE(lap) \
+ ((lap)->la_frame_size - (lap)->la_system_offset)
+
+/*
+ * Virtual Memory Management definitions [OSF/1 PALcode Specific]
+ *
+ * Includes user and kernel space addresses and information,
+ * page table entry definitions, etc.
+ *
+ * NOTE THAT THESE DEFINITIONS MAY CHANGE IN FUTURE ALPHA CPUS!
+ */
+
+#define ALPHA_PGSHIFT 13
+#define ALPHA_PGBYTES (1 << ALPHA_PGSHIFT)
+
+#define ALPHA_USEG_BASE 0 /* virtual */
+#define ALPHA_USEG_END 0x000003ffffffffff
+
+#define ALPHA_K0SEG_BASE 0xfffffc0000000000 /* direct-mapped */
+#define ALPHA_K0SEG_END 0xfffffdffffffffff
+#define ALPHA_K1SEG_BASE 0xfffffe0000000000 /* virtual */
+#define ALPHA_K1SEG_END 0xffffffffffffffff
+
+#define ALPHA_K0SEG_TO_PHYS(x) ((x) & 0x00000003ffffffff)
+#define ALPHA_PHYS_TO_K0SEG(x) ((x) | ALPHA_K0SEG_BASE)
+
+#define ALPHA_PTE_VALID 0x0001
+
+#define ALPHA_PTE_FAULT_ON_READ 0x0002
+#define ALPHA_PTE_FAULT_ON_WRITE 0x0004
+#define ALPHA_PTE_FAULT_ON_EXECUTE 0x0008
+
+#define ALPHA_PTE_ASM 0x0010 /* addr. space match */
+#define ALPHA_PTE_GRANULARITY 0x0060 /* granularity hint */
+
+#define ALPHA_PTE_PROT 0xff00
+#define ALPHA_PTE_KR 0x0100
+#define ALPHA_PTE_UR 0x0200
+#define ALPHA_PTE_KW 0x1000
+#define ALPHA_PTE_UW 0x2000
+
+#define ALPHA_PTE_WRITE (ALPHA_PTE_KW | ALPHA_PTE_KW)
+
+#define ALPHA_PTE_SOFTWARE 0xffff0000
+
+#define ALPHA_PTE_PFN 0xffffffff00000000
+
+#define ALPHA_PTE_TO_PFN(pte) ((pte) >> 32)
+#define ALPHA_PTE_FROM_PFN(pfn) ((pfn) << 32)
+
+typedef unsigned long alpha_pt_entry_t;
+
+/*
+ * Kernel Entry Vectors. [OSF/1 PALcode Specific]
+ */
+
+#define ALPHA_KENTRY_INT 0
+#define ALPHA_KENTRY_ARITH 1
+#define ALPHA_KENTRY_MM 2
+#define ALPHA_KENTRY_IF 3
+#define ALPHA_KENTRY_UNA 4
+#define ALPHA_KENTRY_SYS 5
+
+/*
+ * MMCSR Fault Type Codes. [OSF/1 PALcode Specific]
+ */
+
+#define ALPHA_MMCSR_INVALTRANS 0
+#define ALPHA_MMCSR_ACCESS 1
+#define ALPHA_MMCSR_FOR 2
+#define ALPHA_MMCSR_FOE 3
+#define ALPHA_MMCSR_FOW 4
+
+/*
+ * Instruction Fault Type Codes. [OSF/1 PALcode Specific]
+ */
+
+#define ALPHA_IF_CODE_BPT 0
+#define ALPHA_IF_CODE_BUGCHK 1
+#define ALPHA_IF_CODE_GENTRAP 2
+#define ALPHA_IF_CODE_FEN 3
+#define ALPHA_IF_CODE_OPDEC 4
+
+/*
+ * Translation Buffer Invalidation definitions [OSF/1 PALcode Specific]
+ */
+
+#define ALPHA_TBIA() alpha_pal_tbi(-2, 0) /* all TB entries */
+#define ALPHA_TBIAP() alpha_pal_tbi(-1, 0) /* all per-process */
+#define ALPHA_TBISI(va) alpha_pal_tbi(1, (va)) /* ITB entry for va */
+#define ALPHA_TBISD(va) alpha_pal_tbi(2, (va)) /* DTB entry for va */
+#define ALPHA_TBIS(va) alpha_pal_tbi(3, (va)) /* all for va */
+
+/*
+ * Stubs for Alpha instructions normally inaccessible from C.
+ */
+unsigned long alpha_rpcc __P((void));
+void alpha_mb __P((void));
+void alpha_wmb __P((void));
+
+/*
+ * Stubs for OSF/1 PALcode operations.
+ */
+void alpha_pal_imb __P((void));
+void alpha_pal_draina __P((void));
+void alpha_pal_halt __P((void)) __attribute__((__noreturn__));
+unsigned long alpha_pal_rdmces __P((void));
+unsigned long alpha_pal_rdusp __P((void));
+unsigned long alpha_pal_swpipl __P((unsigned long));
+unsigned long _alpha_pal_swpipl __P((unsigned long)); /* for profiling */
+void alpha_pal_tbi __P((unsigned long, vm_offset_t));
+unsigned long alpha_pal_whami __P((void));
+void alpha_pal_wrent __P((void *, unsigned long));
+void alpha_pal_wrfen __P((unsigned long));
+void alpha_pal_wrusp __P((unsigned long));
+void alpha_pal_wrvptptr __P((unsigned long));
+void alpha_pal_wrmces __P((unsigned long));
+
+#endif __ALPHA_ALPHA_CPU_H__
diff --git a/sys/arch/alpha/include/ansi.h b/sys/arch/alpha/include/ansi.h
index 6e005d9b3b6..7e529f40e07 100644
--- a/sys/arch/alpha/include/ansi.h
+++ b/sys/arch/alpha/include/ansi.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ansi.h,v 1.4 1996/07/29 22:58:23 niklas Exp $ */
-/* $NetBSD: ansi.h,v 1.4 1996/03/16 01:31:45 jtc Exp $ */
+/* $OpenBSD: ansi.h,v 1.5 1996/10/30 22:38:50 niklas Exp $ */
+/* $NetBSD: ansi.h,v 1.5 1996/10/09 21:13:04 cgd Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -55,7 +55,8 @@
#define _BSD_TIME_T_ int /* time() */
typedef struct {
char *base;
- long offset;
+ int offset;
+ int pad;
} __va_list;
#define _BSD_VA_LIST_ __va_list /* va_list */
diff --git a/sys/arch/alpha/include/trap.h b/sys/arch/alpha/include/aout_machdep.h
index 78a6ef53ec6..badaa8c07d8 100644
--- a/sys/arch/alpha/include/trap.h
+++ b/sys/arch/alpha/include/aout_machdep.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: trap.h,v 1.2 1996/07/29 22:59:25 niklas Exp $ */
-/* $NetBSD: trap.h,v 1.1 1995/02/13 23:07:58 cgd Exp $ */
+/* $NetBSD: aout_machdep.h,v 1.1 1995/02/13 23:07:37 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -28,22 +27,12 @@
* rights to redistribute these changes.
*/
-#define T_ASTFLT 0x00
-#define T_UNAFLT 0x01
-#define T_ARITHFLT 0x02
+#ifndef _ALPHA_EXEC_H_
+#define _ALPHA_EXEC_H_
-#define T_IFLT 0x10
-#define T_BPT (T_IFLT|0x00)
-#define T_BUGCHK (T_IFLT|0x01)
-#define T_GENTRAP (T_IFLT|0x02)
-#define T_FPDISABLED (T_IFLT|0x03)
-#define T_OPDEC (T_IFLT|0x04)
+#define cpu_exec_aout_makecmds(p, epp) ENOEXEC
-#define T_MMFLT 0x20
-#define T_INVALTRANS (T_MMFLT|0x00)
-#define T_ACCESS (T_MMFLT|0x01)
-#define T_FOR (T_MMFLT|0x02)
-#define T_FOE (T_MMFLT|0x03)
-#define T_FOW (T_MMFLT|0x04)
+/* Size of a page in an object file. */
+#define __LDPGSZ 8192
-#define T_USER 0x80 /* user-mode flag or'ed with type */
+#endif /* !_ALPHA_EXEC_H_ */
diff --git a/sys/arch/alpha/include/asm.h b/sys/arch/alpha/include/asm.h
index 2c96e4c625c..0dbea2e046f 100644
--- a/sys/arch/alpha/include/asm.h
+++ b/sys/arch/alpha/include/asm.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: asm.h,v 1.4 1996/07/29 22:58:25 niklas Exp $ */
-/* $NetBSD: asm.h,v 1.4 1996/04/12 01:36:51 cgd Exp $ */
+/* $OpenBSD: asm.h,v 1.5 1996/10/30 22:38:52 niklas Exp $ */
+/* $NetBSD: asm.h,v 1.10 1996/10/17 18:33:53 cgd Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
@@ -130,6 +130,22 @@
#define ai $25 /* (T) argument information */
#define pv $27 /* (T) procedure value */
+
+/*
+ * Useful stuff.
+ */
+#ifdef __STDC__
+#define __CONCAT(a,b) a ## b
+#else
+#define __CONCAT(a,b) a/**/b
+#endif
+#define ___CONCAT(a,b) __CONCAT(a,b)
+
+/*
+ * Macro to make a local label name.
+ */
+#define LLABEL(name,num) ___CONCAT(___CONCAT(L,name),num)
+
/*
*
* Debuggers need symbol table information to be able to properly
@@ -203,18 +219,9 @@
#define MCOUNT /* nothing */
#else
#define MCOUNT \
- lda sp, -16(sp); \
- stq pv, 0(sp); \
- \
- br pv, 1f; \
-1: ldgp gp, 0(pv); \
- lda pv, _mcount; \
- jsr at_reg, (pv); \
- br pv, 2f; \
-2: ldgp gp, 0(pv); \
- \
- ldq pv, 0(sp); \
- lda sp, 16(sp)
+ .set noat; \
+ jsr at_reg,_mcount; \
+ .set at
#endif
/*
@@ -434,26 +441,26 @@ _name_:; \
* Allocate space for a message (a read-only ascii string)
*/
#define ASCIZ .asciz
-#define MSG(msg,reg) \
- lda reg, 9f; \
+#define MSG(msg,reg,label) \
+ lda reg, label; \
.data; \
-9: ASCIZ msg; \
+label: ASCIZ msg; \
.text;
/*
* PRINTF
* Print a message
*/
-#define PRINTF(msg) \
- MSG(msg,a0); \
+#define PRINTF(msg,label) \
+ MSG(msg,a0,label); \
CALL(printf)
/*
* PANIC
* Fatal error (KERNEL)
*/
-#define PANIC(msg) \
- MSG(msg,a0); \
+#define PANIC(msg,label) \
+ MSG(msg,a0,label); \
CALL(panic)
/*
@@ -541,9 +548,10 @@ _name_:; \
* are unprivileged.
*/
-/* Common PAL codes. */
+/* Common PAL function codes. */
#define PAL_halt 0x0000 /* P */
#define PAL_draina 0x0002 /* P */
+#define PAL_cserve 0x0009 /* P */
#define PAL_swppal 0x000a /* P */
#define PAL_bpt 0x0080 /* U */
#define PAL_bugchk 0x0081 /* U */
@@ -552,7 +560,7 @@ _name_:; \
#define PAL_wrunique 0x009f /* U */
#define PAL_gentrap 0x00aa /* U */
-/* VMS PAL codes. */
+/* VMS PAL function codes. */
#define PAL_VMS_ldqp 0x0003 /* P */
#define PAL_VMS_stqp 0x0004 /* P */
#define PAL_VMS_mtpr_fen 0x000c /* P */
@@ -575,7 +583,9 @@ _name_:; \
#define PAL_VMS_mfpr_whami 0x003f /* P */
#define PAL_VMS_rei 0x0092 /* U */
-/* OSF/1 PAL codes. */
+/* OSF/1 PAL function codes. */
+#define PAL_OSF1_rdmces 0x0010 /* P */
+#define PAL_OSF1_wrmces 0x0011 /* P */
#define PAL_OSF1_wrfen 0x002b /* P */
#define PAL_OSF1_wrvptptr 0x002d /* P */
#define PAL_OSF1_swpctx 0x0030 /* P */
@@ -594,13 +604,28 @@ _name_:; \
#define PAL_OSF1_callsys 0x0083 /* U */
#define PAL_OSF1_imb 0x0086 /* U */
+
/*
- * Defintions to make things portable between gcc and OSF/1 cc.
+ * System call glue.
*/
-#define SETGP(pv) ldgp gp,0(pv)
+#define SYSCALLNUM(name) \
+ ___CONCAT(SYS_,name)
-#define MF_FPCR(x) mf_fpcr x
-#define MT_FPCR(x) mt_fpcr x
-#define JMP(loc) jmp zero,loc
-#define CONST(c,reg) ldiq reg, c
+#define CALLSYS_NOERROR(name) \
+ ldiq v0, SYSCALLNUM(name); \
+ call_pal PAL_OSF1_callsys
+
+/*
+ * Load the global pointer.
+ */
+#define LDGP(reg) \
+ ldgp gp, 0(reg)
+/*
+ * WEAK_ALIAS: create a weak alias (ELF only).
+ */
+#ifdef __ELF__
+#define WEAK_ALIAS(alias,sym) \
+ .weak alias; \
+ alias = sym
+#endif
diff --git a/sys/arch/alpha/include/autoconf.h b/sys/arch/alpha/include/autoconf.h
index 5531aa9d3f6..517d0f2fc5f 100644
--- a/sys/arch/alpha/include/autoconf.h
+++ b/sys/arch/alpha/include/autoconf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: autoconf.h,v 1.5 1996/10/18 14:47:07 niklas Exp $ */
-/* $NetBSD: autoconf.h,v 1.2.4.2 1996/06/13 18:35:23 cgd Exp $ */
+/* $OpenBSD: autoconf.h,v 1.6 1996/10/30 22:38:54 niklas Exp $ */
+/* $NetBSD: autoconf.h,v 1.5 1996/07/14 04:12:59 cgd Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -81,10 +81,12 @@ struct bootdev_data {
char *ctrl_dev_type;
};
-void device_register __P((struct device *, void *));
-void set_clockintr __P((void));
-void set_iointr __P((void (*)(void *, int)));
-int badaddr __P((void *, u_int64_t));
+void set_clockintr __P((void));
+void set_iointr __P((void (*)(void *, unsigned long)));
+int badaddr __P((void *, size_t));
+void configure __P((void));
+void device_register __P((struct device *, void *));
+void dumpconf __P((void));
#ifdef EVCNT_COUNTERS
extern struct evcnt clock_intr_evcnt;
diff --git a/sys/arch/alpha/include/bus.h b/sys/arch/alpha/include/bus.h
index 61cd8cbcbe5..75e7d3fe992 100644
--- a/sys/arch/alpha/include/bus.h
+++ b/sys/arch/alpha/include/bus.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: bus.h,v 1.2 1996/07/29 22:58:29 niklas Exp $ */
-/* $NetBSD: bus.h,v 1.2.4.2 1996/06/13 17:44:45 cgd Exp $ */
+/* $OpenBSD: bus.h,v 1.3 1996/10/30 22:38:55 niklas Exp $ */
+/* $NetBSD: bus.h,v 1.4 1996/06/11 21:16:21 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/include/cdefs.h b/sys/arch/alpha/include/cdefs.h
index c39c2620736..05b289d79c4 100644
--- a/sys/arch/alpha/include/cdefs.h
+++ b/sys/arch/alpha/include/cdefs.h
@@ -1,8 +1,8 @@
-/* $OpenBSD: cdefs.h,v 1.4 1996/07/29 22:58:30 niklas Exp $ */
-/* $NetBSD: cdefs.h,v 1.2 1995/05/03 00:13:55 cgd Exp $ */
+/* $OpenBSD: cdefs.h,v 1.5 1996/10/30 22:38:56 niklas Exp $ */
+/* $NetBSD: cdefs.h,v 1.5 1996/10/12 18:08:12 cgd Exp $ */
/*
- * Copyright (c) 1995 Carnegie-Mellon University.
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
@@ -33,7 +33,35 @@
#define _C_LABEL(x) _STRING(x)
-#define __indr_references(sym,msg) /* nothing */
+#ifdef __ELF__
+
+#define __indr_reference(sym,alias) /* nada, since we do weak refs */
+
+#ifdef __STDC__
+
+#define __weak_alias(alias,sym) \
+ __asm__(".weak " #alias " ; " #alias " = " #sym)
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning." #sym " ; .ascii \"" msg "\" ; .text")
+
+#else /* !__STDC__ */
+
+#define __weak_alias(alias,sym) \
+ __asm__(".weak alias ; alias = sym")
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning.sym ; .ascii msg ; .text")
+
+#endif /* !__STDC__ */
+
+#else /* !__ELF__ */
+
+/*
+ * Very little to do if not ELF: we support neither indirect or
+ * weak references, and don't do anything with warnings.
+ */
+
#define __warn_references(sym,msg) /* nothing */
+#endif /* !__ELF__ */
+
#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/sys/arch/alpha/include/cfbreg.h b/sys/arch/alpha/include/cfbreg.h
index 4707077c82b..d5e7222a6ad 100644
--- a/sys/arch/alpha/include/cfbreg.h
+++ b/sys/arch/alpha/include/cfbreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cfbreg.h,v 1.2 1996/07/29 22:58:32 niklas Exp $ */
+/* $OpenBSD: cfbreg.h,v 1.3 1996/10/30 22:38:57 niklas Exp $ */
/* $NetBSD: cfbreg.h,v 1.1 1996/05/01 23:25:00 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h
index 9dbabd53d4a..cb08112157d 100644
--- a/sys/arch/alpha/include/cpu.h
+++ b/sys/arch/alpha/include/cpu.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: cpu.h,v 1.4 1996/07/29 22:58:33 niklas Exp $ */
-/* $NetBSD: cpu.h,v 1.7.4.1 1996/06/14 20:42:44 cgd Exp $ */
+/* $OpenBSD: cpu.h,v 1.5 1996/10/30 22:38:58 niklas Exp $ */
+/* $NetBSD: cpu.h,v 1.12 1996/07/14 04:15:10 cgd Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -66,9 +66,11 @@
struct clockframe {
struct trapframe cf_tf;
};
-#define CLKF_USERMODE(framep) (((framep)->cf_tf.tf_ps & PSL_U) != 0)
-#define CLKF_BASEPRI(framep) (((framep)->cf_tf.tf_ps & PSL_IPL) == 0)
-#define CLKF_PC(framep) ((framep)->cf_tf.tf_pc)
+#define CLKF_USERMODE(framep) \
+ (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0)
+#define CLKF_BASEPRI(framep) \
+ (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_IPL_MASK) == 0)
+#define CLKF_PC(framep) ((framep)->cf_tf.tf_regs[FRAME_PC])
/*
* XXX No way to accurately tell if we were in interrupt mode before taking
* clock interrupt.
@@ -101,28 +103,22 @@ u_int64_t want_resched; /* resched() was called */
/*
- * simulated software interrupt register
- */
-extern u_int64_t ssir;
-
-#define SIR_NET 0x1
-#define SIR_CLOCK 0x2
-
-#define siroff(x) ssir &= ~(x)
-#define setsoftnet() ssir |= SIR_NET
-#define setsoftclock() ssir |= SIR_CLOCK
-
-/*
* CTL_MACHDEP definitions.
*/
#define CPU_CONSDEV 1 /* dev_t: console terminal device */
#define CPU_ROOT_DEVICE 2 /* string: root device name */
-#define CPU_MAXID 3 /* number of valid machdep ids */
+#define CPU_UNALIGNED_PRINT 3 /* int: print unaligned accesses */
+#define CPU_UNALIGNED_FIX 4 /* int: fix unaligned accesses */
+#define CPU_UNALIGNED_SIGBUS 5 /* int: SIGBUS unaligned accesses */
+#define CPU_MAXID 6 /* 5 valid machdep IDs */
#define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \
{ "console_device", CTLTYPE_STRUCT }, \
{ "root_device", CTLTYPE_STRING }, \
+ { "unaligned_print", CTLTYPE_INT }, \
+ { "unaligned_fix", CTLTYPE_INT }, \
+ { "unaligned_sigbus", CTLTYPE_INT }, \
}
#endif /* _ALPHA_CPU_H_ */
diff --git a/sys/arch/alpha/include/db_machdep.h b/sys/arch/alpha/include/db_machdep.h
index d7f713a78ba..7a5aadc64b6 100644
--- a/sys/arch/alpha/include/db_machdep.h
+++ b/sys/arch/alpha/include/db_machdep.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: db_machdep.h,v 1.2 1996/07/29 22:58:35 niklas Exp $ */
-/* $NetBSD: db_machdep.h,v 1.1 1995/11/23 02:35:54 cgd Exp $ */
+/* $OpenBSD: db_machdep.h,v 1.3 1996/10/30 22:38:58 niklas Exp $ */
+/* $NetBSD: db_machdep.h,v 1.2 1996/07/11 05:31:31 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -46,12 +46,12 @@ typedef struct trapframe db_regs_t;
db_regs_t ddb_regs; /* register state */
#define DDB_REGS (&ddb_regs)
-#define PC_REGS(regs) ((db_addr_t)(regs)->tf_pc)
+#define PC_REGS(regs) ((db_addr_t)(regs)->tf_regs[FRAME_PC])
#define BKPT_INST 0x00000080 /* breakpoint instruction */
#define BKPT_SIZE (4) /* size of breakpoint inst */
#define BKPT_SET(inst) (BKPT_INST)
-#define FIXUP_PC_AFTER_BREAK ddb_regs.tf_pc -= BKPT_SIZE;
+#define FIXUP_PC_AFTER_BREAK ddb_regs.tf_regs[FRAME_PC] -= BKPT_SIZE;
#endif /* _ALPHA_DB_MACHDEP_H_ */
diff --git a/sys/arch/alpha/include/disklabel.h b/sys/arch/alpha/include/disklabel.h
index fe4987cfead..0bdfb430483 100644
--- a/sys/arch/alpha/include/disklabel.h
+++ b/sys/arch/alpha/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.2 1996/07/29 22:58:37 niklas Exp $ */
+/* $OpenBSD: disklabel.h,v 1.3 1996/10/30 22:38:59 niklas Exp $ */
/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/ecoff.h b/sys/arch/alpha/include/ecoff.h
index a6d8b13363f..b605b5421f2 100644
--- a/sys/arch/alpha/include/ecoff.h
+++ b/sys/arch/alpha/include/ecoff.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ecoff.h,v 1.5 1996/07/29 22:58:39 niklas Exp $ */
+/* $OpenBSD: ecoff.h,v 1.6 1996/10/30 22:39:00 niklas Exp $ */
/* $NetBSD: ecoff.h,v 1.3 1996/05/09 23:47:25 cgd Exp $ */
/*
@@ -43,10 +43,10 @@
u_long gp_value
#define ECOFF_MAGIC_ALPHA 0603
-#define ECOFF_MAGIC_NETBSD_ALPHA 0605
+#define ECOFF_MAGIC_NATIVE_ALPHA 0605
#define ECOFF_BADMAG(ep) \
((ep)->f.f_magic != ECOFF_MAGIC_ALPHA && \
- (ep)->f.f_magic != ECOFF_MAGIC_NETBSD_ALPHA)
+ (ep)->f.f_magic != ECOFF_MAGIC_NATIVE_ALPHA)
#define ECOFF_FLAG_EXEC 0002
#define ECOFF_SEGMENT_ALIGNMENT(ep) \
@@ -93,3 +93,8 @@ struct ecoff_extsym {
unsigned :29;
int es_indexfld;
};
+
+#ifdef _KERNEL
+void cpu_exec_ecoff_setregs
+ __P((struct proc *, struct exec_package *, u_long, register_t *));
+#endif
diff --git a/sys/arch/alpha/include/ecoff_machdep.h b/sys/arch/alpha/include/ecoff_machdep.h
new file mode 100644
index 00000000000..9f2d2447113
--- /dev/null
+++ b/sys/arch/alpha/include/ecoff_machdep.h
@@ -0,0 +1,95 @@
+/* $OpenBSD: ecoff_machdep.h,v 1.1 1996/10/30 22:39:01 niklas Exp $ */
+/* $NetBSD: ecoff_machdep.h,v 1.3 1996/05/09 23:47:25 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Glass.
+ * 4. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Adam Glass BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define ECOFF_LDPGSZ 4096
+
+#define ECOFF_PAD \
+ u_short bldrev; /* XXX */
+
+#define ECOFF_MACHDEP \
+ u_int gprmask; \
+ u_int fprmask; \
+ u_long gp_value
+
+#define ECOFF_MAGIC_ALPHA 0603
+#define ECOFF_MAGIC_NATIVE_ALPHA 0605
+#define ECOFF_BADMAG(ep) \
+ ((ep)->f.f_magic != ECOFF_MAGIC_ALPHA && \
+ (ep)->f.f_magic != ECOFF_MAGIC_NATIVE_ALPHA)
+
+#define ECOFF_FLAG_EXEC 0002
+#define ECOFF_SEGMENT_ALIGNMENT(ep) \
+ (((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
+
+struct ecoff_symhdr {
+ int16_t magic;
+ int16_t vstamp;
+ int32_t lineMax;
+ int32_t densenumMax;
+ int32_t procMax;
+ int32_t lsymMax;
+ int32_t optsymMax;
+ int32_t auxsymMax;
+ int32_t lstrMax;
+ int32_t estrMax;
+ int32_t fdMax;
+ int32_t rfdMax;
+ int32_t esymMax;
+ long linesize;
+ long cbLineOffset;
+ long cbDnOffset;
+ long cbPdOffset;
+ long cbSymOffset;
+ long cbOptOffset;
+ long cbAuxOffset;
+ long cbSsOffset;
+ long cbSsExtOffset;
+ long cbFdOffset;
+ long cbRfdOffset;
+ long cbExtOffset;
+};
+
+struct ecoff_extsym {
+ long es_value;
+ int es_strindex;
+ unsigned es_type:6;
+ unsigned es_class:5;
+ unsigned :1;
+ unsigned es_symauxindex:20;
+ unsigned es_jmptbl:1;
+ unsigned es_cmain:1;
+ unsigned es_weakext:1;
+ unsigned :29;
+ int es_indexfld;
+};
diff --git a/sys/arch/alpha/include/elf_machdep.h b/sys/arch/alpha/include/elf_machdep.h
new file mode 100644
index 00000000000..5f6c6b545f7
--- /dev/null
+++ b/sys/arch/alpha/include/elf_machdep.h
@@ -0,0 +1,9 @@
+/* $OpenBSD: elf_machdep.h,v 1.1 1996/10/30 22:39:02 niklas Exp $ */
+/* $NetBSD: elf_machdep.h,v 1.1 1996/09/26 21:50:57 cgd Exp $ */
+
+#define ELF32_MACHDEP_ID_CASES \
+ /* no 32-bit ELF machine types supported */
+
+#define ELF64_MACHDEP_ID_CASES \
+ case Elf_em_alpha: \
+ break;
diff --git a/sys/arch/alpha/include/endian.h b/sys/arch/alpha/include/endian.h
index 4cbdb950046..ec524c5f64e 100644
--- a/sys/arch/alpha/include/endian.h
+++ b/sys/arch/alpha/include/endian.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: endian.h,v 1.2 1996/07/29 22:58:40 niklas Exp $ */
-/* $NetBSD: endian.h,v 1.1 1995/02/13 23:07:36 cgd Exp $ */
+/* $OpenBSD: endian.h,v 1.3 1996/10/30 22:39:03 niklas Exp $ */
+/* $NetBSD: endian.h,v 1.3 1996/10/13 19:57:59 cgd Exp $ */
/*
* Copyright (c) 1987, 1991, 1993
@@ -58,11 +58,14 @@
#include <sys/cdefs.h>
+typedef u_int32_t in_addr_t;
+typedef u_int16_t in_port_t;
+
__BEGIN_DECLS
-unsigned long htonl __P((unsigned long));
-unsigned short htons __P((unsigned short));
-unsigned long ntohl __P((unsigned long));
-unsigned short ntohs __P((unsigned short));
+in_addr_t htonl __P((in_addr_t));
+in_port_t htons __P((in_port_t));
+in_addr_t ntohl __P((in_addr_t));
+in_port_t ntohs __P((in_port_t));
__END_DECLS
/*
@@ -81,10 +84,10 @@ __END_DECLS
#else
-#define NTOHL(x) (x) = ntohl((u_long)x)
-#define NTOHS(x) (x) = ntohs((u_short)x)
-#define HTONL(x) (x) = htonl((u_long)x)
-#define HTONS(x) (x) = htons((u_short)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 /* !_POSIX_SOURCE */
#endif /* !_ENDIAN_H_ */
diff --git a/sys/arch/alpha/include/fbio.h b/sys/arch/alpha/include/fbio.h
index a9a4c40eae2..bce6db8ba24 100644
--- a/sys/arch/alpha/include/fbio.h
+++ b/sys/arch/alpha/include/fbio.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: fbio.h,v 1.2 1996/07/29 22:58:43 niklas Exp $ */
-/* $NetBSD: fbio.h,v 1.2 1996/05/01 19:44:21 cgd Exp $ */
+/* $OpenBSD: fbio.h,v 1.3 1996/10/30 22:39:04 niklas Exp $ */
+/* $NetBSD: fbio.h,v 1.3 1996/08/23 00:50:25 cgd Exp $ */
/*
* Copyright (c) 1992 Regents of the University of California.
@@ -57,8 +57,9 @@
#define FBTYPE_PCIVGA 7 /* PCI VGA */
#define FBTYPE_TGA 8 /* TGA (PCI) */
#define FBTYPE_SFBP 9 /* SFB+ (TurboChannel) */
+#define FBTYPE_TGA2 10 /* TGA2 (PCI) */
-#define FBTYPE_LASTPLUSONE 10
+#define FBTYPE_LASTPLUSONE 11
/*
* Frame buffer descriptor as returned by FBIOGTYPE.
diff --git a/sys/arch/alpha/include/float.h b/sys/arch/alpha/include/float.h
index 24358b119bc..fa51cc4a5ea 100644
--- a/sys/arch/alpha/include/float.h
+++ b/sys/arch/alpha/include/float.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: float.h,v 1.2 1996/07/29 22:58:45 niklas Exp $ */
+/* $OpenBSD: float.h,v 1.3 1996/10/30 22:39:05 niklas Exp $ */
/* $NetBSD: float.h,v 1.4 1995/06/20 20:45:22 jtc Exp $ */
/*
diff --git a/sys/arch/alpha/include/frame.h b/sys/arch/alpha/include/frame.h
index 981d26dd4ef..a05fc112370 100644
--- a/sys/arch/alpha/include/frame.h
+++ b/sys/arch/alpha/include/frame.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: frame.h,v 1.2 1996/07/29 22:58:47 niklas Exp $ */
-/* $NetBSD: frame.h,v 1.1 1995/02/13 23:07:39 cgd Exp $ */
+/* $OpenBSD: frame.h,v 1.3 1996/10/30 22:39:06 niklas Exp $ */
+/* $NetBSD: frame.h,v 1.3 1996/07/11 05:31:32 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -31,23 +31,22 @@
#ifndef _ALPHA_FRAME_H_
#define _ALPHA_FRAME_H_
-/*
- * XXX where did this info come from?
- */
+#include <machine/alpha_cpu.h>
/*
- * Trap and syscall frame.
+ * Software trap, exception, and syscall frame.
*
- * Hardware puts fields marked "[HW]" on stack. We have to add
- * all of the general-purpose registers except for zero, for sp,
- * which is automatically saved in usp for traps, and implicitly
- * saved for syscalls, and for a0-a2, which are saved by hardware.
+ * Includes "hardware" (PALcode) frame.
+ *
+ * PALcode puts ALPHA_HWFRAME_* fields on stack. We have to add
+ * all of the general-purpose registers except for zero, for sp
+ * (which is automatically saved in the PCB's USP field for entries
+ * from user mode, and which is implicitly saved and restored by the
+ * calling conventions for entries from kernel mode), and (on traps
+ * and exceptions) for a0, a1, and a2 (which are saved by PALcode).
*/
-/* Number of registers saved, including padding. */
-#define FRAME_NSAVEREGS 28
-
-/* The offsets of the registers to be saved, into the array. */
+/* Quadword offsets of the registers to be saved. */
#define FRAME_V0 0
#define FRAME_T0 1
#define FRAME_T1 2
@@ -75,16 +74,22 @@
#define FRAME_T12 24
#define FRAME_AT 25
#define FRAME_SP 26
-#define FRAME_SPARE 27 /* spare; padding */
+
+#define FRAME_SW_SIZE (FRAME_SP + 1)
+#define FRAME_HW_OFFSET FRAME_SW_SIZE
+
+#define FRAME_PS (FRAME_HW_OFFSET + ALPHA_HWFRAME_PS)
+#define FRAME_PC (FRAME_HW_OFFSET + ALPHA_HWFRAME_PC)
+#define FRAME_GP (FRAME_HW_OFFSET + ALPHA_HWFRAME_GP)
+#define FRAME_A0 (FRAME_HW_OFFSET + ALPHA_HWFRAME_A0)
+#define FRAME_A1 (FRAME_HW_OFFSET + ALPHA_HWFRAME_A1)
+#define FRAME_A2 (FRAME_HW_OFFSET + ALPHA_HWFRAME_A2)
+
+#define FRAME_HW_SIZE ALPHA_HWFRAME_SIZE
+#define FRAME_SIZE (FRAME_HW_OFFSET + FRAME_HW_SIZE)
struct trapframe {
- u_int64_t tf_regs[FRAME_NSAVEREGS]; /* GPRs (listed above) */
- u_int64_t tf_ps; /* processor status [HW] */
- u_int64_t tf_pc; /* program counter [HW] */
- u_int64_t tf_gp; /* global pointer [HW] */
- u_int64_t tf_a0; /* saved a0 [HW] */
- u_int64_t tf_a1; /* saved a1 [HW] */
- u_int64_t tf_a2; /* saved a2 [HW] */
+ unsigned long tf_regs[FRAME_SIZE]; /* See above */
};
#endif /* _ALPHA_FRAME_H_ */
diff --git a/sys/arch/alpha/include/ieee.h b/sys/arch/alpha/include/ieee.h
index eed83d82d9e..943ac5052e8 100644
--- a/sys/arch/alpha/include/ieee.h
+++ b/sys/arch/alpha/include/ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee.h,v 1.2 1996/07/29 22:58:48 niklas Exp $ */
+/* $OpenBSD: ieee.h,v 1.3 1996/10/30 22:39:07 niklas Exp $ */
/* $NetBSD: ieee.h,v 1.1 1995/02/13 23:07:40 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/ieeefp.h b/sys/arch/alpha/include/ieeefp.h
index 731366c1ae3..4ebb20b0aa5 100644
--- a/sys/arch/alpha/include/ieeefp.h
+++ b/sys/arch/alpha/include/ieeefp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieeefp.h,v 1.2 1996/07/29 22:58:50 niklas Exp $ */
+/* $OpenBSD: ieeefp.h,v 1.3 1996/10/30 22:39:08 niklas Exp $ */
/* $NetBSD: ieeefp.h,v 1.1 1995/04/29 01:09:17 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/intr.h b/sys/arch/alpha/include/intr.h
index 1e1edaae517..e638077e95d 100644
--- a/sys/arch/alpha/include/intr.h
+++ b/sys/arch/alpha/include/intr.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: intr.h,v 1.2 1996/07/29 22:58:52 niklas Exp $ */
-/* $NetBSD: intr.h,v 1.1 1996/04/12 01:42:17 cgd Exp $ */
+/* $OpenBSD: intr.h,v 1.3 1996/10/30 22:39:09 niklas Exp $ */
+/* $NetBSD: intr.h,v 1.2 1996/07/09 00:33:25 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -28,6 +28,9 @@
* rights to redistribute these changes.
*/
+#ifndef _ALPHA_INTR_H_
+#define _ALPHA_INTR_H_
+
#define IPL_NONE 0 /* disable only this interrupt */
#define IPL_BIO 1 /* disable block I/O interrupts */
#define IPL_NET 2 /* disable network interrupts */
@@ -39,3 +42,30 @@
#define IST_PULSE 1 /* pulsed */
#define IST_EDGE 2 /* edge-triggered */
#define IST_LEVEL 3 /* level-triggered */
+
+#define splx(s) \
+ (s == ALPHA_PSL_IPL_0 ? spl0() : alpha_pal_swpipl(s))
+#define splsoft() alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT)
+#define splsoftclock() splsoft()
+#define splsoftnet() splsoft()
+#define splnet() alpha_pal_swpipl(ALPHA_PSL_IPL_IO)
+#define splbio() alpha_pal_swpipl(ALPHA_PSL_IPL_IO)
+#define splimp() alpha_pal_swpipl(ALPHA_PSL_IPL_IO)
+#define spltty() alpha_pal_swpipl(ALPHA_PSL_IPL_IO)
+#define splclock() alpha_pal_swpipl(ALPHA_PSL_IPL_CLOCK)
+#define splstatclock() alpha_pal_swpipl(ALPHA_PSL_IPL_CLOCK)
+#define splhigh() alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH)
+
+/*
+ * simulated software interrupt register
+ */
+extern u_int64_t ssir;
+
+#define SIR_NET 0x1
+#define SIR_CLOCK 0x2
+
+#define siroff(x) ssir &= ~(x)
+#define setsoftnet() ssir |= SIR_NET
+#define setsoftclock() ssir |= SIR_CLOCK
+
+#endif
diff --git a/sys/arch/alpha/include/intrcnt.h b/sys/arch/alpha/include/intrcnt.h
index fbc8d214a43..50a451798ff 100644
--- a/sys/arch/alpha/include/intrcnt.h
+++ b/sys/arch/alpha/include/intrcnt.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: intrcnt.h,v 1.3 1996/07/29 22:58:53 niklas Exp $ */
-/* $NetBSD: intrcnt.h,v 1.4.4.2 1996/06/05 03:42:24 cgd Exp $ */
+/* $OpenBSD: intrcnt.h,v 1.4 1996/10/30 22:39:10 niklas Exp $ */
+/* $NetBSD: intrcnt.h,v 1.6 1996/06/05 03:38:02 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/include/kbio.h b/sys/arch/alpha/include/kbio.h
index 1923e84da77..30dc944ba83 100644
--- a/sys/arch/alpha/include/kbio.h
+++ b/sys/arch/alpha/include/kbio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kbio.h,v 1.2 1996/07/29 22:58:55 niklas Exp $ */
+/* $OpenBSD: kbio.h,v 1.3 1996/10/30 22:39:11 niklas Exp $ */
/* $NetBSD: kbio.h,v 1.1 1996/04/12 01:45:45 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/kcore.h b/sys/arch/alpha/include/kcore.h
new file mode 100644
index 00000000000..87da4d36d0c
--- /dev/null
+++ b/sys/arch/alpha/include/kcore.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: kcore.h,v 1.1 1996/10/30 22:39:11 niklas Exp $ */
+/* $NetBSD: kcore.h,v 1.1 1996/10/01 18:38:05 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _ALPHA_KCORE_H_
+#define _ALPHA_KCORE_H_
+
+typedef struct cpu_kcore_hdr {
+ u_int64_t lev1map_pa; /* PA of Lev1map */
+ u_int64_t page_size; /* Page size */
+ phys_ram_seg_t core_seg; /* Core addrs; only one seg */
+} cpu_kcore_hdr_t;
+
+#endif /* _ALPHA_KCORE_H_ */
diff --git a/sys/arch/alpha/include/limits.h b/sys/arch/alpha/include/limits.h
index 2ff6b3fcf78..1d2799a3f06 100644
--- a/sys/arch/alpha/include/limits.h
+++ b/sys/arch/alpha/include/limits.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: limits.h,v 1.3 1996/07/29 22:58:56 niklas Exp $ */
+/* $OpenBSD: limits.h,v 1.4 1996/10/30 22:39:12 niklas Exp $ */
/* $NetBSD: limits.h,v 1.2 1996/04/12 01:38:25 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/param.h b/sys/arch/alpha/include/param.h
index e7d8ed09324..40878d41a71 100644
--- a/sys/arch/alpha/include/param.h
+++ b/sys/arch/alpha/include/param.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: param.h,v 1.5 1996/07/29 22:58:58 niklas Exp $ */
-/* $NetBSD: param.h,v 1.12 1996/03/04 05:04:10 cgd Exp $ */
+/* $OpenBSD: param.h,v 1.6 1996/10/30 22:39:13 niklas Exp $ */
+/* $NetBSD: param.h,v 1.13 1996/07/09 00:33:23 cgd Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -52,9 +52,7 @@
#define MACHINE_ARCH "alpha"
#define MID_MACHINE MID_ALPHA
-#ifdef _KERNEL /* XXX */
-#include <machine/cpu.h> /* XXX */
-#endif /* XXX */
+#include <machine/alpha_cpu.h>
/*
* Round p (pointer or byte index) up to a correctly-aligned value for all
@@ -64,9 +62,9 @@
#define ALIGNBYTES 7
#define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
-#define NBPG 8192 /* bytes/page */
+#define NBPG (1 << ALPHA_PGSHIFT) /* bytes/page */
#define PGOFSET (NBPG-1) /* byte off. into pg */
-#define PGSHIFT 13 /* LOG2(NBPG) */
+#define PGSHIFT ALPHA_PGSHIFT /* LOG2(NBPG) */
#define NPTEPG (1 << (PGSHIFT-PTESHIFT)) /* pte's/page */
#define SEGSHIFT (PGSHIFT + (PGSHIFT-PTESHIFT)) /* LOG2(NBSEG) */
@@ -145,34 +143,17 @@
#define alpha_btop(x) ((unsigned long)(x) >> PGSHIFT)
#define alpha_ptob(x) ((unsigned long)(x) << PGSHIFT)
-#include <machine/psl.h>
-
-#define splx(s) (s == PSL_IPL_0 ? spl0() : pal_swpipl(s))
-#define splsoft() pal_swpipl(PSL_IPL_SOFT)
-#define splsoftclock() splsoft()
-#define splsoftnet() splsoft()
-#define splnet() pal_swpipl(PSL_IPL_IO)
-#define splbio() pal_swpipl(PSL_IPL_IO)
-#define splimp() pal_swpipl(PSL_IPL_IO)
-#define spltty() pal_swpipl(PSL_IPL_IO)
-#define splclock() pal_swpipl(PSL_IPL_CLOCK)
-#define splstatclock() pal_swpipl(PSL_IPL_CLOCK)
-#define splhigh() pal_swpipl(PSL_IPL_HIGH)
+#include <machine/intr.h>
#ifdef _KERNEL
#ifndef _LOCORE
-/* This was calibrated empirically */
-extern u_int64_t cycles_per_usec;
-int delay __P((int));
+void delay __P((unsigned long));
#define DELAY(n) delay(n)
+/* XXX ALL OF THE FOLLOWING BELONG IN INTR.H */
int spl0 __P((void)); /* drop ipl to zero */
+/* XXX END INTR.H */
#endif
#endif /* !_KERNEL */
-
-int prtloc;
-extern int ticks;
-#define LOC() do { if (prtloc) printf("(%ld:%ld) %s: %d\n", curproc ? curproc->p_pid : -1, (long)ticks, __FILE__, __LINE__); } while (0)
-#define PLOC(str) panic("XXX: (%ld:%ld) %s at %s: %d\n", curproc ? curproc->p_pid : -1, (long)ticks, str, __FILE__, __LINE__);
diff --git a/sys/arch/alpha/include/pcb.h b/sys/arch/alpha/include/pcb.h
index e24132f82db..bd7530fb65a 100644
--- a/sys/arch/alpha/include/pcb.h
+++ b/sys/arch/alpha/include/pcb.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcb.h,v 1.2 1996/07/29 22:58:59 niklas Exp $ */
-/* $NetBSD: pcb.h,v 1.1 1995/02/13 23:07:43 cgd Exp $ */
+/* $OpenBSD: pcb.h,v 1.3 1996/10/30 22:39:14 niklas Exp $ */
+/* $NetBSD: pcb.h,v 1.4 1996/10/07 23:57:21 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -31,9 +31,7 @@
#include <machine/frame.h>
#include <machine/reg.h>
-/*
- * XXX where did this info come from?
- */
+#include <machine/alpha_cpu.h>
/*
* PCB: process control block
@@ -49,17 +47,11 @@
* So we cache the physical address of the pcb in the md_proc struct.
*/
struct pcb {
- u_int64_t pcb_ksp; /* kernel stack ptr [HW] */
- u_int64_t pcb_usp; /* user stack ptr [HW] */
- u_int64_t pcb_ptbr; /* page table base reg [HW] */
- u_int32_t pcb_pcc; /* process cycle cntr [HW] */
- u_int32_t pcb_asn; /* address space number [HW] */
- u_int64_t pcb_unique; /* process unique value [HW] */
- u_int64_t pcb_fen; /* FP enable (in bit 0) [HW] */
- u_int64_t pcb_decrsv[2]; /* DEC reserved [HW] */
- u_int64_t pcb_context[9]; /* s[0-6], ra, ps [SW] */
+ struct alpha_pcb pcb_hw; /* PALcode defined */
+ unsigned long pcb_context[9]; /* s[0-6], ra, ps [SW] */
struct fpreg pcb_fp; /* FP registers [SW] */
- caddr_t pcb_onfault; /* for copy faults [SW] */
+ unsigned long pcb_onfault; /* for copy faults [SW] */
+ unsigned long pcb_accessaddr; /* for [fs]uswintr [SW] */
};
/*
@@ -69,4 +61,9 @@ struct pcb {
*/
struct md_coredump {
struct trapframe md_tf;
+ struct fpreg md_fpstate;
};
+
+#ifdef _KERNEL
+void savectx __P((struct pcb *));
+#endif
diff --git a/sys/arch/alpha/include/pmap.h b/sys/arch/alpha/include/pmap.h
index ed63680b21d..9b2120cd6ce 100644
--- a/sys/arch/alpha/include/pmap.h
+++ b/sys/arch/alpha/include/pmap.h
@@ -1,127 +1,10 @@
-/* $OpenBSD: pmap.h,v 1.3 1996/07/29 22:59:01 niklas Exp $ */
-/* $NetBSD: pmap.h,v 1.4 1995/11/23 02:36:25 cgd Exp $ */
+/* $OpenBSD: pmap.h,v 1.4 1996/10/30 22:39:16 niklas Exp $ */
+/* $NetBSD: pmap.h,v 1.9 1996/08/20 23:02:30 cgd Exp $ */
-/*
- * Copyright (c) 1987 Carnegie-Mellon University
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department.
- *
- * 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.
- *
- * @(#)pmap.h 8.1 (Berkeley) 6/10/93
- */
+#ifndef NEW_PMAP
+#include <machine/pmap.old.h>
+#else
+#include <machine/pmap.new.h>
+#endif
-#ifndef _PMAP_MACHINE_
-#define _PMAP_MACHINE_
-
-#include <machine/pte.h>
-
-#define ALPHA_PAGE_SIZE NBPG
-#define ALPHA_SEG_SIZE NBSEG
-
-#define alpha_trunc_seg(x) (((u_long)(x)) & ~(ALPHA_SEG_SIZE-1))
-#define alpha_round_seg(x) alpha_trunc_seg((u_long)(x) + ALPHA_SEG_SIZE-1)
-
-/*
- * Pmap stuff
- */
-struct pmap {
- pt_entry_t *pm_ptab; /* KVA of page table */
- pt_entry_t *pm_stab; /* KVA of segment table */
- int pm_stchanged; /* ST changed */
- pt_entry_t pm_stpte; /* PTE mapping STE */
- short pm_sref; /* segment table ref count */
- short pm_count; /* pmap reference count */
- simple_lock_data_t pm_lock; /* lock on pmap */
- struct pmap_statistics pm_stats; /* pmap statistics */
- long pm_ptpages; /* more stats: PT pages */
-};
-
-typedef struct pmap *pmap_t;
-
-extern struct pmap kernel_pmap_store;
-
-#define pmap_kernel() (&kernel_pmap_store)
-#define active_pmap(pm) \
- ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
-
-/*
- * Macros for speed
- */
-#define PMAP_ACTIVATE(pmapp, iscurproc) \
- if ((pmapp) != NULL && (pmapp)->pm_stchanged) { \
- if (iscurproc) \
- loadustp((pmapp)->pm_stpte); \
- (pmapp)->pm_stchanged = FALSE; \
- }
-#define PMAP_DEACTIVATE(pmapp, pcbp)
-
-/*
- * For each vm_page_t, there is a list of all currently valid virtual
- * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
- */
-typedef struct pv_entry {
- struct pv_entry *pv_next; /* next pv_entry */
- struct pmap *pv_pmap; /* pmap where mapping lies */
- vm_offset_t pv_va; /* virtual address for mapping */
- pt_entry_t *pv_ptpte; /* non-zero if VA maps a PT page */
- struct pmap *pv_ptpmap; /* if pv_ptpte, pmap for PT page */
- int pv_flags; /* flags */
-} *pv_entry_t;
-
-#define PV_PTPAGE 0x01 /* header: entry maps a page table page */
-
-/*
- * bits of pmap_attributes[]
- */
-#define PMAP_ATTR_MOD 0x01 /* modified */
-#define PMAP_ATTR_REF 0x02 /* referenced */
-
-#ifdef _KERNEL
-pv_entry_t pv_table; /* array of entries, one per page */
-
-#define pa_index(pa) atop(pa - vm_first_phys)
-#define pa_to_pvh(pa) (&pv_table[pa_index(pa)])
-
-#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
-#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
-
-extern pt_entry_t *Sysmap;
-extern char *vmmap; /* map for mem, dumps, etc. */
-
-/* Machine-specific functions. */
-void pmap_emulate_reference __P((struct proc *p, vm_offset_t v,
- int user, int write));
-#endif /* _KERNEL */
-
-#endif /* _PMAP_MACHINE_ */
+void pmap_unmap_prom __P((void));
diff --git a/sys/arch/alpha/include/pmap.new.h b/sys/arch/alpha/include/pmap.new.h
new file mode 100644
index 00000000000..d70ee7302c9
--- /dev/null
+++ b/sys/arch/alpha/include/pmap.new.h
@@ -0,0 +1,363 @@
+/* $OpenBSD: pmap.new.h,v 1.1 1996/10/30 22:39:17 niklas Exp $ */
+/* $NetBSD: pmap.new.h,v 1.3 1996/08/20 23:02:59 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1996 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * File: pmap.h
+ *
+ * Author: David Golub (mods for Alpha by Alessandro Forin)
+ Mods for use in {Net,Open}BSD/Alpha by Chris Demetriou.
+ * Date: 1988 ca.
+ *
+ * Machine-dependent structures for the physical map module.
+ */
+
+#ifndef _PMAP_MACHINE_
+#define _PMAP_MACHINE_
+
+#include <machine/alpha_cpu.h>
+
+/* XXX */
+typedef struct pcb *pcb_t;
+
+/*
+ * Alpha Page Table Entry
+ */
+
+typedef alpha_pt_entry_t pt_entry_t;
+#define PT_ENTRY_NULL ((pt_entry_t *) 0)
+
+#define ALPHA_OFFMASK (ALPHA_PGBYTES-1) /* offset within page */
+
+#define SEG_MASK ((ALPHA_PGBYTES / 8)-1) /* masks for segments */
+#define SEG3_SHIFT (ALPHA_PGSHIFT) /* shifts for segments */
+#define SEG2_SHIFT (SEG3_SHIFT+(ALPHA_PGSHIFT-3))
+#define SEG1_SHIFT (SEG2_SHIFT+(ALPHA_PGSHIFT-3))
+
+/*
+ * Convert address offset to page descriptor index
+ */
+#define pdenum(a) (((a) >> SEG1_SHIFT) & SEG_MASK)
+
+/*
+ * Convert page descriptor index to user virtual address
+ */
+#define pdetova(a) ((vm_offset_t)(a) << SEG1_SHIFT)
+#define pde2tova(a) ((vm_offset_t)(a) << SEG2_SHIFT)
+#define pde3tova(a) ((vm_offset_t)(a) << SEG3_SHIFT)
+
+/*
+ * Convert address offset to second level page table index
+ */
+#define pte2num(a) (((a) >> SEG2_SHIFT) & SEG_MASK)
+
+/*
+ * Convert address offset to third level page table index
+ */
+#define pte3num(a) (((a) >> SEG3_SHIFT) & SEG_MASK)
+
+#define NPTES (alpha_ptob(1)/sizeof(pt_entry_t))
+#define NPDES (alpha_ptob(1)/sizeof(pt_entry_t))
+
+/*
+ * Hardware/PALcode pte bit definitions (to be used directly
+ * on the ptes without using the bit fields) are defined in
+ * <machine/alpha_cpu.h>. Software-defined bits are defined
+ * here.
+ */
+
+#define ALPHA_PTE_WIRED 0x00010000
+#define ALPHA_PTE_REF 0x00020000
+#define ALPHA_PTE_MOD 0x00040000
+
+
+#define pa_to_pte(a) ALPHA_PTE_FROM_PFN(alpha_btop(a))
+#define pte_to_pa(p) alpha_ptob(ALPHA_PTE_TO_PFN(p))
+#define pte_increment_pa(p) ((p) += pa_to_pte(ALPHA_PGBYTES))
+
+/*
+ * Convert page table entry to kernel virtual address
+ */
+#define ptetokv(a) (phystokv(pte_to_pa(a)))
+
+typedef volatile long cpu_set; /* set of CPUs - must be <= 64 */
+ /* changed by other processors */
+
+#define decl_simple_lock_data(x,y) simple_lock_data_t y;
+
+struct pmap {
+ pt_entry_t *dirbase; /* page directory pointer register */
+ unsigned long dirpfn; /* cached dirbase physical PFN */
+ int pid; /* TLBPID when in use */
+ int ref_count; /* reference count */
+ decl_simple_lock_data(,lock)
+ /* lock on map */
+ struct pmap_statistics stats; /* map statistics */
+ cpu_set cpus_using; /* bitmap of cpus using pmap */
+ int (*hacking)(); /* horrible things needed */
+};
+
+typedef struct pmap *pmap_t;
+
+#define PMAP_NULL ((pmap_t) 0)
+
+#define vtophys(x) kvtophys(x)
+extern vm_offset_t kvtophys __P((vm_offset_t));
+extern void set_ptbr(pmap_t map, pcb_t pcb, boolean_t);
+
+#if NCPUS > 1
+/*
+ * List of cpus that are actively using mapped memory. Any
+ * pmap update operation must wait for all cpus in this list.
+ * Update operations must still be queued to cpus not in this
+ * list.
+ */
+extern cpu_set cpus_active;
+
+/*
+ * List of cpus that are idle, but still operating, and will want
+ * to see any kernel pmap updates when they become active.
+ */
+extern cpu_set cpus_idle;
+
+/*
+ * Quick test for pmap update requests.
+ */
+extern volatile
+boolean_t cpu_update_needed[NCPUS];
+
+/*
+ * External declarations for PMAP_ACTIVATE.
+ */
+
+void pmap_activate __P((pmap_t, struct alpha_pcb *, int));
+void pmap_deactivate __P((pmap_t, struct alpha_pcb *, int));
+void pmap_bootstrap __P((vm_offset_t, vm_offset_t, int));
+void process_pmap_updates __P((pmap_t));
+void pmap_update_interrupt __P((void));
+extern pmap_t kernel_pmap;
+
+#endif /* NCPUS > 1 */
+
+/*
+ * Machine dependent routines that are used only for Alpha.
+ */
+
+pt_entry_t *pmap_pte(pmap_t, vm_offset_t);
+
+/*
+ * Macros for speed.
+ */
+
+#if NCPUS > 1
+
+/*
+ * For multiple CPUS, PMAP_ACTIVATE and PMAP_DEACTIVATE must manage
+ * fields to control TLB invalidation on other CPUS.
+ */
+
+#define PMAP_ACTIVATE_KERNEL(my_cpu) { \
+ \
+ /* \
+ * Let pmap updates proceed while we wait for this pmap. \
+ */ \
+ i_bit_clear((my_cpu), &cpus_active); \
+ \
+ /* \
+ * Lock the pmap to put this cpu in its active set. \
+ * Wait for updates here. \
+ */ \
+ simple_lock(&kernel_pmap->lock); \
+ \
+ /* \
+ * Process invalidate requests for the kernel pmap. \
+ */ \
+ if (cpu_update_needed[(my_cpu)]) \
+ process_pmap_updates(kernel_pmap); \
+ \
+ /* \
+ * Mark that this cpu is using the pmap. \
+ */ \
+ i_bit_set((my_cpu), &kernel_pmap->cpus_using); \
+ \
+ /* \
+ * Mark this cpu active - IPL will be lowered by \
+ * load_context(). \
+ */ \
+ i_bit_set((my_cpu), &cpus_active); \
+ \
+ simple_unlock(&kernel_pmap->lock); \
+}
+
+#define PMAP_DEACTIVATE_KERNEL(my_cpu) { \
+ /* \
+ * Mark pmap no longer in use by this cpu even if \
+ * pmap is locked against updates. \
+ */ \
+ i_bit_clear((my_cpu), &kernel_pmap->cpus_using); \
+}
+
+#define PMAP_ACTIVATE_USER(pmap, th, my_cpu) { \
+ register pmap_t tpmap = (pmap); \
+ register pcb_t pcb = (th)->pcb; \
+ \
+ if (tpmap == kernel_pmap) { \
+ /* \
+ * If this is the kernel pmap, switch to its page tables. \
+ */ \
+ set_ptbr(tpmap,pcb,TRUE); \
+ } \
+ else { \
+ /* \
+ * Let pmap updates proceed while we wait for this pmap. \
+ */ \
+ i_bit_clear((my_cpu), &cpus_active); \
+ \
+ /* \
+ * Lock the pmap to put this cpu in its active set. \
+ * Wait for updates here. \
+ */ \
+ simple_lock(&tpmap->lock); \
+ \
+ /* \
+ * No need to invalidate the TLB - the entire user pmap \
+ * will be invalidated by reloading dirbase. \
+ */ \
+ if (tpmap->pid < 0) pmap_assign_tlbpid(tpmap); \
+ set_ptbr(tpmap, pcb, TRUE); \
+ \
+ /* \
+ * Mark that this cpu is using the pmap. \
+ */ \
+ i_bit_set((my_cpu), &tpmap->cpus_using); \
+ \
+ /* \
+ * Mark this cpu active - IPL will be lowered by \
+ * load_context(). \
+ */ \
+ i_bit_set((my_cpu), &cpus_active); \
+ \
+ simple_unlock(&tpmap->lock); \
+ } \
+}
+
+#define PMAP_DEACTIVATE_USER(pmap, thread, my_cpu) { \
+ register pmap_t tpmap = (pmap); \
+ \
+ /* \
+ * Do nothing if this is the kernel pmap. \
+ */ \
+ if (tpmap != kernel_pmap) { \
+ /* \
+ * Mark pmap no longer in use by this cpu even if \
+ * pmap is locked against updates. \
+ */ \
+ i_bit_clear((my_cpu), &(pmap)->cpus_using); \
+ } \
+}
+
+#define MARK_CPU_IDLE(my_cpu) { \
+ /* \
+ * Mark this cpu idle, and remove it from the active set, \
+ * since it is not actively using any pmap. Signal_cpus \
+ * will notice that it is idle, and avoid signaling it, \
+ * but will queue the update request for when the cpu \
+ * becomes active. \
+ */ \
+ spl_t s = splvm(); \
+ i_bit_set((my_cpu), &cpus_idle); \
+ i_bit_clear((my_cpu), &cpus_active); \
+ splx(s); \
+}
+
+#define MARK_CPU_ACTIVE(my_cpu) { \
+ \
+ spl_t s = splvm(); \
+ /* \
+ * If a kernel_pmap update was requested while this cpu \
+ * was idle, process it as if we got the interrupt. \
+ * Before doing so, remove this cpu from the idle set. \
+ * Since we do not grab any pmap locks while we flush \
+ * our TLB, another cpu may start an update operation \
+ * before we finish. Removing this cpu from the idle \
+ * set assures that we will receive another update \
+ * interrupt if this happens. \
+ */ \
+ i_bit_clear((my_cpu), &cpus_idle); \
+ \
+ if (cpu_update_needed[(my_cpu)]) \
+ pmap_update_interrupt(); \
+ \
+ /* \
+ * Mark that this cpu is now active. \
+ */ \
+ i_bit_set((my_cpu), &cpus_active); \
+ splx(s); \
+}
+
+#else /* NCPUS > 1 */
+
+/*
+ * With only one CPU, we just have to indicate whether the pmap is
+ * in use.
+ */
+
+#define PMAP_ACTIVATE_KERNEL(my_cpu) { \
+ kernel_pmap->cpus_using = TRUE; \
+}
+
+#define PMAP_DEACTIVATE_KERNEL(my_cpu) { \
+ kernel_pmap->cpus_using = FALSE; \
+}
+
+#define PMAP_ACTIVATE_USER(pmap, th, my_cpu) { \
+ register pmap_t tpmap = (pmap); \
+ register pcb_t pcb = (th)->pcb; \
+ \
+ if (tpmap->pid < 0) pmap_assign_tlbpid(tpmap); \
+ set_ptbr(tpmap,pcb,TRUE); \
+ if (tpmap != kernel_pmap) { \
+ tpmap->cpus_using = TRUE; \
+ } \
+}
+
+#define PMAP_DEACTIVATE_USER(pmap, thread, cpu) { \
+ if ((pmap) != kernel_pmap) \
+ (pmap)->cpus_using = FALSE; \
+}
+
+#endif /* NCPUS > 1 */
+
+#define pmap_kernel() (kernel_pmap)
+#define pmap_resident_count(pmap) ((pmap)->stats.resident_count)
+
+/*
+ * Data structures this module exports
+ */
+extern pmap_t kernel_pmap; /* pointer to the kernel pmap */
+
+#endif _PMAP_MACHINE_
diff --git a/sys/arch/alpha/include/pmap.old.h b/sys/arch/alpha/include/pmap.old.h
new file mode 100644
index 00000000000..c60dfc9c485
--- /dev/null
+++ b/sys/arch/alpha/include/pmap.old.h
@@ -0,0 +1,131 @@
+/* $OpenBSD: pmap.old.h,v 1.1 1996/10/30 22:39:18 niklas Exp $ */
+/* $NetBSD: pmap.old.h,v 1.5 1996/07/09 00:39:24 cgd Exp $ */
+
+/*
+ * Copyright (c) 1987 Carnegie-Mellon University
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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.
+ *
+ * @(#)pmap.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _PMAP_MACHINE_
+#define _PMAP_MACHINE_
+
+#include <machine/pte.h>
+
+extern vm_offset_t vtophys(vm_offset_t);
+
+#define ALPHA_PAGE_SIZE NBPG
+#define ALPHA_SEG_SIZE NBSEG
+
+#define alpha_trunc_seg(x) (((u_long)(x)) & ~(ALPHA_SEG_SIZE-1))
+#define alpha_round_seg(x) alpha_trunc_seg((u_long)(x) + ALPHA_SEG_SIZE-1)
+
+/*
+ * Pmap stuff
+ */
+struct pmap {
+ pt_entry_t *pm_ptab; /* KVA of page table */
+ pt_entry_t *pm_stab; /* KVA of segment table */
+ int pm_stchanged; /* ST changed */
+ pt_entry_t pm_stpte; /* PTE mapping STE */
+ short pm_sref; /* segment table ref count */
+ short pm_count; /* pmap reference count */
+ simple_lock_data_t pm_lock; /* lock on pmap */
+ struct pmap_statistics pm_stats; /* pmap statistics */
+ long pm_ptpages; /* more stats: PT pages */
+};
+
+typedef struct pmap *pmap_t;
+
+extern struct pmap kernel_pmap_store;
+
+#define pmap_kernel() (&kernel_pmap_store)
+#define active_pmap(pm) \
+ ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
+
+/*
+ * Macros for speed
+ */
+#define PMAP_ACTIVATE(pmapp, iscurproc) \
+ if ((pmapp) != NULL && (pmapp)->pm_stchanged) { \
+ if (iscurproc) \
+ loadustp((pmapp)->pm_stpte); \
+ (pmapp)->pm_stchanged = FALSE; \
+ }
+#define PMAP_DEACTIVATE(pmapp, pcbp)
+
+/*
+ * For each vm_page_t, there is a list of all currently valid virtual
+ * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
+ */
+typedef struct pv_entry {
+ struct pv_entry *pv_next; /* next pv_entry */
+ struct pmap *pv_pmap; /* pmap where mapping lies */
+ vm_offset_t pv_va; /* virtual address for mapping */
+ pt_entry_t *pv_ptpte; /* non-zero if VA maps a PT page */
+ struct pmap *pv_ptpmap; /* if pv_ptpte, pmap for PT page */
+ int pv_flags; /* flags */
+} *pv_entry_t;
+
+#define PV_PTPAGE 0x01 /* header: entry maps a page table page */
+
+/*
+ * bits of pmap_attributes[]
+ */
+#define PMAP_ATTR_MOD 0x01 /* modified */
+#define PMAP_ATTR_REF 0x02 /* referenced */
+
+#ifdef _KERNEL
+pv_entry_t pv_table; /* array of entries, one per page */
+
+#define pa_index(pa) atop(pa - vm_first_phys)
+#define pa_to_pvh(pa) (&pv_table[pa_index(pa)])
+
+#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
+#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
+
+extern pt_entry_t *Sysmap;
+extern char *vmmap; /* map for mem, dumps, etc. */
+
+/* Machine-specific functions. */
+void pmap_activate __P((pmap_t));
+void pmap_emulate_reference __P((struct proc *p, vm_offset_t v,
+ int user, int write));
+void pmap_bootstrap __P((vm_offset_t, vm_offset_t));
+#endif /* _KERNEL */
+
+#endif /* _PMAP_MACHINE_ */
diff --git a/sys/arch/alpha/include/proc.h b/sys/arch/alpha/include/proc.h
index 4460c2e8c25..5794e0244de 100644
--- a/sys/arch/alpha/include/proc.h
+++ b/sys/arch/alpha/include/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.2 1996/07/29 22:59:03 niklas Exp $ */
+/* $OpenBSD: proc.h,v 1.3 1996/10/30 22:39:19 niklas Exp $ */
/* $NetBSD: proc.h,v 1.2 1995/03/24 15:01:36 cgd Exp $ */
/*
@@ -39,3 +39,8 @@ struct mdproc {
};
#define MDP_FPUSED 0x0001 /* Process used the FPU */
+
+#ifdef _KERNEL
+void switch_exit __P((struct proc *));
+void switch_trampoline __P((void (*) __P((struct proc *)), void *));
+#endif
diff --git a/sys/arch/alpha/include/profile.h b/sys/arch/alpha/include/profile.h
index dd163bc13a6..34b748366d4 100644
--- a/sys/arch/alpha/include/profile.h
+++ b/sys/arch/alpha/include/profile.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: profile.h,v 1.3 1996/07/29 22:59:05 niklas Exp $ */
-/* $NetBSD: profile.h,v 1.3 1995/11/23 02:36:28 cgd Exp $ */
+/* $OpenBSD: profile.h,v 1.4 1996/10/30 22:39:20 niklas Exp $ */
+/* $NetBSD: profile.h,v 1.6 1996/09/15 22:33:28 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -92,8 +92,8 @@ LEAF(_mcount,0) /* XXX */
stq t12, OFFSET_T12(sp)
stq gp, OFFSET_GP(sp)
- br pv, 1f
-1: SETGP(pv)
+ br pv, LX99
+LX99: SETGP(pv)
mov ra, a0
mov at_reg, a1
CALL(mcount)
@@ -118,8 +118,9 @@ LEAF(_mcount,0) /* XXX */
ldq t9, OFFSET_T9(sp)
ldq t10, OFFSET_T10(sp)
ldq t11, OFFSET_T11(sp)
- ldq gp, OFFSET_GP(sp)
ldq ra, OFFSET_RA(sp)
+ stq t12, OFFSET_T12(sp)
+ ldq gp, OFFSET_GP(sp)
ldq at_reg, OFFSET_AT(sp)
@@ -164,8 +165,8 @@ _mcount:; \
stq $27, 176($30); \
stq $29, 184($30); \
\
- br $27, 1f; \
-1: ldgp $29,0($27); \
+ br $27, LX98; \
+LX98: ldgp $29,0($27); \
mov $26, $16; \
mov $28, $17; \
jsr $26,mcount; \
@@ -191,10 +192,10 @@ _mcount:; \
ldq $23, 144($30); \
ldq $24, 152($30); \
ldq $25, 160($30); \
- ldq $29, 184($30); \
+ ldq $25, 160($30); \
ldq $26, 168($30); \
- \
- ldq $28, 0($30); \
+ ldq $27, 176($30); \
+ ldq $29, 184($30); \
\
lda $30, 192($30); \
ret $31, ($28), 1; \
@@ -204,13 +205,13 @@ _mcount:; \
#ifdef _KERNEL
/*
* The following two macros do splhigh and splx respectively.
- * profile_swpipl is a special version of pal_swpipl which
+ * _alpha_pal_swpipl is a special version of alpha_pal_swpipl which
* doesn't include profiling support.
*
* XXX These macros should probably use inline assembly.
*/
#define MCOUNT_ENTER \
- s = profile_swpipl(PSL_IPL_HIGH)
+ s = _alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH)
#define MCOUNT_EXIT \
- (void)profile_swpipl(s);
+ (void)_alpha_pal_swpipl(s);
#endif
diff --git a/sys/arch/alpha/include/prom.h b/sys/arch/alpha/include/prom.h
index d27f11e7b46..827054942bb 100644
--- a/sys/arch/alpha/include/prom.h
+++ b/sys/arch/alpha/include/prom.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: prom.h,v 1.3 1996/07/29 22:59:07 niklas Exp $ */
-/* $NetBSD: prom.h,v 1.2 1996/04/23 15:23:18 cgd Exp $ */
+/* $OpenBSD: prom.h,v 1.4 1996/10/30 22:39:21 niklas Exp $ */
+/* $NetBSD: prom.h,v 1.4 1996/10/15 23:52:49 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -30,7 +30,7 @@
#ifndef ASSEMBLER
struct prom_vec {
- int (*routine)();
+ int (*routine) __P((struct crd *));
struct crd *routine_arg;
};
@@ -55,6 +55,11 @@ void putchar __P((int));
void prom_halt __P((int)) __attribute__((__noreturn__));
int prom_getenv __P((int, char *, int));
+
+void init_prom_interface __P((void));
+void hwrbp_restart_setup __P((void));
+int prom_dispatch __P((int, int, u_char *, int));
+int promcnlookc __P((dev_t, char *));
#endif
/* Prom operation values. */
@@ -64,6 +69,7 @@ int prom_getenv __P((int, char *, int));
#define PROM_R_OPEN 0x10
#define PROM_R_PUTS 0x02
#define PROM_R_READ 0x13
+#define PROM_R_WRITE 0x14
/* Environment variable values. */
#define PROM_E_BOOTED_DEV 0x4
@@ -80,3 +86,5 @@ int prom_getenv __P((int, char *, int));
#define prom_close(chan) prom_dispatch(PROM_R_CLOSE, chan)
#define prom_read(chan, len, buf, blkno) \
prom_dispatch(PROM_R_READ, chan, len, buf, blkno)
+#define prom_write(chan, len, buf, blkno) \
+ prom_dispatch(PROM_R_WRITE, chan, len, buf, blkno)
diff --git a/sys/arch/alpha/include/psl.h b/sys/arch/alpha/include/psl.h
index ef86bc4c563..e37308e86bf 100644
--- a/sys/arch/alpha/include/psl.h
+++ b/sys/arch/alpha/include/psl.h
@@ -1,97 +1,10 @@
-/* $OpenBSD: psl.h,v 1.5 1996/10/17 22:19:45 niklas Exp $ */
-/* $NetBSD: psl.h,v 1.5 1996/04/23 15:24:09 cgd Exp $ */
+/* $OpenBSD: psl.h,v 1.6 1996/10/30 22:39:22 niklas Exp $ */
+/* $NetBSD: psl.h,v 1.6 1996/07/09 00:37:51 cgd Exp $ */
/*
- * Copyright (c) 1994, 1995 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
+ * Everything which would be defined here is defined in
+ * alpha_cpu.h, and this file is no longer necessary for the
+ * Alpha. However, some machine-independent code (e.g.
+ * /sys/compat/common/kern_exit_43.c) still wants a file with
+ * this name to be around.
*/
-
-#ifndef __ALPHA_PSL_H__
-#define __ALPHA_PSL_H__
-
-/*
- * Processor Status register definitions.
- */
-#define PSL_U 0x08 /* PS<3> == 1 -> User mode */
-#define PSL_IPL 0x07 /* PS<2:0> -> Interrupt mask */
-
-/*
- * The interrupt priority levels.
- * Other IPL's are configured in software, and are listed below.
- */
-#define PSL_IPL_0 0 /* all interrupts enabled */
-#define PSL_IPL_SOFT 1 /* block software interrupts */
-#define PSL_IPL_IO 4 /* block I/O device interrupts */
-#define PSL_IPL_CLOCK 5 /* block clock interrupts */
-#define PSL_IPL_HIGH 6 /* block everything except mchecks */
-
-/*
- * Miscellaneous PSL definitions
- */
-#define PSL_MBZ (0xfffffffffffffff0) /* Must be always zero */
-#define PSL_USERSET (PSL_U) /* Must be set for user-mode */
-#define PSL_USERCLR (PSL_MBZ|PSL_IPL) /* Must be clr for user-mode */
-#define USERMODE(ps) ((ps & PSL_U) != 0) /* Is it user-mode? */
-
-#ifdef _KERNEL
-/*
- * Translation buffer invalidation macro definitions.
- */
-#define TBI_A -2 /* Flush all TB entries */
-#define TBI_AP -1 /* Flush all per-process TB entries */
-#define TBI_SI 1 /* Invalidate ITB entry for va */
-#define TBI_SD 2 /* Invalidate DTB entry for va */
-#define TBI_S 3 /* Invalidate all entries for va */
-
-#define TBIA() pal_tbi(TBI_A, NULL)
-#define TBIAP() pal_tbi(TBI_AP, NULL)
-#define TBISI(va) pal_tbi(TBI_SI, va)
-#define TBISD(va) pal_tbi(TBI_SD, va)
-#define TBIS(va) pal_tbi(TBI_S, va)
-
-/*
- * Cache invalidation/flush routines.
- */
-
-/* Flush all write buffers */
-static __inline void wbflush __P((void));
-static __inline void
-wbflush()
-{
- /* XXX? wmb */
- __asm __volatile("mb" : : : "memory");
-}
-
-#define IMB() pal_imb() /* Sync instruction cache w/data */
-
-void alpha_mb __P((void)); /* Flush all write buffers */
-void pal_imb __P((void)); /* Sync instruction cache */
-u_int64_t pal_swpipl __P((u_int64_t)); /* write new IPL, return old */
-u_int64_t profile_swpipl __P((u_int64_t)); /* pal_swpipl w/o profiling */
-void pal_tbi __P((u_int64_t, void *)); /* Invalidate TLB entries */
-void pal_halt __P((void)) __attribute__((__noreturn__)); /* halt/reboot */
-#endif /* _KERNEL */
-
-#endif /* !__ALPHA_PSL_H__ */
diff --git a/sys/arch/alpha/include/pte.h b/sys/arch/alpha/include/pte.h
index f8a669a6206..6fcec6de1b9 100644
--- a/sys/arch/alpha/include/pte.h
+++ b/sys/arch/alpha/include/pte.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pte.h,v 1.4 1996/07/29 22:59:10 niklas Exp $ */
-/* $NetBSD: pte.h,v 1.4 1996/02/01 22:28:56 mycroft Exp $ */
+/* $OpenBSD: pte.h,v 1.5 1996/10/30 22:39:23 niklas Exp $ */
+/* $NetBSD: pte.h,v 1.7 1996/10/01 20:21:05 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -41,42 +41,53 @@
/*
* Alpha Page Table Entry
*/
-typedef u_int64_t pt_entry_t;
+
+#include <machine/alpha_cpu.h>
+
+typedef alpha_pt_entry_t pt_entry_t;
+
#define PT_ENTRY_NULL ((pt_entry_t *) 0)
#define PTESHIFT 3 /* pte size == 1 << PTESHIFT */
-#define PG_V 0x0000000000000001 /* PFN Valid */
-#define PG_NV 0x0000000000000000 /* PFN NOT Valid */
-#define PG_FOR 0x0000000000000002 /* Fault on read */
-#define PG_FOW 0x0000000000000004 /* Fault on write */
-#define PG_FOE 0x0000000000000008 /* Fault on execute */
-#define PG_ASM 0x0000000000000010 /* Address space match */
-#define PG_GH 0x0000000000000060 /* Granularity hint */
-#define PG_KRE 0x0000000000000100 /* Kernel read enable */
-#define PG_URE 0x0000000000000200 /* User read enable */
-#define PG_KWE 0x0000000000001000 /* Kernel write enable */
-#define PG_UWE 0x0000000000002000 /* User write enable */
-#define PG_PROT 0x000000000000ff00
+#define PG_V ALPHA_PTE_VALID
+#define PG_NV 0
+#define PG_FOR ALPHA_PTE_FAULT_ON_READ
+#define PG_FOW ALPHA_PTE_FAULT_ON_WRITE
+#define PG_FOE ALPHA_PTE_FAULT_ON_EXECUTE
+#define PG_ASM ALPHA_PTE_ASM
+#define PG_GH ALPHA_PTE_GRANULARITY
+#define PG_KRE ALPHA_PTE_KR
+#define PG_URE ALPHA_PTE_UR
+#define PG_KWE ALPHA_PTE_KW
+#define PG_UWE ALPHA_PTE_UW
+#define PG_PROT ALPHA_PTE_PROT
#define PG_RSVD 0x000000000000cc80 /* Reserved fpr hardware */
#define PG_WIRED 0x0000000000010000 /* Wired. [SOFTWARE] */
-#define PG_FRAME 0xffffffff00000000
+#define PG_FRAME ALPHA_PTE_RAME
#define PG_SHIFT 32
-#define PG_PFNUM(x) (((x) & PG_FRAME) >> PG_SHIFT)
+#define PG_PFNUM(x) ALPHA_PTE_TO_PFN(x)
+#if 0 /* XXX NOT HERE */
#define K0SEG_BEGIN 0xfffffc0000000000 /* unmapped, cached */
#define K0SEG_END 0xfffffe0000000000
#define PHYS_UNCACHED 0x0000000040000000
+#endif
#ifndef _LOCORE
+#if 0 /* XXX NOT HERE */
#define k0segtophys(x) ((vm_offset_t)(x) & 0x00000003ffffffff)
#define phystok0seg(x) ((vm_offset_t)(x) | K0SEG_BEGIN)
#define phystouncached(x) ((vm_offset_t)(x) | PHYS_UNCACHED)
#define uncachedtophys(x) ((vm_offset_t)(x) & ~PHYS_UNCACHED)
+#endif
#define PTEMASK (NPTEPG - 1)
#define vatopte(va) (((va) >> PGSHIFT) & PTEMASK)
#define vatoste(va) (((va) >> SEGSHIFT) & PTEMASK)
+#define kvtol1pte(va) \
+ (((vm_offset_t)(va) >> (PGSHIFT + 2*(PGSHIFT-PTESHIFT))) & PTEMASK)
+
#define vatopa(va) \
((PG_PFNUM(*kvtopte(va)) << PGSHIFT) | ((vm_offset_t)(va) & PGOFSET))
@@ -92,15 +103,9 @@ typedef u_int64_t pt_entry_t;
#define ptetokv(pte) \
((((pt_entry_t *)(pte) - Sysmap) << PGSHIFT) + VM_MIN_KERNEL_ADDRESS)
-/*
- * Kernel virtual address to Lev1map entry index.
- */
-#define kvtol1pte(va) \
- (((vm_offset_t)(va) >> (PGSHIFT + 2*(PGSHIFT-PTESHIFT))) & PTEMASK)
-
#define loadustp(stpte) { \
Lev1map[kvtol1pte(VM_MIN_ADDRESS)] = stpte; \
- TBIAP(); \
+ ALPHA_TBIAP(); \
}
extern pt_entry_t *Lev1map; /* Alpha Level One page table */
diff --git a/sys/arch/alpha/include/ptrace.h b/sys/arch/alpha/include/ptrace.h
index c729976d16b..a38169df9d0 100644
--- a/sys/arch/alpha/include/ptrace.h
+++ b/sys/arch/alpha/include/ptrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ptrace.h,v 1.2 1996/07/29 22:59:11 niklas Exp $ */
+/* $OpenBSD: ptrace.h,v 1.3 1996/10/30 22:39:24 niklas Exp $ */
/* $NetBSD: ptrace.h,v 1.1 1995/02/13 23:07:51 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/reg.h b/sys/arch/alpha/include/reg.h
index 6dbb8d0ed41..f7f9dcde9ed 100644
--- a/sys/arch/alpha/include/reg.h
+++ b/sys/arch/alpha/include/reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: reg.h,v 1.2 1996/07/29 22:59:13 niklas Exp $ */
+/* $OpenBSD: reg.h,v 1.3 1996/10/30 22:39:25 niklas Exp $ */
/* $NetBSD: reg.h,v 1.2 1995/03/28 18:14:07 jtc Exp $ */
/*
@@ -94,6 +94,8 @@ struct fpreg {
#ifdef _KERNEL
void restorefpstate __P((struct fpreg *));
void savefpstate __P((struct fpreg *));
+void frametoreg __P((struct trapframe *, struct reg *));
+void regtoframe __P((struct reg *, struct trapframe *));
#endif
#endif /* _ALPHA_REG_H_ */
diff --git a/sys/arch/alpha/include/rpb.h b/sys/arch/alpha/include/rpb.h
index ca1f09ab7e8..cbe4b76eccf 100644
--- a/sys/arch/alpha/include/rpb.h
+++ b/sys/arch/alpha/include/rpb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rpb.h,v 1.4 1996/07/29 22:59:15 niklas Exp $ */
+/* $OpenBSD: rpb.h,v 1.5 1996/10/30 22:39:26 niklas Exp $ */
/* $NetBSD: rpb.h,v 1.7 1996/04/29 16:23:11 cgd Exp $ */
/*
@@ -136,11 +136,15 @@ struct rpb {
vm_offset_t rpb_memdat_off; /* C8: memory data offset */
vm_offset_t rpb_condat_off; /* D0: config data offset */
vm_offset_t rpb_fru_off; /* D8: FRU table offset */
- long (*rpb_save_term)(); /* E0: terminal save */
+ /* XXX Are the protos below correct? */
+ long (*rpb_save_term) __P((long));
+ /* E0: terminal save */
long rpb_save_term_val; /* E8: */
- long (*rpb_rest_term)(); /* F0: terminal restore */
+ long (*rpb_rest_term) __P((long));
+ /* F0: terminal restore */
long rpb_rest_term_val; /* F8: */
- long (*rpb_restart)(); /* 100: restart */
+ long (*rpb_restart) __P((long));
+ /* 100: restart */
long rpb_restart_val; /* 108: */
u_int64_t rpb_reserve_os; /* 110: */
u_int64_t rpb_reserve_hw; /* 118: */
@@ -313,7 +317,7 @@ struct ctb {
*/
struct crd {
int64_t descriptor;
- int (*code)();
+ int (*code) __P((struct crd *));
};
/*
diff --git a/sys/arch/alpha/include/setjmp.h b/sys/arch/alpha/include/setjmp.h
index 44cc80a4de4..7b032bb312e 100644
--- a/sys/arch/alpha/include/setjmp.h
+++ b/sys/arch/alpha/include/setjmp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: setjmp.h,v 1.2 1996/07/29 22:59:16 niklas Exp $ */
+/* $OpenBSD: setjmp.h,v 1.3 1996/10/30 22:39:27 niklas Exp $ */
/* $NetBSD: setjmp.h,v 1.1 1995/02/13 23:07:55 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/sfbreg.h b/sys/arch/alpha/include/sfbreg.h
index cdef5423be9..1adff8f3578 100644
--- a/sys/arch/alpha/include/sfbreg.h
+++ b/sys/arch/alpha/include/sfbreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sfbreg.h,v 1.2 1996/07/29 22:59:18 niklas Exp $ */
+/* $OpenBSD: sfbreg.h,v 1.3 1996/10/30 22:39:28 niklas Exp $ */
/* $NetBSD: sfbreg.h,v 1.1 1996/05/01 21:15:46 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/signal.h b/sys/arch/alpha/include/signal.h
index 33fd77a3a79..8df58e92099 100644
--- a/sys/arch/alpha/include/signal.h
+++ b/sys/arch/alpha/include/signal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: signal.h,v 1.2 1996/07/29 22:59:20 niklas Exp $ */
+/* $OpenBSD: signal.h,v 1.3 1996/10/30 22:39:29 niklas Exp $ */
/* $NetBSD: signal.h,v 1.2 1995/02/16 03:08:08 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/stdarg.h b/sys/arch/alpha/include/stdarg.h
index 714090bcd28..6d3b043d87c 100644
--- a/sys/arch/alpha/include/stdarg.h
+++ b/sys/arch/alpha/include/stdarg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: stdarg.h,v 1.3 1996/07/29 22:59:21 niklas Exp $ */
-/* $NetBSD: stdarg.h,v 1.3 1995/12/26 00:15:47 mycroft Exp $ */
+/* $OpenBSD: stdarg.h,v 1.4 1996/10/30 22:39:30 niklas Exp $ */
+/* $NetBSD: stdarg.h,v 1.4 1996/10/09 21:13:05 cgd Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -47,7 +47,7 @@ typedef _BSD_VA_LIST_ va_list;
(((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
#define va_start(ap, last) \
- (__builtin_next_arg(last), (ap) = *(va_list *)__builtin_saveregs())
+ (__builtin_next_arg(last), (ap) = *(va_list *)__builtin_saveregs(), (ap).pad = 0)
#define __REAL_TYPE_CLASS 8
#define __va_arg_offset(ap, type) \
diff --git a/sys/arch/alpha/include/tgareg.h b/sys/arch/alpha/include/tgareg.h
index 59a5f2cc740..f64d01b693c 100644
--- a/sys/arch/alpha/include/tgareg.h
+++ b/sys/arch/alpha/include/tgareg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tgareg.h,v 1.2 1996/07/29 22:59:23 niklas Exp $ */
+/* $OpenBSD: tgareg.h,v 1.3 1996/10/30 22:39:31 niklas Exp $ */
/* $NetBSD: tgareg.h,v 1.1 1996/04/12 01:44:23 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/types.h b/sys/arch/alpha/include/types.h
index 8f4367884a4..a068d7920fb 100644
--- a/sys/arch/alpha/include/types.h
+++ b/sys/arch/alpha/include/types.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: types.h,v 1.2 1996/07/29 22:59:27 niklas Exp $ */
-/* $NetBSD: types.h,v 1.4 1995/07/06 03:39:32 cgd Exp $ */
+/* $OpenBSD: types.h,v 1.3 1996/10/30 22:39:32 niklas Exp $ */
+/* $NetBSD: types.h,v 1.5 1996/10/01 14:26:18 cgd Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -70,6 +70,4 @@ typedef unsigned long u_int64_t;
typedef int64_t register_t;
-#define __BDEVSW_DUMP_OLD_TYPE
-
#endif /* _MACHTYPES_H_ */
diff --git a/sys/arch/alpha/include/varargs.h b/sys/arch/alpha/include/varargs.h
index e6a8c3346dd..38be90fdf3d 100644
--- a/sys/arch/alpha/include/varargs.h
+++ b/sys/arch/alpha/include/varargs.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: varargs.h,v 1.3 1996/07/29 22:59:29 niklas Exp $ */
-/* $NetBSD: varargs.h,v 1.4 1995/12/26 01:16:24 mycroft Exp $ */
+/* $OpenBSD: varargs.h,v 1.4 1996/10/30 22:39:33 niklas Exp $ */
+/* $NetBSD: varargs.h,v 1.5 1996/10/09 21:13:05 cgd Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -57,6 +57,6 @@
#undef va_start
#define va_start(ap) \
- ((ap) = *(va_list *)__builtin_saveregs())
+ ((ap) = *(va_list *)__builtin_saveregs(), (ap).pad = 0)
#endif /* !_ALPHA_VARARGS_H_ */
diff --git a/sys/arch/alpha/include/vmparam.h b/sys/arch/alpha/include/vmparam.h
index 34f99d525cb..62eb118299c 100644
--- a/sys/arch/alpha/include/vmparam.h
+++ b/sys/arch/alpha/include/vmparam.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: vmparam.h,v 1.3 1996/07/29 22:59:31 niklas Exp $ */
-/* $NetBSD: vmparam.h,v 1.2 1995/11/23 02:36:46 cgd Exp $ */
+/* $OpenBSD: vmparam.h,v 1.4 1996/10/30 22:39:34 niklas Exp $ */
+/* $NetBSD: vmparam.h,v 1.3 1996/07/09 00:28:25 cgd Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -84,15 +84,6 @@
#define DMMIN 32 /* smallest swap allocation */
#define DMMAX 4096 /* largest potential swap allocation */
-#ifdef THESE_ARE_WRONG
-/*
- * Sizes of the system and user portions of the system page table.
- */
-/* SYSPTSIZE IS SILLY; (really number of buffers for I/O) */
-#define SYSPTSIZE 1228
-#define USRPTSIZE 1024
-#endif /* WRONG */
-
/*
* PTEs for mapping user space into the kernel for phyio operations.
* 64 pte's are enough to cover 8 disks * MAXBSIZE.
@@ -138,31 +129,21 @@
* swapped in you deserve some resources. We protect the last SAFERSS
* pages against paging and will just swap you out rather than paging you.
* Note that each process has at least UPAGES+CLSIZE pages which are not
- * paged anyways (this is currently 8+2=10 pages or 5k bytes), so this
- * number just means a swapped in process is given around 25k bytes.
- * Just for fun: current memory prices are 4600$ a megabyte on VAX (4/22/81),
- * 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.
+ * paged anyways, in addition to SAFERSS.
*/
-#define SAFERSS 4 /* nominal ``small'' resident set size
+#define SAFERSS 10 /* nominal ``small'' resident set size
protected against replacement */
-#ifdef THESE_ARE_WRONG
-#define mapin(pte, v, pfnum, prot) \
- (*(int *)(pte) = ((pfnum) << PG_SHIFT) | (prot), MachTLBFlushAddr(v))
-#endif /* WRONG */
-
/*
* Mach derived constants
*/
/* user/kernel map constants */
-#define VM_MIN_ADDRESS ((vm_offset_t)0x0000000000000000) /* 0 */
-#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x0000000200000000) /* 8G */
+#define VM_MIN_ADDRESS ((vm_offset_t)ALPHA_USEG_BASE) /* 0 */
+#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x0000000200000000) /* 8G XXX */
#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS
-#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0xfffffe0000000000)
-#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xffffffffffffffff)
+#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)ALPHA_K1SEG_BASE)
+#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)ALPHA_K1SEG_END)
/* virtual sizes (bytes) for various kernel submaps */
#define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES)
@@ -171,8 +152,3 @@
/* some Alpha-specific constants */
#define VPTBASE ((vm_offset_t)0xfffffffc00000000) /* Virt. pg table */
-
-#ifdef THESE_ARE_WRONG
-/* pcb base */
-#define pcbb(p) ((u_int)(p)->p_addr)
-#endif /* WRONG */
diff --git a/sys/arch/alpha/include/vuid_event.h b/sys/arch/alpha/include/vuid_event.h
index a9ca5c9d112..833040b542e 100644
--- a/sys/arch/alpha/include/vuid_event.h
+++ b/sys/arch/alpha/include/vuid_event.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vuid_event.h,v 1.2 1996/07/29 22:59:33 niklas Exp $ */
+/* $OpenBSD: vuid_event.h,v 1.3 1996/10/30 22:39:35 niklas Exp $ */
/* $NetBSD: vuid_event.h,v 1.1 1996/04/12 01:45:47 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/include/wsconsio.h b/sys/arch/alpha/include/wsconsio.h
index 1f4bb1a418d..8dc493b5547 100644
--- a/sys/arch/alpha/include/wsconsio.h
+++ b/sys/arch/alpha/include/wsconsio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsio.h,v 1.2 1996/07/29 22:59:35 niklas Exp $ */
+/* $OpenBSD: wsconsio.h,v 1.3 1996/10/30 22:39:35 niklas Exp $ */
/* $NetBSD: wsconsio.h,v 1.1 1996/04/12 01:43:06 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/isa/isa_machdep.h b/sys/arch/alpha/isa/isa_machdep.h
index e229a164276..75d6cbe4020 100644
--- a/sys/arch/alpha/isa/isa_machdep.h
+++ b/sys/arch/alpha/isa/isa_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isa_machdep.h,v 1.2 1996/07/29 22:59:44 niklas Exp $ */
+/* $OpenBSD: isa_machdep.h,v 1.3 1996/10/30 22:39:37 niklas Exp $ */
/* $NetBSD: isa_machdep.h,v 1.2 1996/04/12 05:39:02 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/isa/isafcns_jensen.c b/sys/arch/alpha/isa/isafcns_jensen.c
index 285d75a90ac..d702ab51f03 100644
--- a/sys/arch/alpha/isa/isafcns_jensen.c
+++ b/sys/arch/alpha/isa/isafcns_jensen.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: isafcns_jensen.c,v 1.3 1996/07/29 22:59:46 niklas Exp $ */
-/* $NetBSD: isafcns_jensen.c,v 1.2 1996/04/12 01:54:04 cgd Exp $ */
+/* $OpenBSD: isafcns_jensen.c,v 1.4 1996/10/30 22:39:38 niklas Exp $ */
+/* $NetBSD: isafcns_jensen.c,v 1.4 1996/10/13 02:59:54 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/isa/mcclock_isa.c b/sys/arch/alpha/isa/mcclock_isa.c
index 30ea94aa83c..11667b25338 100644
--- a/sys/arch/alpha/isa/mcclock_isa.c
+++ b/sys/arch/alpha/isa/mcclock_isa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mcclock_isa.c,v 1.2 1996/07/29 22:59:47 niklas Exp $ */
+/* $OpenBSD: mcclock_isa.c,v 1.3 1996/10/30 22:39:39 niklas Exp $ */
/* $NetBSD: mcclock_isa.c,v 1.2 1996/04/17 22:22:46 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/isa/pckbd.c b/sys/arch/alpha/isa/pckbd.c
index c10ab4a0a20..f43a4961137 100644
--- a/sys/arch/alpha/isa/pckbd.c
+++ b/sys/arch/alpha/isa/pckbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pckbd.c,v 1.5 1996/07/29 22:59:49 niklas Exp $ */
-/* $NetBSD: pckbd.c,v 1.7 1996/05/05 01:41:53 thorpej Exp $ */
+/* $OpenBSD: pckbd.c,v 1.6 1996/10/30 22:39:40 niklas Exp $ */
+/* $NetBSD: pckbd.c,v 1.9 1996/10/13 02:59:56 christos Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
@@ -64,6 +64,7 @@
#include <machine/wsconsio.h>
#include <alpha/wscons/wsconsvar.h>
+#include <alpha/wscons/kbd.h>
#include "wscons.h"
static volatile u_char ack, nak; /* Don't ask. */
@@ -126,6 +127,15 @@ struct wscons_idev_spec pckbd_wscons_idev = {
void pckbd_bell_stop __P((void *));
+static __inline int kbd_wait_output __P((void));
+static __inline int kbd_wait_input __P((void));
+static __inline void kbd_flush_input __P((void));
+u_char kbc_get8042cmd __P((void));
+int kbc_put8042cmd __P((u_char));
+int kbd_cmd __P((u_char, u_char));
+void do_async_update __P((void *));
+void async_update __P((void));
+
/*
* DANGER WIL ROBINSON -- the values of SCROLL, NUM, CAPS, and ALT are
* important.
@@ -142,12 +152,14 @@ void pckbd_bell_stop __P((void *));
#define NONE 0x0400 /* no function */
#define KBD_DELAY \
- { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
- { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
- { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
- { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); }
-
-static inline int
+ do { \
+ bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); \
+ bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); \
+ bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); \
+ bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); \
+ } while(0)
+
+static __inline int
kbd_wait_output()
{
u_int i;
@@ -161,7 +173,7 @@ kbd_wait_output()
return 0;
}
-static inline int
+static __inline int
kbd_wait_input()
{
u_int i;
@@ -175,7 +187,7 @@ kbd_wait_input()
return 0;
}
-static inline void
+static __inline void
kbd_flush_input()
{
u_int i;
@@ -193,7 +205,7 @@ kbd_flush_input()
/*
* Get the current command byte.
*/
-static u_char
+u_char
kbc_get8042cmd()
{
@@ -209,7 +221,7 @@ kbc_get8042cmd()
/*
* Pass command byte to keyboard controller (8042).
*/
-static int
+int
kbc_put8042cmd(val)
u_char val;
{
@@ -416,7 +428,6 @@ int
pckbdintr(arg)
void *arg;
{
- struct pckbd_softc *sc = arg;
u_char data;
static u_char last;
@@ -450,11 +461,10 @@ pckbdintr(arg)
}
void
-do_async_update(poll)
- u_char poll;
+do_async_update(vp)
+ void *vp;
{
- int pos;
- static int old_pos = -1;
+ int poll = *(int *)vp;
async = 0;
@@ -479,16 +489,18 @@ do_async_update(poll)
void
async_update()
{
+ static int nopoll = 0;
+ static int poll = 1;
if (kernel || polling) {
if (async)
- untimeout(do_async_update, NULL);
- do_async_update(1);
+ untimeout(do_async_update, &nopoll);
+ do_async_update(&poll);
} else {
if (async)
return;
async = 1;
- timeout(do_async_update, NULL, 1);
+ timeout(do_async_update, &nopoll, 1);
}
}
@@ -582,134 +594,134 @@ typedef struct {
} Scan_def;
static Scan_def scan_codes[] = {
- NONE, "", "", "", /* 0 unused */
- ASCII, "\033", "\033", "\033", /* 1 ESCape */
- ASCII, "1", "!", "!", /* 2 1 */
- ASCII, "2", "@", "\000", /* 3 2 */
- ASCII, "3", "#", "#", /* 4 3 */
- ASCII, "4", "$", "$", /* 5 4 */
- ASCII, "5", "%", "%", /* 6 5 */
- ASCII, "6", "^", "\036", /* 7 6 */
- ASCII, "7", "&", "&", /* 8 7 */
- ASCII, "8", "*", "\010", /* 9 8 */
- ASCII, "9", "(", "(", /* 10 9 */
- ASCII, "0", ")", ")", /* 11 0 */
- ASCII, "-", "_", "\037", /* 12 - */
- ASCII, "=", "+", "+", /* 13 = */
- ASCII, "\177", "\177", "\010", /* 14 backspace */
- ASCII, "\t", "\177\t", "\t", /* 15 tab */
- ASCII, "q", "Q", "\021", /* 16 q */
- ASCII, "w", "W", "\027", /* 17 w */
- ASCII, "e", "E", "\005", /* 18 e */
- ASCII, "r", "R", "\022", /* 19 r */
- ASCII, "t", "T", "\024", /* 20 t */
- ASCII, "y", "Y", "\031", /* 21 y */
- ASCII, "u", "U", "\025", /* 22 u */
- ASCII, "i", "I", "\011", /* 23 i */
- ASCII, "o", "O", "\017", /* 24 o */
- ASCII, "p", "P", "\020", /* 25 p */
- ASCII, "[", "{", "\033", /* 26 [ */
- ASCII, "]", "}", "\035", /* 27 ] */
- ASCII, "\r", "\r", "\n", /* 28 return */
- CTL, "", "", "", /* 29 control */
- ASCII, "a", "A", "\001", /* 30 a */
- ASCII, "s", "S", "\023", /* 31 s */
- ASCII, "d", "D", "\004", /* 32 d */
- ASCII, "f", "F", "\006", /* 33 f */
- ASCII, "g", "G", "\007", /* 34 g */
- ASCII, "h", "H", "\010", /* 35 h */
- ASCII, "j", "J", "\n", /* 36 j */
- ASCII, "k", "K", "\013", /* 37 k */
- ASCII, "l", "L", "\014", /* 38 l */
- ASCII, ";", ":", ";", /* 39 ; */
- ASCII, "'", "\"", "'", /* 40 ' */
- ASCII, "`", "~", "`", /* 41 ` */
- SHIFT, "", "", "", /* 42 shift */
- ASCII, "\\", "|", "\034", /* 43 \ */
- ASCII, "z", "Z", "\032", /* 44 z */
- ASCII, "x", "X", "\030", /* 45 x */
- ASCII, "c", "C", "\003", /* 46 c */
- ASCII, "v", "V", "\026", /* 47 v */
- ASCII, "b", "B", "\002", /* 48 b */
- ASCII, "n", "N", "\016", /* 49 n */
- ASCII, "m", "M", "\r", /* 50 m */
- ASCII, ",", "<", "<", /* 51 , */
- ASCII, ".", ">", ">", /* 52 . */
- ASCII, "/", "?", "\037", /* 53 / */
- SHIFT, "", "", "", /* 54 shift */
- KP, "*", "*", "*", /* 55 kp * */
- ALT, "", "", "", /* 56 alt */
- ASCII, " ", " ", "\000", /* 57 space */
- CAPS, "", "", "", /* 58 caps */
- FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
- FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
- FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
- FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
- FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
- FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
- FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
- FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
- FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
- FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
- NUM, "", "", "", /* 69 num lock */
- SCROLL, "", "", "", /* 70 scroll lock */
- KP, "7", "\033[H", "7", /* 71 kp 7 */
- KP, "8", "\033[A", "8", /* 72 kp 8 */
- KP, "9", "\033[I", "9", /* 73 kp 9 */
- KP, "-", "-", "-", /* 74 kp - */
- KP, "4", "\033[D", "4", /* 75 kp 4 */
- KP, "5", "\033[E", "5", /* 76 kp 5 */
- KP, "6", "\033[C", "6", /* 77 kp 6 */
- KP, "+", "+", "+", /* 78 kp + */
- KP, "1", "\033[F", "1", /* 79 kp 1 */
- KP, "2", "\033[B", "2", /* 80 kp 2 */
- KP, "3", "\033[G", "3", /* 81 kp 3 */
- KP, "0", "\033[L", "0", /* 82 kp 0 */
- KP, ".", "\177", ".", /* 83 kp . */
- NONE, "", "", "", /* 84 0 */
- NONE, "100", "", "", /* 85 0 */
- NONE, "101", "", "", /* 86 0 */
- FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
- FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
- NONE, "102", "", "", /* 89 0 */
- NONE, "103", "", "", /* 90 0 */
- NONE, "", "", "", /* 91 0 */
- NONE, "", "", "", /* 92 0 */
- NONE, "", "", "", /* 93 0 */
- NONE, "", "", "", /* 94 0 */
- NONE, "", "", "", /* 95 0 */
- NONE, "", "", "", /* 96 0 */
- NONE, "", "", "", /* 97 0 */
- NONE, "", "", "", /* 98 0 */
- NONE, "", "", "", /* 99 0 */
- NONE, "", "", "", /* 100 */
- NONE, "", "", "", /* 101 */
- NONE, "", "", "", /* 102 */
- NONE, "", "", "", /* 103 */
- NONE, "", "", "", /* 104 */
- NONE, "", "", "", /* 105 */
- NONE, "", "", "", /* 106 */
- NONE, "", "", "", /* 107 */
- NONE, "", "", "", /* 108 */
- NONE, "", "", "", /* 109 */
- NONE, "", "", "", /* 110 */
- NONE, "", "", "", /* 111 */
- NONE, "", "", "", /* 112 */
- NONE, "", "", "", /* 113 */
- NONE, "", "", "", /* 114 */
- NONE, "", "", "", /* 115 */
- NONE, "", "", "", /* 116 */
- NONE, "", "", "", /* 117 */
- NONE, "", "", "", /* 118 */
- NONE, "", "", "", /* 119 */
- NONE, "", "", "", /* 120 */
- NONE, "", "", "", /* 121 */
- NONE, "", "", "", /* 122 */
- NONE, "", "", "", /* 123 */
- NONE, "", "", "", /* 124 */
- NONE, "", "", "", /* 125 */
- NONE, "", "", "", /* 126 */
- NONE, "", "", "", /* 127 */
+ { NONE, "", "", "" }, /* 0 unused */
+ { ASCII, "\033", "\033", "\033" }, /* 1 ESCape */
+ { ASCII, "1", "!", "!" }, /* 2 1 */
+ { ASCII, "2", "@", "\000" }, /* 3 2 */
+ { ASCII, "3", "#", "#" }, /* 4 3 */
+ { ASCII, "4", "$", "$" }, /* 5 4 */
+ { ASCII, "5", "%", "%" }, /* 6 5 */
+ { ASCII, "6", "^", "\036" }, /* 7 6 */
+ { ASCII, "7", "&", "&" }, /* 8 7 */
+ { ASCII, "8", "*", "\010" }, /* 9 8 */
+ { ASCII, "9", "(", "(" }, /* 10 9 */
+ { ASCII, "0", ")", ")" }, /* 11 0 */
+ { ASCII, "-", "_", "\037" }, /* 12 - */
+ { ASCII, "=", "+", "+" }, /* 13 = */
+ { ASCII, "\177", "\177", "\010" }, /* 14 backspace */
+ { ASCII, "\t", "\177\t", "\t" }, /* 15 tab */
+ { ASCII, "q", "Q", "\021" }, /* 16 q */
+ { ASCII, "w", "W", "\027" }, /* 17 w */
+ { ASCII, "e", "E", "\005" }, /* 18 e */
+ { ASCII, "r", "R", "\022" }, /* 19 r */
+ { ASCII, "t", "T", "\024" }, /* 20 t */
+ { ASCII, "y", "Y", "\031" }, /* 21 y */
+ { ASCII, "u", "U", "\025" }, /* 22 u */
+ { ASCII, "i", "I", "\011" }, /* 23 i */
+ { ASCII, "o", "O", "\017" }, /* 24 o */
+ { ASCII, "p", "P", "\020" }, /* 25 p */
+ { ASCII, "[", "{", "\033" }, /* 26 [ */
+ { ASCII, "]", "}", "\035" }, /* 27 ] */
+ { ASCII, "\r", "\r", "\n" }, /* 28 return */
+ { CTL, "", "", "" }, /* 29 control */
+ { ASCII, "a", "A", "\001" }, /* 30 a */
+ { ASCII, "s", "S", "\023" }, /* 31 s */
+ { ASCII, "d", "D", "\004" }, /* 32 d */
+ { ASCII, "f", "F", "\006" }, /* 33 f */
+ { ASCII, "g", "G", "\007" }, /* 34 g */
+ { ASCII, "h", "H", "\010" }, /* 35 h */
+ { ASCII, "j", "J", "\n" }, /* 36 j */
+ { ASCII, "k", "K", "\013" }, /* 37 k */
+ { ASCII, "l", "L", "\014" }, /* 38 l */
+ { ASCII, ";", ":", ";" }, /* 39 ; */
+ { ASCII, "'", "\"", "'" }, /* 40 ' */
+ { ASCII, "`", "~", "`" }, /* 41 ` */
+ { SHIFT, "", "", "" }, /* 42 shift */
+ { ASCII, "\\", "|", "\034" }, /* 43 \ */
+ { ASCII, "z", "Z", "\032" }, /* 44 z */
+ { ASCII, "x", "X", "\030" }, /* 45 x */
+ { ASCII, "c", "C", "\003" }, /* 46 c */
+ { ASCII, "v", "V", "\026" }, /* 47 v */
+ { ASCII, "b", "B", "\002" }, /* 48 b */
+ { ASCII, "n", "N", "\016" }, /* 49 n */
+ { ASCII, "m", "M", "\r" }, /* 50 m */
+ { ASCII, ",", "<", "<" }, /* 51 , */
+ { ASCII, ".", ">", ">" }, /* 52 . */
+ { ASCII, "/", "?", "\037" }, /* 53 / */
+ { SHIFT, "", "", "" }, /* 54 shift */
+ { KP, "*", "*", "*" }, /* 55 kp * */
+ { ALT, "", "", "" }, /* 56 alt */
+ { ASCII, " ", " ", "\000" }, /* 57 space */
+ { CAPS, "", "", "" }, /* 58 caps */
+ { FUNC, "\033[M", "\033[Y", "\033[k" }, /* 59 f1 */
+ { FUNC, "\033[N", "\033[Z", "\033[l" }, /* 60 f2 */
+ { FUNC, "\033[O", "\033[a", "\033[m" }, /* 61 f3 */
+ { FUNC, "\033[P", "\033[b", "\033[n" }, /* 62 f4 */
+ { FUNC, "\033[Q", "\033[c", "\033[o" }, /* 63 f5 */
+ { FUNC, "\033[R", "\033[d", "\033[p" }, /* 64 f6 */
+ { FUNC, "\033[S", "\033[e", "\033[q" }, /* 65 f7 */
+ { FUNC, "\033[T", "\033[f", "\033[r" }, /* 66 f8 */
+ { FUNC, "\033[U", "\033[g", "\033[s" }, /* 67 f9 */
+ { FUNC, "\033[V", "\033[h", "\033[t" }, /* 68 f10 */
+ { NUM, "", "", "" }, /* 69 num lock */
+ { SCROLL, "", "", "" }, /* 70 scroll lock */
+ { KP, "7", "\033[H", "7" }, /* 71 kp 7 */
+ { KP, "8", "\033[A", "8" }, /* 72 kp 8 */
+ { KP, "9", "\033[I", "9" }, /* 73 kp 9 */
+ { KP, "-", "-", "-" }, /* 74 kp - */
+ { KP, "4", "\033[D", "4" }, /* 75 kp 4 */
+ { KP, "5", "\033[E", "5" }, /* 76 kp 5 */
+ { KP, "6", "\033[C", "6" }, /* 77 kp 6 */
+ { KP, "+", "+", "+" }, /* 78 kp + */
+ { KP, "1", "\033[F", "1" }, /* 79 kp 1 */
+ { KP, "2", "\033[B", "2" }, /* 80 kp 2 */
+ { KP, "3", "\033[G", "3" }, /* 81 kp 3 */
+ { KP, "0", "\033[L", "0" }, /* 82 kp 0 */
+ { KP, ".", "\177", "." }, /* 83 kp . */
+ { NONE, "", "", "" }, /* 84 0 */
+ { NONE, "100", "", "" }, /* 85 0 */
+ { NONE, "101", "", "" }, /* 86 0 */
+ { FUNC, "\033[W", "\033[i", "\033[u" }, /* 87 f11 */
+ { FUNC, "\033[X", "\033[j", "\033[v" }, /* 88 f12 */
+ { NONE, "102", "", "" }, /* 89 0 */
+ { NONE, "103", "", "" }, /* 90 0 */
+ { NONE, "", "", "" }, /* 91 0 */
+ { NONE, "", "", "" }, /* 92 0 */
+ { NONE, "", "", "" }, /* 93 0 */
+ { NONE, "", "", "" }, /* 94 0 */
+ { NONE, "", "", "" }, /* 95 0 */
+ { NONE, "", "", "" }, /* 96 0 */
+ { NONE, "", "", "" }, /* 97 0 */
+ { NONE, "", "", "" }, /* 98 0 */
+ { NONE, "", "", "" }, /* 99 0 */
+ { NONE, "", "", "" }, /* 100 */
+ { NONE, "", "", "" }, /* 101 */
+ { NONE, "", "", "" }, /* 102 */
+ { NONE, "", "", "" }, /* 103 */
+ { NONE, "", "", "" }, /* 104 */
+ { NONE, "", "", "" }, /* 105 */
+ { NONE, "", "", "" }, /* 106 */
+ { NONE, "", "", "" }, /* 107 */
+ { NONE, "", "", "" }, /* 108 */
+ { NONE, "", "", "" }, /* 109 */
+ { NONE, "", "", "" }, /* 110 */
+ { NONE, "", "", "" }, /* 111 */
+ { NONE, "", "", "" }, /* 112 */
+ { NONE, "", "", "" }, /* 113 */
+ { NONE, "", "", "" }, /* 114 */
+ { NONE, "", "", "" }, /* 115 */
+ { NONE, "", "", "" }, /* 116 */
+ { NONE, "", "", "" }, /* 117 */
+ { NONE, "", "", "" }, /* 118 */
+ { NONE, "", "", "" }, /* 119 */
+ { NONE, "", "", "" }, /* 120 */
+ { NONE, "", "", "" }, /* 121 */
+ { NONE, "", "", "" }, /* 122 */
+ { NONE, "", "", "" }, /* 123 */
+ { NONE, "", "", "" }, /* 124 */
+ { NONE, "", "", "" }, /* 125 */
+ { NONE, "", "", "" }, /* 126 */
+ { NONE, "", "", "" } /* 127 */
};
/*
diff --git a/sys/arch/alpha/isa/pckbdreg.h b/sys/arch/alpha/isa/pckbdreg.h
index 0f5aa607fff..10e63b35074 100644
--- a/sys/arch/alpha/isa/pckbdreg.h
+++ b/sys/arch/alpha/isa/pckbdreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pckbdreg.h,v 1.2 1996/07/29 22:59:51 niklas Exp $ */
+/* $OpenBSD: pckbdreg.h,v 1.3 1996/10/30 22:39:41 niklas Exp $ */
/* $NetBSD: pckbdreg.h,v 1.1 1995/08/03 00:48:30 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/isa/pms.c b/sys/arch/alpha/isa/pms.c
index 3c13fe88153..7b758f43916 100644
--- a/sys/arch/alpha/isa/pms.c
+++ b/sys/arch/alpha/isa/pms.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pms.c,v 1.2 1996/07/29 22:59:53 niklas Exp $ */
-/* $NetBSD: pms.c,v 1.1 1996/04/12 01:53:06 cgd Exp $ */
+/* $OpenBSD: pms.c,v 1.3 1996/10/30 22:39:42 niklas Exp $ */
+/* $NetBSD: pms.c,v 1.3 1996/10/13 02:59:58 christos Exp $ */
/*-
* Copyright (c) 1994 Charles Hannum.
@@ -53,6 +53,7 @@
#include <machine/intr.h>
#include <dev/isa/isavar.h>
#include <alpha/wscons/wsconsvar.h>
+#include <alpha/wscons/ms.h>
#define PMS_DATA 0x60 /* offset for data port, read-write */
#define PMS_CNTRL 0x64 /* offset for control port, write-only */
@@ -126,12 +127,17 @@ struct wscons_mdev_spec pms_mdev_spec = {
pms_disable,
};
-static inline void
+static __inline void pms_flush __P((void));
+static __inline void pms_dev_cmd __P((u_char));
+static __inline void pms_aux_cmd __P((u_char));
+static __inline void pms_pit_cmd __P((u_char));
+
+static __inline void
pms_flush()
{
u_char c;
- while (c = bus_io_read_1(pms_bc, pms_status_ioh, 0) & 0x03)
+ while ((c = bus_io_read_1(pms_bc, pms_status_ioh, 0)) & 0x03)
if ((c & PMS_OBUF_FULL) == PMS_OBUF_FULL) {
/* XXX - delay is needed to prevent some keyboards from
wedging when the system boots */
@@ -140,7 +146,7 @@ pms_flush()
}
}
-static inline void
+static __inline void
pms_dev_cmd(value)
u_char value;
{
@@ -151,7 +157,7 @@ pms_dev_cmd(value)
bus_io_write_1(pms_bc, pms_data_ioh, 0, value);
}
-static inline void
+static __inline void
pms_aux_cmd(value)
u_char value;
{
@@ -160,7 +166,7 @@ pms_aux_cmd(value)
bus_io_write_1(pms_bc, pms_cntrl_ioh, 0, value);
}
-static inline void
+static __inline void
pms_pit_cmd(value)
u_char value;
{
@@ -288,7 +294,6 @@ pmsintr(arg)
static u_char buttons;
u_char changed;
static char dx, dy;
- u_char buffer[5];
if ((sc->sc_state & PMS_OPEN) == 0) {
/* Interrupts are not expected. Discard the byte. */
diff --git a/sys/arch/alpha/isa/spkrreg.h b/sys/arch/alpha/isa/spkrreg.h
index 89a89edd0f5..d6fe4e6c877 100644
--- a/sys/arch/alpha/isa/spkrreg.h
+++ b/sys/arch/alpha/isa/spkrreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: spkrreg.h,v 1.2 1996/07/29 22:59:55 niklas Exp $ */
+/* $OpenBSD: spkrreg.h,v 1.3 1996/10/30 22:39:43 niklas Exp $ */
/* $NetBSD: spkrreg.h,v 1.1 1996/04/12 01:54:46 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/isa/timerreg.h b/sys/arch/alpha/isa/timerreg.h
index 98dfaa75ceb..7314fb10dde 100644
--- a/sys/arch/alpha/isa/timerreg.h
+++ b/sys/arch/alpha/isa/timerreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: timerreg.h,v 1.2 1996/07/29 22:59:57 niklas Exp $ */
+/* $OpenBSD: timerreg.h,v 1.3 1996/10/30 22:39:44 niklas Exp $ */
/* $NetBSD: timerreg.h,v 1.1 1996/04/12 01:54:56 cgd Exp $ */
/*-
diff --git a/sys/arch/alpha/pci/apecs.c b/sys/arch/alpha/pci/apecs.c
index 9c57dbb14a8..fee67e04274 100644
--- a/sys/arch/alpha/pci/apecs.c
+++ b/sys/arch/alpha/pci/apecs.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: apecs.c,v 1.4 1996/07/29 23:00:01 niklas Exp $ */
-/* $NetBSD: apecs.c,v 1.7 1996/04/12 06:08:01 cgd Exp $ */
+/* $OpenBSD: apecs.c,v 1.5 1996/10/30 22:39:46 niklas Exp $ */
+/* $NetBSD: apecs.c,v 1.12 1996/10/13 03:00:00 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -45,7 +45,10 @@
#include <dev/pci/pcivar.h>
#include <alpha/pci/apecsreg.h>
#include <alpha/pci/apecsvar.h>
+#include <alpha/pci/apecs_lca.h>
+#if defined(DEC_2100_A50)
#include <alpha/pci/pci_2100_a50.h>
+#endif
int apecsmatch __P((struct device *, void *, void *));
void apecsattach __P((struct device *, struct device *, void *));
@@ -58,7 +61,7 @@ struct cfdriver apecs_cd = {
NULL, "apecs", DV_DULL,
};
-static int apecsprint __P((void *, char *pnp));
+int apecsprint __P((void *, /* const */ char *pnp));
/* There can be only one. */
int apecsfound;
@@ -69,7 +72,6 @@ apecsmatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct confargs *ca = aux;
/* Make sure that we're looking for an APECS. */
@@ -107,7 +109,7 @@ apecs_init(acp)
/* Turn off DMA window enables in PCI Base Reg 1. */
REGVAL(EPIC_PCI_BASE_1) = 0;
- wbflush();
+ alpha_mb();
/* XXX SGMAP? */
}
@@ -161,10 +163,10 @@ apecsattach(parent, self, aux)
config_found(self, &pba, apecsprint);
}
-static int
+int
apecsprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
register struct pcibus_attach_args *pba = aux;
diff --git a/sys/arch/alpha/pci/apecs_lca.h b/sys/arch/alpha/pci/apecs_lca.h
new file mode 100644
index 00000000000..5fd663e8ad4
--- /dev/null
+++ b/sys/arch/alpha/pci/apecs_lca.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: apecs_lca.h,v 1.1 1996/10/30 22:39:47 niklas Exp $ */
+
+/*
+ * Copyright (c) 1996 Niklas Hallqvist
+ * 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 Niklas Hallqvist.
+ * 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 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.
+ */
+
+void apecs_lca_bus_io_init __P((bus_chipset_tag_t, void *));
+void apecs_lca_bus_mem_init __P((bus_chipset_tag_t, void *));
diff --git a/sys/arch/alpha/pci/apecs_lca_bus_io.c b/sys/arch/alpha/pci/apecs_lca_bus_io.c
index 4aa40d80ab2..8b2fa459a34 100644
--- a/sys/arch/alpha/pci/apecs_lca_bus_io.c
+++ b/sys/arch/alpha/pci/apecs_lca_bus_io.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: apecs_lca_bus_io.c,v 1.2 1996/07/29 23:00:04 niklas Exp $ */
-/* $NetBSD: apecs_lca_bus_io.c,v 1.2.4.1 1996/06/13 18:14:55 cgd Exp $ */
+/* $OpenBSD: apecs_lca_bus_io.c,v 1.3 1996/10/30 22:39:48 niklas Exp $ */
+/* $NetBSD: apecs_lca_bus_io.c,v 1.4 1996/08/27 16:29:23 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
@@ -38,6 +39,7 @@
#include <alpha/pci/apecsreg.h>
#include <alpha/pci/lcareg.h>
+#include <alpha/pci/apecs_lca.h>
#if (APECS_PCI_SIO != LCA_PCI_SIO)
#error Sparse I/O addresses do not match up?
diff --git a/sys/arch/alpha/pci/apecs_lca_bus_mem.c b/sys/arch/alpha/pci/apecs_lca_bus_mem.c
index 6d03c167530..e06744504ac 100644
--- a/sys/arch/alpha/pci/apecs_lca_bus_mem.c
+++ b/sys/arch/alpha/pci/apecs_lca_bus_mem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: apecs_lca_bus_mem.c,v 1.2 1996/07/29 23:00:06 niklas Exp $ */
-/* $NetBSD: apecs_lca_bus_mem.c,v 1.2.4.2 1996/06/13 18:14:58 cgd Exp $ */
+/* $OpenBSD: apecs_lca_bus_mem.c,v 1.3 1996/10/30 22:39:48 niklas Exp $ */
+/* $NetBSD: apecs_lca_bus_mem.c,v 1.5 1996/08/27 16:29:24 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
@@ -38,6 +39,7 @@
#include <alpha/pci/apecsreg.h>
#include <alpha/pci/lcareg.h>
+#include <alpha/pci/apecs_lca.h>
#if (APECS_PCI_SPARSE != LCA_PCI_SPARSE) || (APECS_PCI_DENSE != LCA_PCI_DENSE)
#error Memory addresses do not match up?
diff --git a/sys/arch/alpha/pci/apecs_pci.c b/sys/arch/alpha/pci/apecs_pci.c
index 6086b9807b5..c61fed79b98 100644
--- a/sys/arch/alpha/pci/apecs_pci.c
+++ b/sys/arch/alpha/pci/apecs_pci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: apecs_pci.c,v 1.4 1996/07/29 23:00:07 niklas Exp $ */
-/* $NetBSD: apecs_pci.c,v 1.6 1996/04/12 06:08:09 cgd Exp $ */
+/* $OpenBSD: apecs_pci.c,v 1.5 1996/10/30 22:39:49 niklas Exp $ */
+/* $NetBSD: apecs_pci.c,v 1.9 1996/10/13 03:00:02 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -34,6 +34,8 @@
#include <sys/device.h>
#include <vm/vm.h>
+#include <machine/autoconf.h> /* badaddr() proto */
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/pci/apecsreg.h>
@@ -119,12 +121,12 @@ apecs_conf_read(cpv, tag, offset)
if (secondary) {
s = splhigh();
old_haxr2 = REGVAL(EPIC_HAXR2);
- wbflush();
+ alpha_mb();
REGVAL(EPIC_HAXR2) = old_haxr2 | 0x1;
- wbflush();
+ alpha_mb();
}
- datap = (pcireg_t *)phystok0seg(APECS_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(APECS_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -134,9 +136,9 @@ apecs_conf_read(cpv, tag, offset)
data = *datap;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(EPIC_HAXR2) = old_haxr2;
- wbflush();
+ alpha_mb();
splx(s);
}
@@ -165,12 +167,12 @@ apecs_conf_write(cpv, tag, offset, data)
if (secondary) {
s = splhigh();
old_haxr2 = REGVAL(EPIC_HAXR2);
- wbflush();
+ alpha_mb();
REGVAL(EPIC_HAXR2) = old_haxr2 | 0x1;
- wbflush();
+ alpha_mb();
}
- datap = (pcireg_t *)phystok0seg(APECS_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(APECS_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -178,9 +180,9 @@ apecs_conf_write(cpv, tag, offset, data)
*datap = data;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(EPIC_HAXR2) = old_haxr2;
- wbflush();
+ alpha_mb();
splx(s);
}
diff --git a/sys/arch/alpha/pci/apecsreg.h b/sys/arch/alpha/pci/apecsreg.h
index 5bf5eab8dc6..169faaf6cf1 100644
--- a/sys/arch/alpha/pci/apecsreg.h
+++ b/sys/arch/alpha/pci/apecsreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: apecsreg.h,v 1.3 1996/07/29 23:00:10 niklas Exp $ */
-/* $NetBSD: apecsreg.h,v 1.3 1995/11/23 02:37:19 cgd Exp $ */
+/* $OpenBSD: apecsreg.h,v 1.4 1996/10/30 22:39:51 niklas Exp $ */
+/* $NetBSD: apecsreg.h,v 1.4 1996/07/09 00:54:34 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -35,7 +35,7 @@
* Sheet'' (DEC order number EC-QAEMA-TE), pages 4-1 - 4-27, 10-21 - 10-38.
*/
-#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+#define REGVAL(r) (*(int32_t *)ALPHA_PHYS_TO_K0SEG(r))
/*
* Base addresses
diff --git a/sys/arch/alpha/pci/apecsvar.h b/sys/arch/alpha/pci/apecsvar.h
index 1b9d71b799e..7028f9cb039 100644
--- a/sys/arch/alpha/pci/apecsvar.h
+++ b/sys/arch/alpha/pci/apecsvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: apecsvar.h,v 1.3 1996/07/29 23:00:11 niklas Exp $ */
+/* $OpenBSD: apecsvar.h,v 1.4 1996/10/30 22:39:51 niklas Exp $ */
/* $NetBSD: apecsvar.h,v 1.3 1996/04/12 06:08:14 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/bt485reg.h b/sys/arch/alpha/pci/bt485reg.h
index 4cc8f30bb1c..fcd1b16fc21 100644
--- a/sys/arch/alpha/pci/bt485reg.h
+++ b/sys/arch/alpha/pci/bt485reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt485reg.h,v 1.3 1996/07/29 23:00:13 niklas Exp $ */
+/* $OpenBSD: bt485reg.h,v 1.4 1996/10/30 22:39:52 niklas Exp $ */
/* $NetBSD: bt485reg.h,v 1.4 1996/04/12 06:08:17 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/cia.c b/sys/arch/alpha/pci/cia.c
index 1b2a5dec748..8337d47c48c 100644
--- a/sys/arch/alpha/pci/cia.c
+++ b/sys/arch/alpha/pci/cia.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cia.c,v 1.3 1996/07/29 23:00:15 niklas Exp $ */
-/* $NetBSD: cia.c,v 1.5.4.1 1996/06/10 00:02:39 cgd Exp $ */
+/* $OpenBSD: cia.c,v 1.4 1996/10/30 22:39:53 niklas Exp $ */
+/* $NetBSD: cia.c,v 1.11 1996/10/13 03:00:03 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -60,9 +60,7 @@ struct cfdriver cia_cd = {
NULL, "cia", DV_DULL,
};
-static int ciaprint __P((void *, char *pnp));
-
-#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+int ciaprint __P((void *, /* const */ char *pnp));
/* There can be only one. */
int ciafound;
@@ -73,7 +71,6 @@ ciamatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct confargs *ca = aux;
/* Make sure that we're looking for a CIA. */
@@ -111,7 +108,6 @@ ciaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct confargs *ca = aux;
struct cia_softc *sc = (struct cia_softc *)self;
struct cia_config *ccp;
struct pcibus_attach_args pba;
@@ -149,10 +145,10 @@ ciaattach(parent, self, aux)
config_found(self, &pba, ciaprint);
}
-static int
+int
ciaprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
register struct pcibus_attach_args *pba = aux;
diff --git a/sys/arch/alpha/pci/cia_bus_io.c b/sys/arch/alpha/pci/cia_bus_io.c
index 0416a519c36..75f7d27fc1e 100644
--- a/sys/arch/alpha/pci/cia_bus_io.c
+++ b/sys/arch/alpha/pci/cia_bus_io.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cia_bus_io.c,v 1.2 1996/07/29 23:00:17 niklas Exp $ */
-/* $NetBSD: cia_bus_io.c,v 1.2.4.2 1996/06/13 18:14:59 cgd Exp $ */
+/* $OpenBSD: cia_bus_io.c,v 1.3 1996/10/30 22:39:54 niklas Exp $ */
+/* $NetBSD: cia_bus_io.c,v 1.5 1996/08/27 16:29:25 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
diff --git a/sys/arch/alpha/pci/cia_bus_mem.c b/sys/arch/alpha/pci/cia_bus_mem.c
index 63760ad8fc2..47d83a467fc 100644
--- a/sys/arch/alpha/pci/cia_bus_mem.c
+++ b/sys/arch/alpha/pci/cia_bus_mem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cia_bus_mem.c,v 1.2 1996/07/29 23:00:19 niklas Exp $ */
-/* $NetBSD: cia_bus_mem.c,v 1.2.4.2 1996/06/13 18:15:01 cgd Exp $ */
+/* $OpenBSD: cia_bus_mem.c,v 1.3 1996/10/30 22:39:55 niklas Exp $ */
+/* $NetBSD: cia_bus_mem.c,v 1.5 1996/08/27 16:29:26 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
diff --git a/sys/arch/alpha/pci/cia_pci.c b/sys/arch/alpha/pci/cia_pci.c
index 03f98709a24..ac66d48a0ea 100644
--- a/sys/arch/alpha/pci/cia_pci.c
+++ b/sys/arch/alpha/pci/cia_pci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cia_pci.c,v 1.3 1996/07/29 23:00:21 niklas Exp $ */
-/* $NetBSD: cia_pci.c,v 1.2 1996/04/12 23:37:10 cgd Exp $ */
+/* $OpenBSD: cia_pci.c,v 1.4 1996/10/30 22:39:56 niklas Exp $ */
+/* $NetBSD: cia_pci.c,v 1.5 1996/10/13 03:00:04 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -34,6 +34,8 @@
#include <sys/device.h>
#include <vm/vm.h>
+#include <machine/autoconf.h> /* badaddr proto */
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/pci/ciareg.h>
@@ -119,12 +121,12 @@ cia_conf_read(cpv, tag, offset)
if (secondary) {
s = splhigh();
old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */
- wbflush();
+ alpha_mb();
REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */
- wbflush();
+ alpha_mb();
}
- datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(CIA_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -134,9 +136,9 @@ cia_conf_read(cpv, tag, offset)
data = *datap;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */
- wbflush();
+ alpha_mb();
splx(s);
}
@@ -165,12 +167,12 @@ cia_conf_write(cpv, tag, offset, data)
if (secondary) {
s = splhigh();
old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */
- wbflush();
+ alpha_mb();
REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */
- wbflush();
+ alpha_mb();
}
- datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(CIA_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -178,9 +180,9 @@ cia_conf_write(cpv, tag, offset, data)
*datap = data;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */
- wbflush();
+ alpha_mb();
splx(s);
}
diff --git a/sys/arch/alpha/pci/ciareg.h b/sys/arch/alpha/pci/ciareg.h
index b3cf98b78f3..aa33bf767ae 100644
--- a/sys/arch/alpha/pci/ciareg.h
+++ b/sys/arch/alpha/pci/ciareg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ciareg.h,v 1.3 1996/07/29 23:00:23 niklas Exp $ */
-/* $NetBSD: ciareg.h,v 1.1.4.3 1996/06/13 18:35:27 cgd Exp $ */
+/* $OpenBSD: ciareg.h,v 1.4 1996/10/30 22:39:57 niklas Exp $ */
+/* $NetBSD: ciareg.h,v 1.5 1996/07/09 00:54:44 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -34,7 +34,7 @@
* Taken from XXX
*/
-#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+#define REGVAL(r) (*(int32_t *)ALPHA_PHYS_TO_K0SEG(r))
/*
* Base addresses
diff --git a/sys/arch/alpha/pci/ciavar.h b/sys/arch/alpha/pci/ciavar.h
index 31f9b18b158..a0b5e82be37 100644
--- a/sys/arch/alpha/pci/ciavar.h
+++ b/sys/arch/alpha/pci/ciavar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ciavar.h,v 1.3 1996/07/29 23:00:24 niklas Exp $ */
-/* $NetBSD: ciavar.h,v 1.3.4.1 1996/06/10 00:04:12 cgd Exp $ */
+/* $OpenBSD: ciavar.h,v 1.4 1996/10/30 22:39:58 niklas Exp $ */
+/* $NetBSD: ciavar.h,v 1.4 1996/06/10 00:03:59 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/pci/lca.c b/sys/arch/alpha/pci/lca.c
index 264cab0ec6b..64994855849 100644
--- a/sys/arch/alpha/pci/lca.c
+++ b/sys/arch/alpha/pci/lca.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: lca.c,v 1.3 1996/07/29 23:00:26 niklas Exp $ */
-/* $NetBSD: lca.c,v 1.5 1996/04/23 14:00:53 cgd Exp $ */
+/* $OpenBSD: lca.c,v 1.4 1996/10/30 22:39:59 niklas Exp $ */
+/* $NetBSD: lca.c,v 1.10 1996/10/13 03:00:07 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -45,6 +45,10 @@
#include <dev/pci/pcivar.h>
#include <alpha/pci/lcareg.h>
#include <alpha/pci/lcavar.h>
+#include <alpha/pci/apecs_lca.h>
+#if defined(DEC_AXPPCI_33)
+#include <alpha/pci/pci_axppci_33.h>
+#endif
int lcamatch __P((struct device *, void *, void *));
void lcaattach __P((struct device *, struct device *, void *));
@@ -57,7 +61,7 @@ struct cfdriver lca_cd = {
NULL, "lca", DV_DULL,
};
-static int lcaprint __P((void *, char *pnp));
+int lcaprint __P((void *, /* const */ char *pnp));
/* There can be only one. */
int lcafound;
@@ -68,7 +72,6 @@ lcamatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct confargs *ca = aux;
/* Make sure that we're looking for a LCA. */
@@ -125,7 +128,7 @@ lca_init(lcp)
/* Turn off DMA window enables in Window Base Registers */
/* REGVAL(LCA_IOC_W_BASE0) = 0;
REGVAL(LCA_IOC_W_BASE1) = 0; */
- wbflush();
+ alpha_mb();
}
#ifdef notdef
@@ -139,7 +142,7 @@ lca_init_sgmap(lcp)
bzero(lcp->lc_sgmap, 1024 * 8); /* clear all entries. */
REGVAL(LCA_IOC_W_BASE0) = 0;
- wbflush();
+ alpha_mb();
/* Set up Translated Base Register 1; translate to sybBus addr 0. */
/* check size against APEC XXX JH */
@@ -150,7 +153,7 @@ lca_init_sgmap(lcp)
/* Enable window 1; from PCI address 8MB, direct mapped. */
REGVAL(LCA_IOC_W_BASE0) = 0x300800000;
- wbflush();
+ alpha_mb();
}
#endif
@@ -197,10 +200,10 @@ lcaattach(parent, self, aux)
config_found(self, &pba, lcaprint);
}
-static int
+int
lcaprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
register struct pcibus_attach_args *pba = aux;
diff --git a/sys/arch/alpha/pci/lca_pci.c b/sys/arch/alpha/pci/lca_pci.c
index cdee66d1396..837fbec97be 100644
--- a/sys/arch/alpha/pci/lca_pci.c
+++ b/sys/arch/alpha/pci/lca_pci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: lca_pci.c,v 1.3 1996/07/29 23:00:28 niklas Exp $ */
-/* $NetBSD: lca_pci.c,v 1.3 1996/04/23 14:01:00 cgd Exp $ */
+/* $OpenBSD: lca_pci.c,v 1.4 1996/10/30 22:40:00 niklas Exp $ */
+/* $NetBSD: lca_pci.c,v 1.6 1996/10/13 03:00:08 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -34,6 +34,8 @@
#include <sys/device.h>
#include <vm/vm.h>
+#include <machine/autoconf.h> /* badaddr proto */
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/pci/lcareg.h>
@@ -120,9 +122,9 @@ lca_conf_read(cpv, tag, offset)
pci_decompose_tag(&lcp->lc_pc, tag, &secondary, &device, 0);
if (secondary) {
s = splhigh();
- wbflush();
+ alpha_mb();
REGVAL(LCA_IOC_CONF) = 0x01;
- wbflush();
+ alpha_mb();
} else {
/*
* on the LCA, must frob the tag used for
@@ -133,7 +135,7 @@ lca_conf_read(cpv, tag, offset)
tag = (1 << (device + 11)) | (tag & 0x7ff);
}
- datap = (pcireg_t *)phystok0seg(LCA_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(LCA_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -143,9 +145,9 @@ lca_conf_read(cpv, tag, offset)
data = *datap;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(LCA_IOC_CONF) = 0x00;
- wbflush();
+ alpha_mb();
splx(s);
}
@@ -172,9 +174,9 @@ lca_conf_write(cpv, tag, offset, data)
pci_decompose_tag(&lcp->lc_pc, tag, &secondary, &device, 0);
if (secondary) {
s = splhigh();
- wbflush();
+ alpha_mb();
REGVAL(LCA_IOC_CONF) = 0x01;
- wbflush();
+ alpha_mb();
} else {
/*
* on the LCA, must frob the tag used for
@@ -185,7 +187,7 @@ lca_conf_write(cpv, tag, offset, data)
tag = (1 << (device + 11)) | (tag & 0x7ff);
}
- datap = (pcireg_t *)phystok0seg(LCA_PCI_CONF |
+ datap = (pcireg_t *)ALPHA_PHYS_TO_K0SEG(LCA_PCI_CONF |
tag << 5UL | /* XXX */
(offset & ~0x03) << 5 | /* XXX */
0 << 5 | /* XXX */
@@ -193,9 +195,9 @@ lca_conf_write(cpv, tag, offset, data)
*datap = data;
if (secondary) {
- wbflush();
+ alpha_mb();
REGVAL(LCA_IOC_CONF) = 0x00;
- wbflush();
+ alpha_mb();
splx(s);
}
diff --git a/sys/arch/alpha/pci/lcareg.h b/sys/arch/alpha/pci/lcareg.h
index 0542039990f..d9e9bffd448 100644
--- a/sys/arch/alpha/pci/lcareg.h
+++ b/sys/arch/alpha/pci/lcareg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: lcareg.h,v 1.3 1996/07/29 23:00:30 niklas Exp $ */
-/* $NetBSD: lcareg.h,v 1.2 1996/04/23 14:03:46 cgd Exp $ */
+/* $OpenBSD: lcareg.h,v 1.4 1996/10/30 22:40:00 niklas Exp $ */
+/* $NetBSD: lcareg.h,v 1.3 1996/07/09 00:54:51 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -32,7 +32,7 @@
* 21066 chip registers
*/
-#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+#define REGVAL(r) (*(int32_t *)ALPHA_PHYS_TO_K0SEG(r))
/*
* Base addresses
diff --git a/sys/arch/alpha/pci/lcavar.h b/sys/arch/alpha/pci/lcavar.h
index 7ebd8e751a9..25762783af6 100644
--- a/sys/arch/alpha/pci/lcavar.h
+++ b/sys/arch/alpha/pci/lcavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lcavar.h,v 1.3 1996/07/29 23:00:32 niklas Exp $ */
+/* $OpenBSD: lcavar.h,v 1.4 1996/10/30 22:40:02 niklas Exp $ */
/* $NetBSD: lcavar.h,v 1.3 1996/04/12 06:08:35 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pci_2100_a50.c b/sys/arch/alpha/pci/pci_2100_a50.c
index d396695ef09..1fa315bd8ae 100644
--- a/sys/arch/alpha/pci/pci_2100_a50.c
+++ b/sys/arch/alpha/pci/pci_2100_a50.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pci_2100_a50.c,v 1.6 1996/07/29 23:00:34 niklas Exp $ */
-/* $NetBSD: pci_2100_a50.c,v 1.7 1996/04/23 14:15:55 cgd Exp $ */
+/* $OpenBSD: pci_2100_a50.c,v 1.7 1996/10/30 22:40:03 niklas Exp $ */
+/* $NetBSD: pci_2100_a50.c,v 1.10 1996/10/13 03:00:09 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -36,6 +36,7 @@
#include <sys/device.h>
#include <vm/vm.h>
+#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/intr.h>
@@ -191,8 +192,6 @@ dec_2100_a50_intr_string(acv, ih)
void *acv;
pci_intr_handle_t ih;
{
- struct apecs_config *acp = acv;
-
return sio_intr_string(NULL /*XXX*/, ih);
}
@@ -204,8 +203,6 @@ dec_2100_a50_intr_establish(acv, ih, level, func, arg, name)
int (*func) __P((void *));
char *name;
{
- struct apecs_config *acp = acv;
-
return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func,
arg, name);
}
@@ -214,7 +211,5 @@ void
dec_2100_a50_intr_disestablish(acv, cookie)
void *acv, *cookie;
{
- struct apecs_config *acp = acv;
-
sio_intr_disestablish(NULL /*XXX*/, cookie);
}
diff --git a/sys/arch/alpha/pci/pci_2100_a50.h b/sys/arch/alpha/pci/pci_2100_a50.h
index 48f02de1d39..adee2d737cb 100644
--- a/sys/arch/alpha/pci/pci_2100_a50.h
+++ b/sys/arch/alpha/pci/pci_2100_a50.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_2100_a50.h,v 1.3 1996/07/29 23:00:35 niklas Exp $ */
+/* $OpenBSD: pci_2100_a50.h,v 1.4 1996/10/30 22:40:04 niklas Exp $ */
/* $NetBSD: pci_2100_a50.h,v 1.3 1996/04/12 06:08:42 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pci_axppci_33.c b/sys/arch/alpha/pci/pci_axppci_33.c
index 7c70243290c..2cf58634136 100644
--- a/sys/arch/alpha/pci/pci_axppci_33.c
+++ b/sys/arch/alpha/pci/pci_axppci_33.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pci_axppci_33.c,v 1.5 1996/07/29 23:00:37 niklas Exp $ */
-/* $NetBSD: pci_axppci_33.c,v 1.5 1996/04/23 14:15:28 cgd Exp $ */
+/* $OpenBSD: pci_axppci_33.c,v 1.6 1996/10/30 22:40:05 niklas Exp $ */
+/* $NetBSD: pci_axppci_33.c,v 1.8 1996/10/13 03:00:11 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -36,6 +36,7 @@
#include <sys/device.h>
#include <vm/vm.h>
+#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/intr.h>
@@ -195,8 +196,6 @@ dec_axppci_33_intr_string(lcv, ih)
void *lcv;
pci_intr_handle_t ih;
{
- struct lca_config *lcp = lcv;
-
return sio_intr_string(NULL /*XXX*/, ih);
}
@@ -208,8 +207,6 @@ dec_axppci_33_intr_establish(lcv, ih, level, func, arg, name)
int (*func) __P((void *));
char *name;
{
- struct lca_config *lcp = lcv;
-
return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func,
arg, name);
}
@@ -218,7 +215,5 @@ void
dec_axppci_33_intr_disestablish(lcv, cookie)
void *lcv, *cookie;
{
- struct lca_config *lcp = lcv;
-
sio_intr_disestablish(NULL /*XXX*/, cookie);
}
diff --git a/sys/arch/alpha/pci/pci_axppci_33.h b/sys/arch/alpha/pci/pci_axppci_33.h
index 9f669510798..ef9a3856111 100644
--- a/sys/arch/alpha/pci/pci_axppci_33.h
+++ b/sys/arch/alpha/pci/pci_axppci_33.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_axppci_33.h,v 1.3 1996/07/29 23:00:39 niklas Exp $ */
+/* $OpenBSD: pci_axppci_33.h,v 1.4 1996/10/30 22:40:05 niklas Exp $ */
/* $NetBSD: pci_axppci_33.h,v 1.3 1996/04/12 06:08:47 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pci_kn20aa.c b/sys/arch/alpha/pci/pci_kn20aa.c
index 179d7c56b1b..1106261c1cf 100644
--- a/sys/arch/alpha/pci/pci_kn20aa.c
+++ b/sys/arch/alpha/pci/pci_kn20aa.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pci_kn20aa.c,v 1.6 1996/10/04 03:06:04 deraadt Exp $ */
-/* $NetBSD: pci_kn20aa.c,v 1.3.4.2 1996/06/13 18:35:31 cgd Exp $ */
+/* $OpenBSD: pci_kn20aa.c,v 1.7 1996/10/30 22:40:06 niklas Exp $ */
+/* $NetBSD: pci_kn20aa.c,v 1.18 1996/10/13 03:00:12 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -39,6 +39,8 @@
#include <vm/vm.h>
+#include <machine/autoconf.h>
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -69,7 +71,7 @@ void dec_kn20aa_intr_disestablish __P((void *, void *));
struct kn20aa_intrhand {
TAILQ_ENTRY(kn20aa_intrhand) ih_q;
- int (*ih_fun)();
+ int (*ih_fun) __P((void *));
void *ih_arg;
u_long ih_count;
int ih_level;
@@ -83,7 +85,7 @@ struct evcnt kn20aa_intr_evcnt;
#endif
void kn20aa_pci_strayintr __P((int irq));
-void kn20aa_iointr __P((void *framep, int vec));
+void kn20aa_iointr __P((void *framep, unsigned long vec));
void kn20aa_enable_intr __P((int irq));
void kn20aa_disable_intr __P((int irq));
struct kn20aa_intrhand *kn20aa_attach_intr __P((struct kn20aa_intrchain *,
@@ -94,7 +96,6 @@ pci_kn20aa_pickintr(ccp)
struct cia_config *ccp;
{
int i;
- struct kn20aa_intrhand *nintrhand;
bus_chipset_tag_t bc = &ccp->cc_bc;
pci_chipset_tag_t pc = &ccp->cc_pc;
@@ -132,7 +133,6 @@ dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp)
pci_chipset_tag_t pc = &ccp->cc_pc;
int device;
int kn20aa_irq;
- void *ih;
if (buspin == 0) {
/* No IRQ used. */
@@ -174,6 +174,12 @@ dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp)
break;
default:
+#ifdef KN20AA_BOGUS_IRQ_FROB
+ *ihp = 0xdeadbeef;
+ printf("\n\n BOGUS INTERRUPT MAPPING: dev %d, pin %d\n",
+ device, buspin);
+ return (0);
+#endif
panic("pci_kn20aa_map_int: invalid device number %d\n",
device);
}
@@ -192,9 +198,14 @@ dec_kn20aa_intr_string(ccv, ih)
void *ccv;
pci_intr_handle_t ih;
{
- struct cia_config *ccp = ccv;
static char irqstr[15]; /* 11 + 2 + NULL + sanity */
+#ifdef KN20AA_BOGUS_IRQ_FROB
+ if (ih == 0xdeadbeef) {
+ sprintf(irqstr, "BOGUS");
+ return (irqstr);
+ }
+#endif
if (ih > KN20AA_MAX_IRQ)
panic("dec_kn20aa_a50_intr_string: bogus kn20aa IRQ 0x%x\n",
ih);
@@ -211,9 +222,24 @@ dec_kn20aa_intr_establish(ccv, ih, level, func, arg, name)
int (*func) __P((void *));
char *name;
{
- struct cia_config *ccp = ccv;
void *cookie;
+#ifdef KN20AA_BOGUS_IRQ_FROB
+ if (ih == 0xdeadbeef) {
+ int i;
+ char chars[10];
+
+ printf("dec_kn20aa_intr_establish: BOGUS IRQ\n");
+ do {
+ printf("IRQ to enable? ");
+ getstr(chars, 10);
+ i = atoi(chars);
+ } while (i < 0 || i > 32);
+ printf("ENABLING IRQ %d\n", i);
+ kn20aa_enable_intr(i);
+ return ((void *)0xbabefacedeadbeef);
+ }
+#endif
if (ih > KN20AA_MAX_IRQ)
panic("dec_kn20aa_intr_establish: bogus kn20aa IRQ 0x%x\n",
ih);
@@ -227,8 +253,6 @@ void
dec_kn20aa_intr_disestablish(ccv, cookie)
void *ccv, *cookie;
{
- struct cia_config *ccp = ccv;
-
panic("dec_kn20aa_intr_disestablish not implemented"); /* XXX */
}
@@ -252,7 +276,7 @@ kn20aa_pci_strayintr(irq)
void
kn20aa_iointr(framep, vec)
void *framep;
- int vec;
+ unsigned long vec;
{
struct kn20aa_intrhand *ih;
int irq, handled;
@@ -303,9 +327,9 @@ kn20aa_enable_intr(irq)
* "blech." I'd give valuable body parts for better docs or
* for a good decompiler.
*/
- wbflush();
+ alpha_mb();
REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
- wbflush();
+ alpha_mb();
}
void
@@ -313,9 +337,9 @@ kn20aa_disable_intr(irq)
int irq;
{
- wbflush();
+ alpha_mb();
REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */
- wbflush();
+ alpha_mb();
}
struct kn20aa_intrhand *
diff --git a/sys/arch/alpha/pci/pci_kn20aa.h b/sys/arch/alpha/pci/pci_kn20aa.h
index beaa93248a4..f4abae0c91a 100644
--- a/sys/arch/alpha/pci/pci_kn20aa.h
+++ b/sys/arch/alpha/pci/pci_kn20aa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_kn20aa.h,v 1.3 1996/07/29 23:00:42 niklas Exp $ */
+/* $OpenBSD: pci_kn20aa.h,v 1.4 1996/10/30 22:40:07 niklas Exp $ */
/* $NetBSD: pci_kn20aa.h,v 1.2 1996/04/13 00:24:35 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pci_machdep.c b/sys/arch/alpha/pci/pci_machdep.c
index bc163c277f0..7e6573e0fbb 100644
--- a/sys/arch/alpha/pci/pci_machdep.c
+++ b/sys/arch/alpha/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.4 1996/07/29 23:00:43 niklas Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.5 1996/10/30 22:40:08 niklas Exp $ */
/* $NetBSD: pci_machdep.c,v 1.5 1996/04/12 06:08:49 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pci_machdep.h b/sys/arch/alpha/pci/pci_machdep.h
index 3dd29d4c87c..928a78f09a5 100644
--- a/sys/arch/alpha/pci/pci_machdep.h
+++ b/sys/arch/alpha/pci/pci_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.h,v 1.4 1996/07/29 23:00:45 niklas Exp $ */
+/* $OpenBSD: pci_machdep.h,v 1.5 1996/10/30 22:40:09 niklas Exp $ */
/* $NetBSD: pci_machdep.h,v 1.4 1996/04/12 06:08:52 cgd Exp $ */
/*
@@ -86,3 +86,8 @@ struct alpha_pci_chipset {
(*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a), (nm))
#define pci_intr_disestablish(c, iv) \
(*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv))
+
+#ifdef _KERNEL
+void pci_display_console
+ __P((bus_chipset_tag_t, pci_chipset_tag_t, int, int, int));
+#endif /* _KERNEL */
diff --git a/sys/arch/alpha/pci/pcivga.c b/sys/arch/alpha/pci/pcivga.c
index 68b5f2d4814..1cbcabde789 100644
--- a/sys/arch/alpha/pci/pcivga.c
+++ b/sys/arch/alpha/pci/pcivga.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcivga.c,v 1.6 1996/07/29 23:00:46 niklas Exp $ */
-/* $NetBSD: pcivga.c,v 1.8 1996/04/17 21:49:58 cgd Exp $ */
+/* $OpenBSD: pcivga.c,v 1.7 1996/10/30 22:40:10 niklas Exp $ */
+/* $NetBSD: pcivga.c,v 1.11 1996/10/13 03:00:13 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -49,7 +49,7 @@
int pcivgamatch __P((struct device *, void *, void *));
void pcivgaattach __P((struct device *, struct device *, void *));
-int pcivgaprint __P((void *, char *));
+int pcivgaprint __P((void *, /* const */ char *));
struct cfattach pcivga_ca = {
sizeof(struct pcivga_softc), pcivgamatch, pcivgaattach,
@@ -89,7 +89,6 @@ pcivgamatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct pci_attach_args *pa = aux;
/*
@@ -222,7 +221,7 @@ pcivgaattach(parent, self, aux)
int
pcivgaprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
if (pnp)
@@ -248,7 +247,9 @@ pcivgammap(dev, offset, prot)
off_t offset;
int prot;
{
+#if 0
struct pcivga_softc *sc = (struct pcivga_softc *)dev;
+#endif
int rv;
rv = -1;
@@ -335,7 +336,6 @@ pcivga_putstr(id, row, col, cp, len)
struct pcivga_devconfig *dc = id;
bus_chipset_tag_t bc = dc->dc_bc;
bus_mem_handle_t memh = dc->dc_memh;
- char *dcp;
int i, off;
off = (row * dc->dc_ncol + col) * 2;
diff --git a/sys/arch/alpha/pci/pcivgavar.h b/sys/arch/alpha/pci/pcivgavar.h
index f306534cf91..c8a947a98dd 100644
--- a/sys/arch/alpha/pci/pcivgavar.h
+++ b/sys/arch/alpha/pci/pcivgavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcivgavar.h,v 1.4 1996/07/29 23:00:48 niklas Exp $ */
+/* $OpenBSD: pcivgavar.h,v 1.5 1996/10/30 22:40:11 niklas Exp $ */
/* $NetBSD: pcivgavar.h,v 1.5 1996/04/12 06:08:58 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/pcs_bus_io_common.c b/sys/arch/alpha/pci/pcs_bus_io_common.c
index 8c995d30915..59626ded968 100644
--- a/sys/arch/alpha/pci/pcs_bus_io_common.c
+++ b/sys/arch/alpha/pci/pcs_bus_io_common.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcs_bus_io_common.c,v 1.2 1996/07/29 23:00:50 niklas Exp $ */
-/* $NetBSD: pcs_bus_io_common.c,v 1.2.4.2 1996/06/13 18:16:59 cgd Exp $ */
+/* $OpenBSD: pcs_bus_io_common.c,v 1.3 1996/10/30 22:40:12 niklas Exp $ */
+/* $NetBSD: pcs_bus_io_common.c,v 1.8 1996/10/13 03:00:15 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -123,14 +123,14 @@ __C(CHIP,_io_map)(v, ioaddr, iosize, iohp)
#ifdef CHIP_IO_W1_START
if (ioaddr >= CHIP_IO_W1_START(v) &&
ioaddr <= CHIP_IO_W1_END(v)) {
- *iohp = (phystok0seg(CHIP_IO_W1_BASE(v)) >> 5) +
+ *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W1_BASE(v)) >> 5) +
(ioaddr & CHIP_IO_W1_MASK(v));
} else
#endif
#ifdef CHIP_IO_W2_START
if (ioaddr >= CHIP_IO_W2_START(v) &&
ioaddr <= CHIP_IO_W2_END(v)) {
- *iohp = (phystok0seg(CHIP_IO_W2_BASE(v)) >> 5) +
+ *iohp = (ALPHA_PHYS_TO_K0SEG(CHIP_IO_W2_BASE(v)) >> 5) +
(ioaddr & CHIP_IO_W2_MASK(v));
} else
#endif
@@ -185,7 +185,7 @@ __C(CHIP,_io_read_1)(v, ioh, off)
register u_int8_t rval;
register int offset;
- wbflush();
+ alpha_mb();
tmpioh = ioh + off;
offset = tmpioh & 3;
@@ -207,7 +207,7 @@ __C(CHIP,_io_read_2)(v, ioh, off)
register u_int16_t rval;
register int offset;
- wbflush();
+ alpha_mb();
tmpioh = ioh + off;
offset = tmpioh & 3;
@@ -229,7 +229,7 @@ __C(CHIP,_io_read_4)(v, ioh, off)
register u_int32_t rval;
register int offset;
- wbflush();
+ alpha_mb();
tmpioh = ioh + off;
offset = tmpioh & 3;
@@ -266,7 +266,7 @@ __C(CHIP,_io_read_multi_1)(v, ioh, off, addr, count)
register u_int32_t *port, val;
register int offset;
- wbflush();
+ alpha_mb();
while (count--) {
tmpioh = ioh + off;
@@ -289,7 +289,7 @@ __C(CHIP,_io_read_multi_2)(v, ioh, off, addr, count)
register u_int32_t *port, val;
register int offset;
- wbflush();
+ alpha_mb();
while (count--) {
tmpioh = ioh + off;
@@ -312,7 +312,7 @@ __C(CHIP,_io_read_multi_4)(v, ioh, off, addr, count)
register u_int32_t *port, val;
register int offset;
- wbflush();
+ alpha_mb();
while (count--) {
tmpioh = ioh + off;
@@ -356,7 +356,7 @@ __C(CHIP,_io_write_1)(v, ioh, off, val)
nval = val << (8 * offset);
port = (u_int32_t *)((tmpioh << 5) | (0 << 3));
*port = nval;
- wbflush();
+ alpha_mb();
}
void
@@ -375,7 +375,7 @@ __C(CHIP,_io_write_2)(v, ioh, off, val)
nval = val << (8 * offset);
port = (u_int32_t *)((tmpioh << 5) | (1 << 3));
*port = nval;
- wbflush();
+ alpha_mb();
}
void
@@ -394,7 +394,7 @@ __C(CHIP,_io_write_4)(v, ioh, off, val)
nval = val /*<< (8 * offset)*/;
port = (u_int32_t *)((tmpioh << 5) | (3 << 3));
*port = nval;
- wbflush();
+ alpha_mb();
}
void
@@ -407,7 +407,7 @@ __C(CHIP,_io_write_8)(v, ioh, off, val)
/* XXX XXX XXX */
panic("%s not implemented\n", __S(__C(CHIP,_io_write_8)));
- wbflush();
+ alpha_mb();
}
void
@@ -429,7 +429,7 @@ __C(CHIP,_io_write_multi_1)(v, ioh, off, addr, count)
*port = nval;
off++;
}
- wbflush();
+ alpha_mb();
}
void
@@ -451,7 +451,7 @@ __C(CHIP,_io_write_multi_2)(v, ioh, off, addr, count)
*port = nval;
off++;
}
- wbflush();
+ alpha_mb();
}
void
@@ -473,7 +473,7 @@ __C(CHIP,_io_write_multi_4)(v, ioh, off, addr, count)
*port = nval;
off++;
}
- wbflush();
+ alpha_mb();
}
void
diff --git a/sys/arch/alpha/pci/pcs_bus_mem_common.c b/sys/arch/alpha/pci/pcs_bus_mem_common.c
index 79833a1f9da..3eb14c01f0c 100644
--- a/sys/arch/alpha/pci/pcs_bus_mem_common.c
+++ b/sys/arch/alpha/pci/pcs_bus_mem_common.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcs_bus_mem_common.c,v 1.2 1996/07/29 23:00:51 niklas Exp $ */
-/* $NetBSD: pcs_bus_mem_common.c,v 1.1.4.4 1996/06/13 18:17:01 cgd Exp $ */
+/* $OpenBSD: pcs_bus_mem_common.c,v 1.3 1996/10/30 22:40:13 niklas Exp $ */
+/* $NetBSD: pcs_bus_mem_common.c,v 1.9 1996/10/13 03:00:17 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -106,7 +106,7 @@ __C(CHIP,_mem_map)(v, memaddr, memsize, cacheable, memhp)
#ifdef CHIP_D_MEM_W1_START
if (memaddr >= CHIP_D_MEM_W1_START(v) &&
memaddr <= CHIP_D_MEM_W1_END(v)) {
- *memhp = phystok0seg(CHIP_D_MEM_W1_BASE(v)) +
+ *memhp = ALPHA_PHYS_TO_K0SEG(CHIP_D_MEM_W1_BASE(v)) +
(memaddr & CHIP_D_MEM_W1_MASK(v));
} else
#endif
@@ -124,21 +124,21 @@ __C(CHIP,_mem_map)(v, memaddr, memsize, cacheable, memhp)
#ifdef CHIP_S_MEM_W1_START
if (memaddr >= CHIP_S_MEM_W1_START(v) &&
memaddr <= CHIP_S_MEM_W1_END(v)) {
- *memhp = (phystok0seg(CHIP_S_MEM_W1_BASE(v)) >> 5) +
+ *memhp = (ALPHA_PHYS_TO_K0SEG(CHIP_S_MEM_W1_BASE(v)) >> 5) +
(memaddr & CHIP_S_MEM_W1_MASK(v));
} else
#endif
#ifdef CHIP_S_MEM_W2_START
if (memaddr >= CHIP_S_MEM_W2_START(v) &&
memaddr <= CHIP_S_MEM_W2_END(v)) {
- *memhp = (phystok0seg(CHIP_S_MEM_W2_BASE(v)) >> 5) +
+ *memhp = (ALPHA_PHYS_TO_K0SEG(CHIP_S_MEM_W2_BASE(v)) >> 5) +
(memaddr & CHIP_S_MEM_W2_MASK(v));
} else
#endif
#ifdef CHIP_S_MEM_W3_START
if (memaddr >= CHIP_S_MEM_W3_START(v) &&
memaddr <= CHIP_S_MEM_W3_END(v)) {
- *memhp = (phystok0seg(CHIP_S_MEM_W3_BASE(v)) >> 5) +
+ *memhp = (ALPHA_PHYS_TO_K0SEG(CHIP_S_MEM_W3_BASE(v)) >> 5) +
(memaddr & CHIP_S_MEM_W3_MASK(v));
} else
#endif
@@ -199,7 +199,7 @@ __C(CHIP,_mem_read_1)(v, memh, off)
register u_int8_t rval;
register int offset;
- wbflush();
+ alpha_mb();
if ((memh >> 63) != 0)
return (*(u_int8_t *)(memh + off));
@@ -224,7 +224,7 @@ __C(CHIP,_mem_read_2)(v, memh, off)
register u_int16_t rval;
register int offset;
- wbflush();
+ alpha_mb();
if ((memh >> 63) != 0)
return (*(u_int16_t *)(memh + off));
@@ -249,7 +249,7 @@ __C(CHIP,_mem_read_4)(v, memh, off)
register u_int32_t rval;
register int offset;
- wbflush();
+ alpha_mb();
if ((memh >> 63) != 0)
return (*(u_int32_t *)(memh + off));
@@ -274,7 +274,7 @@ __C(CHIP,_mem_read_8)(v, memh, off)
bus_mem_size_t off;
{
- wbflush();
+ alpha_mb();
if ((memh >> 63) != 0)
return (*(u_int64_t *)(memh + off));
@@ -303,7 +303,7 @@ __C(CHIP,_mem_write_1)(v, memh, off, val)
port = (u_int32_t *)((tmpmemh << 5) | (0 << 3));
*port = nval;
}
- wbflush();
+ alpha_mb();
}
void
@@ -326,7 +326,7 @@ __C(CHIP,_mem_write_2)(v, memh, off, val)
port = (u_int32_t *)((tmpmemh << 5) | (1 << 3));
*port = nval;
}
- wbflush();
+ alpha_mb();
}
void
@@ -349,7 +349,7 @@ __C(CHIP,_mem_write_4)(v, memh, off, val)
port = (u_int32_t *)((tmpmemh << 5) | (3 << 3));
*port = nval;
}
- wbflush();
+ alpha_mb();
}
void
@@ -367,7 +367,7 @@ __C(CHIP,_mem_write_8)(v, memh, off, val)
panic("%s not implemented\n",
__S(__C(CHIP,_mem_write_8)));
}
- wbflush();
+ alpha_mb();
}
vm_offset_t
@@ -375,5 +375,5 @@ __C(CHIP,_XXX_dmamap)(addr)
void *addr;
{
- return (vtophys(addr) | 0x40000000);
+ return (vtophys((vm_offset_t)addr) | 0x40000000);
}
diff --git a/sys/arch/alpha/pci/sio.c b/sys/arch/alpha/pci/sio.c
index 6a4e6901fd2..0923402ac7f 100644
--- a/sys/arch/alpha/pci/sio.c
+++ b/sys/arch/alpha/pci/sio.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: sio.c,v 1.4 1996/07/29 23:00:53 niklas Exp $ */
-/* $NetBSD: sio.c,v 1.8 1996/04/13 00:23:34 cgd Exp $ */
+/* $OpenBSD: sio.c,v 1.5 1996/10/30 22:40:14 niklas Exp $ */
+/* $NetBSD: sio.c,v 1.11 1996/10/13 03:00:18 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -72,7 +72,7 @@ union sio_attach_args {
struct eisabus_attach_args sa_eba;
};
-int sioprint __P((void *, char *pnp));
+int sioprint __P((void *, /* const */ char *pnp));
void sio_isa_attach_hook __P((struct device *, struct device *,
struct isabus_attach_args *));
void sio_eisa_attach_hook __P((struct device *, struct device *,
@@ -85,7 +85,6 @@ siomatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
@@ -100,7 +99,6 @@ pcebmatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
@@ -172,7 +170,7 @@ sioattach(parent, self, aux)
int
sioprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
register union sio_attach_args *sa = aux;
diff --git a/sys/arch/alpha/pci/sio_pic.c b/sys/arch/alpha/pci/sio_pic.c
index 585c14edab6..0a6952ea2a3 100644
--- a/sys/arch/alpha/pci/sio_pic.c
+++ b/sys/arch/alpha/pci/sio_pic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: sio_pic.c,v 1.5 1996/07/29 23:00:55 niklas Exp $ */
-/* $NetBSD: sio_pic.c,v 1.7.4.3 1996/06/05 22:50:23 cgd Exp $ */
+/* $OpenBSD: sio_pic.c,v 1.6 1996/10/30 22:40:15 niklas Exp $ */
+/* $NetBSD: sio_pic.c,v 1.13 1996/10/13 03:00:20 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -70,7 +70,7 @@ bus_io_handle_t sio_ioh_icu1, sio_ioh_icu2, sio_ioh_elcr;
* the list. The handler is called with its (single) argument.
*/
struct intrhand {
- int (*ih_fun)();
+ int (*ih_fun) __P((void *));
void *ih_arg;
u_long ih_count;
struct intrhand *ih_next;
@@ -115,6 +115,8 @@ u_int8_t initial_elcr[2];
#define INITIALLY_LEVEL_TRIGGERED(irq) 0
#endif
+void sio_setirqstat __P((int, int, int));
+
void
sio_setirqstat(irq, enabled, type)
int irq, enabled;
@@ -358,16 +360,27 @@ sio_strayintr(irq)
int irq;
{
- if (++sio_strayintrcnt[irq] <= STRAY_MAX)
- log(LOG_ERR, "stray interrupt %d%s\n", irq,
+ sio_strayintrcnt[irq]++;
+
+#ifdef notyet
+ if (sio_strayintrcnt[irq] == STRAY_MAX)
+ sio_disable_intr(irq);
+
+ log(LOG_ERR, "stray isa irq %d\n", irq);
+ if (sio_strayintrcnt[irq] == STRAY_MAX)
+ log(LOG_ERR, "disabling interrupts on isa irq %d\n", irq);
+#else
+ if (sio_strayintrcnt[irq] <= STRAY_MAX)
+ log(LOG_ERR, "stray isa irq %d%s\n", irq,
sio_strayintrcnt[irq] >= STRAY_MAX ?
"; stopped logging" : "");
+#endif
}
void
sio_iointr(framep, vec)
void *framep;
- int vec;
+ unsigned long vec;
{
int irq, handled;
struct intrhand *ih;
diff --git a/sys/arch/alpha/pci/sioreg.h b/sys/arch/alpha/pci/sioreg.h
index c678b3b6f76..277a60dcdac 100644
--- a/sys/arch/alpha/pci/sioreg.h
+++ b/sys/arch/alpha/pci/sioreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sioreg.h,v 1.2 1996/07/29 23:00:57 niklas Exp $ */
+/* $OpenBSD: sioreg.h,v 1.3 1996/10/30 22:40:16 niklas Exp $ */
/* $NetBSD: sioreg.h,v 1.1 1996/04/23 14:10:53 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/siovar.h b/sys/arch/alpha/pci/siovar.h
index 0537724dc0c..288341d293a 100644
--- a/sys/arch/alpha/pci/siovar.h
+++ b/sys/arch/alpha/pci/siovar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: siovar.h,v 1.3 1996/07/29 23:00:58 niklas Exp $ */
-/* $NetBSD: siovar.h,v 1.3 1996/04/12 06:09:06 cgd Exp $ */
+/* $OpenBSD: siovar.h,v 1.4 1996/10/30 22:40:17 niklas Exp $ */
+/* $NetBSD: siovar.h,v 1.4 1996/07/14 04:08:42 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
*/
void sio_intr_setup __P((bus_chipset_tag_t));
-void sio_iointr __P((void *framep, int vec));
+void sio_iointr __P((void *framep, unsigned long vec));
const char *sio_intr_string __P((void *, int));
void *sio_intr_establish __P((void *, int, int, int, int (*)(void *),
diff --git a/sys/arch/alpha/pci/tga.c b/sys/arch/alpha/pci/tga.c
index e70ddbab10d..7f5b1a12560 100644
--- a/sys/arch/alpha/pci/tga.c
+++ b/sys/arch/alpha/pci/tga.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tga.c,v 1.4 1996/07/29 23:01:00 niklas Exp $ */
-/* $NetBSD: tga.c,v 1.6 1996/04/12 06:09:08 cgd Exp $ */
+/* $OpenBSD: tga.c,v 1.5 1996/10/30 22:40:19 niklas Exp $ */
+/* $NetBSD: tga.c,v 1.10 1996/10/13 03:00:22 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -57,7 +57,7 @@
int tgamatch __P((struct device *, void *, void *));
void tgaattach __P((struct device *, struct device *, void *));
-int tgaprint __P((void *, char *));
+int tgaprint __P((void *, /* const */ char *));
struct cfattach tga_ca = {
sizeof(struct tga_softc), tgamatch, tgaattach,
@@ -94,7 +94,6 @@ tgamatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC ||
@@ -132,7 +131,7 @@ tga_getdevconfig(bc, pc, tag, dc)
/* XXX XXX XXX */
if (bus_mem_map(bc, dc->dc_pcipaddr, pcisize, 1, &dc->dc_vaddr))
return;
- dc->dc_paddr = k0segtophys(dc->dc_vaddr); /* XXX */
+ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS);
dc->dc_tga_type = tga_identify(dc->dc_regs);
@@ -242,6 +241,7 @@ tgaattach(parent, self, aux)
}
/* XXX say what's going on. */
+ intrstr = NULL;
if (sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_intr != NULL) {
if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
pa->pa_intrline, &intrh)) {
@@ -312,7 +312,7 @@ tgaattach(parent, self, aux)
int
tgaprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
if (pnp)
@@ -465,7 +465,10 @@ tga_builtin_set_cursor(dc, fbc)
struct tga_devconfig *dc;
struct fbcursor *fbc;
{
- int v, count;
+ int v;
+#if 0
+ int count;
+#endif
v = fbc->set;
#if 0
@@ -544,6 +547,7 @@ tga_builtin_set_curpos(dc, fbp)
dc->dc_regs[TGA_REG_CXYR] =
((fbp->y & 0xfff) << 12) | (fbp->x & 0xfff);
+ return (0);
}
int
@@ -554,6 +558,7 @@ tga_builtin_get_curpos(dc, fbp)
fbp->x = dc->dc_regs[TGA_REG_CXYR] & 0xfff;
fbp->y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff;
+ return (0);
}
int
@@ -563,4 +568,5 @@ tga_builtin_get_curmax(dc, fbp)
{
fbp->x = fbp->y = 64;
+ return (0);
}
diff --git a/sys/arch/alpha/pci/tga_bt463.c b/sys/arch/alpha/pci/tga_bt463.c
index 54ecdf8087a..b628a0ead93 100644
--- a/sys/arch/alpha/pci/tga_bt463.c
+++ b/sys/arch/alpha/pci/tga_bt463.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tga_bt463.c,v 1.2 1996/07/29 23:01:02 niklas Exp $ */
+/* $OpenBSD: tga_bt463.c,v 1.3 1996/10/30 22:40:19 niklas Exp $ */
/* $NetBSD: tga_bt463.c,v 1.2 1996/04/12 06:09:13 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/tga_bt485.c b/sys/arch/alpha/pci/tga_bt485.c
index 11e9d46e9c3..cefd7d05ed1 100644
--- a/sys/arch/alpha/pci/tga_bt485.c
+++ b/sys/arch/alpha/pci/tga_bt485.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tga_bt485.c,v 1.2 1996/07/29 23:01:04 niklas Exp $ */
-/* $NetBSD: tga_bt485.c,v 1.2 1996/04/12 06:09:16 cgd Exp $ */
+/* $OpenBSD: tga_bt485.c,v 1.3 1996/10/30 22:40:21 niklas Exp $ */
+/* $NetBSD: tga_bt485.c,v 1.3 1996/07/09 00:55:05 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -33,6 +33,9 @@
#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
#include <dev/pci/pcivar.h>
#include <machine/tgareg.h>
@@ -199,7 +202,7 @@ tga_bt485_set_cmap(dc, fbc)
struct fbcmap *fbc;
{
struct bt485data *data = dc->dc_ramdac_private;
- int error, count, index, s;
+ int count, index, s;
if ((u_int)fbc->index >= 256 ||
((u_int)fbc->index + (u_int)fbc->count) > 256)
@@ -256,7 +259,7 @@ tga_bt485_set_cursor(dc, fbc)
struct fbcursor *fbc;
{
struct bt485data *data = dc->dc_ramdac_private;
- int error, count, index, v, s;
+ int count, index, v, s;
v = fbc->set;
@@ -398,8 +401,6 @@ tga_bt485_get_curmax(dc, fbp)
struct tga_devconfig *dc;
struct fbcurpos *fbp;
{
- struct bt485data *data = dc->dc_ramdac_private;
-
fbp->x = fbp->y = CURSOR_MAX_SIZE;
return (0);
}
@@ -434,7 +435,7 @@ tga_bt485_wr_d(tgaregs, btreg, val)
panic("tga_bt485_wr_d: reg %d out of range\n", btreg);
tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */
- wbflush();
+ alpha_mb();
}
inline u_int8_t
@@ -448,7 +449,7 @@ tga_bt485_rd_d(tgaregs, btreg)
panic("tga_bt485_rd_d: reg %d out of range\n", btreg);
tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */
- wbflush();
+ alpha_mb();
rdval = tgaregs[TGA_REG_EPDR];
return (rdval >> 16) & 0xff; /* XXX */
diff --git a/sys/arch/alpha/pci/tga_conf.c b/sys/arch/alpha/pci/tga_conf.c
index abc1fd1b86a..73a65a85a23 100644
--- a/sys/arch/alpha/pci/tga_conf.c
+++ b/sys/arch/alpha/pci/tga_conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tga_conf.c,v 1.2 1996/07/29 23:01:05 niklas Exp $ */
+/* $OpenBSD: tga_conf.c,v 1.3 1996/10/30 22:40:22 niklas Exp $ */
/* $NetBSD: tga_conf.c,v 1.2 1996/04/12 06:09:18 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/pci/tgavar.h b/sys/arch/alpha/pci/tgavar.h
index 2b01f701f92..9b833436a97 100644
--- a/sys/arch/alpha/pci/tgavar.h
+++ b/sys/arch/alpha/pci/tgavar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tgavar.h,v 1.4 1996/07/29 23:01:07 niklas Exp $ */
+/* $OpenBSD: tgavar.h,v 1.5 1996/10/30 22:40:22 niklas Exp $ */
/* $NetBSD: tgavar.h,v 1.5 1996/04/12 06:09:21 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/Makefile b/sys/arch/alpha/stand/Makefile
index a5346cabaf3..e2b081bc13b 100644
--- a/sys/arch/alpha/stand/Makefile
+++ b/sys/arch/alpha/stand/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.3 1996/07/29 23:01:13 niklas Exp $
-# $NetBSD: Makefile,v 1.3 1995/11/23 02:38:45 cgd Exp $
+# $OpenBSD: Makefile,v 1.4 1996/10/30 22:40:26 niklas Exp $
+# $NetBSD: Makefile,v 1.4 1996/09/23 04:28:23 cgd Exp $
-SUBDIR= boot bootxx installboot
+SUBDIR= boot bootxx installboot netboot
.include <bsd.subdir.mk>
diff --git a/sys/arch/alpha/stand/Makefile.inc b/sys/arch/alpha/stand/Makefile.inc
index ba63f5a62ea..351d0e2ef81 100644
--- a/sys/arch/alpha/stand/Makefile.inc
+++ b/sys/arch/alpha/stand/Makefile.inc
@@ -1,5 +1,7 @@
-# $OpenBSD: Makefile.inc,v 1.2 1996/07/29 23:01:14 niklas Exp $
-# $NetBSD: Makefile.inc,v 1.1 1995/11/23 02:38:48 cgd Exp $
+# $OpenBSD: Makefile.inc,v 1.3 1996/10/30 22:40:27 niklas Exp $
+# $NetBSD: Makefile.inc,v 1.3 1996/10/06 18:32:22 cgd Exp $
+
+.include <bsd.own.mk> # for ELF_TOOLCHAIN definition
BINDIR= /usr/mdec
@@ -8,3 +10,8 @@ SECONDARY_LOAD_ADDRESS= 20020000
CPPFLAGS+= -DPRIMARY_LOAD_ADDRESS="0x${PRIMARY_LOAD_ADDRESS}"
CPPFLAGS+= -DSECONDARY_LOAD_ADDRESS="0x${SECONDARY_LOAD_ADDRESS}"
+
+.if !defined(ELF_TOOLCHAIN)
+CPPFLAGS+= -DECOFF_COMPAT
+.endif
+
diff --git a/sys/arch/alpha/stand/OSFpal.c b/sys/arch/alpha/stand/OSFpal.c
index 0dfe77e087f..0bf89c96fd0 100644
--- a/sys/arch/alpha/stand/OSFpal.c
+++ b/sys/arch/alpha/stand/OSFpal.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: OSFpal.c,v 1.3 1996/07/29 23:01:16 niklas Exp $ */
-/* $NetBSD: OSFpal.c,v 1.2 1996/04/12 06:09:30 cgd Exp $ */
+/* $OpenBSD: OSFpal.c,v 1.4 1996/10/30 22:40:27 niklas Exp $ */
+/* $NetBSD: OSFpal.c,v 1.4 1996/10/13 03:00:24 christos Exp $ */
/*
* Copyright (c) 1994, 1996 Carnegie-Mellon University.
diff --git a/sys/arch/alpha/stand/bbinfo.h b/sys/arch/alpha/stand/bbinfo.h
index 71c2bcdbde7..ee15a99b7aa 100644
--- a/sys/arch/alpha/stand/bbinfo.h
+++ b/sys/arch/alpha/stand/bbinfo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bbinfo.h,v 1.3 1996/07/29 23:01:17 niklas Exp $ */
+/* $OpenBSD: bbinfo.h,v 1.4 1996/10/30 22:40:28 niklas Exp $ */
/* $NetBSD: bbinfo.h,v 1.2 1996/04/12 06:09:34 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/boot/Makefile b/sys/arch/alpha/stand/boot/Makefile
index d3c510de833..bf32ff1073a 100644
--- a/sys/arch/alpha/stand/boot/Makefile
+++ b/sys/arch/alpha/stand/boot/Makefile
@@ -1,12 +1,13 @@
-# $OpenBSD: Makefile,v 1.4 1996/07/29 23:01:31 niklas Exp $
-# $NetBSD: Makefile,v 1.6 1996/04/12 01:35:15 cgd Exp $
+# $OpenBSD: Makefile,v 1.5 1996/10/30 22:40:38 niklas Exp $
+# $NetBSD: Makefile,v 1.10 1996/10/18 06:01:41 thorpej Exp $
.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa
BOOT_PROG = boot
BOOT_RELOC = ${SECONDARY_LOAD_ADDRESS}
-BOOT_SRCS = start.S boot.c disk.c conf.c prom.c prom_disp.S OSFpal.c
+BOOT_SRCS = start.S boot.c loadfile.c disk.c conf.c prom.c prom_disp.S OSFpal.c
+
BOOT_SRCS+= alloc.c bzero.c close.c dev.c devopen.c disklabel.c dkcksum.c
BOOT_SRCS+= getfile.c gets.c ioctl.c lseek.c open.c printf.c read.c
BOOT_SRCS+= strcmp.c ufs.c write.c bcopy.c filesystem.c strlen.c
@@ -15,9 +16,11 @@ BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g}
HEADERSIZE_PROG = headersize
-AFLAGS += -DASSEMBLER
+DEFNS= -DCOMPAT_UFS -DALPHA_BOOT_ECOFF -DALPHA_BOOT_ELF
+
+AFLAGS += -DASSEMBLER ${DEFNS}
CPPFLAGS += -I${.CURDIR}/../.. -I${.CURDIR}/../../../..
-CFLAGS = -Werror -mno-fp-regs -g -DCOMPAT_UFS
+CFLAGS = -Werror -mno-fp-regs -g ${DEFNS}
CLEANFILES+= vers.c vers.o
@@ -28,21 +31,21 @@ all: ${BOOT_PROG}
${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG}
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version
${COMPILE.c} vers.c
- ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.coff \
+ ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \
${BOOT_OBJS} vers.o -lc # XXX
- size ${BOOT_PROG}.coff
- strip ${BOOT_PROG}.coff
- dd if=${BOOT_PROG}.coff of=${BOOT_PROG} \
- bs=`./${HEADERSIZE_PROG} < ${BOOT_PROG}.coff` skip=1
+ size ${BOOT_PROG}.hdr
+ strip ${BOOT_PROG}.hdr
+ dd if=${BOOT_PROG}.hdr of=${BOOT_PROG} \
+ bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1
install:
- install -c -o bin -g bin -m 444 ${BOOT_PROG} \
+ ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \
${DESTDIR}${BINDIR}/${BOOT_PROG}
clean: _SUBDIRUSE
rm -f a.out [Ee]rrs mklog core *.core \
${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \
- ${BOOT_PROG}.coff ${HEADERSIZE_PROG}
+ ${BOOT_PROG}.hdr ${HEADERSIZE_PROG}
cleandir: _SUBDIRUSE clean
diff --git a/sys/arch/alpha/stand/boot/boot.c b/sys/arch/alpha/stand/boot/boot.c
index 2ce83ae8f00..a585b2b3ed6 100644
--- a/sys/arch/alpha/stand/boot/boot.c
+++ b/sys/arch/alpha/stand/boot/boot.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: boot.c,v 1.5 1996/07/31 16:24:11 niklas Exp $ */
-/* $NetBSD: boot.c,v 1.6 1996/05/10 00:15:08 cgd Exp $ */
+/* $OpenBSD: boot.c,v 1.6 1996/10/30 22:40:39 niklas Exp $ */
+/* $NetBSD: boot.c,v 1.8 1996/09/17 22:00:26 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -51,52 +51,25 @@
#define _KERNEL
#include "include/pte.h"
-static int aout_exec __P((int, struct exec *, u_int64_t *));
-static int coff_exec __P((int, struct ecoff_exechdr *, u_int64_t *));
-static int loadfile __P((char *, u_int64_t *));
-
-char line[64] = "/bsd";
+int loadfile __P((char *, u_int64_t *));
char boot_file[128];
-char boot_dev[128];
char boot_flags[128];
-char boot_console[8];
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
-#define KERNEL_ARGC 4
-char *kernel_argv[KERNEL_ARGC+1] = {
- boot_file,
- boot_flags,
- boot_console,
- boot_dev,
- NULL
-};
-
vm_offset_t ffp_save, ptbr_save;
void
-main(argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
+main()
{
u_int64_t entry;
- int ask;
- prom_return_t ret;
-
-#ifdef notdef
- {
- extern char *_EDATA, *_end;
- bzero(_EDATA, _end - _EDATA);
- }
-#endif
/* Init prom callback vector. */
init_prom_calls();
/* print a banner */
- printf("\n\n");
+ printf("\n");
printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
printf("\n");
@@ -106,177 +79,19 @@ main(argc, argv, envp)
printf("\n");
- prom_getenv(PROM_E_BOOTED_DEV, boot_dev, sizeof(boot_dev));
prom_getenv(PROM_E_BOOTED_FILE, boot_file, sizeof(boot_file));
prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags));
- prom_getenv(PROM_E_TTY_DEV, boot_console, sizeof(boot_console));
-
- printf("boot_dev = \"%s\"\n", boot_dev);
- printf("boot_file = \"%s\"\n", boot_file);
- printf("boot_flags = \"%s\"\n", boot_flags);
- printf("boot_console = \"%s\"\n", boot_console);
if (boot_file[0] == '\0')
- bcopy(line, boot_file, strlen(line)+1);
-
-#ifdef JUSTASK
- ask = 1;
-#else
- ask = 0;
-#endif
- for (;;) {
- if (ask) {
- (void)printf("Boot: ");
- gets(line);
- if (line[0] == '\0')
- continue;
- if (!strcmp(line, "halt"))
- halt();
-/* XXX TURN LINE INTO BOOT FILE/FLAGS */
- bcopy(line, boot_file, strlen(line)+1);
- } else
- (void)printf("Boot: %s %s\n", boot_file, boot_flags);
-
- if (!loadfile(boot_file, &entry)) {
-
-printf("calling %lx with %lx, %lx, %lx, %lx, %lx\n", entry,
-ffp_save, ptbr_save, KERNEL_ARGC, kernel_argv, NULL);
- (*(void (*)())entry)(ffp_save, ptbr_save, KERNEL_ARGC,
- kernel_argv, NULL);
- }
-
- ask = 1;
- }
- /* NOTREACHED */
-}
-
-/*
- * Open 'filename', read in program and return the entry point or -1 if error.
- */
-static int
-loadfile(fname, entryp)
- char *fname;
- u_int64_t *entryp;
-{
- struct devices *dp;
- union {
- struct exec aout;
- struct ecoff_exechdr coff;
- } hdr;
- ssize_t nr;
- int fd, rval;
-
- /* Open the file. */
- rval = 1;
- if ((fd = open(fname, 0)) < 0) {
- (void)printf("open error: %d\n", errno);
- goto err;
- }
-
- /* Read the exec header. */
- if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
- (void)printf("read error: %d\n", errno);
- goto err;
- }
-
- /* Exec a.out or COFF. */
- rval = ECOFF_BADMAG(&hdr.coff) ? /* XXX check aouthdr */
- aout_exec(fd, &hdr.aout, entryp) :
- coff_exec(fd, &hdr.coff, entryp);
+ bcopy("bsd", boot_file, sizeof "bsd");
-err:
-#ifndef SMALL
- if (fd >= 0)
- (void)close(fd);
-#endif
- if (rval)
- (void)printf("can't boot '%s'\n", fname);
- return (rval);
-}
-
-static int
-aout_exec(fd, aout, entryp)
- int fd;
- struct exec *aout;
- u_int64_t *entryp;
-{
- size_t sz;
+ (void)printf("Boot: %s %s\n", boot_file, boot_flags);
- /* Check the magic number. */
- if (N_GETMAGIC(*aout) != OMAGIC) {
- (void)printf("bad magic: %o\n", N_GETMAGIC(*aout));
- return (1);
- }
-
- /* Read in text, data. */
- (void)printf("%lu+%lu", aout->a_text, aout->a_data);
- if (lseek(fd, (off_t)N_TXTOFF(*aout), SEEK_SET) < 0) {
- (void)printf("lseek: %d\n", errno);
- return (1);
- }
- sz = aout->a_text + aout->a_data;
- if (read(fd, (void *)aout->a_entry, sz) != sz) {
- (void)printf("read text/data: %d\n", errno);
- return (1);
+ if (!loadfile(boot_file, &entry)) {
+ (void)printf("Entering kernel at 0x%lx...\n", entry);
+ (*(void (*)())entry)(ffp_save, ptbr_save, 0);
}
- /* Zero out bss. */
- if (aout->a_bss != 0) {
- (void)printf("+%lu", aout->a_bss);
- bzero(aout->a_entry + sz, aout->a_bss);
- }
-
- ffp_save = aout->a_entry + aout->a_text + aout->a_data + aout->a_bss;
- ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
- ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
-
- (void)printf("\n");
- *entryp = aout->a_entry;
- return (0);
-}
-
-static int
-coff_exec(fd, coff, entryp)
- int fd;
- struct ecoff_exechdr *coff;
- u_int64_t *entryp;
-{
-
- /* Read in text. */
- (void)printf("%lu", coff->a.tsize);
- (void)lseek(fd, ECOFF_TXTOFF(coff), 0);
- if (read(fd, (void *)coff->a.text_start, coff->a.tsize) !=
- coff->a.tsize) {
- (void)printf("read text: %d\n", errno);
- return (1);
- }
-
- /* Read in data. */
- if (coff->a.dsize != 0) {
- (void)printf("+%lu", coff->a.dsize);
- if (read(fd, (void *)coff->a.data_start, coff->a.dsize) !=
- coff->a.dsize) {
- (void)printf("read data: %d\n", errno);
- return (1);
- }
- }
-
-
- /* Zero out bss. */
- if (coff->a.bsize != 0) {
- (void)printf("+%lu", coff->a.bsize);
- bzero(coff->a.bss_start, coff->a.bsize);
- }
-
- ffp_save = coff->a.text_start + coff->a.tsize;
- if (ffp_save < coff->a.data_start + coff->a.dsize)
- ffp_save = coff->a.data_start + coff->a.dsize;
- if (ffp_save < coff->a.bss_start + coff->a.bsize)
- ffp_save = coff->a.bss_start + coff->a.bsize;
- ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
- ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
-
- (void)printf("\n");
- *entryp = coff->a.entry;
- return (0);
+ (void)printf("Boot failed! Halting...\n");
+ halt();
}
diff --git a/sys/arch/alpha/stand/boot/conf.c b/sys/arch/alpha/stand/boot/conf.c
index 4c275c4513c..3883551a738 100644
--- a/sys/arch/alpha/stand/boot/conf.c
+++ b/sys/arch/alpha/stand/boot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.3 1996/07/29 23:01:35 niklas Exp $ */
+/* $OpenBSD: conf.c,v 1.4 1996/10/30 22:40:40 niklas Exp $ */
/* $NetBSD: conf.c,v 1.3 1995/11/23 02:39:31 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/boot/devopen.c b/sys/arch/alpha/stand/boot/devopen.c
index b25bdfb7318..2e9cbc1951d 100644
--- a/sys/arch/alpha/stand/boot/devopen.c
+++ b/sys/arch/alpha/stand/boot/devopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: devopen.c,v 1.2 1996/07/29 23:01:36 niklas Exp $ */
+/* $OpenBSD: devopen.c,v 1.3 1996/10/30 22:40:41 niklas Exp $ */
/* $NetBSD: devopen.c,v 1.1 1995/11/23 02:39:37 cgd Exp $ */
/*-
diff --git a/sys/arch/alpha/stand/boot/disk.c b/sys/arch/alpha/stand/boot/disk.c
index 3566a0036b3..5b70adf9a61 100644
--- a/sys/arch/alpha/stand/boot/disk.c
+++ b/sys/arch/alpha/stand/boot/disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disk.c,v 1.3 1996/07/29 23:01:38 niklas Exp $ */
+/* $OpenBSD: disk.c,v 1.4 1996/10/30 22:40:42 niklas Exp $ */
/* $NetBSD: disk.c,v 1.3 1995/11/23 02:39:40 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/boot/disk.h b/sys/arch/alpha/stand/boot/disk.h
index 43f5e0be52b..264c773ceea 100644
--- a/sys/arch/alpha/stand/boot/disk.h
+++ b/sys/arch/alpha/stand/boot/disk.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disk.h,v 1.2 1996/07/29 23:01:39 niklas Exp $ */
+/* $OpenBSD: disk.h,v 1.3 1996/10/30 22:40:42 niklas Exp $ */
/* $NetBSD: disk.h,v 1.1 1995/11/23 02:39:42 cgd Exp $ */
int diskstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
diff --git a/sys/arch/alpha/stand/boot/filesystem.c b/sys/arch/alpha/stand/boot/filesystem.c
index 4833ce6acec..1956f3504fa 100644
--- a/sys/arch/alpha/stand/boot/filesystem.c
+++ b/sys/arch/alpha/stand/boot/filesystem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filesystem.c,v 1.2 1996/07/29 23:01:41 niklas Exp $ */
+/* $OpenBSD: filesystem.c,v 1.3 1996/10/30 22:40:43 niklas Exp $ */
/* $NetBSD: filesystem.c,v 1.1 1995/11/23 02:39:46 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/boot/newvers.sh b/sys/arch/alpha/stand/boot/newvers.sh
index a65d3cfb37d..605d7141d93 100644
--- a/sys/arch/alpha/stand/boot/newvers.sh
+++ b/sys/arch/alpha/stand/boot/newvers.sh
@@ -1,7 +1,7 @@
#!/bin/sh -
#
-# $OpenBSD: newvers.sh,v 1.4 1996/07/31 16:24:12 niklas Exp $
-# $NetBSD: newvers.sh,v 1.2 1995/11/23 02:39:48 cgd Exp $
+# $OpenBSD: newvers.sh,v 1.5 1996/10/30 22:40:44 niklas Exp $
+# $NetBSD: newvers.sh,v 1.3 1996/06/14 20:03:04 cgd Exp $
#
# Copyright (c) 1984, 1986, 1990, 1993
# The Regents of the University of California. All rights reserved.
@@ -37,9 +37,9 @@
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
u=${USER-root} h=`hostname` t=`date`
-r=`head -1 $1`
+r=`head -1 $1 | awk ' { print $3 } '`
-echo "char bootprog_name[] = \"OpenBSD/Alpha boot\";" > vers.c
+echo "char bootprog_name[] = \"OpenBSD/Alpha Secondary Boot\";" > vers.c
echo "char bootprog_rev[] = \"${r}\";" >> vers.c
echo "char bootprog_date[] = \"${t}\";" >> vers.c
echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c
diff --git a/sys/arch/alpha/stand/boot/prom_swpal.S b/sys/arch/alpha/stand/boot/prom_swpal.S
index 718ad653260..6b0c010ffde 100644
--- a/sys/arch/alpha/stand/boot/prom_swpal.S
+++ b/sys/arch/alpha/stand/boot/prom_swpal.S
@@ -1,5 +1,5 @@
-/* $OpenBSD: prom_swpal.S,v 1.2 1996/07/29 23:01:44 niklas Exp $ */
-/* $NetBSD: prom_swpal.S,v 1.2 1995/02/16 02:32:58 cgd Exp $ */
+/* $OpenBSD: prom_swpal.S,v 1.3 1996/10/30 22:40:45 niklas Exp $ */
+/* $NetBSD: prom_swpal.S,v 1.4 1996/10/17 02:50:41 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -61,13 +61,13 @@
#define PALSW_FRAME_SIZE (14*8)
#define PALSW_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5
- .comm ptbr_save 8
+ .comm ptbr_save,8
.text
.align 4
NESTED(switch_palcode, 0, PALSW_FRAME_SIZE, ra, PALSW_REGS, 0)
- SETGP(pv)
+ LDGP(pv)
/* ldgp gp, 0(pv)*/
lda sp, -PALSW_FRAME_SIZE(sp)
@@ -105,8 +105,7 @@ NESTED(switch_palcode, 0, PALSW_FRAME_SIZE, ra, PALSW_REGS, 0)
call_pal PAL_VMS_mfpr_vptb
mov v0, a3
-/* movi PAL_OSF, a0 */
- CONST(PAL_OSF, a0)
+ ldiq a0, PAL_OSF
lda a1, contin
ldq a2, 16(sp)
diff --git a/sys/arch/alpha/stand/boot/test.c b/sys/arch/alpha/stand/boot/test.c
index 3da120e34b8..82fb6684ffe 100644
--- a/sys/arch/alpha/stand/boot/test.c
+++ b/sys/arch/alpha/stand/boot/test.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test.c,v 1.2 1996/07/29 23:01:46 niklas Exp $ */
+/* $OpenBSD: test.c,v 1.3 1996/10/30 22:40:46 niklas Exp $ */
/* $NetBSD: test.c,v 1.2 1995/02/16 02:33:00 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/boot/version b/sys/arch/alpha/stand/boot/version
index f396a5a7ebf..4343db37627 100644
--- a/sys/arch/alpha/stand/boot/version
+++ b/sys/arch/alpha/stand/boot/version
@@ -1,5 +1,5 @@
-$OpenBSD: version,v 1.4 1996/07/29 23:01:48 niklas Exp $
-$NetBSD: version,v 1.5 1996/05/09 23:54:18 cgd Exp $
+$OpenBSD: version,v 1.5 1996/10/30 22:40:47 niklas Exp $
+$NetBSD: version,v 1.6 1996/06/14 20:03:07 cgd Exp $
1.1: Initial version
1.2: don't forget the Id string!
@@ -7,3 +7,6 @@ $NetBSD: version,v 1.5 1996/05/09 23:54:18 cgd Exp $
1.4-1: Re-import from master sources
1.4-2: Complete rewrite of boot block code
1.5: Update for new ECOFF headers
+1.6: Don't pass arguments to the kernel, trim unnecessary environment
+ calls, kill 'ask' loop (i.e. if boot fails, halt), seperate
+ ECOFF and a.out support into seperate options.
diff --git a/sys/arch/alpha/stand/bootxx.c b/sys/arch/alpha/stand/bootxx.c
index 6e6e5315e50..6586fff8011 100644
--- a/sys/arch/alpha/stand/bootxx.c
+++ b/sys/arch/alpha/stand/bootxx.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: bootxx.c,v 1.4 1996/07/31 10:38:46 niklas Exp $ */
-/* $NetBSD: bootxx.c,v 1.2 1996/04/12 06:09:36 cgd Exp $ */
+/* $OpenBSD: bootxx.c,v 1.5 1996/10/30 22:40:29 niklas Exp $ */
+/* $NetBSD: bootxx.c,v 1.3 1996/06/14 20:04:45 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -136,7 +136,7 @@ main()
/* Init prom callback vector. */
init_prom_calls();
- puts("\nOpenBSD/Alpha primary boot...\n");
+ puts("\nOpenBSD/Alpha Primary Boot\n");
bbinfop = (struct bbinfo *)&_end;
loadaddr = (char *)SECONDARY_LOAD_ADDRESS;
diff --git a/sys/arch/alpha/stand/bootxx/Makefile b/sys/arch/alpha/stand/bootxx/Makefile
index 9bd8a2fc518..f2a724efda2 100644
--- a/sys/arch/alpha/stand/bootxx/Makefile
+++ b/sys/arch/alpha/stand/bootxx/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.3 1996/07/29 23:01:50 niklas Exp $
-# $NetBSD: Makefile,v 1.4 1995/11/23 02:40:29 cgd Exp $
+# $OpenBSD: Makefile,v 1.4 1996/10/30 22:40:48 niklas Exp $
+# $NetBSD: Makefile,v 1.6 1996/10/18 06:02:02 thorpej Exp $
.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa
@@ -12,7 +12,7 @@ BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g}
HEADERSIZE_PROG = headersize
AFLAGS += -DASSEMBLER
-CPPFLAGS += -I${.CURDIR}/../.. -DPRIMARY_BOOTBLOCK
+CPPFLAGS += -I${.CURDIR}/../.. -I${.CURDIR}/../../../.. -DPRIMARY_BOOTBLOCK
CFLAGS = -Werror -mno-fp-regs -g
.PATH: ${.CURDIR}/../../../../lib/libkern
@@ -20,22 +20,22 @@ CFLAGS = -Werror -mno-fp-regs -g
all: ${BOOT_PROG}
${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG}
- ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.coff \
+ ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \
${BOOT_OBJS}
- size ${BOOT_PROG}.coff
- strip ${BOOT_PROG}.coff
- dd if=${BOOT_PROG}.coff of=${BOOT_PROG}.nohdr \
- bs=`./${HEADERSIZE_PROG} < ${BOOT_PROG}.coff` skip=1
+ size ${BOOT_PROG}.hdr
+ strip ${BOOT_PROG}.hdr
+ dd if=${BOOT_PROG}.hdr of=${BOOT_PROG}.nohdr \
+ bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1
dd if=${BOOT_PROG}.nohdr of=${BOOT_PROG} bs=`expr 15 \* 512` conv=sync
install:
- install -c -o bin -g bin -m 444 ${BOOT_PROG} \
+ ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \
${DESTDIR}${BINDIR}/${BOOT_PROG}
clean: _SUBDIRUSE
rm -f a.out [Ee]rrs mklog core *.core \
${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \
- ${BOOT_PROG}.coff ${BOOT_PROG}.nohdr ${HEADERSIZE_PROG}
+ ${BOOT_PROG}.hdr ${BOOT_PROG}.nohdr ${HEADERSIZE_PROG}
cleandir: _SUBDIRUSE clean
diff --git a/sys/arch/alpha/stand/headersize.c b/sys/arch/alpha/stand/headersize.c
index 3b2024e4f25..c7e853d5e18 100644
--- a/sys/arch/alpha/stand/headersize.c
+++ b/sys/arch/alpha/stand/headersize.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: headersize.c,v 1.3 1996/07/29 23:01:20 niklas Exp $ */
-/* $NetBSD: headersize.c,v 1.3.4.1 1996/06/13 18:35:33 cgd Exp $ */
+/* $OpenBSD: headersize.c,v 1.4 1996/10/30 22:40:30 niklas Exp $ */
+/* $NetBSD: headersize.c,v 1.5 1996/09/23 04:32:59 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -28,22 +28,58 @@
* rights to redistribute these changes.
*/
+#define ELFSIZE 64
+
#include <sys/types.h>
+#include <sys/fcntl.h>
#include <sys/exec.h>
#include <sys/exec_ecoff.h>
+#include <sys/exec_elf.h>
+
+#include <unistd.h>
+#include <stdio.h>
#define HDR_BUFSIZE 512
-main()
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
{
- char buf[HDR_BUFSIZE];
- struct ecoff_exechdr *execp;
+ char buf[HDR_BUFSIZE], *fname;
+ struct ecoff_exechdr *ecoffp;
+ Elf_Ehdr *elfp;
+ int fd;
+ unsigned long loadaddr;
+
+ if (argc != 3)
+ errx(1, "must be given two arguments (load addr, file name)");
+ if (sscanf(argv[1], "%lx", &loadaddr) != 1)
+ errx(1, "load addr argument (%s) not valid", argv[1]);
+ fname = argv[2];
+
+ if ((fd = open(fname, O_RDONLY, 0)) == -1)
+ err(1, "%s: open failed", 0);
+
+ if (read(fd, &buf, HDR_BUFSIZE) < HDR_BUFSIZE)
+ err(1, "%s: read failed", fname);
+ ecoffp = (struct ecoff_exechdr *)buf;
+ elfp = (Elf_Ehdr *)buf;
+
+ if (!ECOFF_BADMAG(ecoffp)) {
+ printf("%d\n", ECOFF_TXTOFF(ecoffp));
+ } else if (memcmp(Elf_e_ident, elfp->e_ident, Elf_e_siz) == 0) {
+ Elf_Phdr phdr;
+
+ /* XXX assume the first segment is the one we want */
+ if (lseek(fd, elfp->e_phoff, SEEK_SET) == -1)
+ err(1, "%s: lseek phdr failed", fname);
+ if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr))
+ err(1, "%s: read phdr failed", fname);
- if (read(0, &buf, HDR_BUFSIZE) < HDR_BUFSIZE) {
- perror("read");
- exit(1);
- }
- execp = (struct ecoff_exechdr *)buf;
+ printf("%d\n", phdr.p_offset + (loadaddr - phdr.p_vaddr));
+ } else
+ errx(1, "%s: bad magic number", fname);
- printf("%d\n", ECOFF_TXTOFF(execp));
+ close(fd);
}
diff --git a/sys/arch/alpha/stand/installboot.c b/sys/arch/alpha/stand/installboot.c
index 38744a982c0..f5f664b0075 100644
--- a/sys/arch/alpha/stand/installboot.c
+++ b/sys/arch/alpha/stand/installboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: installboot.c,v 1.3 1996/07/29 23:01:22 niklas Exp $ */
+/* $OpenBSD: installboot.c,v 1.4 1996/10/30 22:40:31 niklas Exp $ */
/* $NetBSD: installboot.c,v 1.2 1995/12/20 00:17:49 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/installboot/Makefile b/sys/arch/alpha/stand/installboot/Makefile
index a06945bb820..68fbe7a5412 100644
--- a/sys/arch/alpha/stand/installboot/Makefile
+++ b/sys/arch/alpha/stand/installboot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.2 1996/07/29 23:01:53 niklas Exp $
+# $OpenBSD: Makefile,v 1.3 1996/10/30 22:40:49 niklas Exp $
# $NetBSD: Makefile,v 1.1 1995/11/23 02:41:18 cgd Exp $
.PATH: ${.CURDIR}/..
diff --git a/sys/arch/alpha/stand/loadfile.c b/sys/arch/alpha/stand/loadfile.c
new file mode 100644
index 00000000000..ffe364ffde1
--- /dev/null
+++ b/sys/arch/alpha/stand/loadfile.c
@@ -0,0 +1,216 @@
+/* $OpenBSD: loadfile.c,v 1.1 1996/10/30 22:40:33 niklas Exp $ */
+/* $NetBSD: loadfile.c,v 1.3 1996/09/23 04:32:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#define ELFSIZE 64
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_ecoff.h>
+#include <sys/exec_elf.h>
+
+#include <machine/prom.h>
+
+#define _KERNEL
+#include "include/pte.h"
+
+#ifdef ALPHA_BOOT_ECOFF
+static int coff_exec __P((int, struct ecoff_exechdr *, u_int64_t *));
+#endif
+#ifdef ALPHA_BOOT_ELF
+static int elf_exec __P((int, Elf_Ehdr *, u_int64_t *));
+#endif
+int loadfile __P((char *, u_int64_t *));
+
+vm_offset_t ffp_save, ptbr_save;
+
+/*
+ * Open 'filename', read in program and return the entry point or -1 if error.
+ */
+int
+loadfile(fname, entryp)
+ char *fname;
+ u_int64_t *entryp;
+{
+ struct devices *dp;
+ union {
+#ifdef ALPHA_BOOT_ECOFF
+ struct ecoff_exechdr coff;
+#endif
+#ifdef ALPHA_BOOT_ELF
+ Elf_Ehdr elf;
+#endif
+ } hdr;
+ ssize_t nr;
+ int fd, rval;
+
+ /* Open the file. */
+ rval = 1;
+ if ((fd = open(fname, 0)) < 0) {
+ (void)printf("open %s: error %d\n", fname, errno);
+ goto err;
+ }
+
+ /* Read the exec header. */
+ if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
+ (void)printf("read header: error %d\n", errno);
+ goto err;
+ }
+
+#ifdef ALPHA_BOOT_ECOFF
+ if (!ECOFF_BADMAG(&hdr.coff)) {
+ rval = coff_exec(fd, &hdr.coff, entryp);
+ } else
+#endif
+#ifdef ALPHA_BOOT_ELF
+ if (memcmp(Elf_e_ident, hdr.elf.e_ident, Elf_e_siz) == 0) {
+ rval = elf_exec(fd, &hdr.elf, entryp);
+ } else
+#endif
+ {
+ (void)printf("%s: unknown executable format\n", fname);
+ }
+
+err:
+ if (fd >= 0)
+ (void)close(fd);
+ return (rval);
+}
+
+#ifdef ALPHA_BOOT_ECOFF
+static int
+coff_exec(fd, coff, entryp)
+ int fd;
+ struct ecoff_exechdr *coff;
+ u_int64_t *entryp;
+{
+
+ /* Read in text. */
+ (void)printf("%lu", coff->a.tsize);
+ (void)lseek(fd, ECOFF_TXTOFF(coff), 0);
+ if (read(fd, (void *)coff->a.text_start, coff->a.tsize) !=
+ coff->a.tsize) {
+ (void)printf("read text: %d\n", errno);
+ return (1);
+ }
+
+ /* Read in data. */
+ if (coff->a.dsize != 0) {
+ (void)printf("+%lu", coff->a.dsize);
+ if (read(fd, (void *)coff->a.data_start, coff->a.dsize) !=
+ coff->a.dsize) {
+ (void)printf("read data: %d\n", errno);
+ return (1);
+ }
+ }
+
+
+ /* Zero out bss. */
+ if (coff->a.bsize != 0) {
+ (void)printf("+%lu", coff->a.bsize);
+ bzero(coff->a.bss_start, coff->a.bsize);
+ }
+
+ ffp_save = coff->a.text_start + coff->a.tsize;
+ if (ffp_save < coff->a.data_start + coff->a.dsize)
+ ffp_save = coff->a.data_start + coff->a.dsize;
+ if (ffp_save < coff->a.bss_start + coff->a.bsize)
+ ffp_save = coff->a.bss_start + coff->a.bsize;
+ ffp_save = ALPHA_K0SEG_TO_PHYS((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
+ ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
+
+ (void)printf("\n");
+ *entryp = coff->a.entry;
+ return (0);
+}
+#endif /* ALPHA_BOOT_ECOFF */
+
+#ifdef ALPHA_BOOT_ELF
+static int
+elf_exec(fd, elf, entryp)
+ int fd;
+ Elf_Ehdr *elf;
+ u_int64_t *entryp;
+{
+ int i;
+ int first = 1;
+
+ for (i = 0; i < elf->e_phnum; i++) {
+ Elf_Phdr phdr;
+ (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, 0);
+ if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
+ (void)printf("read phdr: %d\n", errno);
+ return (1);
+ }
+ if (phdr.p_type != Elf_pt_load ||
+ (phdr.p_flags & (Elf_pf_w|Elf_pf_x)) == 0)
+ continue;
+
+ /* Read in segment. */
+ (void)printf("%s%lu", first ? "" : "+", phdr.p_filesz);
+ (void)lseek(fd, phdr.p_offset, 0);
+ if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
+ phdr.p_filesz) {
+ (void)printf("read text: %d\n", errno);
+ return (1);
+ }
+ if (first || ffp_save < phdr.p_vaddr + phdr.p_memsz)
+ ffp_save = phdr.p_vaddr + phdr.p_memsz;
+
+ /* Zero out bss. */
+ if (phdr.p_filesz < phdr.p_memsz) {
+ (void)printf("+%lu", phdr.p_memsz - phdr.p_filesz);
+ bzero(phdr.p_vaddr + phdr.p_filesz,
+ phdr.p_memsz - phdr.p_filesz);
+ }
+ first = 0;
+ }
+
+ ffp_save = ALPHA_K0SEG_TO_PHYS((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
+ ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
+
+ (void)printf("\n");
+ *entryp = elf->e_entry;
+ return (0);
+}
+#endif /* ALPHA_BOOT_ELF */
diff --git a/sys/arch/alpha/stand/netboot/Makefile b/sys/arch/alpha/stand/netboot/Makefile
new file mode 100644
index 00000000000..f83b46d45ac
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/Makefile
@@ -0,0 +1,61 @@
+# $OpenBSD: Makefile,v 1.1 1996/10/30 22:40:51 niklas Exp $
+# $NetBSD: Makefile,v 1.3 1996/10/18 06:02:24 thorpej Exp $
+
+.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa
+
+BOOT_PROG = netboot
+BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS}
+
+BOOT_SRCS = start.S netboot.c prom.c prom_disp.S OSFpal.c prom_swpal.S
+BOOT_SRCS+= printf.c bzero.c rpcc.S
+
+BOOT_SRCS+= dev_net.c conf.c devopen.c
+BOOT_SRCS+= nfs.c rpc.c alloc.c ntohl.c htonl.c ntohs.c htons.c net.c bootp.c
+BOOT_SRCS+= strlen.c bcopy.c dev.c bcmp.c strerror.c rarp.c read.c lseek.c
+BOOT_SRCS+= in_cksum.c exit.c closeall.c arp.c strncpy.c globals.c open.c
+BOOT_SRCS+= close.c ether.c netif.c
+
+BOOT_SRCS+= if_prom.c loadfile.c getsecs.c
+
+BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g}
+
+HEADERSIZE_PROG = headersize
+
+AFLAGS += -DASSEMBLER
+CPPFLAGS += -I${.CURDIR}/../../../../ \
+ -I${.CURDIR}/../../../../lib/libsa \
+ -I${.CURDIR}/../.. -DPRIMARY_BOOTBLOCK \
+ -DALPHA_BOOT_ECOFF -DALPHA_BOOT_ELF
+CFLAGS = -Werror -mno-fp-regs -g
+
+CLEANFILES+= vers.c vers.o
+
+.PATH: ${.CURDIR} ${.CURDIR}/../../../../lib/libkern ${.CURDIR}/../boot
+
+all: ${BOOT_PROG}
+
+${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG}
+ sh ${.CURDIR}/newvers.sh ${.CURDIR}/version
+ ${COMPILE.c} vers.c
+ ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \
+ ${BOOT_OBJS} vers.o -lc # XXX
+ size ${BOOT_PROG}.hdr
+ strip ${BOOT_PROG}.hdr
+ dd if=${BOOT_PROG}.hdr of=${BOOT_PROG} \
+ bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1
+
+install:
+ ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \
+ ${DESTDIR}${BINDIR}/${BOOT_PROG}
+
+clean: _SUBDIRUSE
+ rm -f a.out [Ee]rrs mklog core *.core \
+ ${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \
+ ${BOOT_PROG}.hdr ${BOOT_PROG}.nohdr ${HEADERSIZE_PROG}
+
+cleandir: _SUBDIRUSE clean
+
+.include "${.CURDIR}/../Makefile.inc"
+.include <bsd.obj.mk>
+.include <bsd.dep.mk>
+.include <bsd.subdir.mk>
diff --git a/sys/arch/alpha/stand/netboot/conf.c b/sys/arch/alpha/stand/netboot/conf.c
new file mode 100644
index 00000000000..b40ffacf7be
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/conf.c
@@ -0,0 +1,26 @@
+/* $OpenBSD: conf.c,v 1.1 1996/10/30 22:40:52 niklas Exp $ */
+/* $NetBSD: conf.c,v 1.2 1996/10/02 21:18:45 cgd Exp $ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "stand.h"
+#include "nfs.h"
+#include "dev_net.h"
+
+struct fs_ops file_system[] = {
+ { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat },
+};
+int nfsys = 1;
+
+struct devsw devsw[] = {
+ { "net", net_strategy, net_open, net_close, net_ioctl },
+};
+int ndevs = 1;
+
+extern struct netif_driver prom_netif_driver;
+
+struct netif_driver *netif_drivers[] = {
+ &prom_netif_driver,
+};
+int n_netif_drivers = (sizeof(netif_drivers) / sizeof(netif_drivers[0]));
diff --git a/sys/arch/alpha/stand/netboot/dev_net.c b/sys/arch/alpha/stand/netboot/dev_net.c
new file mode 100644
index 00000000000..ddb84da844c
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/dev_net.c
@@ -0,0 +1,255 @@
+/* $OpenBSD: dev_net.c,v 1.1 1996/10/30 22:40:53 niklas Exp $ */
+/* $NetBSD: dev_net.c,v 1.1 1996/09/18 20:03:07 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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. The name of the author 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
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface, getting boot
+ * parameters, and performing the NFS mount.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * RARP for IP address - rarp_getipaddress()
+ * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
+ * RPC/mountd - nfs_mount(sock, ip, path)
+ *
+ * the root file handle from mountd is saved in a global
+ * for use by the NFS open code (NFS/lookup).
+ */
+
+#include <stdarg.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+
+#include "stand.h"
+#include "net.h"
+#include "netif.h"
+#include "bootparam.h"
+#include "dev_net.h"
+
+extern int debug;
+extern int nfs_root_node[]; /* XXX - get from nfs_mount() */
+
+/*
+ * Various globals needed by the network code:
+ */
+
+#if 0
+/* for arp.c, rarp.c */
+u_char bcea[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#endif
+
+struct in_addr myip; /* my ip address */
+struct in_addr rootip; /* root ip address */
+struct in_addr gateip; /* swap ip address */
+n_long netmask; /* subnet or net mask */
+
+char rootpath[FNAME_SIZE];
+
+int hostnamelen;
+char hostname[FNAME_SIZE];
+
+int domainnamelen;
+char domainname[FNAME_SIZE];
+
+/*
+ * Local things...
+ */
+static int netdev_sock = -1;
+static int netdev_opens;
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ * This is declared with variable arguments...
+ */
+int
+net_open(struct open_file *f, ...)
+{
+ va_list ap;
+ char *devname; /* Device part of file name (or NULL). */
+ int error = 0;
+
+ va_start(ap, f);
+ devname = va_arg(ap, char*);
+ va_end(ap);
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: %s\n", devname);
+#endif
+
+ /* On first open, do netif open, mount, etc. */
+ if (netdev_opens == 0) {
+ /* Find network interface. */
+ if (netdev_sock < 0) {
+ netdev_sock = netif_open(devname);
+ if (netdev_sock < 0) {
+ printf("net_open: netif_open() failed\n");
+ return (ENXIO);
+ }
+ if (debug)
+ printf("net_open: netif_open() succeeded\n");
+ }
+ if (rootip.s_addr == 0) {
+ /* Get root IP address, and path, etc. */
+ error = net_getparams(netdev_sock);
+ if (error) {
+ /* getparams makes its own noise */
+ goto fail;
+ }
+ /* Get the NFS file handle (mountd). */
+ error = nfs_mount(netdev_sock, rootip, rootpath);
+ if (error) {
+ printf("net_open: NFS mount error=%d\n", error);
+ rootip.s_addr = 0;
+ fail:
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ return (error);
+ }
+ if (debug)
+ printf("net_open: NFS mount succeeded\n");
+ }
+ }
+ netdev_opens++;
+ f->f_devdata = nfs_root_node;
+ return (error);
+}
+
+int
+net_close(f)
+ struct open_file *f;
+{
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: opens=%d\n", netdev_opens);
+#endif
+
+ /* On last close, do netif close, etc. */
+ f->f_devdata = NULL;
+ /* Extra close call? */
+ if (netdev_opens <= 0)
+ return (0);
+ netdev_opens--;
+ /* Not last close? */
+ if (netdev_opens > 0)
+ return(0);
+ rootip.s_addr = 0;
+ if (netdev_sock >= 0) {
+ if (debug)
+ printf("net_close: calling netif_close()\n");
+ netif_close(netdev_sock);
+ netdev_sock = -1;
+ }
+ return (0);
+}
+
+int
+net_ioctl()
+{
+ return EIO;
+}
+
+int
+net_strategy()
+{
+ return EIO;
+}
+
+int
+net_getparams(sock)
+ int sock;
+{
+ /*
+ * Get info for NFS boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ * There are two ways to do this: The old, Sun way,
+ * and the more modern, BOOTP way. (RFC951, RFC1048)
+ */
+
+#ifdef SUN_BOOTPARAMS
+ /* Get our IP address. (rarp.c) */
+ if (rarp_getipaddress(sock)) {
+ printf("net_open: RARP failed\n");
+ return (EIO);
+ }
+#else /* BOOTPARAMS */
+ /*
+ * Get boot info using BOOTP. (RFC951, RFC1048)
+ * This also gets the server IP address, gateway,
+ * root path, etc.
+ */
+ bootp(sock);
+ if (myip.s_addr == 0) {
+ printf("net_open: BOOTP failed\n");
+ return (EIO);
+ }
+#endif /* BOOTPARAMS */
+
+ printf("boot: client addr: %s\n", inet_ntoa(myip));
+
+#ifdef SUN_BOOTPARAMS
+ /* Get our hostname, server IP address, gateway. */
+ if (bp_whoami(sock)) {
+ printf("net_open: bootparam/whoami RPC failed\n");
+ return (EIO);
+ }
+#endif /* BOOTPARAMS */
+
+ printf("boot: client name: %s\n", hostname);
+ if (gateip.s_addr) {
+ printf("boot: subnet mask: %s\n", intoa(netmask));
+ printf("boot: net gateway: %s\n", inet_ntoa(gateip));
+ }
+
+#ifdef SUN_BOOTPARAMS
+ /* Get the root pathname. */
+ if (bp_getfile(sock, "root", &rootip, rootpath)) {
+ printf("net_open: bootparam/getfile RPC failed\n");
+ return (EIO);
+ }
+#endif /* BOOTPARAMS */
+
+ printf("boot: server addr: %s\n", inet_ntoa(rootip));
+ printf("boot: server path: %s\n", rootpath);
+
+ return (0);
+}
diff --git a/sys/arch/alpha/stand/netboot/dev_net.h b/sys/arch/alpha/stand/netboot/dev_net.h
new file mode 100644
index 00000000000..3e3d4b091d6
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/dev_net.h
@@ -0,0 +1,8 @@
+/* $OpenBSD: dev_net.h,v 1.1 1996/10/30 22:40:53 niklas Exp $ */
+
+
+int net_open __P((struct open_file *, ...));
+int net_close __P((struct open_file *));
+int net_ioctl();
+int net_strategy();
+
diff --git a/sys/arch/alpha/stand/netboot/devopen.c b/sys/arch/alpha/stand/netboot/devopen.c
new file mode 100644
index 00000000000..601960fcef4
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/devopen.c
@@ -0,0 +1,162 @@
+/* $OpenBSD: devopen.c,v 1.1 1996/10/30 22:40:54 niklas Exp $ */
+/* $NetBSD: devopen.c,v 1.1 1996/09/18 20:03:09 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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.
+ *
+ * @(#)devopen.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <stand.h>
+
+/*
+ * Decode the string 'fname', open the device and return the remaining
+ * file name if any.
+ */
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file; /* out */
+{
+ register char *cp;
+ register char *ncp;
+ register struct devsw *dp;
+ register int c, i;
+ int ctlr = 0, unit = 0, part = 0;
+ char namebuf[20];
+ int rc;
+
+ cp = (char *)fname;
+ ncp = namebuf;
+
+#if 0
+ /* look for a string like '5/rz0/vmunix' or '5/rz3f/vmunix */
+ if ((c = *cp) >= '0' && c <= '9') {
+ ctlr = c - '0';
+ /* skip the '/' */
+ if (*++cp != '/')
+ return (ENXIO);
+ cp++;
+ while ((c = *cp) != '\0') {
+ if (c == '/')
+ break;
+ if (c >= '0' && c <= '9') {
+ /* read unit number */
+ unit = c - '0';
+
+ /* look for a partition */
+ if ((c = *++cp) >= 'a' && c <= 'h') {
+ part = c - 'a';
+ c = *++cp;
+ }
+ if (c != '/')
+ return (ENXIO);
+ break;
+ }
+ if (ncp < namebuf + sizeof(namebuf) - 1)
+ *ncp++ = c;
+ cp++;
+ }
+ *ncp = '\0';
+ /*
+ * XXX
+ * pulling strchr from the C library, should pull from libkern.
+ */
+ } else if (strchr(cp, '(')) {
+ /* expect a string like 'rz(0,0,0)vmunix' */
+ while ((c = *cp) != '\0') {
+ if (c == '(') {
+ cp++;
+ break;
+ }
+ if (ncp < namebuf + sizeof(namebuf) - 1)
+ *ncp++ = c;
+ cp++;
+ }
+
+ /* get controller number */
+ if ((c = *cp) >= '0' && c <= '9') {
+ ctlr = c - '0';
+ c = *++cp;
+ }
+
+ if (c == ',') {
+ /* get SCSI device number */
+ if ((c = *++cp) >= '0' && c <= '9') {
+ unit = c - '0';
+ c = *++cp;
+ }
+
+ if (c == ',') {
+ /* get partition number */
+ if ((c = *++cp) >= '0' && c <= '9') {
+ part = c - '0';
+ c = *++cp;
+ }
+ }
+ }
+ if (c != ')')
+ return (ENXIO);
+ cp++;
+ *ncp = '\0';
+ } else {
+#endif
+ dp = devsw;
+ ctlr = unit = part = 0;
+ goto fnd;
+#if 0
+ }
+
+ for (dp = devsw, i = 0; i < ndevs; dp++, i++)
+ if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0)
+ goto fnd;
+ printf("Unknown device '%s'\nKnown devices are:", namebuf);
+ for (dp = devsw, i = 0; i < ndevs; dp++, i++)
+ if (dp->dv_name)
+ printf(" %s", dp->dv_name);
+ printf("\n");
+ return (ENXIO);
+#endif
+
+fnd:
+ rc = (dp->dv_open)(f, ctlr, unit, part);
+ if (rc)
+ return (rc);
+
+ f->f_dev = dp;
+ if (file && *cp != '\0')
+ *file = cp;
+ return (0);
+}
diff --git a/sys/arch/alpha/stand/netboot/getsecs.c b/sys/arch/alpha/stand/netboot/getsecs.c
new file mode 100644
index 00000000000..07ca9e539d1
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/getsecs.c
@@ -0,0 +1,34 @@
+/* $OpenBSD: getsecs.c,v 1.1 1996/10/30 22:40:55 niklas Exp $ */
+
+#include <sys/param.h>
+#include "include/prom.h"
+#include "include/rpb.h"
+
+int
+getsecs()
+{
+ static long tnsec;
+ static long lastpcc, wrapsecs;
+ long curpcc, pccdiff;
+
+ if (tnsec == 0) {
+ tnsec = 1;
+ lastpcc = alpha_rpcc() & 0xffffffff;
+ wrapsecs = (0xffffffff /
+ ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq) + 1;
+
+#if 0
+ printf("getsecs: cc freq = %d, time to wrap = %d\n",
+ ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq, wrapsecs);
+#endif
+ }
+
+ curpcc = alpha_rpcc() & 0xffffffff;
+ if (curpcc < lastpcc)
+ curpcc += 0x100000000;
+
+ tnsec += ((curpcc - lastpcc) * 1000000000) / ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
+ lastpcc = curpcc;
+
+ return (tnsec / 1000000000);
+}
diff --git a/sys/arch/alpha/stand/netboot/if_prom.c b/sys/arch/alpha/stand/netboot/if_prom.c
new file mode 100644
index 00000000000..97664bb66ff
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/if_prom.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: if_prom.c,v 1.1 1996/10/30 22:40:56 niklas Exp $ */
+/* $NetBSD: if_prom.c,v 1.4 1996/10/02 21:18:49 cgd 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.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include "netif.h"
+#include "include/prom.h"
+#include "lib/libkern/libkern.h"
+
+int prom_probe();
+int prom_match();
+void prom_init();
+int prom_get();
+int prom_put();
+void prom_end();
+
+extern struct netif_stats prom_stats[];
+
+struct netif_dif prom_ifs[] = {
+/* dif_unit dif_nsel dif_stats dif_private */
+{ 0, 1, &prom_stats[0], 0, },
+};
+
+struct netif_stats prom_stats[NENTS(prom_ifs)];
+
+struct netif_driver prom_netif_driver = {
+ "prom", /* netif_bname */
+ prom_match, /* netif_match */
+ prom_probe, /* netif_probe */
+ prom_init, /* netif_init */
+ prom_get, /* netif_get */
+ prom_put, /* netif_put */
+ prom_end, /* netif_end */
+ prom_ifs, /* netif_ifs */
+ NENTS(prom_ifs) /* netif_nifs */
+};
+
+int netfd;
+
+int
+prom_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+
+ return (1);
+}
+
+int
+prom_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+
+ return 0;
+}
+
+int
+prom_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+
+ prom_write(netfd, len, pkt, 0);
+
+ return len;
+}
+
+
+int
+prom_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+ time_t timeout;
+{
+ prom_return_t ret;
+ time_t t;
+ int cc;
+ char hate[2000];
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ ret.bits = prom_read(netfd, sizeof hate, hate, 0);
+ if (ret.u.status == 0)
+ cc += ret.u.retval;
+ }
+ cc = len;
+ bcopy(hate, pkt, cc);
+
+ return cc;
+}
+
+extern char *strchr();
+
+void
+prom_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ prom_return_t ret;
+ char devname[64];
+ int devlen, i;
+ char *enet_addr;
+
+ ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
+ devlen = ret.u.retval;
+
+ /* Ethernet address is the 9th component of the booted_dev string. */
+ enet_addr = devname;
+ for (i = 0; i < 8; i++) {
+ enet_addr = strchr(enet_addr, ' ');
+ if (enet_addr == NULL) {
+ printf("Boot device name does not contain ethernet address.\n");
+ goto punt;
+ }
+ enet_addr++;
+ }
+ if (enet_addr != NULL) {
+ int hv, lv;
+
+#define dval(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
+ (((c) >= 'A' && (c) <= 'F') ? (10 + (c) - 'A') : \
+ (((c) >= 'a' && (c) <= 'f') ? (10 + (c) - 'a') : -1)))
+
+ for (i = 0; i < 6; i++) {
+ hv = dval(*enet_addr); enet_addr++;
+ lv = dval(*enet_addr); enet_addr++;
+ enet_addr++;
+
+ if (hv == -1 || lv == -1) {
+ printf("Bogus ethernet address.\n");
+ goto punt;
+ }
+
+ desc->myea[i] = (hv << 4) | lv;
+ }
+#undef dval
+ }
+
+ printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
+
+ ret.bits = prom_open(devname, devlen + 1);
+ if (ret.u.status) {
+ printf("prom_init: open failed: %d\n", ret.u.status);
+ goto punt;
+ }
+ netfd = ret.u.retval;
+ return;
+
+punt:
+ printf("Boot device name was: \"%s\"\n", devname);
+ printf("\n");
+ printf("Your firmware may be too old to network-boot OpenBSD/Alpha.\n");
+ halt();
+}
+
+void
+prom_end(nif)
+ struct netif *nif;
+{
+
+ prom_close(netfd);
+}
diff --git a/sys/arch/alpha/stand/netboot/netboot.c b/sys/arch/alpha/stand/netboot/netboot.c
new file mode 100644
index 00000000000..ce23e0918b1
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/netboot.c
@@ -0,0 +1,99 @@
+/* $OpenBSD: netboot.c,v 1.1 1996/10/30 22:40:57 niklas Exp $ */
+/* $NetBSD: netboot.c,v 1.1 1996/09/18 20:03:12 cgd Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_ecoff.h>
+
+#include <machine/prom.h>
+
+#define _KERNEL
+#include "include/pte.h"
+
+int loadfile __P((char *, u_int64_t *));
+
+char boot_file[128];
+char boot_flags[128];
+
+extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
+
+vm_offset_t ffp_save, ptbr_save;
+
+int debug;
+
+void
+main()
+{
+ u_int64_t entry;
+
+ /* Init prom callback vector. */
+ init_prom_calls();
+
+ /* print a banner */
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+ printf("\n");
+
+ /* switch to OSF pal code. */
+ OSFpal();
+
+ printf("\n");
+
+ prom_getenv(PROM_E_BOOTED_FILE, boot_file, sizeof(boot_file));
+ prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags));
+
+ if (boot_file[0] == '\0')
+ bcopy("bsd", boot_file, sizeof "bsd");
+
+ (void)printf("Boot: %s %s\n", boot_file, boot_flags);
+
+ if (!loadfile(boot_file, &entry)) {
+ (void)printf("Entering kernel at 0x%lx...\n", entry);
+ (*(void (*)())entry)(ffp_save, ptbr_save, 0);
+ }
+
+ (void)printf("Boot failed! Halting...\n");
+ halt();
+}
diff --git a/sys/arch/alpha/stand/netboot/newvers.sh b/sys/arch/alpha/stand/netboot/newvers.sh
new file mode 100644
index 00000000000..9699e4f9ee7
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/newvers.sh
@@ -0,0 +1,45 @@
+#!/bin/sh -
+#
+# $OpenBSD: newvers.sh,v 1.1 1996/10/30 22:40:58 niklas Exp $
+# $NetBSD: newvers.sh,v 1.1 1996/09/18 20:03:13 cgd Exp $
+#
+# Copyright (c) 1984, 1986, 1990, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the 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.
+#
+# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
+
+u=${USER-root} h=`hostname` t=`date`
+r=`head -1 $1 | awk ' { print $3 } '`
+
+echo "char bootprog_name[] = \"OpenBSD/Alpha Network Boot\";" > vers.c
+echo "char bootprog_rev[] = \"${r}\";" >> vers.c
+echo "char bootprog_date[] = \"${t}\";" >> vers.c
+echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c
diff --git a/sys/arch/alpha/stand/netboot/rpcc.S b/sys/arch/alpha/stand/netboot/rpcc.S
new file mode 100644
index 00000000000..598534d50bd
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/rpcc.S
@@ -0,0 +1,10 @@
+/* $OpenBSD: rpcc.S,v 1.1 1996/10/30 22:40:59 niklas Exp $ */
+/* $NetBSD: rpcc.S,v 1.2 1996/10/02 21:18:50 cgd Exp $ */
+
+#include <machine/asm.h>
+
+ .text
+LEAF(alpha_rpcc,1)
+ rpcc v0
+ RET
+ END(alpha_rpcc)
diff --git a/sys/arch/alpha/stand/netboot/version b/sys/arch/alpha/stand/netboot/version
new file mode 100644
index 00000000000..16253a53f4d
--- /dev/null
+++ b/sys/arch/alpha/stand/netboot/version
@@ -0,0 +1,5 @@
+$OpenBSD: version,v 1.1 1996/10/30 22:41:00 niklas Exp $
+$NetBSD: version,v 1.2 1996/10/02 21:26:17 cgd Exp $
+
+1.1 Initial version
+1.2 Cleaned and polished a bit
diff --git a/sys/arch/alpha/stand/prom.c b/sys/arch/alpha/stand/prom.c
index 79cee77d833..b8e524ee874 100644
--- a/sys/arch/alpha/stand/prom.c
+++ b/sys/arch/alpha/stand/prom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: prom.c,v 1.2 1996/07/29 23:01:24 niklas Exp $ */
+/* $OpenBSD: prom.c,v 1.3 1996/10/30 22:40:33 niklas Exp $ */
/* $NetBSD: prom.c,v 1.1 1995/11/23 02:39:07 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/stand/prom_disp.S b/sys/arch/alpha/stand/prom_disp.S
index c6346865366..8b56160dc19 100644
--- a/sys/arch/alpha/stand/prom_disp.S
+++ b/sys/arch/alpha/stand/prom_disp.S
@@ -1,5 +1,5 @@
-/* $OpenBSD: prom_disp.S,v 1.3 1996/07/29 23:01:25 niklas Exp $ */
-/* $NetBSD: prom_disp.S,v 1.3 1996/04/12 06:09:38 cgd Exp $ */
+/* $OpenBSD: prom_disp.S,v 1.4 1996/10/30 22:40:34 niklas Exp $ */
+/* $NetBSD: prom_disp.S,v 1.5 1996/10/17 02:50:39 cgd Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -35,7 +35,7 @@
#endif
.globl prom_dispatch_v
- .comm prom_dispatch_v 16
+ .comm prom_dispatch_v,16
.text
.align 4
@@ -56,7 +56,7 @@
#define DISPATCH_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5|IM_S6
NESTED(prom_dispatch, 5, DISPATCH_FRAME_SIZE, ra, DISPATCH_REGS, 0)
- SETGP(pv)
+ LDGP(pv)
lda sp, -DISPATCH_FRAME_SIZE(sp)
stq ra, D_RA(sp)
diff --git a/sys/arch/alpha/stand/puts.c b/sys/arch/alpha/stand/puts.c
index 47ee3340751..06c0b066e38 100644
--- a/sys/arch/alpha/stand/puts.c
+++ b/sys/arch/alpha/stand/puts.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: puts.c,v 1.2 1996/07/29 23:01:27 niklas Exp $ */
+/* $OpenBSD: puts.c,v 1.3 1996/10/30 22:40:35 niklas Exp $ */
void
diff --git a/sys/arch/alpha/stand/start.S b/sys/arch/alpha/stand/start.S
index 6990832353b..a3eb03974e4 100644
--- a/sys/arch/alpha/stand/start.S
+++ b/sys/arch/alpha/stand/start.S
@@ -1,5 +1,5 @@
-/* $OpenBSD: start.S,v 1.2 1996/07/29 23:01:28 niklas Exp $ */
-/* $NetBSD: start.S,v 1.1 1995/11/23 02:39:15 cgd Exp $ */
+/* $OpenBSD: start.S,v 1.3 1996/10/30 22:40:36 niklas Exp $ */
+/* $NetBSD: start.S,v 1.4 1996/10/17 02:50:40 cgd Exp $ */
/*
* Mach Operating System
@@ -45,21 +45,27 @@
#define ENTRY_FRAME 32
NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
- br pv,1f
-1: SETGP(pv)
+ br pv,Lstartgp
+Lstartgp:
+ LDGP(pv)
#ifndef PRIMARY_BOOTBLOCK
lda sp,start /* start stack below text */
lda sp,-ENTRY_FRAME(sp)
#endif
+#ifdef ECOFF_COMPAT
lda a0,_EDATA
+#else
+ lda a0,_edata
+#endif
lda a1,_end
subq a1,a0,a1
CALL(bzero)
CALL(main) /* transfer to C */
+XLEAF(_rtt, 0)
XLEAF(halt, 0)
call_pal PAL_halt /* halt if we ever return */
END(start)
diff --git a/sys/arch/alpha/tc/cfb.c b/sys/arch/alpha/tc/cfb.c
index 3db8a4d2783..0f78f75e769 100644
--- a/sys/arch/alpha/tc/cfb.c
+++ b/sys/arch/alpha/tc/cfb.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cfb.c,v 1.2 1996/07/29 23:01:56 niklas Exp $ */
-/* $NetBSD: cfb.c,v 1.1 1996/05/01 23:25:03 cgd Exp $ */
+/* $OpenBSD: cfb.c,v 1.3 1996/10/30 22:41:01 niklas Exp $ */
+/* $NetBSD: cfb.c,v 1.5 1996/10/13 03:00:27 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -57,7 +57,7 @@
int cfbmatch __P((struct device *, void *, void *));
void cfbattach __P((struct device *, struct device *, void *));
-int cfbprint __P((void *, char *));
+int cfbprint __P((void *, /* const */ char *));
struct cfattach cfb_ca = {
sizeof(struct cfb_softc), cfbmatch, cfbattach,
@@ -89,7 +89,6 @@ cfbmatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct tc_attach_args *ta = aux;
if (strncmp("PMAG-BA ", ta->ta_modname, TC_ROM_LLEN) != 0)
@@ -109,7 +108,7 @@ cfb_getdevconfig(dense_addr, dc)
int i;
dc->dc_vaddr = dense_addr;
- dc->dc_paddr = k0segtophys(dc->dc_vaddr); /* XXX */
+ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
dc->dc_size = CFB_SIZE;
ramdacregp = (char *)dc->dc_vaddr + CFB_RAMDAC_OFFSET;
@@ -169,7 +168,6 @@ cfbattach(parent, self, aux)
struct wscons_attach_args waa;
struct wscons_odev_spec *wo;
int console;
- char *x;
console = 0; /* XXX */
if (console)
@@ -208,7 +206,7 @@ cfbattach(parent, self, aux)
int
cfbprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
if (pnp)
diff --git a/sys/arch/alpha/tc/cfbvar.h b/sys/arch/alpha/tc/cfbvar.h
index 8434cf92910..73a514ece37 100644
--- a/sys/arch/alpha/tc/cfbvar.h
+++ b/sys/arch/alpha/tc/cfbvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cfbvar.h,v 1.2 1996/07/29 23:01:58 niklas Exp $ */
+/* $OpenBSD: cfbvar.h,v 1.3 1996/10/30 22:41:03 niklas Exp $ */
/* $NetBSD: cfbvar.h,v 1.1 1996/05/01 23:25:04 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/esp.c b/sys/arch/alpha/tc/esp.c
index 5e6cfb9fb8d..cb18590130c 100644
--- a/sys/arch/alpha/tc/esp.c
+++ b/sys/arch/alpha/tc/esp.c
@@ -1,5 +1,38 @@
-/* $OpenBSD: esp.c,v 1.5 1996/10/18 16:12:01 niklas Exp $ */
-/* $NetBSD: esp.c,v 1.8.4.1 1996/06/05 00:39:03 cgd Exp $ */
+/* $OpenBSD: esp.c,v 1.6 1996/10/30 22:41:04 niklas Exp $ */
+/* $NetBSD: esp.c,v 1.22 1996/10/15 21:30:19 mycroft Exp $ */
+
+#ifdef __sparc__
+#define SPARC_DRIVER
+#endif
+
+/*
+ * 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
@@ -17,7 +50,7 @@
* 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
+ * 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
@@ -66,7 +99,7 @@
#include <sparc/dev/espreg.h>
#include <sparc/dev/espvar.h>
#else
-#include <machine/autoconf.h>
+#include <machine/autoconf.h> /* badaddr() prototype */
#include <dev/tc/tcvar.h>
#include <alpha/tc/tcdsvar.h>
#include <alpha/tc/espreg.h>
@@ -76,33 +109,39 @@
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 *, char *));
+/*static*/ int espmatch __P((struct device *, void *, void *));
+/*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_select __P((struct esp_softc *, struct esp_ecb *));
+/*static*/ int esp_reselect __P((struct esp_softc *, int));
/*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*/ int esp_poll __P((struct esp_softc *, struct scsi_xfer *, int));
/*static*/ void esp_sched __P((struct esp_softc *));
-/*static*/ void esp_done __P((struct ecb *));
+/*static*/ void esp_done __P((struct esp_softc *, struct esp_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_cpb2stp __P((struct esp_softc *, int));
-int esp_stp2cpb __P((struct esp_softc *, int));
+/*static*/ void esp_abort __P((struct esp_softc *, struct esp_ecb *));
+/*static*/ void esp_dequeue __P((struct esp_softc *, struct esp_ecb *));
+void esp_sense __P((struct esp_softc *, struct esp_ecb *));
+void esp_free_ecb __P((struct esp_softc *, struct esp_ecb *, int));
+struct esp_ecb *esp_get_ecb __P((struct esp_softc *, int));
+static inline int esp_stp2cpb __P((struct esp_softc *, int));
+static inline int esp_cpb2stp __P((struct esp_softc *, int));
+static inline void esp_setsync __P((struct esp_softc *, struct esp_tinfo *));
/* Linkup to the rest of the kernel */
struct cfattach esp_ca = {
- sizeof(struct esp_softc), espmatch, espattach,
+ sizeof(struct esp_softc), espmatch, espattach
};
struct cfdriver esp_cd = {
- NULL, "esp", DV_DULL,
+ NULL, "esp", DV_DULL
};
struct scsi_adapter esp_switch = {
@@ -119,6 +158,9 @@ struct scsi_device esp_dev = {
NULL, /* Use default 'done' routine */
};
+/*
+ * XXX should go when new generic scsiprint finds its way here
+ */
int
espprint(aux, name)
void *aux;
@@ -170,7 +212,7 @@ espattach(parent, self, aux)
struct esp_softc *sc = (void *)self;
#ifdef SPARC_DRIVER
struct bootpath *bp;
- int dmachild = strncmp(parent->dv_xname, "espdma", 6) == 0;
+ int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
#endif
#ifdef SPARC_DRIVER
@@ -256,6 +298,8 @@ espattach(parent, self, aux)
*/
if (sc->sc_dma)
sc->sc_dma->sc_esp = sc;
+ else
+ panic("espattach: no dma found");
}
#else
sc->sc_dma->sc_esp = sc; /* XXX */
@@ -276,7 +320,7 @@ espattach(parent, self, aux)
printf(": ESP100");
sc->sc_rev = ESP100;
} else {
- sc->sc_cfg2 = ESPCFG2_SCSI2 | ESPCFG2_FE;
+ sc->sc_cfg2 = ESPCFG2_SCSI2;
ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
sc->sc_cfg3 = 0;
ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
@@ -286,6 +330,8 @@ espattach(parent, self, aux)
printf(": ESP100A");
sc->sc_rev = ESP100A;
} else {
+ /* ESPCFG2_FE enables > 64K transfers */
+ sc->sc_cfg2 |= ESPCFG2_FE;
sc->sc_cfg3 = 0;
ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
printf(": ESP200");
@@ -318,14 +364,19 @@ espattach(parent, self, aux)
*/
switch (sc->sc_rev) {
case ESP100:
+ sc->sc_maxxfer = 64 * 1024;
sc->sc_minsync = 0; /* No synch on old chip? */
break;
case ESP100A:
+ sc->sc_maxxfer = 64 * 1024;
sc->sc_minsync = esp_cpb2stp(sc, 5); /* Min clocks/byte is 5 */
break;
case ESP200:
+ sc->sc_maxxfer = 16 * 1024 * 1024;
/* XXX - do actually set FAST* bits */
}
+#else
+ sc->sc_maxxfer = 64 * 1024;
#endif
sc->sc_ccf = FREQTOCCF(sc->sc_freq);
@@ -380,6 +431,7 @@ espattach(parent, self, aux)
/*
* fill in the prototype scsi_link.
*/
+ /* sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE; */
sc->sc_link.adapter_softc = sc;
sc->sc_link.adapter_target = sc->sc_id;
sc->sc_link.adapter = &esp_switch;
@@ -410,7 +462,7 @@ espattach(parent, self, aux)
/*
* Now try to attach all the sub-devices
*/
- config_found(self, &sc->sc_link, espprint);
+ config_found(self, &sc->sc_link, /* scsiprint */ espprint); /* XXX */
#ifdef SPARC_DRIVER
bootpath_store(1, NULL);
@@ -425,7 +477,7 @@ espattach(parent, self, aux)
* After reset, registers are loaded with the defaults from the attach
* routine above.
*/
-void
+void
esp_reset(sc)
struct esp_softc *sc;
{
@@ -491,12 +543,13 @@ esp_init(sc, doreset)
struct esp_softc *sc;
int doreset;
{
- struct ecb *ecb;
+ struct esp_ecb *ecb;
int r;
ESP_TRACE(("[ESP_INIT(%d)] ", doreset));
- if (sc->sc_state == 0) { /* First time through */
+ if (sc->sc_state == 0) {
+ /* First time through; initialize. */
TAILQ_INIT(&sc->ready_list);
TAILQ_INIT(&sc->nexus_list);
TAILQ_INIT(&sc->free_list);
@@ -505,21 +558,21 @@ esp_init(sc, doreset)
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;
- if (sc->sc_nexus != NULL) {
- sc->sc_nexus->xs->error = XS_TIMEOUT;
- esp_done(sc->sc_nexus);
+ /* Cancel any active commands. */
+ sc->sc_state = ESP_CLEANING;
+ if ((ecb = sc->sc_nexus) != NULL) {
+ ecb->xs->error = XS_DRIVER_STUFFUP;
+ untimeout(esp_timeout, ecb);
+ esp_done(sc, ecb);
}
- sc->sc_nexus = NULL;
while ((ecb = sc->nexus_list.tqh_first) != NULL) {
- ecb->xs->error = XS_TIMEOUT;
- esp_done(ecb);
+ ecb->xs->error = XS_DRIVER_STUFFUP;
+ untimeout(esp_timeout, ecb);
+ esp_done(sc, ecb);
}
}
@@ -530,24 +583,24 @@ esp_init(sc, doreset)
sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
for (r = 0; r < 8; r++) {
- struct esp_tinfo *tp = &sc->sc_tinfo[r];
-
- tp->flags = (sc->sc_minsync ? T_NEGOTIATE : 0) |
- T_NEED_TO_RESET | (tp->flags & T_XXX);
- tp->period = sc->sc_minsync;
- tp->offset = 0;
+ struct esp_tinfo *ti = &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;
+
+ ti->flags = ((sc->sc_minsync && !(fl & (1<<(r+8))))
+ ? T_NEGOTIATE : 0) |
+ ((fl & (1<<r)) ? T_RSELECTOFF : 0) |
+ T_NEED_TO_RESET;
+ ti->period = sc->sc_minsync;
+ ti->offset = 0;
}
- sc->sc_flags &= ~ESP_ABORTING;
if (doreset) {
sc->sc_state = ESP_SBR;
ESPCMD(sc, ESPCMD_RSTSCSI);
- return;
+ } else {
+ sc->sc_state = ESP_IDLE;
}
-
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- return;
}
/*
@@ -587,9 +640,20 @@ espreadregs(sc)
}
/*
+ * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
+ */
+static inline int
+esp_cpb2stp(sc, cpb)
+ struct esp_softc *sc;
+ int cpb;
+{
+ return ((250 * cpb) / sc->sc_freq);
+}
+
+/*
* Convert Synchronous Transfer Period to chip register Clock Per Byte value.
*/
-int
+static inline int
esp_stp2cpb(sc, period)
struct esp_softc *sc;
int period;
@@ -602,15 +666,19 @@ esp_stp2cpb(sc, period)
return v;
}
-/*
- * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
- */
-int
-esp_cpb2stp(sc, cpb)
+static inline void
+esp_setsync(sc, ti)
struct esp_softc *sc;
- int cpb;
+ struct esp_tinfo *ti;
{
- return ((250 * cpb) / sc->sc_freq);
+
+ 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);
+ }
}
/*
@@ -621,38 +689,36 @@ esp_cpb2stp(sc, cpb)
* by DMA instead of programmed I/O soon.
*/
void
-espselect(sc, target, lun, cmd, clen)
+esp_select(sc, ecb)
struct esp_softc *sc;
- u_char target, lun;
- u_char *cmd;
- u_char clen;
+ struct esp_ecb *ecb;
{
+ struct scsi_link *sc_link = ecb->xs->sc_link;
+ int target = sc_link->target;
struct esp_tinfo *ti = &sc->sc_tinfo[target];
- int i;
+ u_char *cmd;
+ int clen;
- ESP_TRACE(("[espselect(t%d,l%d,cmd:%x)] ", target, lun, *(u_char *)cmd));
+ ESP_TRACE(("[esp_select(t%d,l%d,cmd:%x)] ", sc_link->target, sc_link->lun, ecb->cmd.opcode));
/* 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);
- }
+ esp_setsync(sc, ti);
/*
* 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, 1));
+ ESP_WRITE_REG(sc, ESP_FIFO,
+ MSG_IDENTIFY(sc_link->lun, (ti->flags & T_RSELECTOFF)?0:1));
if (ti->flags & T_NEGOTIATE) {
/* Arbitrate, select and stop after IDENTIFY message */
@@ -661,13 +727,60 @@ espselect(sc, target, lun, cmd, clen)
}
/* Now the command into the FIFO */
- for (i = 0; i < clen; i++)
+ cmd = (u_char *)&ecb->cmd;
+ clen = ecb->clen;
+ while (clen--)
ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
/* And get the targets attention */
ESPCMD(sc, ESPCMD_SELATN);
}
+void
+esp_free_ecb(sc, ecb, flags)
+ struct esp_softc *sc;
+ struct esp_ecb *ecb;
+ int flags;
+{
+ int s;
+
+ s = splbio();
+
+ ecb->flags = 0;
+ TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
+
+ /*
+ * If there were none, wake anybody waiting for one to come free,
+ * starting with queued entries.
+ */
+ if (ecb->chain.tqe_next == 0)
+ wakeup(&sc->free_list);
+
+ splx(s);
+}
+
+struct esp_ecb *
+esp_get_ecb(sc, flags)
+ struct esp_softc *sc;
+ int flags;
+{
+ struct esp_ecb *ecb;
+ int s;
+
+ s = splbio();
+
+ while ((ecb = sc->free_list.tqh_first) == NULL &&
+ (flags & SCSI_NOSLEEP) == 0)
+ tsleep(&sc->free_list, PRIBIO, "especb", 0);
+ if (ecb) {
+ TAILQ_REMOVE(&sc->free_list, ecb, chain);
+ ecb->flags |= ECB_ALLOC;
+ }
+
+ splx(s);
+ return ecb;
+}
+
/*
* DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
*/
@@ -677,73 +790,70 @@ espselect(sc, target, lun, cmd, clen)
* This function is called by the higher level SCSI-driver to queue/run
* SCSI-commands.
*/
-int
+int
esp_scsi_cmd(xs)
struct scsi_xfer *xs;
{
struct scsi_link *sc_link = xs->sc_link;
struct esp_softc *sc = sc_link->adapter_softc;
- struct ecb *ecb;
+ struct esp_ecb *ecb;
int s, flags;
-
+
ESP_TRACE(("[esp_scsi_cmd] "));
- ESP_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
+ 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"));
+ if ((ecb = esp_get_ecb(sc, flags)) == NULL) {
+ xs->error = XS_DRIVER_STUFFUP;
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->timeout = xs->timeout;
+
+ if (xs->flags & SCSI_RESET) {
+ ecb->flags |= ECB_RESET;
+ ecb->clen = 0;
+ ecb->dleft = 0;
+ } else {
+ 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);
+ TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
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;
+ if ((flags & SCSI_POLL) == 0)
+ return SUCCESSFULLY_QUEUED;
+ /* Not allowed to use interrupts, use polling instead */
+ if (esp_poll(sc, xs, ecb->timeout)) {
+ esp_timeout(ecb);
+ if (esp_poll(sc, xs, ecb->timeout))
+ esp_timeout(ecb);
+ }
+ return COMPLETE;
}
/*
* Used when interrupt driven I/O isn't allowed, e.g. during boot.
*/
int
-esp_poll(sc, ecb)
+esp_poll(sc, xs, count)
struct esp_softc *sc;
- struct ecb *ecb;
+ struct scsi_xfer *xs;
+ int count;
{
- struct scsi_xfer *xs = ecb->xs;
- int count = xs->timeout * 100;
ESP_TRACE(("[esp_poll] "));
while (count) {
@@ -754,22 +864,16 @@ esp_poll(sc, ecb)
if (ESP_READ_REG(sc, ESP_STAT) & ESPSTAT_INT)
espintr(sc);
#endif
- if (xs->flags & ITSDONE)
- break;
- DELAY(10);
+ if ((xs->flags & ITSDONE) != 0)
+ return 0;
if (sc->sc_state == ESP_IDLE) {
ESP_TRACE(("[esp_poll: rescheduling] "));
esp_sched(sc);
}
+ DELAY(1000);
count--;
}
-
- if (count == 0) {
- ESP_MISC(("esp_poll: timeout"));
- esp_timeout((caddr_t)ecb);
- }
-
- return COMPLETE;
+ return 1;
}
@@ -787,46 +891,62 @@ void
esp_sched(sc)
struct esp_softc *sc;
{
+ struct esp_ecb *ecb;
struct scsi_link *sc_link;
- struct ecb *ecb;
- int t;
-
+ struct esp_tinfo *ti;
+
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];
-
- if ((ecb->flags & ECB_QBITS) != ECB_QREADY)
- panic("esp: busy entry on ready list");
+ ti = &sc->sc_tinfo[sc_link->target];
+ if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
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);
+ esp_select(sc, ecb);
break;
} else
- ESP_MISC(("%d:%d busy\n", t, sc_link->lun));
+ ESP_MISC(("%d:%d busy\n",
+ sc_link->target, sc_link->lun));
+ }
+}
+
+void
+esp_sense(sc, ecb)
+ struct esp_softc *sc;
+ struct esp_ecb *ecb;
+{
+ struct scsi_xfer *xs = ecb->xs;
+ struct scsi_link *sc_link = xs->sc_link;
+ struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
+ struct scsi_sense *ss = (void *)&ecb->cmd;
+
+ ESP_MISC(("requesting sense "));
+ /* 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_SENSE;
+ ti->senses++;
+ if (ecb->flags & ECB_NEXUS)
+ ti->lubusy &= ~(1 << sc_link->lun);
+ if (ecb == sc->sc_nexus) {
+ esp_select(sc, ecb);
+ } else {
+ esp_dequeue(sc, ecb);
+ TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
+ if (sc->sc_state == ESP_IDLE)
+ esp_sched(sc);
}
}
@@ -834,57 +954,34 @@ esp_sched(sc)
* POST PROCESSING OF SCSI_CMD (usually current)
*/
void
-esp_done(ecb)
- struct ecb *ecb;
+esp_done(sc, ecb)
+ struct esp_softc *sc;
+ struct esp_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
+ * 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
+ * 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) {
+ if ((ecb->flags & ECB_ABORT) != 0) {
+ xs->error = XS_DRIVER_STUFFUP;
+ } else if ((ecb->flags & ECB_SENSE) != 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 */
- 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);
- }
+ esp_sense(sc, ecb);
return;
} else {
xs->resid = ecb->dleft;
@@ -895,52 +992,43 @@ esp_done(ecb)
#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->sense.error_code == 0x70)
- printf("extcode: %x; ", xs->sense.flags);
- }
- }
- 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);
+ if (xs->resid != 0)
+ printf("resid=%d ", xs->resid);
+ if (xs->error == XS_SENSE)
+ printf("sense=0x%02x\n", xs->sense.error_code);
+ else
+ printf("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);
- }
+ if (ecb->flags & ECB_NEXUS)
+ ti->lubusy &= ~(1 << sc_link->lun);
+ if (ecb == sc->sc_nexus) {
+ 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: busy ecb on free list", sc->sc_dev.dv_xname);
- break;
- }
-
- /* Put it on the free list, and clear flags. */
- TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
- ecb->flags = ECB_QFREE;
-
+ } else
+ esp_dequeue(sc, ecb);
+
+ esp_free_ecb(sc, ecb, xs->flags);
ti->cmds++;
scsi_done(xs);
- return;
+}
+
+void
+esp_dequeue(sc, ecb)
+ struct esp_softc *sc;
+ struct esp_ecb *ecb;
+{
+
+ if (ecb->flags & ECB_NEXUS) {
+ TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
+ } else {
+ TAILQ_REMOVE(&sc->ready_list, ecb, chain);
+ }
}
/*
@@ -953,12 +1041,83 @@ esp_done(ecb)
* 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); \
+ do { \
+ ESP_MISC(("esp_sched_msgout %d ", m)); \
+ ESPCMD(sc, ESPCMD_SETATN); \
+ sc->sc_flags |= ESP_ATN; \
+ sc->sc_msgpriq |= (m); \
} while (0)
+int
+esp_reselect(sc, message)
+ struct esp_softc *sc;
+ int message;
+{
+ u_char selid, target, lun;
+ struct esp_ecb *ecb;
+ struct scsi_link *sc_link;
+ struct esp_tinfo *ti;
+
+ /*
+ * The SCSI chip made a snapshot of the data bus while the reselection
+ * was being negotiated. This enables us to determine which target did
+ * the reselect.
+ */
+ selid = sc->sc_selid & ~(1 << sc->sc_id);
+ if (selid & (selid - 1)) {
+ printf("%s: reselect with invalid selid %02x; sending DEVICE RESET\n",
+ sc->sc_dev.dv_xname, selid);
+ goto reset;
+ }
+
+ /*
+ * 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.
+ */
+ target = ffs(selid) - 1;
+ lun = message & 0x07;
+ for (ecb = sc->nexus_list.tqh_first; ecb != NULL;
+ ecb = ecb->chain.tqe_next) {
+ sc_link = ecb->xs->sc_link;
+ if (sc_link->target == target && sc_link->lun == lun)
+ break;
+ }
+ if (ecb == NULL) {
+ printf("%s: reselect from target %d lun %d with no nexus; sending ABORT\n",
+ sc->sc_dev.dv_xname, target, lun);
+ goto abort;
+ }
+
+ /* Make this nexus active again. */
+ TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
+ sc->sc_state = ESP_CONNECTED;
+ sc->sc_nexus = ecb;
+ ti = &sc->sc_tinfo[target];
+ ti->lubusy |= (1 << lun);
+ esp_setsync(sc, ti);
+
+ if (ecb->flags & ECB_RESET)
+ esp_sched_msgout(SEND_DEV_RESET);
+ else if (ecb->flags & ECB_ABORT)
+ esp_sched_msgout(SEND_ABORT);
+
+ /* Do an implicit RESTORE POINTERS. */
+ sc->sc_dp = ecb->daddr;
+ sc->sc_dleft = ecb->dleft;
+
+ return (0);
+
+reset:
+ esp_sched_msgout(SEND_DEV_RESET);
+ return (1);
+
+abort:
+ esp_sched_msgout(SEND_ABORT);
+ return (1);
+}
+
#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
#define ISEXTMSG(m) ((m) == 1)
@@ -974,7 +1133,7 @@ esp_msgin(sc)
register struct esp_softc *sc;
{
register int v;
-
+
ESP_TRACE(("[esp_msgin(curmsglen:%d)] ", sc->sc_imlen));
if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) == 0) {
@@ -1003,7 +1162,6 @@ esp_msgin(sc)
* 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;
}
@@ -1017,7 +1175,6 @@ esp_msgin(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]);
@@ -1029,7 +1186,7 @@ esp_msgin(sc)
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
@@ -1055,209 +1212,159 @@ gotit:
* 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_state) {
+ struct esp_ecb *ecb;
+ struct scsi_link *sc_link;
+ struct esp_tinfo *ti;
+
+ case ESP_CONNECTED:
+ ecb = sc->sc_nexus;
+ 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_link = ecb->xs->sc_link;
+ printf("%s: %d extra bytes from %d:%d\n",
+ sc->sc_dev.dv_xname, -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;
+ sc->sc_state = ESP_CMDCOMPLETE;
break;
case MSG_MESSAGE_REJECT:
if (esp_debug & ESP_SHOWMSGS)
printf("%s: our msg rejected by target\n",
sc->sc_dev.dv_xname);
-#if 0 /* XXX - must remember last message */
-printf("<<target%d: MSG_MESSAGE_REJECT>>", ecb->xs->sc_link->target);
-ti->period = ti->offset = 0;
-sc->sc_flags &= ~ESP_SYNCHNEGO;
-ti->flags &= ~T_NEGOTIATE;
-#endif
- if (sc->sc_flags & ESP_SYNCHNEGO) {
- ti->period = ti->offset = 0;
+ switch (sc->sc_msgout) {
+ case SEND_SDTR:
sc->sc_flags &= ~ESP_SYNCHNEGO;
- ti->flags &= ~T_NEGOTIATE;
+ ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
+ esp_setsync(sc, ti);
+ break;
+ case SEND_INIT_DET_ERR:
+ goto abort;
}
- /* 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;
- break;
+ sc->sc_state = ESP_DISCONNECT;
+ 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;
+ ecb->dleft = sc->sc_dleft;
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("<<esp:target%d: MSG_PARITY_ERROR>>", 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]));
- /*XXX*/if (ti->flags & T_XXX) {
- printf("%s:%d: rejecting SDTR\n",
- "esp", ecb->xs->sc_link->target);
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- esp_sched_msgout(SEND_REJECT);
- break;
- }
+ if (sc->sc_imess[1] != 3)
+ goto reject;
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) {
+ ti->flags &= ~T_NEGOTIATE;
+ if (sc->sc_minsync == 0 ||
+ ti->offset == 0 ||
+ ti->period > 124) {
printf("%s:%d: async\n", "esp",
ecb->xs->sc_link->target);
- ti->offset = 0;
- esp_sched_msgout(SEND_SDTR);
+ if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
+ /* target initiated negotiation */
+ ti->offset = 0;
+ ti->flags &= ~T_SYNCMODE;
+ esp_sched_msgout(SEND_SDTR);
+ } else {
+ /* we are async */
+ ti->flags &= ~T_SYNCMODE;
+ }
} 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);
- if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
- /* Target initiated negotiation */
- sc->sc_flags |= ESP_SYNCHNEGO;
- if (ti->flags & T_SYNCMODE) {
- sc_print_addr(ecb->xs->sc_link);
#ifdef ESP_DEBUG
- printf("%s:%d: dropping out of sync mode\n");
+ sc_print_addr(ecb->xs->sc_link);
+ printf("max sync rate %d.%02dMb/s\n",
+ r, s);
#endif
- }
+ if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
+ /* target initiated negotiation */
+ if (ti->period < sc->sc_minsync)
+ ti->period = sc->sc_minsync;
+ if (ti->offset > 15)
+ ti->offset = 15;
ti->flags &= ~T_SYNCMODE;
- ESP_WRITE_REG(sc,
- ESP_SYNCOFF, 0);
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;
- sc_print_addr(ecb->xs->sc_link);
-#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);
+ sc->sc_flags &= ~ESP_SYNCHNEGO;
+ esp_setsync(sc, ti);
break;
+
+ default:
+ printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
+ sc->sc_dev.dv_xname);
+ goto reject;
}
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);
- }
+ printf("%s: unrecognized MESSAGE; sending REJECT\n",
+ sc->sc_dev.dv_xname);
+ reject:
+ esp_sched_msgout(SEND_REJECT);
break;
}
- } else if (sc->sc_state == ESP_RESELECTED) {
- struct scsi_link *sc_link;
- 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;
- }
- }
+ 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);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- esp_stp2cpb(sc, ti->period));
- 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);
+ case ESP_RESELECTED:
+ if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
+ printf("%s: reselect without IDENTIFY; sending DEVICE RESET\n",
+ sc->sc_dev.dv_xname);
+ goto reset;
}
- } else { /* Neither ESP_HASNEXUS nor ESP_RESELECTED! */
- printf("%s: unexpected message in; will send DEV_RESET\n",
+
+ (void) esp_reselect(sc, sc->sc_imess[0]);
+ break;
+
+ default:
+ printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
sc->sc_dev.dv_xname);
+ reset:
esp_sched_msgout(SEND_DEV_RESET);
+ break;
+
+ abort:
+ esp_sched_msgout(SEND_ABORT);
+ break;
}
/* Ack last message byte */
@@ -1277,18 +1384,37 @@ esp_msgout(sc)
register struct esp_softc *sc;
{
struct esp_tinfo *ti;
- struct ecb *ecb;
+ struct esp_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) {
+ if (sc->sc_flags & ESP_ATN) {
+ if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
+ new:
+ ESPCMD(sc, ESPCMD_FLUSH);
+ DELAY(1);
+ sc->sc_msgoutq = 0;
+ sc->sc_omlen = 0;
+ }
+ } else {
+ if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
+ esp_sched_msgout(sc->sc_msgoutq);
+ goto new;
+ } else {
+ printf("esp at line %d: unexpected MESSAGE OUT phase\n", __LINE__);
+ }
+ }
+
+ if (sc->sc_omlen == 0) {
/* Pick up highest priority message */
sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
+ sc->sc_msgoutq |= sc->sc_msgout;
+ sc->sc_msgpriq &= ~sc->sc_msgout;
sc->sc_omlen = 1; /* "Default" message len */
switch (sc->sc_msgout) {
case SEND_SDTR:
ecb = sc->sc_nexus;
- sc->sc_flags |= ESP_SYNCHNEGO;
ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
sc->sc_omess[0] = MSG_EXTENDED;
sc->sc_omess[1] = 3;
@@ -1296,17 +1422,21 @@ esp_msgout(sc)
sc->sc_omess[3] = ti->period;
sc->sc_omess[4] = ti->offset;
sc->sc_omlen = 5;
+ if ((sc->sc_flags & ESP_SYNCHNEGO) == 0) {
+ ti->flags |= T_SYNCMODE;
+ esp_setsync(sc, ti);
+ }
break;
case SEND_IDENTIFY:
- if (sc->sc_state != ESP_HASNEXUS) {
- printf("esp at line %d: no nexus", __LINE__);
+ if (sc->sc_state != ESP_CONNECTED) {
+ printf("esp at line %d: no nexus\n", __LINE__);
}
ecb = sc->sc_nexus;
sc->sc_omess[0] = MSG_IDENTIFY(ecb->xs->sc_link->lun,0);
break;
case SEND_DEV_RESET:
+ sc->sc_flags |= ESP_ABORTING;
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;
@@ -1316,8 +1446,8 @@ esp_msgout(sc)
sc->sc_omess[0] = MSG_PARITY_ERROR;
break;
case SEND_ABORT:
+ sc->sc_flags |= ESP_ABORTING;
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;
@@ -1326,6 +1456,8 @@ esp_msgout(sc)
sc->sc_omess[0] = MSG_MESSAGE_REJECT;
break;
default:
+ ESPCMD(sc, ESPCMD_RSTATN);
+ sc->sc_flags &= ~ESP_ATN;
sc->sc_omess[0] = MSG_NOOP;
break;
}
@@ -1334,16 +1466,24 @@ esp_msgout(sc)
#if 1
/* (re)send the message */
- DMA_START(sc->sc_dma, &sc->sc_omp, &sc->sc_omlen, 0);
+ 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, 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
+ sc->sc_omlen = 0;
}
#endif
}
@@ -1357,17 +1497,18 @@ printf("<<XXXmsgoutdoneXXX>>");
*
* Most of this needs verifying.
*/
-int
+int
espintr(sc)
register struct esp_softc *sc;
{
- register struct ecb *ecb;
+ register struct esp_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
@@ -1387,7 +1528,7 @@ espintr(sc)
* This is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
* at 40Mhz. This needs testing.
*/
- for (loop = 0; ; loop++, DELAY(50/sc->sc_freq)) {
+ for (loop = 0; 1;loop++, DELAY(50/sc->sc_freq)) {
/* a feeling of deja-vu */
if (!DMA_ISINTR(sc->sc_dma))
return (loop != 0);
@@ -1439,9 +1580,7 @@ espintr(sc)
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;
+ goto sched;
}
ecb = sc->sc_nexus;
@@ -1456,10 +1595,10 @@ espintr(sc)
ESPCMD(sc, ESPCMD_FLUSH);
DELAY(1);
}
- if (sc->sc_state == ESP_HASNEXUS ||
+ if (sc->sc_state == ESP_CONNECTED ||
sc->sc_state == ESP_SELECTING) {
ecb->xs->error = XS_DRIVER_STUFFUP;
- esp_done(ecb);
+ esp_done(sc, ecb);
}
return 1;
}
@@ -1486,14 +1625,30 @@ espintr(sc)
* again in case there is no more DMA queued, but a phase
* change is expected.
*/
- if (sc->sc_dma->sc_active && DMA_INTR(sc->sc_dma)) {
+ if (DMA_ISACTIVE(sc->sc_dma)) {
+ DMA_INTR(sc->sc_dma);
/* If DMA active here, then go back to work... */
- if (sc->sc_dma->sc_active)
+ if (DMA_ISACTIVE(sc->sc_dma))
return 1;
- if (!(sc->sc_espstat & ESPSTAT_TC))
- printf("%s: !TC\n", sc->sc_dev.dv_xname);
- continue;
+
+ 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
@@ -1503,12 +1658,13 @@ espintr(sc)
sc->sc_dev.dv_xname);
if (sc->sc_prevphase == MESSAGE_IN_PHASE)
esp_sched_msgout(SEND_PARITY_ERROR);
- else
+ else
esp_sched_msgout(SEND_INIT_DET_ERR);
}
if (sc->sc_espintr & ESPINTR_DIS) {
- ESP_MISC(("<DISC [intr %x, stat %x, step %d]>", sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
+ 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);
@@ -1518,38 +1674,59 @@ espintr(sc)
* 250mS of a disconnect. So here you are...
*/
ESPCMD(sc, ESPCMD_ENSEL);
- if (sc->sc_state != ESP_IDLE) {
+ switch (sc->sc_state) {
+ case ESP_RESELECTED:
+ goto sched;
+
+ case ESP_SELECTING:
+ ecb->xs->error = XS_SELTIMEOUT;
+ goto finish;
+
+ case ESP_CONNECTED:
if ((sc->sc_flags & ESP_SYNCHNEGO)) {
- printf("%s: sync nego not completed!\n",
- sc->sc_dev.dv_xname);
+#ifdef ESP_DEBUG
+ if (ecb)
+ sc_print_addr(ecb->xs->sc_link);
+ printf("sync nego not completed!\n");
+#endif
+ ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
+ sc->sc_flags &= ~ESP_SYNCHNEGO;
+ ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
}
- /*XXX*/sc->sc_msgpriq = sc->sc_msgout = 0;
/* it may be OK to disconnect */
- if (!(sc->sc_flags & ESP_BUSFREE_OK))
- 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;
- esp_sched(sc);
- return 1;
+ if ((sc->sc_flags & ESP_ABORTING) == 0) {
+ /*
+ * Section 5.1.1 of the SCSI 2 spec
+ * suggests issuing a REQUEST SENSE
+ * following an unexpected disconnect.
+ * Some devices go into a contingent
+ * allegiance condition when
+ * disconnecting, and this is necessary
+ * to clean up their state.
+ */
+ printf("%s: unexpected disconnect; ",
+ sc->sc_dev.dv_xname);
+ if (ecb->flags & ECB_SENSE) {
+ printf("resetting\n");
+ goto reset;
+ }
+ printf("sending REQUEST SENSE\n");
+ esp_sense(sc, ecb);
+ goto out;
}
- esp_done(ecb);
- return 1;
- }
- printf("DISCONNECT in IDLE state!\n");
- }
+ ecb->xs->error = XS_DRIVER_STUFFUP;
+ goto finish;
+
+ case ESP_DISCONNECT:
+ TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
+ sc->sc_nexus = NULL;
+ goto sched;
- /* 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 */
- sc->sc_msgpriq &= ~sc->sc_msgout;
- sc->sc_msgout = 0;
+ case ESP_CMDCOMPLETE:
+ goto finish;
+ }
}
switch (sc->sc_state) {
@@ -1572,7 +1749,7 @@ espintr(sc)
printf("<<RESELECT CONT'd>>");
#if XXXX
esp_msgin(sc);
- if (sc->sc_state != ESP_HASNEXUS) {
+ if (sc->sc_state != ESP_CONNECTED) {
/* IDENTIFY fail?! */
printf("%s: identify failed\n",
sc->sc_dev.dv_xname);
@@ -1585,6 +1762,8 @@ printf("<<RESELECT CONT'd>>");
case ESP_IDLE:
if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
case ESP_SELECTING:
+ sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
+ sc->sc_flags = 0;
if (sc->sc_espintr & ESPINTR_RESEL) {
/*
@@ -1598,8 +1777,6 @@ if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
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;
@@ -1608,19 +1785,23 @@ if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
* Things are seriously fucked up.
* Pull the brakes, i.e. reset
*/
- printf("%s: target didn't identify\n",
+ 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("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF);
+ 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) {
+ if (sc->sc_state != ESP_CONNECTED) {
/* IDENTIFY fail?! */
printf("%s: identify failed\n",
sc->sc_dev.dv_xname);
@@ -1643,25 +1824,24 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
case 0:
printf("%s: select timeout/no disconnect\n",
sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
+ ecb->xs->error = XS_SELTIMEOUT;
+ goto finish;
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;
+ goto reset;
}
if (sc->sc_phase != MESSAGE_OUT_PHASE) {
printf("%s: !MSGOUT\n",
sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
+ goto reset;
}
/* Start negotiating */
ti->period = sc->sc_minsync;
ti->offset = 15;
- sc->sc_msgpriq = SEND_SDTR;
+ sc->sc_flags |= ESP_SYNCHNEGO;
+ esp_sched_msgout(SEND_SDTR);
break;
case 3:
/*
@@ -1686,7 +1866,7 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
sc->sc_espintr, sc->sc_espstat,
sc->sc_espstep);
- sc->sc_flags |= ESP_ABORTING;
+ ESPCMD(sc, ESPCMD_FLUSH);
esp_sched_msgout(SEND_ABORT);
return 1;
case 2:
@@ -1694,25 +1874,31 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
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;
+ esp_sched_msgout(SEND_DEV_RESET);
else if (ti->flags & T_NEGOTIATE)
- sc->sc_msgpriq =
- SEND_IDENTIFY | SEND_SDTR;
+ esp_sched_msgout(
+ SEND_IDENTIFY | SEND_SDTR);
else
- sc->sc_msgpriq = SEND_IDENTIFY;
+ esp_sched_msgout(SEND_IDENTIFY);
#endif
- sc->sc_state = ESP_HASNEXUS;
- /*???sc->sc_flags = 0; */
+
+ ecb->flags |= ECB_NEXUS;
+ ti->lubusy |= (1 << sc_link->lun);
+
sc->sc_prevphase = INVALID_PHASE; /* ?? */
+ /* Do an implicit RESTORE POINTERS. */
sc->sc_dp = ecb->daddr;
sc->sc_dleft = ecb->dleft;
- ti->lubusy |= (1<<sc_link->lun);
+
+ /* On our first connection, schedule a timeout. */
+ if ((ecb->xs->flags & SCSI_POLL) == 0)
+ timeout(esp_timeout, ecb, (ecb->timeout * hz) / 1000);
+
+ sc->sc_state = ESP_CONNECTED;
break;
} else {
printf("%s: unexpected status after select"
@@ -1722,7 +1908,7 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
sc->sc_espstep);
ESPCMD(sc, ESPCMD_FLUSH);
DELAY(1);
- esp_abort(sc, ecb);
+ goto reset;
}
if (sc->sc_state == ESP_IDLE) {
printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
@@ -1730,9 +1916,9 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
}
break;
- case ESP_HASNEXUS:
+ case ESP_CONNECTED:
if (sc->sc_flags & ESP_ICCS) {
- unsigned char msg;
+ u_char msg;
sc->sc_flags &= ~ESP_ICCS;
@@ -1744,22 +1930,16 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
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;
+ int i = (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) - 2;
+ while (i--)
+ (void) ESP_READ_REG(sc, ESP_FIFO);
}
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;
+ sc->sc_state = ESP_CMDCOMPLETE;
} else
printf("%s: STATUS_PHASE: msg %d\n",
sc->sc_dev.dv_xname, msg);
@@ -1774,10 +1954,10 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
}
/*
- * Driver is now in state ESP_HASNEXUS, i.e. we
+ * Driver is now in state ESP_CONNECTED, i.e. we
* have a current command working the SCSI bus.
*/
- if (sc->sc_state != ESP_HASNEXUS || ecb == NULL) {
+ if (sc->sc_state != ESP_CONNECTED || ecb == NULL) {
panic("esp no nexus");
}
@@ -1833,31 +2013,39 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
case DATA_OUT_PHASE:
ESP_PHASE(("DATA_OUT_PHASE [%d] ", sc->sc_dleft));
ESPCMD(sc, ESPCMD_FLUSH);
- DMA_START(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft, 0);
+ 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;
- return 1;
+ goto setup_xfer;
case DATA_IN_PHASE:
ESP_PHASE(("DATA_IN_PHASE "));
if (sc->sc_rev == ESP100)
ESPCMD(sc, ESPCMD_FLUSH);
-#if 0 /* Why is the fifo sometimes full after re-connect? */
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- static int xxx;
- if (xxx <= 3) {
- printf("%s: lost %d bytes from FIFO ",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF);
- printf(" previous phase %x\n",
- sc->sc_prevphase);
- if (xxx == 3)
- printf("(stopped logging)");
- ++xxx;
- }
- }
-#endif
- DMA_DRAIN(sc->sc_dma);
- DMA_START(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft, 1);
+ 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 "));
@@ -1867,31 +2055,52 @@ printf("<RESELECT: %d bytes in FIFO>", ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF)
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");
+ printf("%s: unexpected bus phase; resetting\n",
+ sc->sc_dev.dv_xname);
+ goto reset;
}
}
panic("esp: should not get here..");
+
+reset:
+ esp_init(sc, 1);
+ return 1;
+
+finish:
+ untimeout(esp_timeout, ecb);
+ esp_done(sc, ecb);
+ goto out;
+
+sched:
+ sc->sc_state = ESP_IDLE;
+ esp_sched(sc);
+ goto out;
+
+out:
+ return 1;
}
void
esp_abort(sc, ecb)
struct esp_softc *sc;
- struct ecb *ecb;
+ struct esp_ecb *ecb;
{
+
+ /* 2 secs for the abort */
+ ecb->timeout = ESP_ABORT_TIMEOUT;
+ ecb->flags |= ECB_ABORT;
+
if (ecb == sc->sc_nexus) {
-/*XXX*/sc->sc_tinfo[ecb->xs->sc_link->target].flags |= T_XXX;
- if (sc->sc_state == ESP_HASNEXUS) {
- sc->sc_flags |= ESP_ABORTING;
+ /*
+ * If we're still selecting, the message will be scheduled
+ * after selection is complete.
+ */
+ if (sc->sc_state == ESP_CONNECTED)
esp_sched_msgout(SEND_ABORT);
- }
} else {
+ esp_dequeue(sc, ecb);
+ TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
if (sc->sc_state == ESP_IDLE)
esp_sched(sc);
}
@@ -1901,58 +2110,36 @@ void
esp_timeout(arg)
void *arg;
{
- int s = splbio();
- struct ecb *ecb = (struct ecb *)arg;
- struct esp_softc *sc;
+ struct esp_ecb *ecb = arg;
struct scsi_xfer *xs = ecb->xs;
+ struct scsi_link *sc_link = xs->sc_link;
+ struct esp_softc *sc = sc_link->adapter_softc;
+ int s;
+
+ sc_print_addr(sc_link);
+ 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
- sc = xs->sc_link->adapter_softc;
- sc_print_addr(xs->sc_link);
-again:
- printf("timed out (ecb 0x%x (flags 0x%x, dleft %x), state %d, phase %d, msgpriq %x, msgout %x)",
- ecb, ecb->flags, ecb->dleft, sc->sc_state, sc->sc_phase,
- sc->sc_msgpriq, sc->sc_msgout);
+ s = splbio();
- if (ecb->flags == ECB_QFREE) {
- printf("note: ecb already on free list\n");
- splx(s);
- return;
- }
- if (ecb->flags & ECB_ABORTED) {
+ if (ecb->flags & ECB_ABORT) {
/* abort timed out */
printf(" AGAIN\n");
- xs->retries = 0;
esp_init(sc, 1);
} else {
/* abort the operation that has timed out */
printf("\n");
xs->error = XS_TIMEOUT;
- ecb->flags |= ECB_ABORTED;
-#if 0
-if (sc->sc_dma->sc_active) {
- int x = esp_debug; esp_debug=0x3ff;
- DMA_INTR(sc->sc_dma);
- esp_debug = x;
-}
-#endif
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);
}
diff --git a/sys/arch/alpha/tc/espreg.h b/sys/arch/alpha/tc/espreg.h
index d6602261f90..8492f1d5378 100644
--- a/sys/arch/alpha/tc/espreg.h
+++ b/sys/arch/alpha/tc/espreg.h
@@ -1,9 +1,8 @@
-/* $OpenBSD: espreg.h,v 1.3 1996/07/29 23:02:02 niklas Exp $ */
-/* $NetBSD: espreg.h,v 1.2 1995/12/20 00:40:25 cgd Exp $ */
+/* $OpenBSD: espreg.h,v 1.4 1996/10/30 22:41:06 niklas Exp $ */
+/* $NetBSD: espreg.h,v 1.3 1996/09/09 18:10:37 cgd 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:
@@ -132,10 +131,8 @@
#define ESP_TEST 0x0a /* WO - Test (Chip Test Only) */
#define ESP_CFG2 0x0b /* RW - Configuration #2 */
-#if 0
-#define ESPCFG2_RSVD 0xa0 /* reserved */
+#define ESPCFG2_RSVD 0xa0 /* reserved */
#define ESPCFG2_FE 0x40 /* Features Enable */
-#endif
#define ESPCFG2_DREQ 0x10 /* DREQ High Impedance */
#define ESPCFG2_SCSI2 0x08 /* SCSI-2 Enable */
#define ESPCFG2_BPA 0x04 /* Target Bad Parity Abort */
@@ -144,11 +141,9 @@
/* Config #3 only on 53C9X */
#define ESP_CFG3 0x0c /* RW - Configuration #3 */
-#if 0
#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) */
-#endif
diff --git a/sys/arch/alpha/tc/espvar.h b/sys/arch/alpha/tc/espvar.h
index 0564fcbdc1e..c21eb0d92c9 100644
--- a/sys/arch/alpha/tc/espvar.h
+++ b/sys/arch/alpha/tc/espvar.h
@@ -1,5 +1,9 @@
-/* $OpenBSD: espvar.h,v 1.4 1996/10/18 16:12:03 niklas Exp $ */
-/* $NetBSD: espvar.h,v 1.3 1995/12/20 00:40:26 cgd Exp $ */
+/* $OpenBSD: espvar.h,v 1.5 1996/10/30 22:41:07 niklas Exp $ */
+/* $NetBSD: espvar.h,v 1.10 1996/10/15 21:31:37 mycroft Exp $ */
+
+#if defined(__sparc__) && !defined(SPARC_DRIVER)
+#define SPARC_DRIVER
+#endif
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -30,7 +34,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define ESP_DEBUG 0
+#define ESP_DEBUG 0
+
+#define ESP_ABORT_TIMEOUT 2000 /* time to wait for abort */
#define FREQTOCCF(freq) (((freq + 4) / 5))
@@ -40,7 +46,7 @@
#define ESP200 0x03
#define NCR53C94 0x04
-/*
+/*
* 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
@@ -48,28 +54,41 @@
* We'll generally update: xs->{flags,resid,error,sense,status} and
* occasionally xs->retries.
*/
-struct ecb {
- TAILQ_ENTRY(ecb) chain;
+struct esp_ecb {
+ TAILQ_ENTRY(esp_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)
+ int flags;
+#define ECB_ALLOC 0x01
+#define ECB_NEXUS 0x02
+#define ECB_SENSE 0x04
+#define ECB_ABORT 0x40
+#define ECB_RESET 0x80
+ int timeout;
+
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
+/*
+ * 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 {
@@ -84,8 +103,8 @@ struct esp_tinfo {
#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_XXX 0x10 /* Target is XXX */
-#define T_SYNCHNEGO 0x20 /* .. */
+#define T_SYNCHOFF 0x10 /* .. */
+#define T_RSELECTOFF 0x20 /* .. */
u_char period; /* Period suggestion */
u_char offset; /* Offset suggestion */
} tinfo_t;
@@ -106,15 +125,15 @@ struct esp_tinfo {
#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)
+#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)
@@ -160,12 +179,12 @@ struct esp_softc {
u_char sc_espfflags;
/* Lists of command blocks */
- TAILQ_HEAD(ecb_list, ecb) free_list,
- ready_list,
- nexus_list;
+ TAILQ_HEAD(ecb_list, esp_ecb) free_list,
+ ready_list,
+ nexus_list;
- struct ecb *sc_nexus; /* current command */
- struct ecb sc_ecb[8]; /* one per target */
+ struct esp_ecb *sc_nexus; /* current command */
+ struct esp_ecb sc_ecb[16]; /* one per target */
struct esp_tinfo sc_tinfo[8];
/* Data about the current nexus (updated for every cmd switch) */
@@ -183,6 +202,7 @@ struct esp_softc {
/* 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_msgoutq; /* What messages have been sent so far? */
u_char sc_omess[ESP_MAX_MSG_LEN];
caddr_t sc_omp; /* Message pointer (for multibyte messages) */
size_t sc_omlen;
@@ -199,48 +219,39 @@ struct esp_softc {
int sc_id; /* our scsi id */
int sc_rev; /* esp revision */
int sc_minsync; /* minimum sync period / 4 */
+ int sc_maxxfer; /* maximum transfer size */
};
/* 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 */
+#define ESP_IDLE 1 /* waiting for something to do */
+#define ESP_SELECTING 2 /* SCSI command is arbiting */
+#define ESP_RESELECTED 3 /* Has been reselected */
+#define ESP_CONNECTED 4 /* Actively using the SCSI bus */
+#define ESP_DISCONNECT 5 /* MSG_DISCONNECT received */
+#define ESP_CMDCOMPLETE 6 /* MSG_CMDCOMPLETE received */
+#define ESP_CLEANING 7
+#define ESP_SBR 8 /* 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_ABORTING 0x02 /* Bailing out */
+#define ESP_DOINGDMA 0x04 /* The FIFO data path is active! */
#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 */
+#define ESP_ICCS 0x10 /* Expect status phase results */
+#define ESP_WAITI 0x20 /* Waiting for non-DMA data to arrive */
+#define ESP_ATN 0x40 /* ATN asserted */
/* values for sc_msgout */
#define SEND_DEV_RESET 0x01
#define SEND_PARITY_ERROR 0x02
-#define SEND_ABORT 0x04
+#define SEND_INIT_DET_ERR 0x04
#define SEND_REJECT 0x08
-#define SEND_INIT_DET_ERR 0x10
-#define SEND_IDENTIFY 0x20
+#define SEND_IDENTIFY 0x10
+#define SEND_ABORT 0x20
#define SEND_SDTR 0x40
+#define SEND_WDTR 0x80
/* 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 */
@@ -263,8 +274,21 @@ struct esp_softc {
#define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
#define PSEUDO_PHASE 0x100 /* "pseudo" bit */
+/*
+ * Macros to read and write the chip's registers.
+ */
+#ifdef SPARC_DRIVER
+#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)
+#else /* ! SPARC_DRIVER */
#if 1
static __inline u_char ESP_READ_REG __P((struct esp_softc *, int));
+
static __inline u_char
ESP_READ_REG(sc, reg)
struct esp_softc *sc;
@@ -273,7 +297,7 @@ ESP_READ_REG(sc, reg)
u_char v;
v = sc->sc_reg[reg * 2] & 0xff;
- wbflush();
+ alpha_mb();
return v;
}
#else
@@ -284,8 +308,9 @@ ESP_READ_REG(sc, reg)
do { \
u_char v = (val); \
(sc)->sc_reg[(reg) * 2] = v; \
- wbflush(); \
+ alpha_mb(); \
} while (0)
+#endif /* SPARC_DRIVER */
#ifdef ESP_DEBUG
#define ESPCMD(sc, cmd) do { \
@@ -302,24 +327,13 @@ ESP_READ_REG(sc, reg)
((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
(bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
+#ifndef SPARC_DRIVER
/* DMA macros for ESP */
-#ifdef SPARC_DRIVER
-#define DMA_ENINTR(r) ((r->enintr)(r))
-#define DMA_ISINTR(r) ((r->isintr)(r))
-#define DMA_RESET(r) ((r->reset)(r))
-#define DMA_START(a, b, c, d) ((a->start)(a, b, c, d))
-#define DMA_INTR(r) ((r->intr)(r))
-#define DMA_DRAIN(sc) if (sc->sc_rev < DMAREV_2) { \
- DMACSR(sc) |= D_DRAIN; \
- DMAWAIT1(sc); \
- }
-#else
-int tcds_dma_intr __P((struct tcds_slotconfig *));
-
-#define DMA_ENINTR(r) tcds_dma_enintr(r)
-#define DMA_ISINTR(r) tcds_dma_isintr(r)
-#define DMA_RESET(r) tcds_dma_reset(r)
-#define DMA_START(a, b, c, d) tcds_dma_start(a, b, c, d)
-#define DMA_INTR(r) tcds_dma_intr(r)
-#define DMA_DRAIN(sc)
+#define DMA_ISINTR(sc) tcds_dma_isintr(sc)
+#define DMA_RESET(sc) tcds_dma_reset(sc)
+#define DMA_INTR(sc) tcds_dma_intr(sc)
+#define DMA_SETUP(sc, addr, len, datain, dmasize) \
+ tcds_dma_setup(sc, addr, len, datain, dmasize)
+#define DMA_GO(sc) tcds_dma_go(sc)
+#define DMA_ISACTIVE(sc) tcds_dma_isactive(sc)
#endif
diff --git a/sys/arch/alpha/tc/ioasic.c b/sys/arch/alpha/tc/ioasic.c
index b6e09102e31..37e6d1bf17d 100644
--- a/sys/arch/alpha/tc/ioasic.c
+++ b/sys/arch/alpha/tc/ioasic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ioasic.c,v 1.3 1996/07/29 23:02:06 niklas Exp $ */
-/* $NetBSD: ioasic.c,v 1.4.4.1 1996/06/05 00:39:05 cgd Exp $ */
+/* $OpenBSD: ioasic.c,v 1.4 1996/10/30 22:41:08 niklas Exp $ */
+/* $NetBSD: ioasic.c,v 1.9 1996/10/13 03:00:32 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -54,7 +54,7 @@ struct ioasic_softc {
/* Definition of the driver for autoconfig. */
int ioasicmatch __P((struct device *, void *, void *));
void ioasicattach __P((struct device *, struct device *, void *));
-int ioasicprint(void *, char *);
+int ioasicprint(void *, /* const */ char *);
struct cfattach ioasic_ca = {
sizeof(struct ioasic_softc), ioasicmatch, ioasicattach,
@@ -190,7 +190,7 @@ ioasicattach(parent, self, aux)
int
ioasicprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
struct ioasicdev_attach_args *d = aux;
@@ -288,10 +288,10 @@ ioasic_intr(val)
void *val;
{
register struct ioasic_softc *sc = val;
- register int i, ifound;
+ register int ifound;
int gifound;
- u_int32_t sir, junk;
- volatile u_int32_t *sirp, *junkp;
+ u_int32_t sir;
+ volatile u_int32_t *sirp;
sirp = (volatile u_int32_t *)IOASIC_REG_INTR(sc->sc_base);
diff --git a/sys/arch/alpha/tc/ioasicreg.h b/sys/arch/alpha/tc/ioasicreg.h
index 370c0d47d14..2c09ef47776 100644
--- a/sys/arch/alpha/tc/ioasicreg.h
+++ b/sys/arch/alpha/tc/ioasicreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ioasicreg.h,v 1.2 1996/07/29 23:02:07 niklas Exp $ */
+/* $OpenBSD: ioasicreg.h,v 1.3 1996/10/30 22:41:09 niklas Exp $ */
/* $NetBSD: ioasicreg.h,v 1.1 1995/12/20 00:43:22 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/mcclock_ioasic.c b/sys/arch/alpha/tc/mcclock_ioasic.c
index 6a01a25b5ee..235fff4e901 100644
--- a/sys/arch/alpha/tc/mcclock_ioasic.c
+++ b/sys/arch/alpha/tc/mcclock_ioasic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mcclock_ioasic.c,v 1.2 1996/07/29 23:02:09 niklas Exp $ */
+/* $OpenBSD: mcclock_ioasic.c,v 1.3 1996/10/30 22:41:10 niklas Exp $ */
/* $NetBSD: mcclock_ioasic.c,v 1.2 1996/04/17 22:22:58 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/scc.c b/sys/arch/alpha/tc/scc.c
index eeae075cba2..bfa713ad8d0 100644
--- a/sys/arch/alpha/tc/scc.c
+++ b/sys/arch/alpha/tc/scc.c
@@ -1,27 +1,27 @@
-/* $OpenBSD: scc.c,v 1.5 1996/07/29 23:02:11 niklas Exp $ */
-/* $NetBSD: scc.c,v 1.16.4.2 1996/06/03 19:44:41 cgd Exp $ */
+/* $OpenBSD: scc.c,v 1.6 1996/10/30 22:41:11 niklas Exp $ */
+/* $NetBSD: scc.c,v 1.26 1996/10/16 05:07:57 jonathan Exp $ */
-/*
+/*
* Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
@@ -101,6 +101,7 @@
#include <pmax/dev/fbreg.h>
#endif
+#include <machine/autoconf.h> /* For the badaddr() proto */
#include <machine/rpb.h>
#include <dev/tc/tcvar.h>
@@ -112,14 +113,24 @@ extern void ttrstrt __P((void *));
#undef SCCDEV
#define SCCDEV 15 /* XXX */
-#define NSCCLINE (NSCC*2)
+/*
+ * rcons glass-tty console (as used on pmax) needs lk-201 ASCII input
+ * support from the tty drivers. This is ugly and broken and won't
+ * compile on Alphas.
+ */
+#ifdef pmax
+#define HAVE_RCONS
+extern int pending_remcons;
+#endif
+
+#define NSCCLINE (NSCC*2)
#define SCCUNIT(dev) (minor(dev) >> 1)
#define SCCLINE(dev) (minor(dev) & 0x1)
-struct tty *scc_tty[NSCCLINE];
-void (*sccDivertXInput)(); /* X windows keyboard input routine */
-void (*sccMouseEvent)(); /* X windows mouse motion event routine */
-void (*sccMouseButtons)(); /* X windows mouse buttons event routine */
+/* QVSS-compatible in-kernel X input event parser, pointer tracker */
+void (*sccDivertXInput) __P((int cc)); /* X windows keyboard input routine */
+void (*sccMouseEvent) __P((int)); /* X windows mouse motion event routine */
+void (*sccMouseButtons) __P((int)); /* X windows mouse buttons event routine */
#ifdef DEBUG
int debugChar;
#endif
@@ -134,13 +145,21 @@ struct scc_softc {
u_char wr5;
u_char wr14;
} scc_wreg[2];
+ struct tty *scc_tty[2];
int scc_softCAR;
+
+ int scc_flags[2];
+#define SCC_CHAN_NEEDSDELAY 0x01 /* sw must delay 1.6us between output*/
+#define SCC_CHAN_NOMODEM 0x02 /* don't touch modem ctl lines (may
+ be left floating or x-wired */
+#define SCC_CHAN_MODEM_CROSSED 0x04 /* modem lines wired to other channel*/
+#define SCC_CHAN_KBDLINE 0x08 /* XXX special-case keyboard lines */
};
/*
* BRG formula is:
* ClockFrequency
- * BRGconstant = --------------------------- - 2
+ * BRGconstant = --------------------------- - 2
* 2 * BaudRate * ClockDivider
*
* Speed selections with Pclk=7.3728Mhz, clock x16
@@ -159,9 +178,13 @@ struct speedtab sccspeedtab[] = {
{ 1800, 126, },
{ 2400, 94, },
{ 4800, 46, },
+ { 7200, 30, }, /* non-POSIX */
{ 9600, 22, },
+ { 14400, 14, }, /* non-POSIX */
{ 19200, 10, },
- { 38400, 4, },
+ { 28800, 6, }, /* non-POSIX */
+ { 38400, 4, }, /* non-POSIX */
+ { 57600, 2, }, /* non-POSIX */
{ -1, -1, },
};
@@ -174,9 +197,10 @@ struct speedtab sccspeedtab[] = {
#endif
/* Definition of the driver for autoconfig. */
-static int sccmatch(struct device *, void *, void *);
-static void sccattach(struct device *, struct device *, void *);
-
+static int sccmatch __P((struct device * parent, void *cfdata,
+ void *aux));
+static void sccattach __P((struct device *parent, struct device *self,
+ void *aux));
struct cfattach scc_ca = {
sizeof (struct scc_softc), sccmatch, sccattach,
};
@@ -185,12 +209,21 @@ struct cfdriver scc_cd = {
NULL, "scc", DV_TTY,
};
+int sccopen __P((dev_t, int, int, struct proc *));
+int sccclose __P((dev_t, int, int, struct proc *));
+int sccread __P((dev_t, struct uio *, int));
+int sccwrite __P((dev_t, struct uio *, int));
+struct tty *scctty __P((dev_t));
+int sccioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+void sccstop __P((struct tty *, int));
int sccGetc __P((dev_t));
void sccPutc __P((dev_t, int));
void sccPollc __P((dev_t, int));
int sccparam __P((struct tty *, struct termios *));
void sccstart __P((struct tty *));
int sccmctl __P((dev_t, int, int));
+static int cold_sccparam __P((struct tty *, struct termios *,
+ struct scc_softc *sc));
#ifdef SCC_DEBUG
static void rr __P((char *, scc_regmap_t *));
@@ -201,9 +234,97 @@ static void sccreset __P((struct scc_softc *));
int sccintr __P((void *));
void scc_alphaintr __P((int));
+
+/*
+ * console variables, for using serial console while still cold and
+ * autoconfig has not attached the scc device.
+ */
+extern int cold;
+scc_regmap_t *scc_cons_addr = 0;
+static struct scc_softc coldcons_softc;
+static struct consdev scccons = {
+ NULL, NULL, sccGetc, sccPutc, sccPollc, NODEV, 0
+};
+void scc_consinit __P((dev_t dev, scc_regmap_t *sccaddr));
+void scc_oconsinit __P((struct scc_softc *, dev_t));
+
+
+/*
+ * Set up a given unit as a serial console device.
+ * We need console output when cold, and before any device is configured.
+ * Should be callable when cold, to reset the chip and set parameters
+ * for a remote (serial) console or kgdb line.
+ * XXX
+ * As most DECstations only bring out one rs-232 lead from an SCC
+ * to the bulkhead, and use the other for mouse and keyboard, we
+ * only allow one unit per SCC to be console.
+ */
+void
+scc_consinit(dev, sccaddr)
+ dev_t dev;
+ scc_regmap_t *sccaddr;
+{
+ struct scc_softc *sc;
+ struct termios cterm;
+ struct tty ctty;
+ int s;
+
+ /* Save address in case we're cold. */
+ if (cold && scc_cons_addr == 0) {
+ scc_cons_addr = sccaddr;
+ sc = &coldcons_softc;
+ coldcons_softc.scc_pdma[0].p_addr = sccaddr;
+ coldcons_softc.scc_pdma[1].p_addr = sccaddr;
+ } else {
+ /* being called from sccattach() to reset console */
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ }
+
+ /* Reset chip. */
+ sccreset(sc);
+ /* XXX make sure sccreset() called only once for this chip? */
+
+ /* set console-line parameters */
+ s = spltty();
+ ctty.t_dev = dev;
+ scccons.cn_dev = dev;
+ cterm.c_cflag = CS8;
+#ifdef pmax
+ /* XXX -- why on pmax, not on Alpha? */
+ cterm.c_cflag |= CLOCAL;
+#endif
+ cterm.c_ospeed = cterm.c_ispeed = 9600;
+ (void) cold_sccparam(&ctty, &cterm, sc);
+ *cn_tab = scccons;
+ DELAY(1000);
+ splx(s);
+}
+
+void
+scc_oconsinit(sc, dev)
+ struct scc_softc *sc;
+ dev_t dev;
+{
+ struct termios cterm;
+ struct tty ctty;
+ int s;
+
+ s = spltty();
+ ctty.t_dev = dev;
+ cterm.c_cflag = CS8;
+#ifdef pmax
+ /* XXX -- why on pmax, not on Alpha? */
+ cterm.c_cflag |= CLOCAL;
+#endif
+ cterm.c_ospeed = cterm.c_ispeed = 9600;
+ (void) sccparam(&ctty, &cterm);
+ DELAY(1000);
+ splx(s);
+}
+
/*
* Test to see if device is present.
- * Return true if found and initialized ok.
+ * Return true if found.
*/
int
sccmatch(parent, cfdata, aux)
@@ -215,10 +336,16 @@ sccmatch(parent, cfdata, aux)
struct ioasicdev_attach_args *d = aux;
void *sccaddr;
- /* XXX BUS TYPE? */
+ if (parent->dv_cfdata->cf_driver != &ioasic_cd) {
+#ifdef DIAGNOSTIC
+ printf("Cannot attach scc on %s\n", parent->dv_xname);
+#endif
+ return (0);
+ }
/* Make sure that we're looking for this type of device. */
- if (strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN))
+ if ((strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN) != 0) &&
+ (strncmp(d->iada_modname, "scc", TC_ROM_LLEN)!= 0))
return (0);
/* XXX MATCH CFLOC */
@@ -236,6 +363,11 @@ sccmatch(parent, cfdata, aux)
return (1);
}
+#ifdef alpha
+/*
+ * Enable ioasic SCC interrupts and scc DMA engine interrupts.
+ * XXX does not really belong here.
+ */
void
scc_alphaintr(onoff)
int onoff;
@@ -257,14 +389,15 @@ scc_alphaintr(onoff)
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2);
#endif
}
- wbflush();
+ tc_mb();
}
+#endif /* alpha */
void
sccattach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
+ struct device *parent;
+ struct device *self;
+ void *aux;
{
struct scc_softc *sc = (struct scc_softc *)self;
struct ioasicdev_attach_args *d = aux;
@@ -272,9 +405,9 @@ sccattach(parent, self, aux)
struct tty *tp;
void *sccaddr;
int cntr;
- struct termios cterm;
- struct tty ctty;
- int s;
+ struct termios cterm;
+ struct tty ctty;
+ int s;
extern int cputype;
/* Get the address, and check it for validity. */
@@ -285,7 +418,7 @@ sccattach(parent, self, aux)
/* Register the interrupt handler. */
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY,
- sccintr, (void *)(long)sc->sc_dv.dv_unit);
+ sccintr, (void *)sc);
/*
* For a remote console, wait a while for previous output to
@@ -305,68 +438,73 @@ sccattach(parent, self, aux)
/* init pseudo DMA structures */
for (cntr = 0; cntr < 2; cntr++) {
pdp->p_addr = (void *)sccaddr;
- tp = scc_tty[sc->sc_dv.dv_unit * 2 + cntr] = ttymalloc();
+ tp = sc->scc_tty[cntr] = ttymalloc();
if (cntr == 0)
tty_attach(tp);
pdp->p_arg = (long)tp;
- pdp->p_fcn = (void (*)())0;
+ pdp->p_fcn = (void (*)__P((struct tty*)))0;
tp->t_dev = (dev_t)((sc->sc_dv.dv_unit << 1) | cntr);
pdp++;
}
+ /* What's the warning here? Defaulting to softCAR on line 2? */
sc->scc_softCAR = 0x2; /* XXX */
- /* reset chip */
+ /* reset chip, initialize register-copies in softc */
sccreset(sc);
- /*
- * Special handling for consoles.
- */
- if (0 /* cn_tab.cn_screen */) {
- if (1 /* cn_tab.cn_kbdgetc == sccGetc */) {
- if (sc->sc_dv.dv_unit == 1) {
- s = spltty();
- ctty.t_dev = makedev(SCCDEV, SCCKBD_PORT);
- cterm.c_cflag = CS8;
- cterm.c_ospeed = cterm.c_ispeed = 4800;
- (void) sccparam(&ctty, &cterm);
- DELAY(10000);
+ /*
+ * Special handling for consoles.
+ */
+ if (0 /* cn_tab.cn_screen */) {
+ if (1 /* cn_tab.cn_kbdgetc == sccGetc */) {
+ if (sc->sc_dv.dv_unit == 1) {
+ s = spltty();
+ ctty.t_dev = makedev(SCCDEV, SCCKBD_PORT);
+ cterm.c_cflag = CS8;
+#ifdef pmax
+ /* XXX -- why on pmax, not on Alpha? */
+ cterm.c_cflag |= CLOCAL;
+#endif /* pmax */
+ cterm.c_ospeed = cterm.c_ispeed = 4800;
+ (void) sccparam(&ctty, &cterm);
+ DELAY(10000);
#ifdef notyet
- /*
- * For some reason doing this hangs the 3min
- * during booting. Fortunately the keyboard
- * works ok without it.
- */
- KBDReset(ctty.t_dev, sccPutc);
+ /*
+ * For some reason doing this hangs the 3min
+ * during booting. Fortunately the keyboard
+ * works ok without it.
+ */
+ KBDReset(ctty.t_dev, sccPutc);
#endif
- DELAY(10000);
- splx(s);
- } else if (sc->sc_dv.dv_unit == 0) {
- s = spltty();
- ctty.t_dev = makedev(SCCDEV, SCCMOUSE_PORT);
- cterm.c_cflag = CS8 | PARENB | PARODD;
- cterm.c_ospeed = cterm.c_ispeed = 4800;
- (void) sccparam(&ctty, &cterm);
+ DELAY(10000);
+ splx(s);
+ } else if (sc->sc_dv.dv_unit == 0) {
+ s = spltty();
+ ctty.t_dev = makedev(SCCDEV, SCCMOUSE_PORT);
+ cterm.c_cflag = CS8 | PARENB | PARODD;
+ cterm.c_ospeed = cterm.c_ispeed = 4800;
+ (void) sccparam(&ctty, &cterm);
#ifdef TK_NOTYET
- DELAY(10000);
- MouseInit(ctty.t_dev, sccPutc, sccGetc);
- DELAY(10000);
+ DELAY(10000);
+ MouseInit(ctty.t_dev, sccPutc, sccGetc);
+ DELAY(10000);
#endif
- splx(s);
- }
- }
- } else if (1 /* SCCUNIT(cn_tab.cn_dev) == sc->sc_dv.dv_unit */) {
- s = spltty();
- ctty.t_dev = makedev(SCCDEV,
- sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
- cterm.c_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8;
- cterm.c_ospeed = cterm.c_ispeed = 9600;
- (void) sccparam(&ctty, &cterm);
- DELAY(1000);
+ splx(s);
+ }
+ }
+ } else if (1 /* SCCUNIT(cn_tab.cn_dev) == sc->sc_dv.dv_unit */) {
+ s = spltty();
+ ctty.t_dev = makedev(SCCDEV,
+ sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
+ cterm.c_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8;
+ cterm.c_ospeed = cterm.c_ispeed = 9600;
+ (void) sccparam(&ctty, &cterm);
+ DELAY(1000);
#ifdef TK_NOTYET
- cn_tab.cn_disabled = 0;
+ cn_tab.cn_disabled = 0;
#endif
- splx(s);
- }
+ splx(s);
+ }
/*
* XXX
@@ -374,9 +512,6 @@ sccattach(parent, self, aux)
*/
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) {
- static struct consdev scccons = {
- NULL, NULL, sccGetc, sccPutc, sccPollc, NODEV, 0
- };
cn_tab = &scccons;
cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2);
@@ -475,9 +610,9 @@ sccopen(dev, flag, mode, p)
line = SCCLINE(dev);
if (sc->scc_pdma[line].p_addr == NULL)
return (ENXIO);
- tp = scc_tty[minor(dev)];
+ tp = sc->scc_tty[line];
if (tp == NULL) {
- tp = scc_tty[minor(dev)] = ttymalloc();
+ tp = sc->scc_tty[line] = ttymalloc();
tty_attach(tp);
}
tp->t_oproc = sccstart;
@@ -506,7 +641,7 @@ sccopen(dev, flag, mode, p)
(void) sccmctl(dev, DML_DTR, DMSET);
s = spltty();
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
- !(tp->t_state & TS_CARR_ON)) {
+ !(tp->t_state & TS_CARR_ON)) {
tp->t_state |= TS_WOPEN;
if ((error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
ttopen, 0)) != 0)
@@ -529,8 +664,8 @@ sccclose(dev, flag, mode, p)
register struct tty *tp;
register int line;
- tp = scc_tty[minor(dev)];
line = SCCLINE(dev);
+ tp = sc->scc_tty[line];
if (sc->scc_wreg[line].wr5 & ZSWR5_BREAK) {
sc->scc_wreg[line].wr5 &= ~ZSWR5_BREAK;
ttyoutput(0, tp);
@@ -548,9 +683,11 @@ sccread(dev, uio, flag)
struct uio *uio;
int flag;
{
+ register struct scc_softc *sc;
register struct tty *tp;
- tp = scc_tty[minor(dev)];
+ sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/
+ tp = sc->scc_tty[SCCLINE(dev)];
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
@@ -560,9 +697,11 @@ sccwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
+ register struct scc_softc *sc;
register struct tty *tp;
- tp = scc_tty[minor(dev)];
+ sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/
+ tp = sc->scc_tty[SCCLINE(dev)];
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
@@ -570,9 +709,14 @@ struct tty *
scctty(dev)
dev_t dev;
{
- struct tty *tp = scc_tty[minor(dev)]; /* XXX */
+ register struct scc_softc *sc;
+ register struct tty *tp;
+ register int unit = SCCUNIT(dev);
- return (tp);
+ if ((unit >= scc_cd.cd_ndevs) || (sc = scc_cd.cd_devs[unit]) == 0)
+ return (0);
+ tp = sc->scc_tty[SCCLINE(dev)];
+ return (tp);
}
/*ARGSUSED*/
@@ -588,7 +732,9 @@ sccioctl(dev, cmd, data, flag, p)
register struct tty *tp;
int error, line;
- tp = scc_tty[minor(dev)];
+ line = SCCLINE(dev);
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ tp = sc->scc_tty[line];
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return (error);
@@ -596,8 +742,6 @@ sccioctl(dev, cmd, data, flag, p)
if (error >= 0)
return (error);
- line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
switch (cmd) {
case TIOCSBRK:
@@ -640,32 +784,55 @@ sccioctl(dev, cmd, data, flag, p)
return (0);
}
+
+
+/*
+ * Set line parameters -- tty t_param entry point.
+ */
int
sccparam(tp, t)
register struct tty *tp;
register struct termios *t;
{
register struct scc_softc *sc;
+
+ /* Extract the softc and call cold_sccparam to do all the work. */
+ sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)];
+ return cold_sccparam(tp, t, sc);
+}
+
+
+/*
+ * Do what sccparam() (t_param entry point) does, but callable when cold.
+ */
+static int
+cold_sccparam(tp, t, sc)
+ register struct tty *tp;
+ register struct termios *t;
+ register struct scc_softc *sc;
+{
register scc_regmap_t *regs;
register int line;
register u_char value, wvalue;
register int cflag = t->c_cflag;
int ospeed;
- if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
- return (EINVAL);
+ /* Check arguments */
+ if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
+ return (EINVAL);
ospeed = ttspeedtab(t->c_ospeed, sccspeedtab);
- if (ospeed < 0)
- return (EINVAL);
- /* and copy to tty */
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
- tp->t_cflag = cflag;
+ if (ospeed < 0)
+ return (EINVAL);
+ /* and copy to tty */
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = cflag;
/*
* Handle console specially.
*/
- if (0 /* cn_tab.cn_screen */) {
+#ifdef HAVE_RCONS
+ if (cn_tab->cn_getc == LKgetc) {
if (minor(tp->t_dev) == SCCKBD_PORT) {
cflag = CS8;
ospeed = ttspeedtab(4800, sccspeedtab);
@@ -673,7 +840,9 @@ sccparam(tp, t)
cflag = CS8 | PARENB | PARODD;
ospeed = ttspeedtab(4800, sccspeedtab);
}
- } else /* if (tp->t_dev == cn_tab.cn_dev) */ {
+ } else if (tp->t_dev == cn_tab->cn_dev)
+#endif /*HAVE_RCONS*/
+ {
cflag = CS8;
ospeed = ttspeedtab(9600, sccspeedtab);
}
@@ -682,10 +851,14 @@ sccparam(tp, t)
return (0);
}
- sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)];
line = SCCLINE(tp->t_dev);
regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ /*
+ * pmax driver used to reset the SCC here. That reset causes the
+ * other channel on the SCC to drop outpur chars: at least that's
+ * what CGD reports for the Alpha. It's a bug.
+ */
#if 0
/* reset line */
if (line == SCC_CHANNEL_A)
@@ -715,7 +888,7 @@ sccparam(tp, t)
SCC_WRITE_REG(regs, line, ZSWR_IVEC, 0xf0);
/* clear break, keep rts dtr */
- wvalue = sc->scc_wreg[line].wr5 & (ZSWR5_DTR | ZSWR5_RTS);
+ wvalue = sc->scc_wreg[line].wr5 & (ZSWR5_DTR|ZSWR5_RTS);
switch (cflag & CSIZE) {
case CS5:
value = ZSWR3_RX_5;
@@ -740,9 +913,14 @@ sccparam(tp, t)
sc->scc_wreg[line].wr5 = wvalue;
SCC_WRITE_REG(regs, line, SCC_WR5, wvalue);
+ /*
+ * XXX Does the SCC chip require us to refresh the WR5 register
+ * for the other channel after writing the other, or not?
+ */
#ifdef notdef
/* XXX */
- {int otherline = (line + 1) & 1;
+ {
+ int otherline = (line + 1) & 1;
SCC_WRITE_REG(regs, otherline, SCC_WR5, sc->scc_wreg[otherline].wr5);
}
#endif
@@ -757,11 +935,15 @@ sccparam(tp, t)
SCC_SET_TIMING_BASE(regs, line, ospeed);
value = sc->scc_wreg[line].wr14;
SCC_WRITE_REG(regs, line, SCC_WR14, value);
- if (SCCUNIT(tp->t_dev) != 1) {
- value = ZSWR15_BREAK_IE | ZSWR15_CTS_IE | ZSWR15_DCD_IE;
- } else {
+
+#ifdef alpha
+ if (SCCUNIT(tp->t_dev) == 1) {
/* On unit one, on the flamingo, modem control is floating! */
value = ZSWR15_BREAK_IE;
+ } else
+#endif
+ {
+ value = ZSWR15_BREAK_IE | ZSWR15_CTS_IE | ZSWR15_DCD_IE;
}
SCC_WRITE_REG(regs, line, SCC_WR15, value);
@@ -776,28 +958,32 @@ sccparam(tp, t)
value = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
SCC_WRITE_REG(regs, line, SCC_WR9, value);
SCC_WRITE_REG(regs, line, SCC_WR1, sc->scc_wreg[line].wr1);
+ tc_mb();
+#ifdef alpha
scc_alphaintr(1); /* XXX XXX XXX */
+#endif /*alpha*/
return (0);
}
+
/*
* Check for interrupts from all devices.
*/
int
-sccintr(xxxunit)
- void *xxxunit;
+sccintr(xxxsc)
+ void *xxxsc;
{
- register int unit = (long)xxxunit;
+ register struct scc_softc *sc = (struct scc_softc *)xxxsc;
+ register int unit = (long)sc->sc_dv.dv_unit;
register scc_regmap_t *regs;
register struct tty *tp;
register struct pdma *dp;
- register struct scc_softc *sc;
register int cc, chan, rr1, rr2, rr3;
int overrun = 0;
- sc = scc_cd.cd_devs[unit];
+ rr1 = 0; /* shut up gcc -Wall */
regs = (scc_regmap_t *)sc->scc_pdma[0].p_addr;
unit <<= 1;
for (;;) {
@@ -807,18 +993,21 @@ sccintr(xxxunit)
if (rr2 == 6) { /* strange, distinguished value */
SCC_READ_REG(regs, SCC_CHANNEL_A, ZSRR_IPEND, rr3);
if (rr3 == 0)
- return;
+ return 0; /* XXX */
}
SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_RR0, ZSWR0_CLR_INTR);
if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) {
chan = (rr2 == SCC_RR2_A_XMIT_DONE) ?
SCC_CHANNEL_A : SCC_CHANNEL_B;
- tp = scc_tty[unit | chan];
+ tp = sc->scc_tty[chan];
dp = &sc->scc_pdma[chan];
if (dp->p_mem < dp->p_end) {
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
- wbflush();
+#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
+ DELAY(2);
+#endif
+ tc_mb();
} else {
tp->t_state &= ~TS_BUSY;
if (tp->t_state & TS_FLUSH)
@@ -839,7 +1028,7 @@ sccintr(xxxunit)
cc = sc->scc_wreg[chan].wr1 & ~ZSWR1_TIE;
SCC_WRITE_REG(regs, chan, SCC_WR1, cc);
sc->scc_wreg[chan].wr1 = cc;
- wbflush();
+ tc_mb();
}
}
} else if (rr2 == SCC_RR2_A_RECV_DONE ||
@@ -849,7 +1038,7 @@ sccintr(xxxunit)
chan = SCC_CHANNEL_A;
else
chan = SCC_CHANNEL_B;
- tp = scc_tty[unit | chan];
+ tp = sc->scc_tty[chan];
SCC_READ_DATA(regs, chan, cc);
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
@@ -865,12 +1054,12 @@ sccintr(xxxunit)
/*
* Keyboard needs special treatment.
*/
- if (tp == scc_tty[SCCKBD_PORT] /* && cn_tab.cn_screen */) {
+ if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT)) /* && cn_tab.cn_screen */) {
#ifdef KADB
if (cc == LK_DO) {
spl0();
kdbpanic();
- return;
+ return 0; /* XXX */
}
#endif
#ifdef DEBUG
@@ -887,40 +1076,11 @@ sccintr(xxxunit)
/*
* Now for mousey
*/
- } else if (tp == scc_tty[SCCMOUSE_PORT] && sccMouseButtons) {
-#if 0
- register MouseReport *mrp;
- static MouseReport currentRep;
-
- mrp = &currentRep;
- mrp->byteCount++;
- if (cc & MOUSE_START_FRAME) {
- /*
- * The first mouse report byte (button state).
- */
- mrp->state = cc;
- if (mrp->byteCount > 1)
- mrp->byteCount = 1;
- } else if (mrp->byteCount == 2) {
- /*
- * The second mouse report byte (delta x).
- */
- mrp->dx = cc;
- } else if (mrp->byteCount == 3) {
- /*
- * The final mouse report byte (delta y).
- */
- mrp->dy = cc;
- mrp->byteCount = 0;
- if (mrp->dx != 0 || mrp->dy != 0) {
- /*
- * If the mouse moved,
- * post a motion event.
- */
- (*sccMouseEvent)(mrp);
- }
- (*sccMouseButtons)(mrp);
- }
+ } else if (tp == scctty(makedev(SCCDEV, SCCMOUSE_PORT)) &&
+ sccMouseButtons) {
+#ifdef HAVE_RCONS
+ /*XXX*/
+ mouseInput(cc);
#endif
continue;
}
@@ -941,11 +1101,12 @@ sccintr(xxxunit)
(*linesw[tp->t_line].l_rint)(cc, tp);
} else if ((rr2 == SCC_RR2_A_EXT_STATUS) || (rr2 == SCC_RR2_B_EXT_STATUS)) {
chan = (rr2 == SCC_RR2_A_EXT_STATUS) ?
- SCC_CHANNEL_A : SCC_CHANNEL_B;
+ SCC_CHANNEL_A : SCC_CHANNEL_B;
SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_STATUS);
scc_modem_intr(unit | chan);
}
}
+ return 0; /* XXX */
}
void
@@ -975,7 +1136,7 @@ sccstart(tp)
if (tp->t_outq.c_cc == 0)
goto out;
/* handle console specially */
- if (tp == scc_tty[SCCKBD_PORT] /* && cn_tab.cn_screen */) {
+ if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) /* && cn_tab.cn_screen */) {
while (tp->t_outq.c_cc > 0) {
cc = getc(&tp->t_outq) & 0x7f;
cnputc(cc);
@@ -993,21 +1154,8 @@ sccstart(tp)
}
goto out;
}
-#if 0
- if (tp->t_flags & (RAW|LITOUT))
- cc = ndqb(&tp->t_outq, 0);
- else {
- cc = ndqb(&tp->t_outq, 0200);
- if (cc == 0) {
- cc = getc(&tp->t_outq);
- timeout(ttrstrt, (void *)tp, (cc & 0x7f) + 6);
- tp->t_state |= TS_TIMEOUT;
- goto out;
- }
- }
-#else
cc = ndqb(&tp->t_outq, 0);
-#endif
+
tp->t_state |= TS_BUSY;
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
dp->p_end += cc;
@@ -1030,8 +1178,11 @@ sccstart(tp)
panic("sccstart: No chars");
#endif
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
+#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
+ DELAY(2);
+#endif
}
- wbflush();
+ tc_mb();
out:
splx(s);
}
@@ -1040,7 +1191,7 @@ out:
* Stop output on a line.
*/
/*ARGSUSED*/
-int
+void
sccstop(tp, flag)
register struct tty *tp;
int flag;
@@ -1058,8 +1209,6 @@ sccstop(tp, flag)
tp->t_state |= TS_FLUSH;
}
splx(s);
-
- return 0; /* XXX should be void */
}
int
@@ -1118,7 +1267,7 @@ sccmctl(dev, bits, how)
sc->scc_wreg[SCC_CHANNEL_A].wr5);
}
if ((mbits & DML_DTR) || (sc->scc_softCAR & (1 << line)))
- scc_tty[minor(dev)]->t_state |= TS_CARR_ON;
+ sc->scc_tty[line]->t_state |= TS_CARR_ON;
(void) splx(s);
return (mbits);
}
@@ -1137,9 +1286,9 @@ scc_modem_intr(dev)
register u_char value;
int s;
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- tp = scc_tty[minor(dev)];
chan = SCCLINE(dev);
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ tp = sc->scc_tty[chan];
regs = (scc_regmap_t *)sc->scc_pdma[chan].p_addr;
if (chan == SCC_CHANNEL_A)
return;
@@ -1150,6 +1299,13 @@ scc_modem_intr(dev)
SCC_READ_REG_ZERO(regs, chan, value);
car = value & ZSRR0_DCD;
}
+
+ /*
+ * The pmax driver follows carrier-detect. The Alpha does not.
+ * XXX Why doesn't the Alpha driver follow carrier-detect?
+ * (in the Alpha driver, this is an "#ifdef notdef").
+ * Is it related to console handling?
+ */
#ifdef notdef
if (car) {
/* carrier present */
@@ -1171,15 +1327,25 @@ sccGetc(dev)
register scc_regmap_t *regs;
register int c, line;
register u_char value;
- struct scc_softc *sc;
int s;
line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ if (cold && scc_cons_addr) {
+ regs = scc_cons_addr;
+ } else {
+ register struct scc_softc *sc;
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ }
+
if (!regs)
return (0);
+#ifdef pmax
+ /*s = spltty(); */ /* XXX why different spls? */
+ s = splhigh();
+#else
s = splhigh();
+#endif
for (;;) {
SCC_READ_REG(regs, line, SCC_RR0, value);
if (value & ZSRR0_RX_READY) {
@@ -1212,13 +1378,21 @@ sccPutc(dev, c)
register scc_regmap_t *regs;
register int line;
register u_char value;
- struct scc_softc *sc;
int s;
+#ifdef pmax
+ s = spltty(); /* XXX why different spls? */
+#else
s = splhigh();
+#endif
line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ if (cold && scc_cons_addr) {
+ regs = scc_cons_addr;
+ } else {
+ register struct scc_softc *sc;
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ }
/*
* Wait for transmitter to be not busy.
@@ -1234,7 +1408,7 @@ sccPutc(dev, c)
* Send the char.
*/
SCC_WRITE_DATA(regs, line, c);
- wbflush();
+ tc_mb();
splx(s);
return;
@@ -1285,5 +1459,5 @@ rr(msg, regs)
printf("B: 0: %x 1: %x 2(state): %x 10: %x 15: %x\n",
r0, r1, r2, r10, r15);
}
-#endif
+#endif /* SCC_DEBUG */
#endif /* NSCC */
diff --git a/sys/arch/alpha/tc/sccreg.h b/sys/arch/alpha/tc/sccreg.h
index 2207605a58a..f51a1083921 100644
--- a/sys/arch/alpha/tc/sccreg.h
+++ b/sys/arch/alpha/tc/sccreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sccreg.h,v 1.2 1996/07/29 23:02:13 niklas Exp $ */
+/* $OpenBSD: sccreg.h,v 1.3 1996/10/30 22:41:12 niklas Exp $ */
/* $NetBSD: sccreg.h,v 1.2 1995/04/11 03:41:10 mycroft Exp $ */
/*
diff --git a/sys/arch/alpha/tc/sccvar.h b/sys/arch/alpha/tc/sccvar.h
index 5ffdb5baa11..c0c8285fb35 100644
--- a/sys/arch/alpha/tc/sccvar.h
+++ b/sys/arch/alpha/tc/sccvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: sccvar.h,v 1.2 1996/07/29 23:02:15 niklas Exp $ */
-/* $NetBSD: sccvar.h,v 1.2 1995/08/03 00:52:23 cgd Exp $ */
+/* $OpenBSD: sccvar.h,v 1.3 1996/10/30 22:41:13 niklas Exp $ */
+/* $NetBSD: sccvar.h,v 1.3 1996/07/09 00:55:21 cgd Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
@@ -98,7 +98,7 @@ typedef struct {
#define scc_get_datum(d, v) \
do { (v) = ((d) >> 8) & 0xff; } while (0)
#define scc_set_datum(d, v) \
- do { (d) = (volatile unsigned int)(v) << 8; wbflush(); } while (0)
+ do { (d) = (volatile unsigned int)(v) << 8; alpha_mb(); } while (0)
/*
* Minor device numbers for scc. Weird because B channel comes first and
diff --git a/sys/arch/alpha/tc/sfb.c b/sys/arch/alpha/tc/sfb.c
index d593bc89fa1..1d6abccf59b 100644
--- a/sys/arch/alpha/tc/sfb.c
+++ b/sys/arch/alpha/tc/sfb.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: sfb.c,v 1.2 1996/07/29 23:02:16 niklas Exp $ */
-/* $NetBSD: sfb.c,v 1.1 1996/05/01 21:15:50 cgd Exp $ */
+/* $OpenBSD: sfb.c,v 1.3 1996/10/30 22:41:14 niklas Exp $ */
+/* $NetBSD: sfb.c,v 1.5 1996/10/13 03:00:35 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -57,7 +57,7 @@
int sfbmatch __P((struct device *, void *, void *));
void sfbattach __P((struct device *, struct device *, void *));
-int sfbprint __P((void *, char *));
+int sfbprint __P((void *, /* const */ char *));
struct cfattach sfb_ca = {
sizeof(struct sfb_softc), sfbmatch, sfbattach,
@@ -92,7 +92,6 @@ sfbmatch(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct cfdata *cf = match;
struct tc_attach_args *ta = aux;
if (strncmp("PMAGB-BA", ta->ta_modname, TC_ROM_LLEN) != 0)
@@ -112,7 +111,7 @@ sfb_getdevconfig(dense_addr, dc)
int i;
dc->dc_vaddr = dense_addr;
- dc->dc_paddr = k0segtophys(dc->dc_vaddr); /* XXX */
+ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
dc->dc_size = SFB_SIZE;
regp = (char *)dc->dc_vaddr + SFB_ASIC_OFFSET;
@@ -209,7 +208,6 @@ sfbattach(parent, self, aux)
struct wscons_attach_args waa;
struct wscons_odev_spec *wo;
int console;
- char *x;
console = 0; /* XXX */
if (console)
@@ -253,7 +251,7 @@ sfbattach(parent, self, aux)
int
sfbprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
if (pnp)
diff --git a/sys/arch/alpha/tc/sfbvar.h b/sys/arch/alpha/tc/sfbvar.h
index a1fa2952d72..c1e46e511a2 100644
--- a/sys/arch/alpha/tc/sfbvar.h
+++ b/sys/arch/alpha/tc/sfbvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sfbvar.h,v 1.2 1996/07/29 23:02:18 niklas Exp $ */
+/* $OpenBSD: sfbvar.h,v 1.3 1996/10/30 22:41:15 niklas Exp $ */
/* $NetBSD: sfbvar.h,v 1.1 1996/05/01 21:15:51 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/tc_3000_300.c b/sys/arch/alpha/tc/tc_3000_300.c
index dc7c0b41fb9..890bfa6fc7f 100644
--- a/sys/arch/alpha/tc/tc_3000_300.c
+++ b/sys/arch/alpha/tc/tc_3000_300.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_300.c,v 1.4 1996/07/29 23:02:19 niklas Exp $ */
-/* $NetBSD: tc_3000_300.c,v 1.7.4.1 1996/06/05 00:39:06 cgd Exp $ */
+/* $OpenBSD: tc_3000_300.c,v 1.5 1996/10/30 22:41:16 niklas Exp $ */
+/* $NetBSD: tc_3000_300.c,v 1.12 1996/10/13 03:00:37 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
@@ -46,12 +47,12 @@ void tc_3000_300_intr_setup __P((void));
void tc_3000_300_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
void tc_3000_300_intr_disestablish __P((struct device *, void *));
-void tc_3000_300_iointr __P((void *, int));
+void tc_3000_300_iointr __P((void *, unsigned long));
int tc_3000_300_intrnull __P((void *));
#define C(x) ((void *)(u_long)x)
-#define KV(x) (phystok0seg(x))
+#define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
/*
* We have to read and modify the IOASIC registers directly, because
@@ -184,18 +185,19 @@ tc_3000_300_intrnull(val)
void
tc_3000_300_iointr(framep, vec)
void *framep;
- int vec;
+ unsigned long vec;
{
u_int32_t tcir, ioasicir, ioasicimr;
- int opt0intr, opt1intr, ifound;
+ int ifound;
#ifdef DIAGNOSTIC
int s;
if (vec != 0x800)
- panic("INVALID ASSUMPTION: vec %x, not 0x800", vec);
+ panic("INVALID ASSUMPTION: vec 0x%lx, not 0x800", vec);
s = splhigh();
- if (s != PSL_IPL_IO)
- panic("INVALID ASSUMPTION: IPL %d, not %d", s, PSL_IPL_IO);
+ if (s != ALPHA_PSL_IPL_IO)
+ panic("INVALID ASSUMPTION: IPL %d, not %d", s,
+ ALPHA_PSL_IPL_IO);
splx(s);
#endif
diff --git a/sys/arch/alpha/tc/tc_3000_300.h b/sys/arch/alpha/tc/tc_3000_300.h
index 8ef82e58802..475eefad00b 100644
--- a/sys/arch/alpha/tc/tc_3000_300.h
+++ b/sys/arch/alpha/tc/tc_3000_300.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_3000_300.h,v 1.3 1996/07/29 23:02:21 niklas Exp $ */
+/* $OpenBSD: tc_3000_300.h,v 1.4 1996/10/30 22:41:17 niklas Exp $ */
/* $NetBSD: tc_3000_300.h,v 1.2 1995/12/20 00:43:28 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/tc_3000_500.c b/sys/arch/alpha/tc/tc_3000_500.c
index ccda3b062bd..9e8133619b2 100644
--- a/sys/arch/alpha/tc/tc_3000_500.c
+++ b/sys/arch/alpha/tc/tc_3000_500.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_500.c,v 1.4 1996/07/29 23:02:23 niklas Exp $ */
-/* $NetBSD: tc_3000_500.c,v 1.4.4.3 1996/06/13 18:35:35 cgd Exp $ */
+/* $OpenBSD: tc_3000_500.c,v 1.5 1996/10/30 22:41:18 niklas Exp $ */
+/* $NetBSD: tc_3000_500.c,v 1.11 1996/10/13 03:00:38 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
@@ -45,12 +46,12 @@ void tc_3000_500_intr_setup __P((void));
void tc_3000_500_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
void tc_3000_500_intr_disestablish __P((struct device *, void *));
-void tc_3000_500_iointr __P((void *, int));
+void tc_3000_500_iointr __P((void *, unsigned long));
int tc_3000_500_intrnull __P((void *));
#define C(x) ((void *)(u_long)x)
-#define KV(x) (phystok0seg(x))
+#define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
struct tc_slotdesc tc_3000_500_slots[] = {
{ KV(0x100000000), C(TC_3000_500_DEV_OPT0), }, /* 0 - opt slot 0 */
@@ -175,7 +176,7 @@ tc_3000_500_intrnull(val)
void
tc_3000_500_iointr(framep, vec)
void *framep;
- int vec;
+ unsigned long vec;
{
u_int32_t ir;
int ifound;
@@ -183,10 +184,11 @@ tc_3000_500_iointr(framep, vec)
#ifdef DIAGNOSTIC
int s;
if (vec != 0x800)
- panic("INVALID ASSUMPTION: vec %x, not 0x800", vec);
+ panic("INVALID ASSUMPTION: vec 0x%lx, not 0x800", vec);
s = splhigh();
- if (s != PSL_IPL_IO)
- panic("INVALID ASSUMPTION: IPL %d, not %d", s, PSL_IPL_IO);
+ if (s != ALPHA_PSL_IPL_IO)
+ panic("INVALID ASSUMPTION: IPL %d, not %d", s,
+ ALPHA_PSL_IPL_IO);
splx(s);
#endif
@@ -248,6 +250,7 @@ tc_3000_500_iointr(framep, vec)
} while (ifound);
}
+#if 0
/*
* tc_3000_500_ioslot --
* Set the PBS bits for devices on the TC.
@@ -273,3 +276,4 @@ tc_3000_500_ioslot(slot, flags, set)
tc_mb();
splx(s);
}
+#endif
diff --git a/sys/arch/alpha/tc/tc_3000_500.h b/sys/arch/alpha/tc/tc_3000_500.h
index ea5a236e165..b9249b9a857 100644
--- a/sys/arch/alpha/tc/tc_3000_500.h
+++ b/sys/arch/alpha/tc/tc_3000_500.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_3000_500.h,v 1.3 1996/07/29 23:02:24 niklas Exp $ */
+/* $OpenBSD: tc_3000_500.h,v 1.4 1996/10/30 22:41:19 niklas Exp $ */
/* $NetBSD: tc_3000_500.h,v 1.2 1995/12/20 00:43:31 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/tc/tc_bus_io.c b/sys/arch/alpha/tc/tc_bus_io.c
index e553611c1b4..731d237b820 100644
--- a/sys/arch/alpha/tc/tc_bus_io.c
+++ b/sys/arch/alpha/tc/tc_bus_io.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_bus_io.c,v 1.2 1996/07/29 23:02:26 niklas Exp $ */
-/* $NetBSD: tc_bus_io.c,v 1.1.4.1 1996/06/13 17:41:51 cgd Exp $ */
+/* $OpenBSD: tc_bus_io.c,v 1.3 1996/10/30 22:41:20 niklas Exp $ */
+/* $NetBSD: tc_bus_io.c,v 1.3 1996/07/09 00:55:31 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -34,12 +34,14 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <vm/vm.h>
#include <machine/bus.h>
+#include <dev/tc/tcvar.h>
int tc_io_map __P((void *, bus_io_addr_t, bus_io_size_t,
bus_io_handle_t *));
diff --git a/sys/arch/alpha/tc/tc_bus_mem.c b/sys/arch/alpha/tc/tc_bus_mem.c
index b82678694fc..558dd764c0f 100644
--- a/sys/arch/alpha/tc/tc_bus_mem.c
+++ b/sys/arch/alpha/tc/tc_bus_mem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_bus_mem.c,v 1.2 1996/07/29 23:02:27 niklas Exp $ */
-/* $NetBSD: tc_bus_mem.c,v 1.2.4.2 1996/06/13 17:42:51 cgd Exp $ */
+/* $OpenBSD: tc_bus_mem.c,v 1.3 1996/10/30 22:41:21 niklas Exp $ */
+/* $NetBSD: tc_bus_mem.c,v 1.7 1996/07/09 00:55:33 cgd Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
@@ -33,6 +33,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
@@ -105,9 +106,9 @@ tc_mem_map(v, memaddr, memsize, cacheable, memhp)
if (memaddr & 0x7)
panic("tc_mem_map needs 8 byte alignment");
if (cacheable)
- *memhp = phystok0seg(memaddr);
+ *memhp = ALPHA_PHYS_TO_K0SEG(memaddr);
else
- *memhp = phystok0seg(TC_DENSE_TO_SPARSE(memaddr));
+ *memhp = ALPHA_PHYS_TO_K0SEG(TC_DENSE_TO_SPARSE(memaddr));
return (0);
}
@@ -148,7 +149,7 @@ tc_mem_read_1(v, memh, off)
{
volatile u_int8_t *p;
- wbflush();
+ alpha_mb();
if ((memh & TC_SPACE_SPARSE) != 0)
panic("tc_mem_read_1 not implemented for sparse space");
@@ -165,7 +166,7 @@ tc_mem_read_2(v, memh, off)
{
volatile u_int16_t *p;
- wbflush();
+ alpha_mb();
if ((memh & TC_SPACE_SPARSE) != 0)
panic("tc_mem_read_2 not implemented for sparse space");
@@ -182,7 +183,7 @@ tc_mem_read_4(v, memh, off)
{
volatile u_int32_t *p;
- wbflush();
+ alpha_mb();
if ((memh & TC_SPACE_SPARSE) != 0)
/* Nothing special to do for 4-byte sparse space accesses */
@@ -200,7 +201,7 @@ tc_mem_read_8(v, memh, off)
{
volatile u_int64_t *p;
- wbflush();
+ alpha_mb();
if ((memh & TC_SPACE_SPARSE) != 0)
panic("tc_mem_read_8 not implemented for sparse space");
@@ -236,7 +237,7 @@ tc_mem_write_1(v, memh, off, val)
p = (u_int8_t *)(memh + off);
*p = val;
}
- wbflush();
+ alpha_mb();
}
void
@@ -266,7 +267,7 @@ tc_mem_write_2(v, memh, off, val)
p = (u_int16_t *)(memh + off);
*p = val;
}
- wbflush();
+ alpha_mb();
}
void
@@ -284,7 +285,7 @@ tc_mem_write_4(v, memh, off, val)
else
p = (u_int32_t *)(memh + off);
*p = val;
- wbflush();
+ alpha_mb();
}
void
@@ -301,7 +302,7 @@ tc_mem_write_8(v, memh, off, val)
p = (u_int64_t *)(memh + off);
*p = val;
- wbflush();
+ alpha_mb();
}
/* XXX DOES NOT BELONG */
@@ -310,5 +311,5 @@ tc_XXX_dmamap(addr)
void *addr;
{
- return (vtophys(addr));
+ return (vtophys((vm_offset_t)addr));
}
diff --git a/sys/arch/alpha/tc/tc_conf.h b/sys/arch/alpha/tc/tc_conf.h
index 948014a6e3f..479cea7eb6b 100644
--- a/sys/arch/alpha/tc/tc_conf.h
+++ b/sys/arch/alpha/tc/tc_conf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_conf.h,v 1.2 1996/07/29 23:02:29 niklas Exp $ */
-/* $NetBSD: tc_conf.h,v 1.1 1995/12/20 00:43:32 cgd Exp $ */
+/* $OpenBSD: tc_conf.h,v 1.3 1996/10/30 22:41:22 niklas Exp $ */
+/* $NetBSD: tc_conf.h,v 1.2 1996/07/14 04:06:30 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -34,7 +34,7 @@
#ifdef DEC_3000_500
extern void tc_3000_500_intr_setup __P((void));
-extern void tc_3000_500_iointr __P((void *, int));
+extern void tc_3000_500_iointr __P((void *, unsigned long));
extern void tc_3000_500_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
@@ -48,7 +48,7 @@ extern struct tc_builtin tc_3000_500_builtins[];
#ifdef DEC_3000_300
extern void tc_3000_300_intr_setup __P((void));
-extern void tc_3000_300_iointr __P((void *, int));
+extern void tc_3000_300_iointr __P((void *, unsigned long));
extern void tc_3000_300_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
diff --git a/sys/arch/alpha/tc/tc_machdep.h b/sys/arch/alpha/tc/tc_machdep.h
index f5a55ec646b..842c8bc023a 100644
--- a/sys/arch/alpha/tc/tc_machdep.h
+++ b/sys/arch/alpha/tc/tc_machdep.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_machdep.h,v 1.2 1996/07/29 23:02:31 niklas Exp $ */
-/* $NetBSD: tc_machdep.h,v 1.1 1995/12/20 00:09:29 cgd Exp $ */
+/* $OpenBSD: tc_machdep.h,v 1.3 1996/10/30 22:41:23 niklas Exp $ */
+/* $NetBSD: tc_machdep.h,v 1.2 1996/07/09 00:55:35 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -61,8 +61,8 @@
typedef u_int64_t tc_addr_t;
typedef int32_t tc_offset_t;
-#define tc_mb() wbflush()
-#define tc_wmb() wbflush()
+#define tc_mb() alpha_mb()
+#define tc_wmb() alpha_wmb()
/*
* A junk address to read from, to make sure writes are complete. See
@@ -73,7 +73,7 @@ typedef int32_t tc_offset_t;
do { \
volatile u_int32_t no_optimize; \
no_optimize = \
- *(volatile u_int32_t *)phystok0seg(0x00000001f0080220); \
+ *(volatile u_int32_t *)ALPHA_PHYS_TO_K0SEG(0x00000001f0080220); \
} while (0)
#define tc_badaddr(tcaddr) \
@@ -91,3 +91,6 @@ typedef int32_t tc_offset_t;
#define TC_PHYS_TO_UNCACHED(addr) \
(addr)
+
+void tc_bus_io_init __P((bus_chipset_tag_t bc, void *iov));;
+void tc_bus_mem_init __P((bus_chipset_tag_t bc, void *memv));;
diff --git a/sys/arch/alpha/tc/tcasic.c b/sys/arch/alpha/tc/tcasic.c
index c1f2223032f..6ea1615408c 100644
--- a/sys/arch/alpha/tc/tcasic.c
+++ b/sys/arch/alpha/tc/tcasic.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcasic.c,v 1.3 1996/07/29 23:02:32 niklas Exp $ */
-/* $NetBSD: tcasic.c,v 1.5 1996/05/17 23:58:43 cgd Exp $ */
+/* $OpenBSD: tcasic.c,v 1.4 1996/10/30 22:41:24 niklas Exp $ */
+/* $NetBSD: tcasic.c,v 1.10 1996/10/13 03:00:39 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,6 +29,7 @@
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
@@ -49,7 +50,7 @@ struct cfdriver tcasic_cd = {
NULL, "tcasic", DV_DULL,
};
-int tcasicprint __P((void *, char *));
+int tcasicprint __P((void *, /* const */ char *));
extern int cputype;
@@ -86,7 +87,7 @@ tcasicattach(parent, self, aux)
{
struct tcbus_attach_args tba;
void (*intr_setup) __P((void));
- void (*iointr) __P((void *, int));
+ void (*iointr) __P((void *, unsigned long));
struct alpha_bus_chipset bc;
printf("\n");
@@ -144,7 +145,7 @@ tcasicattach(parent, self, aux)
int
tcasicprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
/* only TCs can attach to tcasics; easy. */
diff --git a/sys/arch/alpha/tc/tcds.c b/sys/arch/alpha/tc/tcds.c
index dd8da7b9903..a3cb6ae6b1b 100644
--- a/sys/arch/alpha/tc/tcds.c
+++ b/sys/arch/alpha/tc/tcds.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcds.c,v 1.4 1996/07/29 23:02:34 niklas Exp $ */
-/* $NetBSD: tcds.c,v 1.9.4.2 1996/06/05 01:32:26 cgd Exp $ */
+/* $OpenBSD: tcds.c,v 1.5 1996/10/30 22:41:27 niklas Exp $ */
+/* $NetBSD: tcds.c,v 1.15 1996/10/13 03:00:41 christos Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -58,7 +58,7 @@ struct tcds_softc {
/* Definition of the driver for autoconfig. */
int tcdsmatch __P((struct device *, void *, void *));
void tcdsattach __P((struct device *, struct device *, void *));
-int tcdsprint(void *, char *);
+int tcdsprint __P((void *, /* const */ char *));
struct cfattach tcds_ca = {
sizeof(struct tcds_softc), tcdsmatch, tcdsattach,
@@ -120,7 +120,7 @@ tcdsattach(parent, self, aux)
* not useful) bits set in it when the system boots. Clear it.
*/
*sc->sc_imer = 0;
- wbflush();
+ alpha_mb();
/* XXX Initial contents of CIR? */
@@ -204,7 +204,7 @@ tcdsattach(parent, self, aux)
int
tcdsprint(aux, pnp)
void *aux;
- char *pnp;
+ /* const */ char *pnp;
{
struct tc_attach_args *ta = aux;
@@ -279,10 +279,10 @@ tcds_scsi_reset(sc)
tcds_scsi_enable(sc, 0);
TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_resetbits);
- wbflush();
+ alpha_mb();
DELAY(1);
TCDS_CIR_SET(*sc->sc_tcds->sc_cir, sc->sc_resetbits);
- wbflush();
+ alpha_mb();
tcds_scsi_enable(sc, 1);
tcds_dma_enable(sc, 1);
@@ -298,7 +298,7 @@ tcds_scsi_enable(sc, on)
*sc->sc_tcds->sc_imer |= sc->sc_intrmaskbits;
else
*sc->sc_tcds->sc_imer &= ~sc->sc_intrmaskbits;
- wbflush();
+ alpha_mb();
}
void
@@ -312,7 +312,7 @@ tcds_dma_enable(sc, on)
TCDS_CIR_SET(*sc->sc_tcds->sc_cir, sc->sc_dmabits);
else
TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_dmabits);
- wbflush();
+ alpha_mb();
}
int
@@ -324,7 +324,7 @@ tcds_scsi_isintr(sc, clear)
if ((*sc->sc_tcds->sc_cir & sc->sc_intrbits) != 0) {
if (clear) {
TCDS_CIR_CLR(*sc->sc_tcds->sc_cir, sc->sc_intrbits);
- wbflush();
+ alpha_mb();
}
return (1);
} else
@@ -353,11 +353,11 @@ tcds_intr(val)
* Copy and clear (gag!) the interrupts.
*/
ir = *sc->sc_cir;
- wbflush();
+ alpha_mb();
TCDS_CIR_CLR(*sc->sc_cir, TCDS_CIR_ALLINTR);
- wbflush();
+ alpha_mb();
tc_syncbus();
- wbflush();
+ alpha_mb();
#ifdef EVCNT_COUNTERS
/* No interrupt counting via evcnt counters */
@@ -411,4 +411,6 @@ tcds_intr(val)
* This is wrong, but machine keeps dying.
*/
DELAY(1);
+
+ return (1);
}
diff --git a/sys/arch/alpha/tc/tcds_dma.c b/sys/arch/alpha/tc/tcds_dma.c
index c62f8ea7926..b7173fdc931 100644
--- a/sys/arch/alpha/tc/tcds_dma.c
+++ b/sys/arch/alpha/tc/tcds_dma.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcds_dma.c,v 1.3 1996/07/29 23:02:36 niklas Exp $ */
-/* $NetBSD: tcds_dma.c,v 1.6 1995/12/20 00:40:32 cgd Exp $ */
+/* $OpenBSD: tcds_dma.c,v 1.4 1996/10/30 22:41:28 niklas Exp $ */
+/* $NetBSD: tcds_dma.c,v 1.13 1996/10/13 03:00:43 christos Exp $ */
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -61,15 +61,6 @@ tcds_dma_reset(sc)
sc->sc_active = 0; /* and of course we aren't */
}
-
-void
-tcds_dma_enintr(sc)
- struct tcds_slotconfig *sc;
-{
-
- /* XXX */
-}
-
int
tcds_dma_isintr(sc)
struct tcds_slotconfig *sc;
@@ -85,79 +76,6 @@ tcds_dma_isintr(sc)
return x;
}
-#define ESPMAX (64 * 1024)
-#define DMAMAX(a) (0x02000 - ((a) & 0x1fff))
-
-/*
- * start a dma transfer or keep it going
- */
-void
-tcds_dma_start(sc, addr, len, datain)
- struct tcds_slotconfig *sc;
- caddr_t *addr;
- size_t *len;
- int datain; /* DMA into main memory */
-{
- u_int32_t dic;
- size_t size;
-
- sc->sc_dmaaddr = addr;
- sc->sc_dmalen = len;
- sc->sc_iswrite = datain;
-
- ESP_DMA(("tcds_dma %d: start %d@0x%lx,%d\n", sc->sc_slot, *sc->sc_dmalen, *sc->sc_dmaaddr, sc->sc_iswrite));
-
- /*
- * the rules say we cannot transfer more than the limit
- * of this DMA chip (64k) and we cannot cross a 8k boundary.
- */
- size = min(*sc->sc_dmalen, ESPMAX);
- size = min(size, DMAMAX((size_t) *sc->sc_dmaaddr));
- sc->sc_dmasize = size;
-
- ESP_DMA(("dma_start: dmasize = %d\n", sc->sc_dmasize));
-
- /* Load address, set/clear unaligned transfer and read/write bits. */
- /* XXX PICK AN ADDRESS TYPE, AND STICK TO IT! */
- if ((u_long)*addr > VM_MIN_KERNEL_ADDRESS) {
- *sc->sc_sda = vatopa((u_long)*addr) >> 2;
- } else {
- *sc->sc_sda = k0segtophys((u_long)*addr) >> 2;
- }
- wbflush();
- dic = *sc->sc_dic;
- dic &= ~TCDS_DIC_ADDRMASK;
- dic |= (vm_offset_t)*addr & TCDS_DIC_ADDRMASK;
- if (datain)
- dic |= TCDS_DIC_WRITE;
- else
- dic &= ~TCDS_DIC_WRITE;
- *sc->sc_dic = dic;
- wbflush();
-
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc->sc_esp, ESP_TCL, size);
- ESP_WRITE_REG(sc->sc_esp, ESP_TCM, size >> 8);
- if (sc->sc_esp->sc_rev == ESP200) {
- ESP_WRITE_REG(sc->sc_esp, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc->sc_esp, ESPCMD_NOP|ESPCMD_DMA);
-
- /*
- * Note that if `size' is 0, we've already transceived all
- * the bytes we want but we're still in the DATA PHASE.
- * Apparently, the device needs padding. Also, a transfer
- * size of 0 means "maximum" to the chip DMA logic.
- */
- ESPCMD(sc->sc_esp, (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
-
- sc->sc_active = 1;
-
- /* Start DMA */
- tcds_dma_enable(sc, 1);
-}
-
/*
* Pseudo (chained) interrupt from the esp driver to kick the
* current running DMA transfer. I am replying on espintr() to
@@ -246,7 +164,7 @@ tcds_dma_intr(sc)
#endif
ESP_DMA(("dud0 at 0x%lx dudmask 0x%x\n",
addr, dudmask));
- addr = (u_int32_t *)phystok0seg(addr);
+ addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG((vm_offset_t)addr);
*addr = (*addr & ~dudmask) | (dud & dudmask);
}
dud = *sc->sc_dud1;
@@ -267,7 +185,7 @@ tcds_dma_intr(sc)
#endif
ESP_DMA(("dud1 at 0x%lx dudmask 0x%x\n",
addr, dudmask));
- addr = (u_int32_t *)phystok0seg(addr);
+ addr = (u_int32_t *)ALPHA_PHYS_TO_K0SEG((vm_offset_t)addr);
*addr = (*addr & ~dudmask) | (dud & dudmask);
}
/* XXX deal with saved residual byte? */
@@ -287,3 +205,75 @@ tcds_dma_intr(sc)
#endif
return 0;
}
+
+#define DMAMAX(a) (0x02000 - ((a) & 0x1fff))
+
+/*
+ * start a dma transfer or keep it going
+ */
+int
+tcds_dma_setup(sc, addr, len, datain, dmasize)
+ struct tcds_slotconfig *sc;
+ caddr_t *addr;
+ size_t *len, *dmasize;
+ int datain; /* DMA into main memory */
+{
+ u_int32_t dic;
+ size_t size;
+
+ sc->sc_dmaaddr = addr;
+ sc->sc_dmalen = len;
+ sc->sc_iswrite = datain;
+
+ ESP_DMA(("tcds_dma %d: start %d@0x%lx,%d\n", sc->sc_slot, *sc->sc_dmalen, *sc->sc_dmaaddr, sc->sc_iswrite));
+
+ /*
+ * the rules say we cannot transfer more than the limit
+ * of this DMA chip (64k) and we cannot cross a 8k boundary.
+ */
+
+ size = min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
+ *dmasize = sc->sc_dmasize = size;
+
+ ESP_DMA(("dma_start: dmasize = %d\n", sc->sc_dmasize));
+
+ /* Load address, set/clear unaligned transfer and read/write bits. */
+ /* XXX PICK AN ADDRESS TYPE, AND STICK TO IT! */
+ if ((u_long)*addr > VM_MIN_KERNEL_ADDRESS) {
+ *sc->sc_sda = vatopa((u_long)*addr) >> 2;
+ } else {
+ *sc->sc_sda = ALPHA_K0SEG_TO_PHYS((u_long)*addr) >> 2;
+ }
+ alpha_mb();
+ dic = *sc->sc_dic;
+ dic &= ~TCDS_DIC_ADDRMASK;
+ dic |= (vm_offset_t)*addr & TCDS_DIC_ADDRMASK;
+ if (datain)
+ dic |= TCDS_DIC_WRITE;
+ else
+ dic &= ~TCDS_DIC_WRITE;
+ *sc->sc_dic = dic;
+ alpha_mb();
+
+ return (0);
+}
+
+void
+tcds_dma_go(sc)
+ struct tcds_slotconfig *sc;
+{
+
+ /* mark unit as DMA-active */
+ sc->sc_active = 1;
+
+ /* Start DMA */
+ tcds_dma_enable(sc, 1);
+}
+
+int
+tcds_dma_isactive(sc)
+ struct tcds_slotconfig *sc;
+{
+
+ return (sc->sc_active);
+}
diff --git a/sys/arch/alpha/tc/tcdsreg.h b/sys/arch/alpha/tc/tcdsreg.h
index beec02040ea..c8839b8cf7c 100644
--- a/sys/arch/alpha/tc/tcdsreg.h
+++ b/sys/arch/alpha/tc/tcdsreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcdsreg.h,v 1.2 1996/07/29 23:02:38 niklas Exp $ */
-/* $NetBSD: tcdsreg.h,v 1.1 1995/12/20 00:40:36 cgd Exp $ */
+/* $OpenBSD: tcdsreg.h,v 1.3 1996/10/30 22:41:29 niklas Exp $ */
+/* $NetBSD: tcdsreg.h,v 1.2 1996/07/09 00:55:42 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -132,7 +132,7 @@ void tcds_scsi_reset __P((int));
/*
* XXX
- * Start of MACH #defines, minimal changes to port to NetBSD.
+ * Start of MACH #defines, minimal changes to port to {Net/Open}BSD.
*
* The following register is the SCSI control interrupt register. It
* starts, stops and resets scsi DMA. It takes over the SCSI funtions
@@ -209,7 +209,7 @@ void tcds_scsi_reset __P((int));
# define SCSI_DUDE_MASK01 0x2000000 /* Mask bit for byte[01] */
# define SCSI_DUDE_MASK10 0x4000000 /* Mask bit for byte[10] */
-#define SCSI_CIR phystok0seg(KN15AA_REG_SCSI_CIR)
-#define SCSI_IMER phystok0seg(KN15AA_REG_SCSI_IMER)
+#define SCSI_CIR ALPHA_PHYS_TO_K0SEG(KN15AA_REG_SCSI_CIR)
+#define SCSI_IMER ALPHA_PHYS_TO_K0SEG(KN15AA_REG_SCSI_IMER)
#endif
diff --git a/sys/arch/alpha/tc/tcdsvar.h b/sys/arch/alpha/tc/tcdsvar.h
index 82dd5f57b50..a877de2dc7f 100644
--- a/sys/arch/alpha/tc/tcdsvar.h
+++ b/sys/arch/alpha/tc/tcdsvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: tcdsvar.h,v 1.3 1996/07/29 23:02:40 niklas Exp $ */
-/* $NetBSD: tcdsvar.h,v 1.3 1996/04/12 06:10:18 cgd Exp $ */
+/* $OpenBSD: tcdsvar.h,v 1.4 1996/10/30 22:41:31 niklas Exp $ */
+/* $NetBSD: tcdsvar.h,v 1.4 1996/09/09 18:10:39 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -91,16 +91,18 @@ void tcds_dma_enable __P((struct tcds_slotconfig *, int));
void tcds_scsi_enable __P((struct tcds_slotconfig *, int));
int tcds_scsi_isintr __P((struct tcds_slotconfig *, int));
void tcds_scsi_reset __P((struct tcds_slotconfig *));
+int tcds_scsi_iserr __P((struct tcds_slotconfig *));
/*
* TCDS DMA functions (used the the 53c94 driver)
*/
-void tcds_dma_reset __P((struct tcds_slotconfig *));
-void tcds_dma_enintr __P((struct tcds_slotconfig *));
int tcds_dma_isintr __P((struct tcds_slotconfig *));
-void tcds_dma_start __P((struct tcds_slotconfig *, caddr_t *,
- size_t *, int));
-int tcds_dmaintr __P((struct tcds_slotconfig *));
+void tcds_dma_reset __P((struct tcds_slotconfig *));
+int tcds_dma_intr __P((struct tcds_slotconfig *));
+int tcds_dma_setup __P((struct tcds_slotconfig *, caddr_t *, size_t *,
+ int, size_t *));
+void tcds_dma_go __P((struct tcds_slotconfig *));
+int tcds_dma_isactive __P((struct tcds_slotconfig *));
/*
* The TCDS (bus) cfdriver, so that subdevices can more
diff --git a/sys/arch/alpha/wscons/ascii.h b/sys/arch/alpha/wscons/ascii.h
index 7569e04fa31..e5a508d5d9c 100644
--- a/sys/arch/alpha/wscons/ascii.h
+++ b/sys/arch/alpha/wscons/ascii.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ascii.h,v 1.2 1996/07/29 23:02:46 niklas Exp $ */
+/* $OpenBSD: ascii.h,v 1.3 1996/10/30 22:41:35 niklas Exp $ */
/* $NetBSD: ascii.h,v 1.1 1996/04/12 02:00:42 cgd Exp $ */
#define ASCII_BEL 0x07 /* bell */
diff --git a/sys/arch/alpha/wscons/event.c b/sys/arch/alpha/wscons/event.c
index 614704b3f9d..57874c90736 100644
--- a/sys/arch/alpha/wscons/event.c
+++ b/sys/arch/alpha/wscons/event.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: event.c,v 1.2 1996/07/29 23:02:48 niklas Exp $ */
-/* $NetBSD: event.c,v 1.1.4.1 1996/05/29 22:26:54 cgd Exp $ */
+/* $OpenBSD: event.c,v 1.3 1996/10/30 22:41:36 niklas Exp $ */
+/* $NetBSD: event.c,v 1.3 1996/09/15 17:15:26 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -55,6 +55,10 @@
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/vnode.h>
+#include <sys/select.h>
+#ifdef notyet
+#include <sys/poll.h>
+#endif
#include <machine/vuid_event.h>
#include <alpha/wscons/event_var.h>
@@ -85,7 +89,7 @@ ev_fini(ev)
}
/*
- * User-level interface: read, select.
+ * User-level interface: read, poll.
* (User cannot write an event queue.)
*/
int
@@ -145,6 +149,26 @@ ev_read(ev, uio, flags)
return (error);
}
+#ifdef notyet
+int
+ev_poll(ev, events, p)
+ register struct evvar *ev;
+ int events;
+ struct proc *p;
+{
+ int revents = 0;
+ int s = splev();
+
+ if (events & (POLLIN | POLLRDNORM))
+ if (ev->ev_get != ev->ev_put)
+ revents |= events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(p, &ev->ev_sel);
+
+ splx(s);
+ return (revents);
+}
+#else
int
ev_select(ev, rw, p)
register struct evvar *ev;
@@ -171,3 +195,4 @@ ev_select(ev, rw, p)
splx(s);
return (0);
}
+#endif
diff --git a/sys/arch/alpha/wscons/event_var.h b/sys/arch/alpha/wscons/event_var.h
index bb8d9337c32..f9f0e00070c 100644
--- a/sys/arch/alpha/wscons/event_var.h
+++ b/sys/arch/alpha/wscons/event_var.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: event_var.h,v 1.2 1996/07/29 23:02:50 niklas Exp $ */
-/* $NetBSD: event_var.h,v 1.1 1996/04/12 02:00:45 cgd Exp $ */
+/* $OpenBSD: event_var.h,v 1.3 1996/10/30 22:41:37 niklas Exp $ */
+/* $NetBSD: event_var.h,v 1.2 1996/09/15 17:15:27 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -79,7 +79,11 @@ struct evvar {
void ev_init __P((struct evvar *));
void ev_fini __P((struct evvar *));
int ev_read __P((struct evvar *, struct uio *, int));
+#ifdef notyet
+int ev_poll __P((struct evvar *, int, struct proc *));
+#else
int ev_select __P((struct evvar *, int, struct proc *));
+#endif
/*
* PEVENT is set just above PSOCK, which is just above TTIPRI, on the
diff --git a/sys/arch/alpha/wscons/kbd.c b/sys/arch/alpha/wscons/kbd.c
index dbc00f0c542..c2782435e2b 100644
--- a/sys/arch/alpha/wscons/kbd.c
+++ b/sys/arch/alpha/wscons/kbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: kbd.c,v 1.2 1996/07/29 23:02:51 niklas Exp $ */
-/* $NetBSD: kbd.c,v 1.1 1996/04/12 02:00:46 cgd Exp $ */
+/* $OpenBSD: kbd.c,v 1.3 1996/10/30 22:41:39 niklas Exp $ */
+/* $NetBSD: kbd.c,v 1.2 1996/09/15 17:15:28 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -57,6 +57,7 @@
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/tty.h>
@@ -68,6 +69,7 @@
#include <machine/wsconsio.h> /* XXX for bell ioctls */
#include <alpha/wscons/event_var.h>
#include <alpha/wscons/wsconsvar.h>
+#include <alpha/wscons/kbd.h>
struct kbd_softc {
struct device *k_idev; /* the input device */
@@ -169,9 +171,6 @@ kbd_input(register int c)
int
kbdopen(dev_t dev, int flags, int mode, struct proc *p)
{
- int s;
- struct tty *tp;
-
if (kbd_softc.k_events.ev_io)
return (EBUSY);
kbd_softc.k_events.ev_io = p;
@@ -286,12 +285,19 @@ kbdioctl(dev_t dev, u_long cmd, register caddr_t data, int flag, struct proc *p)
return (rv);
}
+#ifdef notyet
+int
+kbdpoll(dev_t dev, int events, struct proc *p)
+{
+ return (ev_poll(&kbd_softc.k_events, events, p));
+}
+#else
int
kbdselect(dev_t dev, int rw, struct proc *p)
{
-
return (ev_select(&kbd_softc.k_events, rw, p));
}
+#endif
/* Ring the console bell. (For wscons terminal emulator and other code) */
void
diff --git a/sys/arch/alpha/wscons/kbd.h b/sys/arch/alpha/wscons/kbd.h
new file mode 100644
index 00000000000..e2bcf6ed5af
--- /dev/null
+++ b/sys/arch/alpha/wscons/kbd.h
@@ -0,0 +1,49 @@
+/* $OpenBSD: kbd.h,v 1.1 1996/10/30 22:41:41 niklas Exp $ */
+
+/*
+ * Copyright (c) 1996 Niklas Hallqvist
+ * 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 Niklas Hallqvist.
+ * 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 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.
+ */
+
+extern void kbdattach __P((struct device *, struct wscons_idev_spec *));
+extern void kbd_repeat __P((void *));
+extern void kbd_input __P((int));
+extern int kbdopen __P((dev_t, int, int, struct proc *));
+extern int kbdclose __P((dev_t, int, int, struct proc *p));
+extern int kbdread __P((dev_t, struct uio *, int));
+extern int kbdwrite __P((dev_t, struct uio *, int));
+extern int kbdioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+#ifdef notyet
+extern int kbdpoll __P((dev_t, int, struct proc *));
+#else
+extern int kbdselect __P((dev_t, int, struct proc *));
+#endif
+extern int kbd_cngetc __P((dev_t));
+extern void kbd_cnpollc __P((dev_t, int));
+extern void wscons_kbd_bell __P((void));
diff --git a/sys/arch/alpha/wscons/ms.c b/sys/arch/alpha/wscons/ms.c
index ed544fec876..938cffd4b8d 100644
--- a/sys/arch/alpha/wscons/ms.c
+++ b/sys/arch/alpha/wscons/ms.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ms.c,v 1.2 1996/07/29 23:02:53 niklas Exp $ */
-/* $NetBSD: ms.c,v 1.1 1996/04/12 02:00:47 cgd Exp $ */
+/* $OpenBSD: ms.c,v 1.3 1996/10/30 22:41:43 niklas Exp $ */
+/* $NetBSD: ms.c,v 1.2 1996/09/15 17:15:29 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -54,6 +54,7 @@
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
+#include <sys/signalvar.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/tty.h>
@@ -61,6 +62,7 @@
#include <machine/vuid_event.h>
#include <alpha/wscons/event_var.h>
#include <alpha/wscons/wsconsvar.h>
+#include <alpha/wscons/ms.h>
struct ms_softc {
struct device *ms_dev;
@@ -177,7 +179,7 @@ msopen(dev, flags, mode, p)
int flags, mode;
struct proc *p;
{
- int s, error;
+ int error;
if (ms_softc.ms_dev == NULL) /* never attached! */
return (ENXIO);
@@ -246,8 +248,6 @@ msioctl(dev, cmd, data, flag, p)
int flag;
struct proc *p;
{
- int s;
-
switch (cmd) {
case FIONBIO: /* we will remove this someday (soon???) */
@@ -275,12 +275,22 @@ msioctl(dev, cmd, data, flag, p)
return (ENOTTY);
}
+#ifdef notyet
+int
+mspoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
+{
+ return (ev_poll(&ms_softc.ms_events, events, p));
+}
+#else
int
msselect(dev, rw, p)
dev_t dev;
int rw;
struct proc *p;
{
-
return (ev_select(&ms_softc.ms_events, rw, p));
}
+#endif
diff --git a/sys/arch/alpha/wscons/ms.h b/sys/arch/alpha/wscons/ms.h
new file mode 100644
index 00000000000..cedfd65f73b
--- /dev/null
+++ b/sys/arch/alpha/wscons/ms.h
@@ -0,0 +1,45 @@
+/* $OpenBSD: ms.h,v 1.1 1996/10/30 22:41:44 niklas Exp $ */
+
+/*
+ * Copyright (c) 1996 Niklas Hallqvist
+ * 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 Niklas Hallqvist.
+ * 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 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.
+ */
+
+extern void msattach __P((struct device *, struct wscons_mdev_spec *));
+extern void ms_event __P((char, int, int));
+extern int msopen __P((dev_t, int, int, struct proc *));
+extern int msclose __P((dev_t, int, int, struct proc *));
+extern int msread __P((dev_t, struct uio *, int));
+extern int mswrite __P((dev_t, struct uio *, int));
+extern int msioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+#ifdef notyet
+extern int mspoll __P((dev_t, int, struct proc *));
+#else
+extern int msselect __P((dev_t, int, struct proc *));
+#endif
diff --git a/sys/arch/alpha/wscons/wscons.c b/sys/arch/alpha/wscons/wscons.c
index 9d8be9ab787..c86feeea15e 100644
--- a/sys/arch/alpha/wscons/wscons.c
+++ b/sys/arch/alpha/wscons/wscons.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wscons.c,v 1.2 1996/07/29 23:02:55 niklas Exp $ */
-/* $NetBSD: wscons.c,v 1.3.4.1 1996/06/03 18:54:35 cgd Exp $ */
+/* $OpenBSD: wscons.c,v 1.3 1996/10/30 22:41:46 niklas Exp $ */
+/* $NetBSD: wscons.c,v 1.7 1996/10/13 03:00:45 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -42,6 +42,7 @@
#include <dev/cons.h>
#include <alpha/wscons/wsconsvar.h>
#include <alpha/wscons/wscons_emul.h>
+#include <alpha/wscons/kbd.h>
#include <machine/wsconsio.h>
cdev_decl(wscons);
@@ -432,6 +433,7 @@ wsconsstop(tp, flag)
if (!ISSET(tp->t_state, TS_TTSTOP))
SET(tp->t_state, TS_FLUSH);
splx(s);
+ return 0;
}
/*
@@ -492,5 +494,5 @@ wscons_cnpollc(dev, i)
int i;
{
- kbd_cngetc(dev, i); /* XXX XXX */
+ kbd_cnpollc(dev, i); /* XXX XXX */
}
diff --git a/sys/arch/alpha/wscons/wscons_emul.c b/sys/arch/alpha/wscons/wscons_emul.c
index 623ee8d2511..0fd4450c4a3 100644
--- a/sys/arch/alpha/wscons/wscons_emul.c
+++ b/sys/arch/alpha/wscons/wscons_emul.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wscons_emul.c,v 1.2 1996/07/29 23:02:57 niklas Exp $ */
-/* $NetBSD: wscons_emul.c,v 1.2 1996/04/12 06:10:29 cgd Exp $ */
+/* $OpenBSD: wscons_emul.c,v 1.3 1996/10/30 22:41:47 niklas Exp $ */
+/* $NetBSD: wscons_emul.c,v 1.4 1996/10/13 03:00:47 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -36,8 +36,18 @@
#include <sys/systm.h>
#include <alpha/wscons/wsconsvar.h>
#include <alpha/wscons/wscons_emul.h>
+#include <alpha/wscons/kbd.h>
#include <alpha/wscons/ascii.h>
+static __inline int wscons_emul_input_normal
+ __P((struct wscons_emul_data *, char));
+static __inline int wscons_emul_input_haveesc
+ __P((struct wscons_emul_data *, char));
+static __inline void wscons_emul_docontrol
+ __P((struct wscons_emul_data *, char));
+static __inline int wscons_emul_input_control
+ __P((struct wscons_emul_data *, char));
+
void
wscons_emul_attach(we, wo)
struct wscons_emul_data *we;
@@ -74,7 +84,7 @@ wscons_emul_attach(we, wo)
(*we->ac_ef->wef_cursor)(we->ac_efa, 1, we->ac_crow, we->ac_ccol);
}
-static inline int
+static __inline int
wscons_emul_input_normal(we, c)
struct wscons_emul_data *we;
char c;
@@ -195,7 +205,7 @@ wscons_emul_input_normal(we, c)
return newstate;
}
-static inline int
+static __inline int
wscons_emul_input_haveesc(we, c)
struct wscons_emul_data *we;
char c;
@@ -219,7 +229,7 @@ wscons_emul_input_haveesc(we, c)
return newstate;
}
-static inline void
+static __inline void
wscons_emul_docontrol(we, c)
struct wscons_emul_data *we;
char c;
@@ -349,7 +359,7 @@ wscons_emul_docontrol(we, c)
}
}
-static inline int
+static __inline int
wscons_emul_input_control(we, c)
struct wscons_emul_data *we;
char c;
diff --git a/sys/arch/alpha/wscons/wscons_emul.h b/sys/arch/alpha/wscons/wscons_emul.h
index 334e556464d..12368860050 100644
--- a/sys/arch/alpha/wscons/wscons_emul.h
+++ b/sys/arch/alpha/wscons/wscons_emul.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_emul.h,v 1.2 1996/07/29 23:02:59 niklas Exp $ */
+/* $OpenBSD: wscons_emul.h,v 1.3 1996/10/30 22:41:49 niklas Exp $ */
/* $NetBSD: wscons_emul.h,v 1.2 1996/04/12 06:10:32 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/wscons/wscons_raster.h b/sys/arch/alpha/wscons/wscons_raster.h
index 9de352b40cd..5a1d4a6b336 100644
--- a/sys/arch/alpha/wscons/wscons_raster.h
+++ b/sys/arch/alpha/wscons/wscons_raster.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: wscons_raster.h,v 1.2 1996/07/29 23:03:00 niklas Exp $ */
-/* $NetBSD: wscons_raster.h,v 1.1 1996/04/12 02:00:51 cgd Exp $ */
+/* $OpenBSD: wscons_raster.h,v 1.3 1996/10/30 22:41:50 niklas Exp $ */
+/* $NetBSD: wscons_raster.h,v 1.2 1996/07/09 00:55:47 cgd Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -75,7 +75,9 @@ struct rcons {
};
#define RC_STANDOUT 0x001 /* standout mode */
-/* #define RC_BOLD 0x? /* boldface mode */
+#if 0
+#define RC_BOLD 0x? /* boldface mode */
+#endif
#define RC_INVERT 0x002 /* inverted screen colors */
#define RC_CURSOR 0x004 /* cursor currently displayed */
diff --git a/sys/arch/alpha/wscons/wscons_rfont.h b/sys/arch/alpha/wscons/wscons_rfont.h
index b9321173025..65c1e878dc9 100644
--- a/sys/arch/alpha/wscons/wscons_rfont.h
+++ b/sys/arch/alpha/wscons/wscons_rfont.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_rfont.h,v 1.2 1996/07/29 23:03:02 niklas Exp $ */
+/* $OpenBSD: wscons_rfont.h,v 1.3 1996/10/30 22:41:52 niklas Exp $ */
/* $NetBSD: wscons_rfont.h,v 1.1 1996/04/12 02:00:52 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/wscons/wscons_rinit.c b/sys/arch/alpha/wscons/wscons_rinit.c
index 66e3dcaeb6d..3556c285800 100644
--- a/sys/arch/alpha/wscons/wscons_rinit.c
+++ b/sys/arch/alpha/wscons/wscons_rinit.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: wscons_rinit.c,v 1.2 1996/07/29 23:03:04 niklas Exp $ */
-/* $NetBSD: wscons_rinit.c,v 1.1 1996/04/12 02:00:54 cgd Exp $ */
+/* $OpenBSD: wscons_rinit.c,v 1.3 1996/10/30 22:41:54 niklas Exp $ */
+/* $NetBSD: wscons_rinit.c,v 1.2 1996/07/09 00:55:50 cgd Exp $ */
/*
* Copyright (c) 1991, 1993
@@ -46,7 +46,7 @@
*/
#include <sys/param.h>
-#include <sys/kernel.h>
+#include <sys/systm.h>
#include <sys/device.h>
#include <dev/rcons/raster.h>
@@ -54,6 +54,8 @@
#include <alpha/wscons/wscons_rfont.h>
+void rcons_initfont __P((struct rcons *, struct raster_font *));
+
void
rcons_initfont(rc, fp)
struct rcons *rc;
diff --git a/sys/arch/alpha/wscons/wscons_rops.c b/sys/arch/alpha/wscons/wscons_rops.c
index 98ed8eab10b..24a461cca38 100644
--- a/sys/arch/alpha/wscons/wscons_rops.c
+++ b/sys/arch/alpha/wscons/wscons_rops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_rops.c,v 1.2 1996/07/29 23:03:06 niklas Exp $ */
+/* $OpenBSD: wscons_rops.c,v 1.3 1996/10/30 22:41:55 niklas Exp $ */
/* $NetBSD: wscons_rops.c,v 1.1 1996/04/12 02:00:55 cgd Exp $ */
/*
diff --git a/sys/arch/alpha/wscons/wsconsvar.h b/sys/arch/alpha/wscons/wsconsvar.h
index 361113545eb..27db5939d40 100644
--- a/sys/arch/alpha/wscons/wsconsvar.h
+++ b/sys/arch/alpha/wscons/wsconsvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsvar.h,v 1.2 1996/07/29 23:03:07 niklas Exp $ */
+/* $OpenBSD: wsconsvar.h,v 1.3 1996/10/30 22:41:56 niklas Exp $ */
/* $NetBSD: wsconsvar.h,v 1.2 1996/04/12 06:10:36 cgd Exp $ */
/*