summaryrefslogtreecommitdiff
path: root/sys/arch/solbourne
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/solbourne')
-rw-r--r--sys/arch/solbourne/Makefile45
-rw-r--r--sys/arch/solbourne/compile/.cvsignore2
-rw-r--r--sys/arch/solbourne/conf/GENERIC38
-rw-r--r--sys/arch/solbourne/conf/Makefile.solbourne168
-rw-r--r--sys/arch/solbourne/conf/files.solbourne33
-rw-r--r--sys/arch/solbourne/conf/ld.script53
-rw-r--r--sys/arch/solbourne/dev/obio.c142
-rw-r--r--sys/arch/solbourne/dev/tod.c236
-rw-r--r--sys/arch/solbourne/dev/todreg.h72
-rw-r--r--sys/arch/solbourne/dev/zsclock.c192
-rw-r--r--sys/arch/solbourne/include/_float.h3
-rw-r--r--sys/arch/solbourne/include/_types.h3
-rw-r--r--sys/arch/solbourne/include/asm.h3
-rw-r--r--sys/arch/solbourne/include/atomic.h10
-rw-r--r--sys/arch/solbourne/include/autoconf.h3
-rw-r--r--sys/arch/solbourne/include/bppioctl.h3
-rw-r--r--sys/arch/solbourne/include/bsd_openprom.h3
-rw-r--r--sys/arch/solbourne/include/bus.h3
-rw-r--r--sys/arch/solbourne/include/cdefs.h3
-rw-r--r--sys/arch/solbourne/include/conf.h3
-rw-r--r--sys/arch/solbourne/include/cpu.h3
-rw-r--r--sys/arch/solbourne/include/ctlreg.h3
-rw-r--r--sys/arch/solbourne/include/db_machdep.h3
-rw-r--r--sys/arch/solbourne/include/disklabel.h3
-rw-r--r--sys/arch/solbourne/include/eeprom.h3
-rw-r--r--sys/arch/solbourne/include/endian.h3
-rw-r--r--sys/arch/solbourne/include/exec.h3
-rw-r--r--sys/arch/solbourne/include/fbvar.h3
-rw-r--r--sys/arch/solbourne/include/fenv.h3
-rw-r--r--sys/arch/solbourne/include/frame.h3
-rw-r--r--sys/arch/solbourne/include/fsr.h3
-rw-r--r--sys/arch/solbourne/include/idprom.h3
-rw-r--r--sys/arch/solbourne/include/idt.h189
-rw-r--r--sys/arch/solbourne/include/ieee.h3
-rw-r--r--sys/arch/solbourne/include/ieeefp.h3
-rw-r--r--sys/arch/solbourne/include/instr.h3
-rw-r--r--sys/arch/solbourne/include/ioctl_fd.h3
-rw-r--r--sys/arch/solbourne/include/kap.h173
-rw-r--r--sys/arch/solbourne/include/kcore.h3
-rw-r--r--sys/arch/solbourne/include/limits.h3
-rw-r--r--sys/arch/solbourne/include/lock.h3
-rw-r--r--sys/arch/solbourne/include/mutex.h3
-rw-r--r--sys/arch/solbourne/include/oldmon.h3
-rw-r--r--sys/arch/solbourne/include/openpromio.h3
-rw-r--r--sys/arch/solbourne/include/param.h132
-rw-r--r--sys/arch/solbourne/include/pcb.h3
-rw-r--r--sys/arch/solbourne/include/pmap.h112
-rw-r--r--sys/arch/solbourne/include/proc.h3
-rw-r--r--sys/arch/solbourne/include/profile.h3
-rw-r--r--sys/arch/solbourne/include/prom.h109
-rw-r--r--sys/arch/solbourne/include/psl.h3
-rw-r--r--sys/arch/solbourne/include/pte.h95
-rw-r--r--sys/arch/solbourne/include/ptrace.h3
-rw-r--r--sys/arch/solbourne/include/reg.h3
-rw-r--r--sys/arch/solbourne/include/reloc.h3
-rw-r--r--sys/arch/solbourne/include/setjmp.h3
-rw-r--r--sys/arch/solbourne/include/signal.h3
-rw-r--r--sys/arch/solbourne/include/spinlock.h3
-rw-r--r--sys/arch/solbourne/include/stdarg.h3
-rw-r--r--sys/arch/solbourne/include/sun_disklabel.h3
-rw-r--r--sys/arch/solbourne/include/tcb.h3
-rw-r--r--sys/arch/solbourne/include/trap.h3
-rw-r--r--sys/arch/solbourne/include/varargs.h3
-rw-r--r--sys/arch/solbourne/include/vmparam.h27
-rw-r--r--sys/arch/solbourne/include/z8530var.h3
-rw-r--r--sys/arch/solbourne/solbourne/autoconf.c603
-rw-r--r--sys/arch/solbourne/solbourne/clock.c169
-rw-r--r--sys/arch/solbourne/solbourne/genassym.cf109
-rw-r--r--sys/arch/solbourne/solbourne/locore.s4662
-rw-r--r--sys/arch/solbourne/solbourne/machdep.c745
-rw-r--r--sys/arch/solbourne/solbourne/mem.c225
-rw-r--r--sys/arch/solbourne/solbourne/pmap.c1625
-rw-r--r--sys/arch/solbourne/solbourne/prom_machdep.c302
-rw-r--r--sys/arch/solbourne/solbourne/trap.c902
74 files changed, 0 insertions, 11311 deletions
diff --git a/sys/arch/solbourne/Makefile b/sys/arch/solbourne/Makefile
deleted file mode 100644
index d6e52d62bdc..00000000000
--- a/sys/arch/solbourne/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-# $OpenBSD: Makefile,v 1.8 2013/12/08 14:46:39 espie Exp $
-
-S= ${.CURDIR}/../..
-KFILE= GENERIC
-.if exists(conf/GENERIC.MP)
-KFILE= GENERIC.MP
-.endif
-TDIRS= ${_arch} include
-TAGS= ${.CURDIR}/tags
-
-NOPROG=
-NOMAN=
-NOOBJ=
-SUBDIR=
-
-# config the fattest kernel we can find into a temporary dir
-# to create a Makefile. Then use make to pull some variables
-# out and push them into the sub-shell to expand the paths,
-# and finally run ctags.
-tags::
- TDIR=`mktemp -d /tmp/_tagXXXXXXXXXX` || exit 1; \
- eval "S=${S}" && \
- config -s ${S} -b $${TDIR} ${.CURDIR}/conf/${KFILE} && \
- eval "_arch=\"`make -V _arch -f $${TDIR}/Makefile`\"" && \
- eval "_mach=\"`make -V _mach -f $${TDIR}/Makefile`\"" && \
- eval "_machdir=\$S/arch/$${_mach}" && \
- eval "_archdir=\$S/arch/$${_arch}" && \
- eval "HFILES=\"`find $S \( -path $S/'arch' -o -path $S/stand -o -path $S/lib/libsa -o -path $S'/lib/libkern/arch' \) -prune -o -name '*.h'; find $${_machdir} $${_archdir} $S/lib/libkern/arch/$${_mach} \( -name boot -o -name stand \) -prune -o -name '*.h'`\"" && \
- eval "SFILES=\"`make -V SFILES -f $${TDIR}/Makefile`\"" && \
- eval "CFILES=\"`make -V CFILES -f $${TDIR}/Makefile`\"" && \
- eval "AFILES=\"`make -V AFILES -f $${TDIR}/Makefile`\"" && \
- ctags -wd -f ${TAGS} $${CFILES} $${HFILES} && \
- egrep "^[_A-Z]*ENTRY[_A-Z]*\(.*\)" $${SFILES} $${AFILES} | \
- sed "s;\\([^:]*\\):\\([^(]*\\)(\\([^, )]*\\)\\(.*\\);\\3 \\1 /^\\2(\\3\\4$$/;" \
- >> ${TAGS} && \
- sort -o ${TAGS} ${TAGS} && \
- rm -rf $${TDIR}
-
-links:
- -for i in conf ${TDIRS}; do \
- (cd $$i && rm -f tags; ln -s tags tags); done
-
-obj: _SUBDIRUSE
-
-.include <bsd.prog.mk>
diff --git a/sys/arch/solbourne/compile/.cvsignore b/sys/arch/solbourne/compile/.cvsignore
deleted file mode 100644
index b72af3039e6..00000000000
--- a/sys/arch/solbourne/compile/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-GENERIC
-RAMDISK
diff --git a/sys/arch/solbourne/conf/GENERIC b/sys/arch/solbourne/conf/GENERIC
deleted file mode 100644
index 358de46af88..00000000000
--- a/sys/arch/solbourne/conf/GENERIC
+++ /dev/null
@@ -1,38 +0,0 @@
-# $OpenBSD: GENERIC,v 1.3 2005/04/30 00:49:36 deraadt Exp $
-#
-# For further information on compiling OpenBSD kernels, see the config(8)
-# man page.
-#
-# For further information on hardware support for this architecture, see
-# the intro(4) man page. For further information about kernel options
-# for this architecture, see the options(4) man page. For an explanation
-# of each device driver in this file see the section 4 man page for the
-# device.
-
-machine solbourne sparc
-include "../../../conf/GENERIC"
-maxusers 32 # estimated number of users
-
-option SOLBOURNE # necessary for proper config(8) operation
-
-# Generic swap; second partition of root disk or network.
-config bsd swap generic
-
-# Main bus and CPU .. all systems.
-mainbus0 at root
-cpu0 at mainbus0
-obio0 at mainbus0
-
-# Oki MSM62X42BRS TODclock
-tod0 at obio0
-
-# Zilog 8530 serial chips. Each has two-channels.
-# zs0 is ttya and ttyb. zs1 is the keyboard and mouse.
-zs0 at obio0
-zs1 at obio0
-
-zstty* at zs?
-zsclock0 at zs1
-
-# On-board Ethernet
-le0 at obio0
diff --git a/sys/arch/solbourne/conf/Makefile.solbourne b/sys/arch/solbourne/conf/Makefile.solbourne
deleted file mode 100644
index 1607941a4bc..00000000000
--- a/sys/arch/solbourne/conf/Makefile.solbourne
+++ /dev/null
@@ -1,168 +0,0 @@
-# $OpenBSD: Makefile.solbourne,v 1.47 2015/01/13 01:12:50 deraadt Exp $
-
-# For instructions on building kernels consult the config(8) and options(4)
-# manual pages.
-#
-# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
-# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
-# DEBUG is set to -g by config if debugging is requested (config -g).
-# PROF is set to -pg by config if profiling is requested (config -p).
-
-.include <bsd.own.mk>
-
-SIZE?= size
-STRIP?= strip
-
-# source tree is located via $S relative to the compilation directory
-.ifndef S
-S!= cd ../../../..; pwd
-.endif
-
-_machdir?= $S/arch/${_mach}
-_archdir?= $S/arch/${_arch}
-
-INCLUDES= -nostdinc -I$S -I. -I$S/arch
-CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -D__${_mach}__ -MD -MP
-CWARNFLAGS= -Werror -Wall -Wimplicit-function-declaration \
- -Wno-main -Wno-uninitialized \
- -Wframe-larger-than=2047
-
-CMACHFLAGS= -mno-fpu
-CMACHFLAGS+= -fno-builtin-printf -fno-builtin-snprintf \
- -fno-builtin-vsnprintf -fno-builtin-log \
- -fno-builtin-log2 -fno-builtin-malloc ${NOPIE_FLAGS}
-.if ${IDENT:M-DNO_PROPOLICE}
-CMACHFLAGS+= -fno-stack-protector
-.endif
-
-COPTS?= -O2
-CFLAGS= ${DEBUG} ${CWARNFLAGS} ${CMACHFLAGS} ${COPTS} ${PIPE}
-AFLAGS= -D_LOCORE -x assembler-with-cpp ${CWARNFLAGS} ${CMACHFLAGS}
-LDSCRIPT= ${_machdir}/conf/ld.script
-LINKFLAGS= -N -e start -T ${LDSCRIPT} -Ttext FD084000 --warn-common -nopie
-
-.if ${IDENT:M-DDDB_STRUCT}
-DB_STRUCTINFO= db_structinfo.h
-.else
-DB_STRUCTINFO=
-.endif
-
-HOSTCC?= ${CC}
-HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}
-HOSTED_CFLAGS= ${CFLAGS}
-HOSTED_C= ${HOSTCC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
-
-NORMAL_C_NOP= ${CC} ${CFLAGS} ${CPPFLAGS} -c $<
-NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
-NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
-
-%OBJS
-
-%CFILES
-
-%SFILES
-
-# load lines for config "xxx" will be emitted as:
-# xxx: ${SYSTEM_DEP} swapxxx.o
-# ${SYSTEM_LD_HEAD}
-# ${SYSTEM_LD} swapxxx.o
-# ${SYSTEM_LD_TAIL}
-SYSTEM_HEAD= locore.o param.o ioconf.o
-SYSTEM_OBJ= ${SYSTEM_HEAD} ${OBJS}
-SYSTEM_DEP= Makefile ${SYSTEM_OBJ} ${LDSCRIPT}
-SYSTEM_LD_HEAD= @rm -f $@
-SYSTEM_LD= @echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_HEAD} vers.o $${OBJS}'; \
- ${LD} ${LINKFLAGS} -o $@ ${SYSTEM_HEAD} vers.o ${OBJS}
-SYSTEM_LD_TAIL= @${SIZE} $@; chmod 755 $@
-
-DEBUG?=
-.if ${DEBUG} == "-g"
-LINKFLAGS+= -X
-STRIPFLAGS= -g -x
-SYSTEM_LD_TAIL+=; \
- echo mv $@ $@.gdb; rm -f $@.gdb; mv $@ $@.gdb; \
- echo ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb; \
- ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb
-.else
-LINKFLAGS+= -S -x
-.endif
-
-%LOAD
-
-# cc's -MD puts the source and output paths in the dependency file;
-# since those are temp files here we need to fix it up. It also
-# puts the file in /tmp, so we use -MF to put it in the current
-# directory as assym.P and then generate assym.d from it with a
-# good target name
-assym.h: $S/kern/genassym.sh Makefile \
- ${_archdir}/${_arch}/genassym.cf ${_machdir}/${_mach}/genassym.cf
- cat ${_archdir}/${_arch}/genassym.cf ${_machdir}/${_mach}/genassym.cf | \
- sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} -MF assym.P > assym.h.tmp
- sed '1s/.*/assym.h: \\/' assym.P > assym.d
- sort -u assym.h.tmp > assym.h
-
-param.c: $S/conf/param.c
- rm -f param.c
- cp $S/conf/param.c .
-
-param.o: param.c Makefile
- ${NORMAL_C}
-
-mcount.o: $S/lib/libkern/mcount.c Makefile
- ${NORMAL_C_NOP}
-
-ioconf.o: ioconf.c
- ${NORMAL_C}
-
-vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
- sh $S/conf/newvers.sh
- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
-
-clean::
- rm -f eddep *bsd *bsd.gdb tags *.[dio] [a-z]*.s \
- [Ee]rrs linterrs assym.h ${DB_STRUCTINFO}
-
-lint:
- @lint -hbxncez -Dvolatile= ${CPPFLAGS} -UKGDB \
- ${CFILES} ioconf.c param.c | \
- grep -v 'static function .* unused'
-
-depend:
- @touch $@
-
-tags:
- @echo "see $S/kern/Makefile for tags"
-
-db_structinfo.h: $S/ddb/db_structinfo.c $S/ddb/parse_structinfo.pl
- ${CC} ${CFLAGS} ${CPPFLAGS} -MT $@ -gstabs -c $S/ddb/db_structinfo.c
- objdump -g db_structinfo.o | perl $S/ddb/parse_structinfo.pl > $@
- rm -f db_structinfo.o
-
-locore.o: ${_machdir}/${_mach}/locore.s assym.h
-
-# The install target can be redefined by putting a
-# install-kernel-${MACHINE_NAME} target into /etc/mk.conf
-MACHINE_NAME!= uname -n
-install: install-kernel-${MACHINE_NAME}
-.if !target(install-kernel-${MACHINE_NAME}})
-install-kernel-${MACHINE_NAME}:
- cmp -s bsd /bsd || ln -f /bsd /obsd
- cp bsd /nbsd
- mv /nbsd /bsd
-.endif
-
-# pull in the dependency information
-.if !empty(DB_STRUCTINFO) && !exists(${DB_STRUCTINFO})
- ${SYSTEM_OBJ}: ${DB_STRUCTINFO}
-.endif
-.ifnmake clean
-. for o in ${SYSTEM_OBJ} assym.h ${DB_STRUCTINFO}
-. if exists(${o:R}.d)
-. include "${o:R}.d"
-. elif exists($o)
- .PHONY: $o
-. endif
-. endfor
-.endif
-
-%RULES
diff --git a/sys/arch/solbourne/conf/files.solbourne b/sys/arch/solbourne/conf/files.solbourne
deleted file mode 100644
index c6e3b04bea0..00000000000
--- a/sys/arch/solbourne/conf/files.solbourne
+++ /dev/null
@@ -1,33 +0,0 @@
-# $OpenBSD: files.solbourne,v 1.2 2006/06/19 15:13:35 deraadt Exp $
-
-# Kernel configuration rules for OpenBSD/solbourne.
-# Most device definitions and files rules are imported from
-# sys/arch/sparc/conf/files.sparc and are not repeated here.
-# Hence, this file only lists solbourne-specific changes from
-# the sparc port.
-
-maxpartitions 16
-
-maxusers 2 8 64
-
-# obio on solbourne is just an administrative wrapper on which
-# all on-board devices attach.
-file arch/solbourne/dev/obio.c obio
-
-# OKI TODclock chip
-device tod
-attach tod at obio
-file arch/solbourne/dev/tod.c tod
-
-# Z8530 clock hijack
-device zsclock
-attach zsclock at zs
-file arch/solbourne/dev/zsclock.c zsclock
-
-file arch/solbourne/solbourne/autoconf.c
-file arch/solbourne/solbourne/clock.c
-file arch/solbourne/solbourne/machdep.c
-file arch/solbourne/solbourne/mem.c
-file arch/solbourne/solbourne/pmap.c
-file arch/solbourne/solbourne/prom_machdep.c
-file arch/solbourne/solbourne/trap.c
diff --git a/sys/arch/solbourne/conf/ld.script b/sys/arch/solbourne/conf/ld.script
deleted file mode 100644
index 7ba21f5dd27..00000000000
--- a/sys/arch/solbourne/conf/ld.script
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $OpenBSD: ld.script,v 1.2 2007/04/12 18:36:15 miod Exp $ */
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-OUTPUT_FORMAT("a.out-sparc-netbsd")
-OUTPUT_ARCH(sparc)
-ENTRY(start)
-SECTIONS
-{
- .text :
- {
- *(.text)
- . = ALIGN(0x2000);
- PROVIDE(etext = ABSOLUTE(.));
- }
- .data :
- {
- *(.rodata)
- *(.data)
- PROVIDE(edata = ABSOLUTE(.));
- }
- .bss :
- {
- *(.bss)
- }
- PROVIDE(end = ABSOLUTE(.));
- /DISCARD/ :
- {
- *(.comment)
- }
-}
diff --git a/sys/arch/solbourne/dev/obio.c b/sys/arch/solbourne/dev/obio.c
deleted file mode 100644
index 99f1ce5d906..00000000000
--- a/sys/arch/solbourne/dev/obio.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* $OpenBSD: obio.c,v 1.1 2005/04/20 01:00:16 miod Exp $ */
-/* OpenBSD: obio.c,v 1.16 2004/09/29 07:35:11 miod Exp */
-
-/*
- * Copyright (c) 1993, 1994 Theo de Raadt
- * Copyright (c) 1995, 1997 Paul Kranenburg
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. 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/device.h>
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/idt.h>
-
-/* autoconfiguration driver */
-static int obiomatch(struct device *, void *, void *);
-static void obioattach(struct device *, struct device *, void *);
-
-int obioprint(void *, const char *);
-int obio_scan(struct device *, void *, void *);
-
-struct cfattach obio_ca = {
- sizeof(struct device), obiomatch, obioattach
-};
-
-struct cfdriver obio_cd = {
- NULL, "obio", DV_DULL
-};
-
-/*
- * A list of the on-board devices in the IDT systems. This is better than
- * having people playing with locators in their kernel configuration
- * files, and necessary because the device tree built by the PROM does not
- * list all on-board devices (audio and floppy are missing).
- */
-const struct {
- char *devname;
- paddr_t address;
- int intr;
-} obio_devices[] = {
- { "tod", TODCLOCK_BASE, -1 },
- { "nvram", NVRAM_BASE, -1 },
- { "zs", ZS0_BASE, 12 },
- { "zs", ZS1_BASE, 12 },
- { "fdc", FDC_BASE, 11 },
- { "audioamd", AUDIO_BASE, 13 },
- { "wdsc", SE_BASE + 0x20, 4 },
- { "le", SE_BASE + 0x30, 6 },
- { NULL, 0 }
-};
-
-int
-obiomatch(parent, vcf, aux)
- struct device *parent;
- void *vcf, *aux;
-{
- register struct cfdata *cf = vcf;
- register struct confargs *ca = aux;
- register struct romaux *ra = &ca->ca_ra;
-
- return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0);
-}
-
-int
-obioprint(args, obio)
- void *args;
- const char *obio;
-{
- register struct confargs *ca = args;
-
- if (ca->ca_ra.ra_name == NULL)
- ca->ca_ra.ra_name = "<unknown>";
-
- if (obio)
- printf("%s at %s", ca->ca_ra.ra_name, obio);
-
- printf(" addr %p", ca->ca_ra.ra_paddr);
-
- return (UNCONF);
-}
-
-void
-obioattach(parent, self, args)
- struct device *parent, *self;
- void *args;
-{
- struct confargs *ca = args;
- struct confargs oca;
- int i;
-
- if (self->dv_unit > 0) {
- printf(" unsupported\n");
- return;
- }
- printf("\n");
-
- for (i = 0; obio_devices[i].devname != NULL; i++) {
- /* fake a rom_reg */
- bzero(&oca, sizeof oca);
- oca.ca_ra.ra_paddr = (caddr_t)obio_devices[i].address;
- oca.ca_ra.ra_vaddr = NULL;
- oca.ca_ra.ra_len = 0;
- oca.ca_ra.ra_nreg = 1;
- oca.ca_ra.ra_iospace = 0;
- oca.ca_ra.ra_intr[0].int_pri = obio_devices[i].intr;
- oca.ca_ra.ra_intr[0].int_vec = -1;
- oca.ca_ra.ra_nintr = oca.ca_ra.ra_intr[0].int_pri < 0 ? 0 : 1;
- oca.ca_ra.ra_name = obio_devices[i].devname;
- if (ca->ca_ra.ra_bp != NULL)
- oca.ca_ra.ra_bp = ca->ca_ra.ra_bp + 1;
- else
- oca.ca_ra.ra_bp = NULL;
- oca.ca_bustype = BUS_OBIO;
-
- config_found(self, &oca, obioprint);
- }
-}
diff --git a/sys/arch/solbourne/dev/tod.c b/sys/arch/solbourne/dev/tod.c
deleted file mode 100644
index 86f8503bb51..00000000000
--- a/sys/arch/solbourne/dev/tod.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* $OpenBSD: tod.c,v 1.1 2005/04/20 01:00:16 miod Exp $ */
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TODclock driver. We only use it to know the current time during boot,
- * as we do not get interrupts from it.
- *
- * The clock in the IDT machines is the Oki MSM62X42BRS.
- *
- * A datasheet for this chip is available from:
- * http://www.datasheetarchive.com/datasheet/pdf/19/196099.html
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-#include <sys/systm.h>
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-
-#include <solbourne/dev/todreg.h>
-#include <dev/clock_subr.h>
-
-#include <machine/idt.h>
-#include <machine/kap.h>
-
-int todmatch(struct device *, void *, void *);
-void todattach(struct device *, struct device *, void *);
-
-struct cfattach tod_ca = {
- sizeof(struct device), todmatch, todattach
-};
-
-struct cfdriver tod_cd = {
- NULL, "tod", DV_DULL
-};
-
-volatile u_char *tod_regs;
-
-u_char msm_read(u_int);
-void msm_write(u_int, u_char);
-
-int
-todmatch(parent, vcf, aux)
- struct device *parent;
- void *vcf, *aux;
-{
- struct confargs *ca = aux;
-
- return (strcmp(tod_cd.cd_name, ca->ca_ra.ra_name) == 0);
-}
-
-void
-todattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- printf(": OKI MSM62X42BRS\n");
-
- /* the register are already mapped 1:1 by pmap_bootstrap() */
- tod_regs = (volatile u_char *)TODCLOCK_BASE;
-}
-
-/*
- * Read or write a register of the Oki clock.
- *
- * The clock registers are not directly accessible (while control registers
- * are). We need to freeze them first. To do so, we set the hold bit in
- * D, and if the busy bit clears, we are free to proceed. If the busy bit
- * is still set, we need to clear the hold bit and retry.
- */
-u_char
-msm_read(u_int regno)
-{
- u_char d, r;
-
- /* no need to do the hold dance for control registers */
- if (regno >= MSM_D)
- return (tod_regs[regno] & 0x0f);
-
- d = tod_regs[MSM_D] & 0x0f & ~MSM_D_HOLD;
- for (;;) {
- tod_regs[MSM_D] = d | MSM_D_HOLD;
- if (!ISSET(tod_regs[MSM_D], MSM_D_BUSY))
- break;
- tod_regs[MSM_D] = d;
- }
-
- r = tod_regs[regno] & 0x0f;
- tod_regs[MSM_D] = d;
-
- return (r);
-}
-
-void
-msm_write(u_int regno, u_char value)
-{
- u_char d;
-
- /* no need to do the hold dance for control registers */
- if (regno >= MSM_D) {
- tod_regs[regno] = value;
- return;
- }
-
- d = tod_regs[MSM_D] & 0x0f & ~MSM_D_HOLD;
- for (;;) {
- tod_regs[MSM_D] = d | MSM_D_HOLD;
- if (!ISSET(tod_regs[MSM_D], MSM_D_BUSY))
- break;
- tod_regs[MSM_D] = d;
- }
-
- tod_regs[regno] = value;
- tod_regs[MSM_D] = d;
-}
-
-void
-inittodr(base)
- time_t base;
-{
- struct clock_ymdhms dt;
-
- dt.dt_sec = msm_read(MSM_SEC_UNITS) + 10 * msm_read(MSM_SEC_TENS);
- dt.dt_min = msm_read(MSM_MIN_UNITS) + 10 * msm_read(MSM_MIN_TENS);
-#if 0
- dt.dt_hour = msm_read(MSM_HOUR_UNITS) + 10 * msm_read(MSM_HOUR_TENS);
-#else
- dt.dt_hour = msm_read(MSM_HOUR_TENS);
- if (dt.dt_hour & MSM_HOUR_PM)
- dt.dt_hour = 12 + 10 * (dt.dt_hour & ~MSM_HOUR_TENS);
- else
- dt.dt_hour *= 10;
- dt.dt_hour += msm_read(MSM_HOUR_UNITS);
-#endif
- dt.dt_day = msm_read(MSM_DAY_UNITS) + 10 * msm_read(MSM_DAY_TENS);
- dt.dt_mon = msm_read(MSM_MONTH_UNITS) + 10 * msm_read(MSM_MONTH_TENS);
- dt.dt_year = msm_read(MSM_YEAR_UNITS) + 10 * msm_read(MSM_YEAR_TENS);
- dt.dt_year += CLOCK_YEAR_BASE;
- /* dt_wday left uninitialized */
-
- time.tv_sec = clock_ymdhms_to_secs(&dt);
-
- if (time.tv_sec == 0) {
- /*
- * Believe the time in the file system for lack of
- * anything better, resetting the clock.
- */
- if (base < 35 * SECYR) {/* this port did not exist until 2005 */
- /*
- * If base is 0, assume filesystem time is just unknown
- * in stead of preposterous. Don't bark.
- */
- if (base != 0)
- printf("WARNING: preposterous time in file system\n");
- /* not going to use it anyway, if the chip is readable */
- time.tv_sec = 35 * SECYR + 90 * SECDAY + SECDAY / 2;
- } else {
- printf("WARNING: bad date in battery clock");
- time.tv_sec = base;
- resettodr();
- }
- } else {
- int deltat = time.tv_sec - base;
-
- if (deltat < 0)
- deltat = -deltat;
- if (deltat < 2 * SECDAY)
- return;
-
-#ifndef SMALL_KERNEL
- printf("WARNING: clock %s %d days",
- time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
-#endif
- }
- printf(" -- CHECK AND RESET THE DATE!\n");
-}
-
-void
-resettodr()
-{
- struct clock_ymdhms dt;
-
- if (time.tv_sec == 0 || tod_regs == NULL)
- return;
-
- clock_secs_to_ymdhms(time.tv_sec, &dt);
-
- /*
- * Since we don't know if the clock is in AM/PM or 24 hour mode,
- * we need to reset it and force one mode. Being an evil european
- * person, I'll force 24 hour mode, of course.
- */
- msm_write(MSM_F, MSM_F_RESET | MSM_F_24HR);
- msm_write(MSM_F, MSM_F_STOP); /* leave reset mode, but stop clock */
-
- dt.dt_year -= CLOCK_YEAR_BASE;
- msm_write(MSM_YEAR_TENS, dt.dt_year / 10);
- msm_write(MSM_YEAR_UNITS, dt.dt_year % 10);
- msm_write(MSM_MONTH_TENS, dt.dt_mon / 10);
- msm_write(MSM_MONTH_UNITS, dt.dt_mon % 10);
- msm_write(MSM_DAY_TENS, dt.dt_day / 10);
- msm_write(MSM_DAY_UNITS, dt.dt_day % 10);
- msm_write(MSM_HOUR_TENS, dt.dt_hour / 10);
- msm_write(MSM_HOUR_UNITS, dt.dt_hour % 10);
- msm_write(MSM_MIN_TENS, dt.dt_min / 10);
- msm_write(MSM_MIN_UNITS, dt.dt_min % 10);
- msm_write(MSM_SEC_TENS, dt.dt_sec / 10);
- msm_write(MSM_SEC_UNITS, dt.dt_sec % 10);
-
- msm_write(MSM_F, 0); /* restart clock */
-}
diff --git a/sys/arch/solbourne/dev/todreg.h b/sys/arch/solbourne/dev/todreg.h
deleted file mode 100644
index 540fdf2f06f..00000000000
--- a/sys/arch/solbourne/dev/todreg.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $OpenBSD: todreg.h,v 1.1 2005/04/20 01:00:16 miod Exp $ */
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Oki MSM62X42BRS registers.
- *
- * A datasheet for this chip is available from:
- * http://www.datasheetarchive.com/datasheet/pdf/19/196099.html
- */
-
-#define MSM_REG(x) ((x) << 3)
-
-#define MSM_SEC_UNITS MSM_REG(0) /* seconds, low digit */
-#define MSM_SEC_TENS MSM_REG(1) /* seconds, high digit */
-#define MSM_MIN_UNITS MSM_REG(2) /* minutes, low digit */
-#define MSM_MIN_TENS MSM_REG(3) /* minutes, high digit */
-#define MSM_HOUR_UNITS MSM_REG(4) /* hours, low digit */
-#define MSM_HOUR_TENS MSM_REG(5) /* hours, high digit */
-#define MSM_HOUR_PM 0x04 /* PM bit if PM mode */
-#define MSM_DAY_UNITS MSM_REG(6) /* day, low digit */
-#define MSM_DAY_TENS MSM_REG(7) /* day, high digit */
-#define MSM_MONTH_UNITS MSM_REG(8) /* month, low digit */
-#define MSM_MONTH_TENS MSM_REG(9) /* month, high digit */
-#define MSM_YEAR_UNITS MSM_REG(10) /* year, low digit */
-#define MSM_YEAR_TENS MSM_REG(11) /* year, high digit */
-#define CLOCK_YEAR_BASE 1968
-#define MSM_DOW MSM_REG(12) /* day of week, 0 = sunday */
-
-#define MSM_D MSM_REG(13) /* control register D */
-#define MSM_D_HOLD 0x01 /* hold clock for access */
-#define MSM_D_BUSY 0x02 /* clock is busy */
-#define MSM_D_INTR 0x04 /* interrupt pending */
-#define MSM_D_30 0x08 /* 30 seconds adjustment */
-
-#define MSM_E MSM_REG(14) /* control register E */
-#define MSM_E_MASK 0x01 /* output mask (set to disable) */
-#define MSM_E_INTR 0x02 /* output interrupts (1) or pulse (0) */
-#define MSM_E_PERIOD 0x04 /* interrupt (or pulse) period - needs
- to be written twice! (2 bits) */
-#define MSM_PERIOD_64HZ 0x00
-#define MSM_PERIOD_1HZ 0x01
-#define MSM_PERIOD_1MIN 0x10
-#define MSM_PERIOD_1HOUR 0x11
-
-#define MSM_F MSM_REG(15) /* control register F */
-#define MSM_F_RESET 0x01 /* reset clock */
-#define MSM_F_STOP 0x02 /* stop clock */
-#define MSM_F_24HR 0x04 /* 24 hour mode (valid on reset only) */
-#define MSM_F_TEST 0x08 /* assert test signal */
diff --git a/sys/arch/solbourne/dev/zsclock.c b/sys/arch/solbourne/dev/zsclock.c
deleted file mode 100644
index 4b0c19557a0..00000000000
--- a/sys/arch/solbourne/dev/zsclock.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* $OpenBSD: zsclock.c,v 1.4 2014/11/18 20:51:01 krw Exp $ */
-/* $NetBSD: clock.c,v 1.11 1995/05/16 07:30:46 phil Exp $ */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz and Don Ahn.
- *
- * 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.
- *
- * @(#)clock.c 7.2 (Berkeley) 5/12/91
- *
- */
-
-/*
- * Primitive clock interrupt routines.
- *
- * Improved by Phil Budne ... 10/17/94.
- * Pulled over code from i386/isa/clock.c (Matthias Pfaller 12/03/94).
- */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/device.h>
-#include <sys/conf.h>
-#include <sys/ioctl.h>
-
-#include <dev/ic/z8530reg.h>
-#include <machine/z8530var.h>
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-
-/*
- * Zilog Z8530 Dual UART driver (clock interface)
- */
-
-/* Clock state. */
-struct zsclock_softc {
- struct device zsc_dev;
- struct zs_chanstate *zsc_cs;
-};
-
-int zsclock_match(struct device *, void *, void *);
-void zsclock_attach(struct device *, struct device *, void *);
-
-struct cfattach zsclock_ca = {
- sizeof(struct zsclock_softc), zsclock_match, zsclock_attach
-};
-
-struct cfdriver zsclock_cd = {
- NULL, "zsclock", DV_DULL
-};
-
-void zsclock_stint(struct zs_chanstate *, int);
-
-struct zsops zsops_clock = {
- NULL,
- zsclock_stint,
- NULL,
- NULL
-};
-
-static int zsclock_attached;
-
-/*
- * clock_match: how is this zs channel configured?
- */
-int
-zsclock_match(struct device *parent, void *match, void *aux)
-{
- struct cfdata *cf = match;
- struct zsc_attach_args *args = aux;
-
- /* only attach one instance */
- if (zsclock_attached)
- return (0);
-
- /* make sure we'll win a probe over zstty or zskbd */
- if (cf->cf_loc[ZSCCF_CHANNEL] == args->channel)
- return (2 + 2);
-
- if (cf->cf_loc[ZSCCF_CHANNEL] == ZSCCF_CHANNEL_DEFAULT)
- return (2 + 1);
-
- return (0);
-}
-
-/*
- * The Solbourne IDT systems provide a 4.9152 MHz clock to the ZS chips.
- */
-#define PCLK (9600 * 512) /* PCLK pin input clock rate */
-
-void
-zsclock_attach(struct device *parent, struct device *self, void *aux)
-{
- struct zsc_softc *zsc = (void *)parent;
- struct zsclock_softc *sc = (void *)self;
- struct zsc_attach_args *args = aux;
- struct zs_chanstate *cs;
- int channel;
- int reset, s, tconst;
-
- channel = args->channel;
-
- cs = &zsc->zsc_cs[channel];
- cs->cs_private = zsc;
- cs->cs_ops = &zsops_clock;
-
- sc->zsc_cs = cs;
-
- printf("\n");
-
- hz = 100;
- tconst = ((PCLK / 2) / hz) - 2;
-
- s = splclock();
-
- reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
- zs_write_reg(cs, 9, reset);
-
- cs->cs_preg[1] = 0;
- cs->cs_preg[3] = ZSWR3_RX_8 | ZSWR3_RX_ENABLE;
- cs->cs_preg[4] = ZSWR4_CLK_X1 | ZSWR4_ONESB | ZSWR4_PARENB;
- cs->cs_preg[5] = ZSWR5_TX_8 | ZSWR5_TX_ENABLE;
- cs->cs_preg[9] = ZSWR9_MASTER_IE;
- cs->cs_preg[10] = 0;
- cs->cs_preg[11] = ZSWR11_RXCLK_RTXC | ZSWR11_TXCLK_RTXC |
- ZSWR11_TRXC_OUT_ENA | ZSWR11_TRXC_BAUD;
- cs->cs_preg[12] = tconst;
- cs->cs_preg[13] = tconst >> 8;
- cs->cs_preg[14] = ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA;
- cs->cs_preg[15] = ZSWR15_ZERO_COUNT_IE;
-
- zs_loadchannelregs(cs);
-
- splx(s);
-
- /* enable interrupts */
- cs->cs_preg[1] |= ZSWR1_SIE;
- zs_write_reg(cs, 1, cs->cs_preg[1]);
-
- zsclock_attached = 1;
-}
-
-void
-zsclock_stint(struct zs_chanstate *cs, int force)
-{
- u_char rr0;
-
- rr0 = zs_read_csr(cs);
- cs->cs_rr0 = rr0;
-
- /*
- * Retrigger the interrupt as a soft interrupt, because we need
- * a trap frame for hardclock().
- */
- ienab_bis(IE_L10);
-
- zs_write_csr(cs, ZSWR0_RESET_STATUS);
-}
diff --git a/sys/arch/solbourne/include/_float.h b/sys/arch/solbourne/include/_float.h
deleted file mode 100644
index fc0d5fae677..00000000000
--- a/sys/arch/solbourne/include/_float.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: _float.h,v 1.1 2012/06/26 16:12:45 deraadt Exp $ */
-
-#include <sparc/_float.h>
diff --git a/sys/arch/solbourne/include/_types.h b/sys/arch/solbourne/include/_types.h
deleted file mode 100644
index 8fb97f7b1e0..00000000000
--- a/sys/arch/solbourne/include/_types.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: _types.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/_types.h>
diff --git a/sys/arch/solbourne/include/asm.h b/sys/arch/solbourne/include/asm.h
deleted file mode 100644
index 4f19a2ca879..00000000000
--- a/sys/arch/solbourne/include/asm.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: asm.h,v 1.1 2005/04/19 21:30:17 miod Exp $ */
-/* public domain */
-#include <sparc/asm.h>
diff --git a/sys/arch/solbourne/include/atomic.h b/sys/arch/solbourne/include/atomic.h
deleted file mode 100644
index 255818f8e0c..00000000000
--- a/sys/arch/solbourne/include/atomic.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* $OpenBSD: atomic.h,v 1.3 2011/03/23 16:54:37 pirofti Exp $ */
-
-/* Public Domain */
-
-#ifndef _MACHINE_ATOMIC_H_
-#define _MACHINE_ATOMIC_H_
-
-#include <sparc/atomic.h>
-
-#endif /* _MACHINE_ATOMIC_H_ */
diff --git a/sys/arch/solbourne/include/autoconf.h b/sys/arch/solbourne/include/autoconf.h
deleted file mode 100644
index 286c94b4d1a..00000000000
--- a/sys/arch/solbourne/include/autoconf.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: autoconf.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/autoconf.h>
diff --git a/sys/arch/solbourne/include/bppioctl.h b/sys/arch/solbourne/include/bppioctl.h
deleted file mode 100644
index e7825b78a65..00000000000
--- a/sys/arch/solbourne/include/bppioctl.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: bppioctl.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/bppioctl.h>
diff --git a/sys/arch/solbourne/include/bsd_openprom.h b/sys/arch/solbourne/include/bsd_openprom.h
deleted file mode 100644
index aa37b7e5b20..00000000000
--- a/sys/arch/solbourne/include/bsd_openprom.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: bsd_openprom.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/bsd_openprom.h>
diff --git a/sys/arch/solbourne/include/bus.h b/sys/arch/solbourne/include/bus.h
deleted file mode 100644
index c4ba781eab0..00000000000
--- a/sys/arch/solbourne/include/bus.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: bus.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/bus.h>
diff --git a/sys/arch/solbourne/include/cdefs.h b/sys/arch/solbourne/include/cdefs.h
deleted file mode 100644
index 1910212e0d8..00000000000
--- a/sys/arch/solbourne/include/cdefs.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: cdefs.h,v 1.3 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/cdefs.h>
diff --git a/sys/arch/solbourne/include/conf.h b/sys/arch/solbourne/include/conf.h
deleted file mode 100644
index 2b6350ef997..00000000000
--- a/sys/arch/solbourne/include/conf.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: conf.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/conf.h>
diff --git a/sys/arch/solbourne/include/cpu.h b/sys/arch/solbourne/include/cpu.h
deleted file mode 100644
index 1f3a883f177..00000000000
--- a/sys/arch/solbourne/include/cpu.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: cpu.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/cpu.h>
diff --git a/sys/arch/solbourne/include/ctlreg.h b/sys/arch/solbourne/include/ctlreg.h
deleted file mode 100644
index 7eea08a1a49..00000000000
--- a/sys/arch/solbourne/include/ctlreg.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: ctlreg.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/ctlreg.h>
diff --git a/sys/arch/solbourne/include/db_machdep.h b/sys/arch/solbourne/include/db_machdep.h
deleted file mode 100644
index 18625753f3e..00000000000
--- a/sys/arch/solbourne/include/db_machdep.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: db_machdep.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/db_machdep.h>
diff --git a/sys/arch/solbourne/include/disklabel.h b/sys/arch/solbourne/include/disklabel.h
deleted file mode 100644
index b666b70a0d2..00000000000
--- a/sys/arch/solbourne/include/disklabel.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: disklabel.h,v 1.3 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/disklabel.h>
diff --git a/sys/arch/solbourne/include/eeprom.h b/sys/arch/solbourne/include/eeprom.h
deleted file mode 100644
index a34c175d266..00000000000
--- a/sys/arch/solbourne/include/eeprom.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: eeprom.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/eeprom.h>
diff --git a/sys/arch/solbourne/include/endian.h b/sys/arch/solbourne/include/endian.h
deleted file mode 100644
index d0b2d04fc3a..00000000000
--- a/sys/arch/solbourne/include/endian.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: endian.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/endian.h>
diff --git a/sys/arch/solbourne/include/exec.h b/sys/arch/solbourne/include/exec.h
deleted file mode 100644
index db385fc4f92..00000000000
--- a/sys/arch/solbourne/include/exec.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: exec.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/exec.h>
diff --git a/sys/arch/solbourne/include/fbvar.h b/sys/arch/solbourne/include/fbvar.h
deleted file mode 100644
index 688e40a6ffb..00000000000
--- a/sys/arch/solbourne/include/fbvar.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: fbvar.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/fbvar.h>
diff --git a/sys/arch/solbourne/include/fenv.h b/sys/arch/solbourne/include/fenv.h
deleted file mode 100644
index 37ae677c085..00000000000
--- a/sys/arch/solbourne/include/fenv.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: fenv.h,v 1.2 2013/06/01 21:20:54 jasper Exp $ */
-/* public domain */
-#include <sparc/fenv.h>
diff --git a/sys/arch/solbourne/include/frame.h b/sys/arch/solbourne/include/frame.h
deleted file mode 100644
index 7fbd9b2430b..00000000000
--- a/sys/arch/solbourne/include/frame.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: frame.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/frame.h>
diff --git a/sys/arch/solbourne/include/fsr.h b/sys/arch/solbourne/include/fsr.h
deleted file mode 100644
index 42028d94dd2..00000000000
--- a/sys/arch/solbourne/include/fsr.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: fsr.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/fsr.h>
diff --git a/sys/arch/solbourne/include/idprom.h b/sys/arch/solbourne/include/idprom.h
deleted file mode 100644
index a9bb99fd509..00000000000
--- a/sys/arch/solbourne/include/idprom.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: idprom.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/idprom.h>
diff --git a/sys/arch/solbourne/include/idt.h b/sys/arch/solbourne/include/idt.h
deleted file mode 100644
index 6357ca91c8a..00000000000
--- a/sys/arch/solbourne/include/idt.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/* $OpenBSD: idt.h,v 1.3 2013/03/21 02:10:37 deraadt Exp $ */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_IDT_H_
-#define _MACHINE_IDT_H_
-
-/*
- * Definitions for the core chips found on the IDT motherboard.
- *
- * All addresses are physical.
- */
-
-/*
- * iGLU: GLUE Logic
- */
-
-#define GLU_BASE 0x60000000
-
-/* profiling timer (level 14) */
-#define GLU_L14_DIVISOR 0x60000000
-#define GLU_L14_RESOLUTION (256 / 5) /* in microseconds */
-#define GLU_L14_ENABLE 0x60000008
-#define GLU_L14_IACK 0x6000000c
-
-/* scheduling timer (level 10) */
-#define GLU_L10_IACK 0x60000800
-
-/* board status register */
-#define GLU_BSR 0x60001800
-#define GBSR_LED_MASK 0x07
-#define GBSR_LED_OFF 00
-#define GBSR_LED_AMBER 02
-#define GBSR_LED_AMBER_BLINK 03
-#define GBSR_LED_GREEN 04
-#define GBSR_LED_GREEN_BLINK 05
-#define GBSR_LED_BOTH_BLINK 07
-#define GBSR_DIAG 0x08
-#define GBSR_WARM 0x10
-#define GBSR_NMI 0x20
-
-/* board diagnostic register */
-#define GLU_DIAG 0x60001808
-#define GD_EXTRA_MEMORY 0x10
-#define GD_36MHZ 0x20
-#define GD_L2_CACHE 0x40
-
-/* interrupt control register */
-#define GLU_ICR 0x60002000
-#define GICR_DISPATCH_MASK 0x0000000f /* post a software interrupt */
-#define GICR_DISABLE_ALL 0x00000010
-
-/* programmable interrupt levels for sbus and onboard audio */
-#define GLU_SBUS1 0x60002008
-#define GLU_SBUS2 0x60002010
-#define GLU_SBUS3 0x60002018
-#define GLU_SBUS4 0x60002020
-#define GLU_SBUS5 0x60002028
-#define GLU_SBUS6 0x60002030
-#define GLU_SBUS7 0x60002038
-#define GLU_AUDIO 0x60002040
-
-/* reset register */
-#define GLU_RESET 0x60002800
-
-/* programmable base for on-board i/o devices */
-#define GLU_IOBASE 0x60003800
-
-/*
- * iMC: Memory Controller
- */
-
-#define MC_BASE 0x70000000
-
-#define MC0_MCR 0x70000001
-#define MC1_MCR 0x71000001 /* may be missing */
-#define MCR_BANK1_AVAIL 0x08
-#define MCR_BANK0_AVAIL 0x04
-#define MCR_BANK1_32M 0x02
-#define MCR_BANK0_32M 0x01
-
-/*
- * iCU: DMA and Interrupt Controller
- */
-
-#define ICU_BASE 0x50000000
-
-/* interrupt status register */
-#define ICU_ISR 0x50000000
-#define ISR_S0_DMA_SECC 0x00000001
-#define ISR_S0_DMA_MECC 0x00000002
-#define ISR_S0_DMA_SERR 0x00000004
-#define ISR_S1_DMA_SECC 0x00000008
-#define ISR_S1_DMA_MECC 0x00000010
-#define ISR_S1_DMA_SERR 0x00000020
-#define ISR_S2_DMA_SECC 0x00000040
-#define ISR_S2_DMA_MECC 0x00000080
-#define ISR_S2_DMA_SERR 0x00000100
-#define ISR_EN_DMA_SECC 0x00000200
-#define ISR_EN_DMA_MECC 0x00000400
-#define ISR_EN_DMA_SERR 0x00000800
-#define ISR_SCSI_DMA_SECC 0x00001000
-#define ISR_SCSI_DMA_MECC 0x00002000
-#define ISR_SCSI_DMA_SERR 0x00004000
-#define ISR_RIO_NMI_ENABLE 0x00008000
-#define ISR_DMA_NMI_ENABLE 0x00010000
-#define ISR_ICU_INT_ENABLE 0x00020000
-#define ISR_SECC_COUNT 0x003c0000
-#define ISR_SECC_OVERFLOW 0x00400000
-#define ISR_MEMDEC_MISS 0x00800000
-#define ISR_XLAT_INVALID 0x01000000
-#define ISR_WIN_MISS 0x02000000
-#define ISR_FAULT 0x04000000
-#define ISR_S0_RIO_ERR 0x08000000
-#define ISR_S1_RIO_ERR 0x10000000
-#define ISR_S2_RIO_ERR 0x20000000
-#define ISR_EN_RIO_ERR 0x40000000
-#define ISR_RIO_RETRY_TMO 0x80000000
-
-#define ISR_BITS "\020" \
- "\01S0_SECC\02S0_MECC\03S0_SERR\04S1_SECC\05S1_MECC\06S1_SERR" \
- "\07S2_SECC\10S2_MECC\11S2_SERR\12EN_SECC\13EN_MECC\14EN_SERR" \
- "\15SCSI_SECC\16SCSSI_MECC\17SCSI_SERR\20RIO_NMIE\21DMA_NMIE\22ICU_IE" \
- "\27SECC_OVERFLOW\30MEMDEC_MISS\31XLAT_INVALID\32WIN_MISS\33FAULT" \
- "\34S0_RIO\35S1_RIO\36S2_RIO\37RIO_TMO"
-
-#define ICU_TIR 0x50000008
-
-#define ICU_TER 0x5000000c
-#define TER_S0 0x00000002
-#define TER_S1 0x00000004
-#define TER_S2 0x00000008
-#define TER_ETHERNET 0x00000010
-#define TER_SCSI 0x00000020
-#define TER_IO_DISABLE 0x00000040
-#define TER_W_COMP_DIS 0x00000080
-
-#define ICU_TWR 0x50000010
-
-#define ICU_TRR 0x50000014
-
-#define ICU_CONF 0x50000018
-#define CONF_ECC_ENABLE 0x00000004
-#define CONF_NO_EXTRA_MEMORY 0x00000008
-#define CONF_SBUS_25MHZ 0x00000020
-#define CONF_SLOW_DMA_WRITE 0x00000080
-#define CONF_SLOW_DMA_READ 0x00000100
-#define CONF_ICACHE_DISABLE 0x00000400
-
-/*
- * Onboard devices
- */
-
-#define SE_BASE 0x40000000 /* scsi and ethernet */
-#define NVRAM_BASE 0x80000000
-#define ZS1_BASE 0x80004000
-#define ZS0_BASE 0x80008000
-#define FDC_BASE 0x8000c000
-#define AUDIO_BASE 0x80010000
-#define TODCLOCK_BASE 0x80014000
-
-/* we map the following range 1:1 in kernel space */
-#define OBIO_PA_START 0x80000000
-#define OBIO_PA_END 0x80018000
-
-#endif /* _MACHINE_IDT_H_ */
diff --git a/sys/arch/solbourne/include/ieee.h b/sys/arch/solbourne/include/ieee.h
deleted file mode 100644
index 736dd276afd..00000000000
--- a/sys/arch/solbourne/include/ieee.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: ieee.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/ieee.h>
diff --git a/sys/arch/solbourne/include/ieeefp.h b/sys/arch/solbourne/include/ieeefp.h
deleted file mode 100644
index a0473c94dfe..00000000000
--- a/sys/arch/solbourne/include/ieeefp.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: ieeefp.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/ieeefp.h>
diff --git a/sys/arch/solbourne/include/instr.h b/sys/arch/solbourne/include/instr.h
deleted file mode 100644
index 4c32a7f6309..00000000000
--- a/sys/arch/solbourne/include/instr.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: instr.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/instr.h>
diff --git a/sys/arch/solbourne/include/ioctl_fd.h b/sys/arch/solbourne/include/ioctl_fd.h
deleted file mode 100644
index 278e061b9c6..00000000000
--- a/sys/arch/solbourne/include/ioctl_fd.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: ioctl_fd.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/ioctl_fd.h>
diff --git a/sys/arch/solbourne/include/kap.h b/sys/arch/solbourne/include/kap.h
deleted file mode 100644
index c5a163a14ce..00000000000
--- a/sys/arch/solbourne/include/kap.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* $OpenBSD: kap.h,v 1.4 2013/03/21 02:10:37 deraadt Exp $ */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_KAP_H_
-#define _MACHINE_KAP_H_
-
-/*
- * KAP specific control registers
- */
-
-#ifdef _KERNEL
-
-/* TLB handling - write only */
-#define ASI_GTLB_RANDOM 0xc0 /* random TLB drop-in */
-#define ASI_GTLB_DROPIN 0xc1 /* TLB drop-in */
-#define ASI_GTLB_INVAL_ENTRY 0xc2 /* invalidate entry */
-#define ASI_GTLB_INVAL_PID 0xc3 /* invalidate PID */
-#define ASI_GTLB_INVALIDATE 0xc4 /* invalidate entire TLB */
-#define ASI_ITLB_DROPIN 0xc8 /* iTLB drop-in */
-
-/* TLB position addressing */
-#define TLB_SLOT(x) ((x) << 3)
-#define TLB_INCR (1 << 3)
-#define GTLB_SLOTS (128 + 8) /* XXX unsure */
-#define ITLB_SLOTS 8 /* XXX unsure */
-
-/* data cache handling - read only except ASI_DCACHE_RW */
-#define ASI_DCACHE_FLUSH 0xd0 /* flush dcache block */
-#define ASI_DCACHE_LOOKUP 0xd1 /* check for dcache hit */
-#define ASI_DCACHE_RW 0xd2 /* read/write dcache */
-#define ASI_DCACHE_INVAL 0xd3 /* invalidate dcache */
-
-/* cache line addressing (for D flushes) */
-#define DCACHE_LINE(x) ((x) << 2)
-#define DCACHE_INCR (1 << 2)
-#define DCACHE_LINES 256
-
-/* bus access - read/write */
-#define ASI_PHYS_IO 0xd4 /* not cached */
-#define ASI_PHYS_CACHED 0xd5 /* cached */
-#define ASI_PHYS_NBW 0xd6 /* non byte writeable shared */
-#define ASI_PHYS_BW 0xd7 /* byte writeable shared */
-
-/* inst cache handling - read only except ASI_ICACHE_RW */
-#define ASI_ICACHE_LOOKUP 0xd9 /* check for icache hit */
-#define ASI_ICACHE_RW 0xda /* read/write icache */
-#define ASI_ICACHE_INVAL 0xdb /* invalidate icache */
-
-/* MMU registers */
-#define ASI_MMCR 0xe0 /* control register, rw */
-#define ASI_PDBR 0xe1 /* page directory base address, rw */
-#define ASI_FVAR 0xe2 /* fault va, rw */
-#define ASI_PDER 0xe3 /* page directory entry pointer, ro */
-#define ASI_PTOR 0xe4 /* page table offset, ro */
-#define ASI_FPAR 0xe5 /* fault pa, rw */
-#define ASI_FPSR 0xe6 /* fault ASI, rw */
-#define ASI_PIID 0xe7 /* process ID invalidation, rw */
-#define ASI_PID 0xe8 /* process ID, rw */
-#define ASI_BCR 0xe9 /* bus control, rw */
-#define ASI_FCR 0xea /* fault cause, rw */
-#define ASI_PTW0 0xeb /* translation window #0, rw */
-#define ASI_PTW1 0xec /* translation window #0, rw */
-#define ASI_PTW2 0xed /* translation window #0, rw */
-
-/* Hardware watchdog */
-#define ASI_WAR0 0xee /* watchpoint address 0, rw */
-#define ASI_WAR1 0xef /* watchpoint address 1, rw */
-#define ASI_WCR 0xf0 /* watchpoint control register, rw */
-
-/* MMCR fields */
-#define MMCR_ENABLE 0x00000001 /* MMU enable */
-#define MMCR_MATCH_PTW 0x00000002 /* lookup matches PTW */
-#define MMCR_MATCH_ITLB 0x00000004 /* lookup matches ITLB */
-#define MMCR_MATCH_GTLB 0x00000008 /* lookup matches GTLB */
-#define MMCR_ISET0 0x00000080 /* icache set 0 */
-#define MMCR_ISET1 0x00000100 /* icache set 1 */
-#define MMCR_ISET2 0x00000200 /* icache set 2 */
-#define MMCR_DSET0 0x00000400 /* dcache set 0 */
-#define MMCR_DSET1 0x00000800 /* dcache set 1 */
-
-/* BCR fields */
-#define BCR_FAULT_SYNDROME 0x000000ff /* ECC syndrome byte */
-#define BCR_ECC 0x00000100 /* ECC enable */
-#define BCR_FAULT_DISABLE 0x00000200 /* disable ECC faults */
-
-/* FCR fields */
-#define FCR_PROTMASK 0x0000000f
-#define FCR_V 0x00000001 /* page not valid */
-#define FCR_RO 0x00000002 /* write access on read only */
-#define FCR_S 0x00000004 /* user access on sup. only */
-#define FCR_EXTERNAL 0x00000100 /* external fault */
-#define FCR_ECC_SINGLE 0x00000200 /* single bit ECC */
-#define FCR_ECC_MULTIPLE 0x00000400 /* multiple bit ECC */
-
-#define FCR_BITS "\020\01V\02RO\03S\011EXTERNAL\012ECCS\013ECCM"
-
-/* PTW fields */
-#define PTW_V 0x00000001 /* valid */
-#define PTW_RO 0x00000002 /* read only */
-#define PTW_RW 0x00000000
-#define PTW_S 0x00000004 /* supervisor only */
-#define PTW_CACHEABLE 0x00000008
-#define PTW_BYTE_SHARED 0x00000010
-#define PTW_SHARED 0x00000018
-#define PTW_MASK_MASK 0x0000ff00 /* window address mask */
-#define PTW_MASK_SHIFT 8
-#define PTW_PA_MASK 0x00ff0000 /* physical window */
-#define PTW_PA_SHIFT 16
-#define PTW_VA_MASK 0xff000000 /* virtual window */
-#define PTW_VA_SHIFT 24
-
-#define PTW_WINDOW_SIZE 0x01000000
-#define PTW_WINDOW_MASK 0xff000000
-#define PTW_WINDOW_SHIFT 24
-
-#define PTW_TEMPLATE(va,pa,size) \
- (((va) << PTW_VA_SHIFT) | ((pa) << PTW_PA_SHIFT) | \
- (((~((size) - 1) >> 24) << PTW_MASK_SHIFT) & PTW_MASK_MASK))
-
-/*
- * Initial virtual memory settings
- */
-
-#define ROM_WINDOW 0x00
-#define PTW0_BASE (vaddr_t)(ROM_WINDOW << PTW_WINDOW_SHIFT)
-#define PHYSMEM_WINDOW 0xf0
-#define PHYSMEM_BASE (vaddr_t)(PHYSMEM_WINDOW << PTW_WINDOW_SHIFT)
-#define PTW1_WINDOW 0xfd
-#define PTW1_BASE (vaddr_t)(PTW1_WINDOW << PTW_WINDOW_SHIFT)
-#define PTW2_WINDOW 0xfe
-#define PTW2_BASE (vaddr_t)(PTW2_WINDOW << PTW_WINDOW_SHIFT)
-#define PTW0_DEFAULT \
- PTW_TEMPLATE(ROM_WINDOW, ROM_WINDOW, 0x10000000) | PTW_S | PTW_V
-#define PTW1_DEFAULT PTW_CACHEABLE | \
- PTW_TEMPLATE(PTW1_WINDOW, PHYSMEM_WINDOW, 0x01000000) | PTW_S | PTW_V
-#define PTW2_DEFAULT PTW_SHARED | \
- PTW_TEMPLATE(PTW2_WINDOW, PHYSMEM_WINDOW, 0x01000000) | PTW_S | PTW_V
-
-#define PTW0_TO_PHYS(va) (paddr_t)(va)
-#define PTW1_TO_PHYS(va) (paddr_t)((va) - PTW1_BASE + PHYSMEM_BASE)
-#define PTW2_TO_PHYS(va) (paddr_t)((va) - PTW2_BASE + PHYSMEM_BASE)
-
-#define PHYS_TO_PTW0(pa) (vaddr_t)(pa)
-#define PHYS_TO_PTW1(pa) (vaddr_t)((pa) - PHYSMEM_BASE + PTW1_BASE)
-#define PHYS_TO_PTW2(pa) (vaddr_t)((pa) - PHYSMEM_BASE + PTW2_BASE)
-
-#endif /* _KERNEL */
-
-#endif /* _MACHINE_KAP_H_ */
diff --git a/sys/arch/solbourne/include/kcore.h b/sys/arch/solbourne/include/kcore.h
deleted file mode 100644
index c1787372375..00000000000
--- a/sys/arch/solbourne/include/kcore.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: kcore.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/kcore.h>
diff --git a/sys/arch/solbourne/include/limits.h b/sys/arch/solbourne/include/limits.h
deleted file mode 100644
index 07bc416ec8a..00000000000
--- a/sys/arch/solbourne/include/limits.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: limits.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/limits.h>
diff --git a/sys/arch/solbourne/include/lock.h b/sys/arch/solbourne/include/lock.h
deleted file mode 100644
index 08003af08ac..00000000000
--- a/sys/arch/solbourne/include/lock.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: lock.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/lock.h>
diff --git a/sys/arch/solbourne/include/mutex.h b/sys/arch/solbourne/include/mutex.h
deleted file mode 100644
index 38a96b5bec6..00000000000
--- a/sys/arch/solbourne/include/mutex.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: mutex.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/mutex.h>
diff --git a/sys/arch/solbourne/include/oldmon.h b/sys/arch/solbourne/include/oldmon.h
deleted file mode 100644
index b5b02c4c59e..00000000000
--- a/sys/arch/solbourne/include/oldmon.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: oldmon.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/oldmon.h>
diff --git a/sys/arch/solbourne/include/openpromio.h b/sys/arch/solbourne/include/openpromio.h
deleted file mode 100644
index b5cdb8e126e..00000000000
--- a/sys/arch/solbourne/include/openpromio.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: openpromio.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/openpromio.h>
diff --git a/sys/arch/solbourne/include/param.h b/sys/arch/solbourne/include/param.h
deleted file mode 100644
index 6e04748c643..00000000000
--- a/sys/arch/solbourne/include/param.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $OpenBSD: param.h,v 1.14 2013/11/20 23:57:07 miod Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. 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.
- */
-
-#ifndef _MACHINE_PARAM_H_
-#define _MACHINE_PARAM_H_
-
-#ifdef _KERNEL /* XXX */
-#ifndef _LOCORE /* XXX */
-#include <machine/cpu.h> /* XXX */
-#endif /* XXX */
-#endif /* XXX */
-
-#define _MACHINE solbourne
-#define MACHINE "solbourne"
-#define _MACHINE_ARCH sparc
-#define MACHINE_ARCH "sparc"
-#define MID_MACHINE MID_SPARC
-
-#define SUN4_PGSHIFT 13 /* for a sun4 machine */
-#define SUN4CM_PGSHIFT 12 /* for a sun4c or sun4m machine */
-#define PAGE_SHIFT SUN4_PGSHIFT
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-#define KERNBASE 0xfd080000
-
-#ifdef _KERNEL
-
-#define KERNTEXTOFF 0xfd084000 /* start of kernel text */
-#define MSGBUF_PA PTW1_TO_PHYS(KERNBASE) /* msgbuf physical address */
-
-#define NBPG PAGE_SIZE /* bytes/page */
-#define PGSHIFT PAGE_SHIFT /* LOG2(PAGE_SIZE) */
-#define PGOFSET PAGE_MASK /* byte offset into page */
-
-#define UPAGES 1
-#define USPACE 8192 /* total size of u-area */
-#define USPACE_ALIGN 0 /* u-area alignment 0-none */
-
-#define NMBCLUSTERS 2048 /* map size, max cluster allocation */
-
-#define MSGBUFSIZE (1 * PAGE_SIZE) /* larger than on sparc! */
-
-/*
- * Maximum size of the kernel malloc arena in PAGE_SIZE-sized
- * logical pages.
- */
-#define NKMEMPAGES_MAX_DEFAULT ((64 * 1024 * 1024) >> PAGE_SHIFT)
-
-/*
- * dvmamap manages a range of DVMA addresses intended to create double
- * mappings of physical memory. In a way, `dvmamap' is a submap of the
- * VM map `phys_map'. The difference is the use of the `extent'
- * routines to manage page allocation, allowing DVMA addresses to be
- * allocated and freed from within interrupt routines.
- *
- * Note that `phys_map' can still be used to allocate memory-backed pages
- * in DVMA space.
- */
-#ifndef _LOCORE
-extern vaddr_t dvma_base;
-extern vaddr_t dvma_end;
-extern struct extent *dvmamap_extent;
-
-extern caddr_t kdvma_mapin(caddr_t, int, int);
-extern caddr_t dvma_malloc_space(size_t, void *, int, int);
-extern void dvma_free(caddr_t, size_t, void *);
-#define dvma_malloc(len,kaddr,flags) dvma_malloc_space(len,kaddr,flags,0)
-
-extern void delay(unsigned int);
-#define DELAY(n) delay(n)
-
-extern int cputyp;
-
-#endif /* _LOCORE */
-
-/*
- * Values for the cputyp variable.
- */
-#define CPU_KAP 5
-
-/*
- * Shorthand CPU-type macros.
- * Let compiler optimize away code conditional on constants.
- */
-#define CPU_ISSUN4M (0)
-#define CPU_ISSUN4C (0)
-#define CPU_ISSUN4 (0)
-#define CPU_ISSUN4OR4C (0)
-#define CPU_ISSUN4COR4M (0)
-#define CPU_ISKAP (1)
-
-#endif /* _KERNEL */
-
-#endif /* _MACHINE_PARAM_H_ */
diff --git a/sys/arch/solbourne/include/pcb.h b/sys/arch/solbourne/include/pcb.h
deleted file mode 100644
index ac6f06d160b..00000000000
--- a/sys/arch/solbourne/include/pcb.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: pcb.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/pcb.h>
diff --git a/sys/arch/solbourne/include/pmap.h b/sys/arch/solbourne/include/pmap.h
deleted file mode 100644
index fc2ea553806..00000000000
--- a/sys/arch/solbourne/include/pmap.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* $OpenBSD: pmap.h,v 1.10 2015/02/15 21:34:33 miod Exp $ */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_PMAP_H_
-#define _MACHINE_PMAP_H_
-
-#include <machine/pte.h>
-
-/*
- * PMAP structure
- */
-struct pmap {
- pd_entry_t *pm_segtab; /* first level table */
- paddr_t pm_psegtab; /* pa of above */
-
- int pm_refcount; /* reference count */
- struct pmap_statistics pm_stats; /* pmap statistics */
-};
-
-typedef struct pmap *pmap_t;
-
-/*
- * Extra constants passed in the low bits of pa in pmap_enter() to
- * request specific memory attributes.
- */
-
-#define PMAP_NC 1
-#define PMAP_OBIO PMAP_NC
-#define PMAP_BWS 2
-
-/*
- * Macro to pass iospace bits in the low bits of pa in pmap_enter().
- * Provided for source code compatibility - we don't need such bits.
- */
-
-#define PMAP_IOENC(x) 0
-
-#ifdef _KERNEL
-
-extern struct pmap kernel_pmap_store;
-
-#define kvm_recache(addr, npages) kvm_setcache(addr, npages, 1)
-#define kvm_uncache(addr, npages) kvm_setcache(addr, npages, 0)
-#define pmap_copy(a,b,c,d,e) do { /* nothing */ } while (0)
-#define pmap_deactivate(p) do { /* nothing */ } while (0)
-#define pmap_kernel() (&kernel_pmap_store)
-#define pmap_resident_count(p) ((p)->pm_stats.resident_count)
-#define pmap_update(p) do { /* nothing */ } while (0)
-#define pmap_wired_count(p) ((p)->pm_stats.wired_count)
-#define pmap_remove_holes(vm) do { /* nothing */ } while (0)
-
-#define PMAP_PREFER(fo, ap) pmap_prefer((fo), (ap))
-
-struct proc;
-void kvm_setcache(caddr_t, int, int);
-void switchexit(struct proc *); /* locore.s */
-void pmap_bootstrap(size_t);
-void pmap_cache_enable(void);
-void pmap_changeprot(pmap_t, vaddr_t, vm_prot_t, int);
-vaddr_t pmap_map(vaddr_t, paddr_t, paddr_t, int);
-int pmap_pa_exists(paddr_t);
-vaddr_t pmap_prefer(vaddr_t, vaddr_t);
-void pmap_release(pmap_t);
-void pmap_redzone(void);
-void pmap_virtual_space(vaddr_t *, vaddr_t *);
-void pmap_writetext(unsigned char *, int);
-
-#endif /* _KERNEL */
-
-struct pvlist {
- struct pvlist *pv_next; /* next pvlist, if any */
- struct pmap *pv_pmap; /* pmap of this va */
- vaddr_t pv_va; /* virtual address */
- int pv_flags; /* flags (below) */
-};
-
-struct vm_page_md {
- struct pvlist pv_head;
-};
-
-#define VM_MDPAGE_INIT(pg) do { \
- (pg)->mdpage.pv_head.pv_next = NULL; \
- (pg)->mdpage.pv_head.pv_pmap = NULL; \
- (pg)->mdpage.pv_head.pv_va = 0; \
- (pg)->mdpage.pv_head.pv_flags = 0; \
-} while (0)
-
-#endif /* _MACHINE_PMAP_H_ */
diff --git a/sys/arch/solbourne/include/proc.h b/sys/arch/solbourne/include/proc.h
deleted file mode 100644
index 71d1af6ec43..00000000000
--- a/sys/arch/solbourne/include/proc.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: proc.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/proc.h>
diff --git a/sys/arch/solbourne/include/profile.h b/sys/arch/solbourne/include/profile.h
deleted file mode 100644
index 9ecd98bc6fb..00000000000
--- a/sys/arch/solbourne/include/profile.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: profile.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/profile.h>
diff --git a/sys/arch/solbourne/include/prom.h b/sys/arch/solbourne/include/prom.h
deleted file mode 100644
index 1034ee72189..00000000000
--- a/sys/arch/solbourne/include/prom.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* $OpenBSD: prom.h,v 1.3 2013/03/21 02:10:37 deraadt Exp $ */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_PROM_H_
-#define _MACHINE_PROM_H_
-
-/*
- * The following describes the PROM communication structure,
- * which appears at the beginning of physical memory.
- */
-
-#define PROM_CODE_PA 0x00000000
-#define PROM_CODE_VA PTW0_BASE
-#define PROM_DATA_PA PHYSMEM_BASE
-#define PROM_DATA_VA PTW1_BASE
-
-struct sb_prom {
- int sp_interface; /* interface version */
- int (*sp_interp)(const char *); /* prom commands */
- char sp_version[128]; /* prom version */
- int (*sp_eval)(const char *); /* forth commands */
- int sp_ramdisk; /* ramdisk size if any in MB */
- int sp_promend; /* first available va */
- int sp_memsize; /* memory size in pages... */
- int sp_memsize_mb; /* ...and in MB */
- int sp_reserve_start; /* reserved area (in pages) */
- int sp_reserve_len; /* and length (in pages) */
- vaddr_t sp_msgbufp; /* PROM msgbuf pointer */
- int sp_sash_usrtrap;
- int sp_rootnode;
- int sp_validregs; /* nonzero if registers... */
- int sp_regs[100]; /* ...array is valid */
- int sp_revision; /* prom revision */
-};
-
-#define PROM_INTERFACE 4
-
-/*
- * Reset strings
- */
-
-#define PROM_RESET_COLD "cold"
-#define PROM_RESET_WARM "warm"
-#define PROM_RESET_HALT "halt"
-
-/*
- * Environment variables (all upper-case)
- */
-
-#define ENV_ETHERADDR "ENETADDR"
-#define ENV_INPUTDEVICE "INPUT-DEVICE"
-#define ENV_MODEL "MODEL"
-#define ENV_OUTPUTDEVICE "OUTPUT-DEVICE"
-#define ENV_TTYA "TTYA_MODE"
-#define ENV_TTYB "TTYB_MODE"
-
-/*
- * Node structures
- */
-
-struct prom_node {
- int pn_sibling;
- int pn_child;
- vaddr_t pn_props;
- char *pn_name;
-};
-
-struct prom_prop {
- struct prom_prop *pp_next;
- size_t pp_size;
- char pp_data[0];
-};
-
-/*
- * System model
- */
-
-extern int sysmodel;
-
-#define SYS_S4000 0xf4
-#define SYS_S4100 0xf5
-
-const char *prom_getenv(const char *);
-
-#endif /* _MACHINE_PROM_H_ */
diff --git a/sys/arch/solbourne/include/psl.h b/sys/arch/solbourne/include/psl.h
deleted file mode 100644
index 7845f667a58..00000000000
--- a/sys/arch/solbourne/include/psl.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: psl.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/psl.h>
diff --git a/sys/arch/solbourne/include/pte.h b/sys/arch/solbourne/include/pte.h
deleted file mode 100644
index 8b6f295d29b..00000000000
--- a/sys/arch/solbourne/include/pte.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $OpenBSD: pte.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * KAP page table entries.
- *
- * Ref/Mod bits are handled in software.
- */
-
-/*
- * First-level : Page Directory Tables (topmost 9 bits of a va)
- *
- * Page directory entries contain both the pa and the va of the page
- * tables they point to.
- */
-
-#define PDT_INDEX_SIZE 9
-#define PDT_INDEX_SHIFT 23
-#define PDT_INDEX_MASK 0xff800000
-
-/*
- * Second-level: Page Table Entries (middle 10 bits of a va)
- */
-
-#define PT_INDEX_SIZE 10
-#define PT_INDEX_SHIFT 13
-#define PT_INDEX_MASK 0x007fe000
-
-#define PG_V 0x00000001
-#define PG_NV 0x00000000
-#define PG_RO 0x00000002 /* read only */
-#define PG_RW 0x00000000
-#define PG_PROT (PG_RO | PG_S)
-#define PG_S 0x00000004 /* supervisor only */
-#define PG_MA 0x00000018 /* memory attributes mask */
-#define PG_G 0x00000020 /* global */
-/* software bits from now on... */
-#define PG_W 0x00000040 /* wired */
-#define PG_M 0x00000080 /* modified */
-#define PG_U 0x00000100 /* referenced */
- /* 0x00001e00 unused */
-#define PG_FRAME 0xffffe000 /* PFN mask */
-
-/* memory attributes */
-#define PG_IO 0x00000000 /* not cached */
-#define PG_CACHE 0x00000008 /* cached */
-#define PG_BYTE_SHARED 0x00000010 /* byte-writeable shared */
-#define PG_SHARED 0x00000018 /* non byte-writeable shared */
-
-/*
- * Page directory constants
- */
-
-#define PDT_SIZE 4096 /* size of a page directory table */
-#define PT_SIZE 4096 /* size of a page table */
-
-#define NBR_PDE (PDT_SIZE / 8)
-#define NBR_PTE (PT_SIZE / 4)
-
-#define NBSEG (1 << PDT_INDEX_SHIFT)
-
-#if !defined(_LOCORE)
-
-typedef u_int32_t pt_entry_t;
-
-typedef struct {
- u_int32_t pde_pa;
- pt_entry_t* pde_va;
-} pd_entry_t;
-
-#endif
diff --git a/sys/arch/solbourne/include/ptrace.h b/sys/arch/solbourne/include/ptrace.h
deleted file mode 100644
index 7421f6aa4d9..00000000000
--- a/sys/arch/solbourne/include/ptrace.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: ptrace.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/ptrace.h>
diff --git a/sys/arch/solbourne/include/reg.h b/sys/arch/solbourne/include/reg.h
deleted file mode 100644
index c964a71a080..00000000000
--- a/sys/arch/solbourne/include/reg.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: reg.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/reg.h>
diff --git a/sys/arch/solbourne/include/reloc.h b/sys/arch/solbourne/include/reloc.h
deleted file mode 100644
index 2fbeec8d2b5..00000000000
--- a/sys/arch/solbourne/include/reloc.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: reloc.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/reloc.h>
diff --git a/sys/arch/solbourne/include/setjmp.h b/sys/arch/solbourne/include/setjmp.h
deleted file mode 100644
index 8ab5e73206e..00000000000
--- a/sys/arch/solbourne/include/setjmp.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: setjmp.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/setjmp.h>
diff --git a/sys/arch/solbourne/include/signal.h b/sys/arch/solbourne/include/signal.h
deleted file mode 100644
index ebcbd63a212..00000000000
--- a/sys/arch/solbourne/include/signal.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: signal.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/signal.h>
diff --git a/sys/arch/solbourne/include/spinlock.h b/sys/arch/solbourne/include/spinlock.h
deleted file mode 100644
index c9739a45ea9..00000000000
--- a/sys/arch/solbourne/include/spinlock.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: spinlock.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/spinlock.h>
diff --git a/sys/arch/solbourne/include/stdarg.h b/sys/arch/solbourne/include/stdarg.h
deleted file mode 100644
index 78485966c67..00000000000
--- a/sys/arch/solbourne/include/stdarg.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: stdarg.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/stdarg.h>
diff --git a/sys/arch/solbourne/include/sun_disklabel.h b/sys/arch/solbourne/include/sun_disklabel.h
deleted file mode 100644
index 34cf78dc129..00000000000
--- a/sys/arch/solbourne/include/sun_disklabel.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: sun_disklabel.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/sun_disklabel.h>
diff --git a/sys/arch/solbourne/include/tcb.h b/sys/arch/solbourne/include/tcb.h
deleted file mode 100644
index d85400bb72c..00000000000
--- a/sys/arch/solbourne/include/tcb.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: tcb.h,v 1.2 2013/06/01 21:20:54 jasper Exp $ */
-/* public domain */
-#include <sparc/tcb.h>
diff --git a/sys/arch/solbourne/include/trap.h b/sys/arch/solbourne/include/trap.h
deleted file mode 100644
index 2bb2f5e6fe2..00000000000
--- a/sys/arch/solbourne/include/trap.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: trap.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/trap.h>
diff --git a/sys/arch/solbourne/include/varargs.h b/sys/arch/solbourne/include/varargs.h
deleted file mode 100644
index a072f898879..00000000000
--- a/sys/arch/solbourne/include/varargs.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: varargs.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/varargs.h>
diff --git a/sys/arch/solbourne/include/vmparam.h b/sys/arch/solbourne/include/vmparam.h
deleted file mode 100644
index db2e0d866ee..00000000000
--- a/sys/arch/solbourne/include/vmparam.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $OpenBSD: vmparam.h,v 1.4 2013/03/21 02:10:37 deraadt Exp $ */
-/* public domain */
-
-#ifndef _MACHINE_VMPARAM_H_
-#define _MACHINE_VMPARAM_H_
-
-#include <sparc/vmparam.h>
-
-/*
- * User/kernel map constants. We slightly differ from sparc here.
- */
-#undef VM_MIN_KERNEL_ADDRESS
-#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0xf8000000)
-#undef VM_MAX_KERNEL_ADDRESS
-#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)0xfd000000)
-
-#undef IOSPACE_BASE
-#define IOSPACE_BASE ((vaddr_t)0xff000000)
-#undef IOSPACE_LEN
-#define IOSPACE_LEN 0x00f00000 /* 15 MB of iospace */
-
-#undef VM_PHYSSEG_MAX
-#define VM_PHYSSEG_MAX 2
-#undef VM_PHYSSEG_STRAT
-#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
-
-#endif /* _MACHINE_VMPARAM_H_ */
diff --git a/sys/arch/solbourne/include/z8530var.h b/sys/arch/solbourne/include/z8530var.h
deleted file mode 100644
index e760841ca6c..00000000000
--- a/sys/arch/solbourne/include/z8530var.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* $OpenBSD: z8530var.h,v 1.2 2013/03/21 02:10:37 deraadt Exp $ */
-
-#include <sparc/z8530var.h>
diff --git a/sys/arch/solbourne/solbourne/autoconf.c b/sys/arch/solbourne/solbourne/autoconf.c
deleted file mode 100644
index cd0d7035ae3..00000000000
--- a/sys/arch/solbourne/solbourne/autoconf.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/* $OpenBSD: autoconf.c,v 1.12 2010/11/18 21:13:19 miod Exp $ */
-/* OpenBSD: autoconf.c,v 1.64 2005/03/23 17:10:24 miod Exp */
-
-/*
- * Copyright (c) 1996
- * The President and Fellows of Harvard College. All rights reserved.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Harvard University.
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. 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.
- *
- * @(#)autoconf.c 8.4 (Berkeley) 10/1/93
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/disklabel.h>
-#include <sys/device.h>
-#include <sys/disk.h>
-#include <sys/conf.h>
-#include <sys/reboot.h>
-#include <sys/socket.h>
-#include <sys/malloc.h>
-#include <sys/queue.h>
-
-#include <net/if.h>
-
-#include <dev/cons.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <machine/autoconf.h>
-#include <machine/bsd_openprom.h>
-#include <machine/cpu.h>
-#include <machine/ctlreg.h>
-#include <machine/pmap.h>
-#include <sparc/sparc/asm.h>
-#include <sparc/sparc/cpuvar.h>
-#include <sparc/sparc/timerreg.h>
-
-#ifdef DDB
-#include <machine/db_machdep.h>
-#include <ddb/db_sym.h>
-#include <ddb/db_extern.h>
-#endif
-
-#include <machine/idt.h>
-#include <machine/kap.h>
-#include <machine/prom.h>
-
-/*
- * The following several variables are related to
- * the configuration process, and are used in initializing
- * the machine.
- */
-int fbnode; /* node ID of ROM's console frame buffer */
-
-#ifdef KGDB
-extern int kgdb_debug_panic;
-#endif
-
-static int mbprint(void *, const char *);
-void sync_crash(void);
-int mainbus_match(struct device *, void *, void *);
-static void mainbus_attach(struct device *, struct device *, void *);
-
-struct bootpath bootpath[8];
-int nbootpath;
-static void bootpath_build(void);
-char mainbus_model[30];
-
-u_int prom_argc;
-char **prom_argv;
-char **prom_environ;
-vaddr_t prom_data;
-
-/*
- * locore.s code calls bootstrap() just before calling main(), after double
- * mapping the kernel to high memory and setting up the trap base register.
- * We must finish mapping the kernel properly and glean any bootstrap info.
- */
-void
-bootstrap()
-{
- char **old_argv, **old_environ;
- u_int i, nenv;
- size_t asize;
- char *dst;
-
- bzero(&cpuinfo, sizeof(struct cpu_softc));
- cpuinfo.master = 1;
- getcpuinfo(&cpuinfo, 0);
-
- /*
- * Compute how much memory is used by the PROM arguments.
- */
- asize = prom_argc * sizeof(const char *);
- for (i = 0; i < prom_argc; i++)
- asize += 1 + strlen(prom_argv[i]);
- asize = roundup(asize, 4);
-
- for (nenv = 0; prom_environ[nenv] != NULL; nenv++)
- asize += 1 + strlen(prom_environ[i]);
- asize = roundup(asize, 4);
- asize += (1 + nenv) * sizeof(const char *);
-
- /*
- * Setup the initial mappings.
- */
- pmap_bootstrap(asize);
-
- /*
- * Now that we have allocated memory for the commandline arguments
- * and the environment, save them.
- */
- old_argv = prom_argv;
- prom_argv = (char **)prom_data;
- dst = (char *)(prom_data + prom_argc * sizeof(char *));
- for (i = 0; i < prom_argc; i++) {
- prom_argv[i] = dst;
- asize = 1 + strlen(old_argv[i]);
- bcopy(old_argv[i], dst, asize);
- dst += asize;
- }
- old_environ = prom_environ;
- prom_environ = (char **)roundup((vaddr_t)dst, 4);
- dst = (char *)((vaddr_t)prom_environ + (1 + nenv) * sizeof(char *));
- for (i = 0; i < nenv; i++) {
- prom_environ[i] = dst;
- asize = 1 + strlen(old_environ[i]);
- bcopy(old_environ[i], dst, asize);
- dst += asize;
- }
- prom_environ[nenv] = NULL;
-
- /* Moved zs_kgdb_init() to zs.c:consinit() */
-#ifdef DDB
- db_machine_init();
- ddb_init();
-#endif
-}
-
-/*
- * bootpath_build: build a bootpath. Used when booting a generic
- * kernel to find our root device. Newer proms give us a bootpath,
- * for older proms we have to create one. An element in a bootpath
- * has 4 fields: name (device name), val[0], val[1], and val[2]. Note that:
- * Interpretation of val[] is device-dependent. Some examples:
- *
- * if (val[0] == -1) {
- * val[1] is a unit number (happens most often with old proms)
- * } else {
- * [sbus device] val[0] is a sbus slot, and val[1] is an sbus offset
- * [scsi disk] val[0] is target, val[1] is lun, val[2] is partition
- * [scsi tape] val[0] is target, val[1] is lun, val[2] is file #
- * }
- *
- */
-
-static void
-bootpath_build()
-{
- u_int i;
- char *cp;
-
-/* XXX needs a rewrite for S4000 - we do not need to do things that way */
-
- bzero(bootpath, sizeof(bootpath));
-
- /*
- * The boot path is contained in argv[0] only.
- * It has the form:
- * [subdevice.]device([[ctrl],[unit],[partition]])[/]path
- */
-
- printf("bootpath: %s\n", prom_argv[0]);
-
- /*
- * Remaining arguments are interpreted as options, with or without
- * leading dashes.
- */
- for (i = 1; i < prom_argc; i++) {
- for (cp = prom_argv[i]; *cp != '\0'; cp++)
- switch (*cp) {
- case 'a':
- boothowto |= RB_ASKNAME;
- break;
-
- case 'c':
- boothowto |= RB_CONFIG;
- break;
-
-#ifdef DDB
- case 'd':
- Debugger();
- break;
-#endif
-
- case 's':
- boothowto |= RB_SINGLE;
- break;
- }
- }
-}
-
-/*
- * save or read a bootpath pointer from the boothpath store.
- *
- * XXX. required because of SCSI... we don't have control over the "sd"
- * device, so we can't set boot device there. we patch in with
- * device_register(), and use this to recover the bootpath.
- */
-
-struct bootpath *
-bootpath_store(storep, bp)
- int storep;
- struct bootpath *bp;
-{
- static struct bootpath *save;
- struct bootpath *retval;
-
- retval = save;
- if (storep)
- save = bp;
-
- return (retval);
-}
-
-/*
- * Determine mass storage and memory configuration for a machine.
- * We get the PROM's root device and make sure we understand it, then
- * attach it as `mainbus0'. We also set up to handle the PROM `sync'
- * command.
- */
-void
-cpu_configure()
-{
- struct confargs oca;
- register int node = 0;
- register char *cp;
- int s;
- extern struct user *proc0paddr;
-
- /* build the bootpath */
- bootpath_build();
-
- if (boothowto & RB_CONFIG) {
-#ifdef BOOT_CONFIG
- user_config();
-#else
- printf("kernel does not support -c; continuing..\n");
-#endif
- }
-
- node = findroot();
-
- oca.ca_ra.ra_node = node;
- oca.ca_ra.ra_name = cp = "mainbus";
- if (config_rootfound(cp, (void *)&oca) == NULL)
- panic("mainbus not configured");
-
- /* Enable device interrupts */
- sta(GLU_ICR, ASI_PHYS_IO,
- ((lda(GLU_ICR, ASI_PHYS_IO) >> 24) & ~GICR_DISABLE_ALL) << 24);
- (void)spl0();
-
- cold = 0;
-
- /*
- * Re-zero proc0's user area, to nullify the effect of the
- * stack running into it during auto-configuration.
- * XXX - should fix stack usage.
- */
- s = splhigh();
- bzero(proc0paddr, sizeof(struct user));
-
- pmap_redzone();
- splx(s);
-}
-
-void
-diskconf(void)
-{
- struct bootpath *bp;
- struct device *bootdv;
- int bootpart;
-
- /*
- * Configure swap area and related system
- * parameter based on device(s) used.
- */
- bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1];
- bootdv = (bp == NULL) ? NULL : bp->dev;
- bootpart = (bp == NULL) ? 0 : bp->val[2];
-
- setroot(bootdv, bootpart, RB_USERREQ | RB_HALT);
- dumpconf();
-}
-
-/*
- * Console `sync' command. SunOS just does a `panic: zero' so I guess
- * no one really wants anything fancy...
- */
-void
-sync_crash()
-{
-
- panic("PROM sync command");
-}
-
-char *
-clockfreq(freq)
- register int freq;
-{
- register char *p;
- static char buf[10];
-
- freq /= 1000;
- snprintf(buf, sizeof buf, "%d", freq / 1000);
- freq %= 1000;
- if (freq) {
- freq += 1000; /* now in 1000..1999 */
- p = buf + strlen(buf);
- snprintf(p, buf + sizeof buf - p, "%d", freq);
- *p = '.'; /* now buf = %d.%3d */
- }
- return (buf);
-}
-
-/* ARGSUSED */
-static int
-mbprint(aux, name)
- void *aux;
- const char *name;
-{
- register struct confargs *ca = aux;
-
- if (name)
- printf("%s at %s", ca->ca_ra.ra_name, name);
- if (ca->ca_ra.ra_paddr)
- printf(" %saddr 0x%x", ca->ca_ra.ra_iospace ? "io" : "",
- (int)ca->ca_ra.ra_paddr);
- return (UNCONF);
-}
-
-/*
- * Given a `first child' node number, locate the node with the given name.
- * Return the node number, or 0 if not found.
- */
-int
-findnode(first, name)
- int first;
- register const char *name;
-{
- register int node;
-
- for (node = first; node; node = nextsibling(node))
- if (strcmp(getpropstring(node, "name"), name) == 0)
- return (node);
- return (0);
-}
-
-int
-mainbus_match(parent, self, aux)
- struct device *parent;
- void *self;
- void *aux;
-{
- struct cfdata *cf = self;
- register struct confargs *ca = aux;
- register struct romaux *ra = &ca->ca_ra;
-
- return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0);
-}
-
-/*
- * Attach the mainbus.
- *
- * Our main job is to attach the CPU (the root node we got in cpu_configure())
- * and iterate down the list of `mainbus devices' (children of that node).
- * We also record the `node id' of the default frame buffer, if any.
- */
-static void
-mainbus_attach(parent, dev, aux)
- struct device *parent, *dev;
- void *aux;
-{
- struct confargs oca;
- struct confargs *ca = aux;
- int node0;
- const char *model;
-
- node0 = ca->ca_ra.ra_node; /* i.e., the root node */
-
- model = getpropstring(node0, "model");
- if (model == NULL)
- model = sysmodel == SYS_S4000 ? "S4000" : "S4100";
- strlcpy(mainbus_model, model, sizeof mainbus_model);
- printf(": %s\n", mainbus_model);
-
- /*
- * Locate and configure the ``early'' devices. These must be
- * configured before we can do the rest. For instance, the
- * EEPROM contains the Ethernet address for the LANCE chip.
- * If the device cannot be located or configured, panic.
- */
-
- /* Configure the CPU. */
- bzero(&oca, sizeof(oca));
- oca.ca_bustype = BUS_MAIN;
- oca.ca_ra.ra_node = node0;
- oca.ca_ra.ra_name = "cpu";
- (void)config_found(dev, (void *)&oca, mbprint);
-
- /*
- * XXX we don't support frame buffers, yet
- */
- fbnode = 0;
-
- bzero(&oca, sizeof(oca));
- oca.ca_bustype = BUS_MAIN;
- oca.ca_ra.ra_node = node0;
- oca.ca_ra.ra_name = "obio";
- (void)config_found(dev, (void *)&oca, mbprint);
-}
-
-struct cfattach mainbus_ca = {
- sizeof(struct device), mainbus_match, mainbus_attach
-};
-
-struct cfdriver mainbus_cd = {
- NULL, "mainbus", DV_DULL
-};
-
-/*
- * findzs() is called from the zs driver (which is, at least in theory,
- * generic to any machine with a Zilog ZSCC chip). It should return the
- * address of the corresponding zs channel. It may not fail, and it
- * may be called before the VM code can be used. Here we count on the
- * FORTH PROM to map in the required zs chips.
- */
-void *
-findzs(zs)
- int zs;
-{
-
- if (CPU_ISKAP) {
- struct rom_reg rr;
- register void *vaddr;
-
- switch (zs) {
- case 0:
- rr.rr_paddr = (void *)ZS0_BASE;
- break;
- case 1:
- rr.rr_paddr = (void *)ZS1_BASE;
- break;
- default:
- panic("findzs: unknown zs device %d", zs);
- }
-
- rr.rr_iospace = PMAP_OBIO;
- rr.rr_len = PAGE_SIZE;
- vaddr = mapiodev(&rr, 0, PAGE_SIZE);
- if (vaddr != NULL)
- return (vaddr);
- }
-
- panic("findzs: cannot find zs%d", zs);
- /* NOTREACHED */
-}
-
-/*
- * Return a string property. There is a (small) limit on the length;
- * the string is fetched into a static buffer which is overwritten on
- * subsequent calls.
- */
-char *
-getpropstring(node, name)
- int node;
- char *name;
-{
- register int len;
- static char stringbuf[32];
-
- len = getprop(node, name, (void *)stringbuf, sizeof stringbuf - 1);
- if (len == -1)
- len = 0;
- stringbuf[len] = '\0'; /* usually unnecessary */
- return (stringbuf);
-}
-
-/*
- * Fetch an integer (or pointer) property.
- * The return value is the property, or the default if there was none.
- */
-int
-getpropint(node, name, deflt)
- int node;
- char *name;
- int deflt;
-{
- register int len;
- char intbuf[16];
-
- len = getprop(node, name, (void *)intbuf, sizeof intbuf);
- if (len != 4)
- return (deflt);
- return (*(int *)intbuf);
-}
-
-int
-node_has_property(node, prop) /* returns 1 if node has given property */
- register int node;
- register const char *prop;
-{
-
- return (getproplen(node, (char *)prop) != -1);
-}
-
-void
-callrom()
-{
-
-#ifdef notyet
- promvec->pv_abort();
-#endif
-}
-
-/*
- * find a device matching "name" and unit number
- */
-struct device *
-getdevunit(name, unit)
- char *name;
- int unit;
-{
- struct device *dev = TAILQ_FIRST(&alldevs);
- char num[10], fullname[16];
- int lunit;
-
- /* compute length of name and decimal expansion of unit number */
- snprintf(num, sizeof num, "%d", unit);
- lunit = strlen(num);
- if (strlen(name) + lunit >= sizeof(fullname) - 1)
- panic("config_attach: device name too long");
-
- strlcpy(fullname, name, sizeof fullname);
- strlcat(fullname, num, sizeof fullname);
-
- while (strcmp(dev->dv_xname, fullname) != 0) {
- if ((dev = TAILQ_NEXT(dev, dv_list)) == NULL)
- return NULL;
- }
- return dev;
-}
-
-void
-device_register(struct device *dev, void *aux)
-{
-}
-
-struct nam2blk nam2blk[] = {
- { "sd", 7 },
- { "st", 11 },
- { "fd", 16 },
- { "rd", 17 },
- { "cd", 18 },
- { NULL, -1 }
-};
diff --git a/sys/arch/solbourne/solbourne/clock.c b/sys/arch/solbourne/solbourne/clock.c
deleted file mode 100644
index d42f1f7488b..00000000000
--- a/sys/arch/solbourne/solbourne/clock.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* $OpenBSD: clock.c,v 1.1 2005/04/19 21:30:18 miod Exp $ */
-/* OpenBSD: clock.c,v 1.19 2004/04/08 01:11:21 deraadt Exp */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1993 Adam Glass
- * Copyright (c) 1996 Paul Kranenburg
- * Copyright (c) 1996
- * The President and Fellows of Harvard College. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Harvard University.
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * This product includes software developed by Paul Kranenburg.
- * This product includes software developed by Harvard University.
- * 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.
- *
- * @(#)clock.c 8.1 (Berkeley) 6/11/93
- *
- */
-
-/*
- * Clock driver. This is the id prom and eeprom driver as well
- * and includes the timer register functions too.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-#include <sys/systm.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-
-#include <sparc/sparc/asm.h>
-#include <machine/idt.h>
-#include <machine/kap.h>
-
-/*
- * Statistics clock interval and variance, in usec. Variance must be a
- * power of two. Since this gives us an even number, not an odd number,
- * we discard one case and compensate. That is, a variance of 1024 would
- * give us offsets in [0..1023]. Instead, we take offsets in [1..1023].
- * This is symmetric about the point 512, or statvar/2, and thus averages
- * to that value (assuming uniform random numbers).
- */
-/* XXX fix comment to match value */
-int statvar = 8192;
-int statmin; /* statclock interval - 1/2*variance */
-
-int timerblurb = 10; /* Guess a value; used before clock is attached */
-
-/*
- * Set up the real-time and statistics clocks. Leave stathz 0 only if
- * no alternative timer is available.
- *
- * The frequencies of these clocks must be an even number of microseconds.
- */
-void
-cpu_initclocks()
-{
- profhz = hz;
- tick = 1000000 / hz;
-}
-
-/*
- * Dummy setstatclockrate(), since we know profhz==hz.
- */
-/* ARGSUSED */
-void
-setstatclockrate(newhz)
- int newhz;
-{
- /* nothing */
-}
-
-/*
- * Level 10 (clock) interrupts.
- */
-int
-clockintr(cap)
- void *cap;
-{
- hardclock((struct clockframe *)cap);
-
- return (1);
-}
-
-/*
- * Level 14 (stat clock) interrupt handler.
- */
-int
-statintr(cap)
- void *cap;
-{
-#if 1
- panic("level 14 interrupt");
-#else
- statclock((struct clockframe *)cap);
-#endif
-
- return (1);
-}
-
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points. We do this by returning the current time
- * plus the amount of time since the last clock interrupt.
- *
- * Check that this time is no less than any previously-reported time,
- * which could happen around the time of a clock adjustment. Just for
- * fun, we guarantee that the time will be greater than the value
- * obtained by a previous call.
- */
-void
-microtime(tvp)
- struct timeval *tvp;
-{
- int s;
- static struct timeval lasttime;
- static struct timeval oneusec = {0, 1};
-
- s = splhigh();
- *tvp = time;
- splx(s);
-
- if (timercmp(tvp, &lasttime, <=))
- timeradd(&lasttime, &oneusec, tvp);
-
- lasttime = *tvp;
-}
diff --git a/sys/arch/solbourne/solbourne/genassym.cf b/sys/arch/solbourne/solbourne/genassym.cf
deleted file mode 100644
index be35c2e61b8..00000000000
--- a/sys/arch/solbourne/solbourne/genassym.cf
+++ /dev/null
@@ -1,109 +0,0 @@
-# $OpenBSD: genassym.cf,v 1.3 2015/02/09 09:21:30 miod Exp $
-#
-# Copyright (c) 2005, Miodrag Vallat
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-
-include <sys/param.h>
-include <sys/syscall.h>
-include <sys/user.h>
-
-include <uvm/uvm_extern.h>
-
-include <machine/cpu.h>
-include <machine/frame.h>
-include <machine/kap.h>
-include <machine/pmap.h>
-include <machine/prom.h>
-
-include <sparc/sparc/cpuvar.h>
-
-#
-# Solbourne PROM specific constants
-#
-
-struct frame
-member FRAME_ARGC fr_argx
-
-export PROM_DATA_PA
-
-struct sb_prom SB_
-member REGS sp_regs
-
-#
-# Sparc general constants and structures
-#
-
-export VM_MIN_KERNEL_ADDRESS
-
-export SYS_exit
-export SYS_sigreturn
-
-export EFAULT
-export ENAMETOOLONG
-
-struct fpstate
-member fs_fsr
-member fs_qsize
-member fs_queue
-member fs_regs
-export FSR_QNE
-
-# intrhand fields.
-struct intrhand
-member ih_arg
-member IH_COUNT ih_count.ec_count
-member ih_fun
-member ih_ipl
-member ih_next
-
-struct pcb
-member pcb_nsaved
-member pcb_onfault
-member pcb_psr
-member pcb_rw
-member pcb_sp
-member pcb_uw
-member pcb_wim
-member pcb_wcookie
-
-struct pmap
-member PMAP_PSEGTAB pm_psegtab
-define VM_PMAP offsetof(struct vmspace, vm_map.pmap)
-
-struct proc
-member p_addr
-member p_stat
-member p_vmspace
-member p_wchan
-
-export SRUN
-export SONPROC
-
-struct uvmexp V_
-member INTR intrs
-member swtch
-
-# CPU info structure
-struct cpu_softc
-member CPUINFO_CURPROC ci.ci_curproc
diff --git a/sys/arch/solbourne/solbourne/locore.s b/sys/arch/solbourne/solbourne/locore.s
deleted file mode 100644
index 2272aac7db3..00000000000
--- a/sys/arch/solbourne/solbourne/locore.s
+++ /dev/null
@@ -1,4662 +0,0 @@
-/* $OpenBSD: locore.s,v 1.19 2015/02/09 09:21:30 miod Exp $ */
-/* OpenBSD: locore.s,v 1.64 2005/04/17 18:47:50 miod Exp */
-
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1996 Paul Kranenburg
- * Copyright (c) 1996
- * The President and Fellows of Harvard College. All rights reserved.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- * This product includes software developed by Harvard University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * This product includes software developed by Harvard University.
- * This product includes software developed by Paul Kranenburg.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)locore.s 8.4 (Berkeley) 12/10/93
- */
-
-#include "assym.h"
-#include "ksyms.h"
-
-#include <machine/param.h>
-#include <machine/asm.h>
-#include <machine/idt.h>
-#include <machine/kap.h>
-#include <machine/pte.h>
-
-#include <sparc/sparc/intreg.h>
-
-#include <machine/psl.h>
-#include <machine/pte.h>
-#include <machine/signal.h>
-#include <machine/trap.h>
-
-#include <dev/ic/z8530reg.h>
-
-/*
- * GNU assembler does not understand `.empty' directive; Sun assembler
- * gripes about labels without it. To allow cross-compilation using
- * the Sun assembler, and because .empty directives are useful documentation,
- * we use this trick.
- */
-#ifdef SUN_AS
-#define EMPTY .empty
-#else
-#define EMPTY /* .empty */
-#endif
-
-/* use as needed to align things on longword boundaries */
-#define _ALIGN .align 4
-
-/*
- * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if
- * a function is to call C code. It should be just 64, but Sun defined
- * their frame with space to hold arguments 0 through 5 (plus some junk),
- * and varargs routines (such as printf) demand this, and gcc uses this
- * area at times anyway.
- */
-#define CCFSZ 96
-
-/*
- * A handy macro for maintaining instrumentation counters.
- * Note that this clobbers %o0 and %o1. Normal usage is
- * something like:
- * foointr:
- * TRAP_SETUP(...) ! makes %o registers safe
- * INCR(_C_LABEL(cnt)+V_FOO) ! count a foo
- */
-#define INCR(what) \
- sethi %hi(what), %o0; \
- ld [%o0 + %lo(what)], %o1; \
- inc %o1; \
- st %o1, [%o0 + %lo(what)]
-
-/*
- * Another handy macro: load one register window, given `base' address.
- * This can be either a simple register (e.g., %sp) or include an initial
- * offset (e.g., %g6 + PCB_RW).
- */
-#define LOADWIN(addr) \
- ldd [addr], %l0; \
- ldd [addr + 8], %l2; \
- ldd [addr + 16], %l4; \
- ldd [addr + 24], %l6; \
- ldd [addr + 32], %i0; \
- ldd [addr + 40], %i2; \
- ldd [addr + 48], %i4; \
- ldd [addr + 56], %i6
-
-/*
- * To return from trap we need the two-instruction sequence
- * `jmp %l1; rett %l2', which is defined here for convenience.
- */
-#define RETT jmp %l1; rett %l2
-
-/*
- * On some KAP models, the FCR register is not cleared after being read,
- * or when being written to by the hardware, so we have to clear it by
- * ourselves after every read.
- */
-#define CLEAR_FCR \
- sta %g0, [%g0] ASI_FCR
-
- .data
-/*
- * The interrupt stack.
- *
- * This is the very first thing in the data segment, and therefore has
- * the lowest kernel stack address. We count on this in the interrupt
- * trap-frame setup code, since we may need to switch from the kernel
- * stack to the interrupt stack (iff we are not already on the interrupt
- * stack). One sethi+cmp is all we need since this is so carefully
- * arranged.
- */
- .globl _C_LABEL(intstack)
- .globl _C_LABEL(eintstack)
-_C_LABEL(intstack):
- .skip 128 * 128 ! 16k = 128 128-byte stack frames
-_C_LABEL(eintstack):
-
-/*
- * When a process exits and its u. area goes away, we set cpcb to point
- * to this `u.', leaving us with something to use for an interrupt stack,
- * and letting all the register save code have a pcb_uw to examine.
- * This is also carefully arranged (to come just before u0, so that
- * process 0's kernel stack can quietly overrun into it during bootup, if
- * we feel like doing that).
- */
- .globl _C_LABEL(idle_u)
-_C_LABEL(idle_u):
- .skip USPACE
-
-/*
- * Process 0's u.
- *
- * This must be aligned on an 8 byte boundary.
- */
- .globl _C_LABEL(u0)
-_C_LABEL(u0): .skip USPACE
-estack0:
-
-#ifdef KGDB
-/*
- * Another item that must be aligned, easiest to put it here.
- */
-KGDB_STACK_SIZE = 2048
- .globl _C_LABEL(kgdb_stack)
-_C_LABEL(kgdb_stack):
- .skip KGDB_STACK_SIZE ! hope this is enough
-#endif
-
-/*
- * cpcb points to the current pcb (and hence u. area).
- * Initially this is the special one.
- */
- .globl _C_LABEL(cpcb)
-_C_LABEL(cpcb): .word _C_LABEL(u0)
-
-curproc = CPUINFO_VA + CPUINFO_CURPROC
-
-/*
- * cputyp is the current cpu type, used to distinguish between
- * the many variations of different sun4* machines. It contains
- * the value CPU_SUN4, CPU_SUN4C, or CPU_SUN4M.
- */
- .globl _C_LABEL(cputyp)
-_C_LABEL(cputyp):
- .word CPU_KAP
-/*
- * cpumod is the current cpu model, used to distinguish between variants
- * in the Sun4 and Sun4M families. See /sys/arch/sparc/include/param.h for
- * possible values.
- */
- .globl _C_LABEL(cpumod)
-_C_LABEL(cpumod):
- .word 1
-
-/*
- * nbpg is used by pmap_bootstrap(), pgofset is used internally.
- */
- .globl _C_LABEL(nbpg)
-_C_LABEL(nbpg):
- .word PAGE_SIZE
-_C_LABEL(pgofset):
- .word PAGE_MASK
-
- .globl _C_LABEL(trapbase)
-_C_LABEL(trapbase):
- .word _C_LABEL(trapbase_kap)
-
- _ALIGN
-
- .text
-
-/*
- * The first thing in the real text segment is the trap vector table,
- * which must be aligned on a page boundary. The text segment
- * starts beyond page 0 of KERNBASE so that there is a red zone
- * between user and kernel space. We place the message buffer in this
- * area. Because the message buffer is in our "red zone" between user
- * and kernel space we remap it in configure() to another location and
- * invalidate the mapping at KERNBASE.
- */
-
-/*
- * Each trap has room for four instructions, of which one perforce must
- * be a branch. On entry the hardware has copied pc and npc to %l1 and
- * %l2 respectively. We use two more to read the psr into %l0, and to
- * put the trap type value into %l3 (with a few exceptions below).
- * We could read the trap type field of %tbr later in the code instead,
- * but there is no need, and that would require more instructions
- * (read+mask, vs 1 `mov' here).
- *
- * I used to generate these numbers by address arithmetic, but gas's
- * expression evaluator has about as much sense as your average slug
- * (oddly enough, the code looks about as slimy too). Thus, all the
- * trap numbers are given as arguments to the trap macros. This means
- * there is one line per trap. Sigh.
- *
- * Note that only the local registers may be used, since the trap
- * window is potentially the last window. Its `in' registers are
- * the previous window's outs (as usual), but more important, its
- * `out' registers may be in use as the `topmost' window's `in' registers.
- * The global registers are of course verboten (well, until we save
- * them away).
- *
- * Hardware interrupt vectors can be `linked'---the linkage is to regular
- * C code---or rewired to fast in-window handlers. The latter are good
- * for unbuffered hardware like the Zilog serial chip and the AMD audio
- * chip, where many interrupts can be handled trivially with pseudo-DMA or
- * similar. Only one `fast' interrupt can be used per level, however, and
- * direct and `fast' interrupts are incompatible. Routines in intr.c
- * handle setting these, with optional paranoia.
- */
-
- /* regular vectored traps */
-#define VTRAP(type, label) \
- rd %wim, %l0; mov (type), %l3; b label; mov %psr, %l0
-
- /* hardware interrupts (can be linked or made `fast') */
-#define HARDINTKAP(lev) \
- mov (lev), %l3; b sparc_interruptkap; mov %psr, %l0; nop
-
- /* software interrupts (may not be made direct, sorry---but you
- should not be using them trivially anyway) */
-#define SOFTINTKAP(lev, bit) \
- mov (lev), %l3; mov (bit - 1), %l4; b softintr_kap; mov %psr, %l0
-
- /* traps that just call trap() */
-#define TRAP(type) VTRAP(type, slowtrap)
-
- /* architecturally undefined traps (cause panic) */
-#define UTRAP(type) VTRAP(type, slowtrap)
-
- /* software undefined traps (may be replaced) */
-#define STRAP(type) VTRAP(type, slowtrap)
-
-/* breakpoint acts differently under kgdb */
-#ifdef KGDB
-#define BPT VTRAP(T_BREAKPOINT, bpt)
-#define BPT_KGDB_EXEC VTRAP(T_KGDB_EXEC, bpt)
-#else
-#define BPT TRAP(T_BREAKPOINT)
-#define BPT_KGDB_EXEC TRAP(T_KGDB_EXEC)
-#endif
-
-/* special high-speed 1-instruction-shaved-off traps (get nothing in %l3) */
-#define SYSCALL b _C_LABEL(_syscall); mov %psr, %l0; nop; nop
-#define TLBTRAP(label) b label; mov %psr, %l0; nop; nop
-#define WINDOW_OF b window_of; mov %psr, %l0; nop; nop
-#define WINDOW_UF b window_uf; mov %psr, %l0; nop; nop
-#ifdef notyet
-#define ZS_INTERRUPT b zshard; mov %psr, %l0; nop; nop
-#else
-#define ZS_INTERRUPTKAP HARDINTKAP(12)
-#endif
-
- .globl start, _C_LABEL(kernel_text)
-_C_LABEL(kernel_text):
-start:
-/*
- * The traptable needs to be aligned on a 4096 bytes boundary on KAP.
- */
-trapbase_kap:
-/* trap 0 is special since we cannot receive it */
- b dostart; nop; nop; nop ! 00 = reset (fake)
- VTRAP(T_TEXTFAULT, mem_fault) ! 01 = instr. fetch fault
- TRAP(T_ILLINST) ! 02 = illegal instruction
- TRAP(T_PRIVINST) ! 03 = privileged instruction
- TRAP(T_FPDISABLED) ! 04 = fp instr, but EF bit off in psr
- WINDOW_OF ! 05 = window overflow
- WINDOW_UF ! 06 = window underflow
- TRAP(T_ALIGN) ! 07 = address alignment error
- VTRAP(T_FPE, fp_exception) ! 08 = fp exception
- VTRAP(T_DATAFAULT, mem_fault) ! 09 = data fetch fault
- TRAP(T_TAGOF) ! 0a = tag overflow
- UTRAP(0x0b)
- UTRAP(0x0c)
- UTRAP(0x0d)
- UTRAP(0x0e)
- UTRAP(0x0f)
- UTRAP(0x10)
- SOFTINTKAP(1, IE_L1) ! 11 = level 1 interrupt
- HARDINTKAP(2) ! 12 = level 2 interrupt
- HARDINTKAP(3) ! 13 = level 3 interrupt
- SOFTINTKAP(4, IE_L4) ! 14 = level 4 interrupt
- HARDINTKAP(5) ! 15 = level 5 interrupt
- SOFTINTKAP(6, IE_L6) ! 16 = level 6 interrupt
- HARDINTKAP(7) ! 17 = level 7 interrupt
- HARDINTKAP(8) ! 18 = level 8 interrupt
- HARDINTKAP(9) ! 19 = level 9 interrupt
- SOFTINTKAP(10, IE_L10) ! 1a = level 10 interrupt (clock)
- HARDINTKAP(11) ! 1b = level 11 interrupt
- ZS_INTERRUPTKAP ! 1c = level 12 (zs) interrupt
- HARDINTKAP(13) ! 1d = level 13 interrupt
- HARDINTKAP(14) ! 1e = level 14 interrupt
- VTRAP(15, nmi) ! 1f = nonmaskable interrupt
- VTRAP(0x20, double_trap) ! 20 = double trap
- UTRAP(0x21)
- UTRAP(0x22)
- UTRAP(0x23)
- TRAP(T_CPDISABLED) ! 24 = coprocessor instr, EC bit off in psr
- UTRAP(0x25)
- UTRAP(0x26)
- UTRAP(0x27)
- TRAP(T_CPEXCEPTION) ! 28 = coprocessor exception
- UTRAP(0x29)
- UTRAP(0x2a)
- UTRAP(0x2b)
- TLBTRAP(dtlb_miss) ! 2c = dtlb lookup miss
- UTRAP(0x2d)
- UTRAP(0x2e)
- UTRAP(0x2f)
- UTRAP(0x30)
- UTRAP(0x31)
- UTRAP(0x32)
- UTRAP(0x33)
- UTRAP(0x34)
- UTRAP(0x35)
- UTRAP(0x36)
- UTRAP(0x37)
- UTRAP(0x38)
- UTRAP(0x39)
- UTRAP(0x3a)
- UTRAP(0x3b)
- TLBTRAP(itlb_miss) ! 3c itlb lookup miss
- UTRAP(0x3d)
- UTRAP(0x3e)
- UTRAP(0x3f)
- UTRAP(0x40)
- UTRAP(0x41)
- UTRAP(0x42)
- UTRAP(0x43)
- UTRAP(0x44)
- UTRAP(0x45)
- UTRAP(0x46)
- UTRAP(0x47)
- UTRAP(0x48)
- UTRAP(0x49)
- UTRAP(0x4a)
- UTRAP(0x4b)
- UTRAP(0x4c)
- UTRAP(0x4d)
- UTRAP(0x4e)
- UTRAP(0x4f)
- UTRAP(0x50)
- UTRAP(0x51)
- UTRAP(0x52)
- UTRAP(0x53)
- UTRAP(0x54)
- UTRAP(0x55)
- UTRAP(0x56)
- UTRAP(0x57)
- UTRAP(0x58)
- UTRAP(0x59)
- UTRAP(0x5a)
- UTRAP(0x5b)
- UTRAP(0x5c)
- UTRAP(0x5d)
- UTRAP(0x5e)
- UTRAP(0x5f)
- UTRAP(0x60)
- UTRAP(0x61)
- UTRAP(0x62)
- UTRAP(0x63)
- UTRAP(0x64)
- UTRAP(0x65)
- UTRAP(0x66)
- UTRAP(0x67)
- UTRAP(0x68)
- UTRAP(0x69)
- UTRAP(0x6a)
- UTRAP(0x6b)
- UTRAP(0x6c)
- UTRAP(0x6d)
- UTRAP(0x6e)
- UTRAP(0x6f)
- UTRAP(0x70)
- UTRAP(0x71)
- UTRAP(0x72)
- UTRAP(0x73)
- UTRAP(0x74)
- UTRAP(0x75)
- UTRAP(0x76)
- UTRAP(0x77)
- UTRAP(0x78)
- UTRAP(0x79)
- UTRAP(0x7a)
- UTRAP(0x7b)
- UTRAP(0x7c)
- UTRAP(0x7d)
- UTRAP(0x7e)
- UTRAP(0x7f)
- SYSCALL ! 80 = sun syscall
- BPT ! 81 = pseudo breakpoint instruction
- TRAP(T_DIV0) ! 82 = divide by zero
- TRAP(T_FLUSHWIN) ! 83 = flush windows
- TRAP(T_CLEANWIN) ! 84 = provide clean windows
- TRAP(T_RANGECHECK) ! 85 = ???
- TRAP(T_FIXALIGN) ! 86 = fix up unaligned accesses
- TRAP(T_INTOF) ! 87 = integer overflow
- SYSCALL ! 88 = svr4 syscall
- SYSCALL ! 89 = bsd syscall
- BPT_KGDB_EXEC ! 8a = enter kernel gdb on kernel startup
- STRAP(0x8b)
- STRAP(0x8c)
- STRAP(0x8d)
- STRAP(0x8e)
- STRAP(0x8f)
- STRAP(0x90)
- STRAP(0x91)
- STRAP(0x92)
- STRAP(0x93)
- STRAP(0x94)
- STRAP(0x95)
- STRAP(0x96)
- STRAP(0x97)
- STRAP(0x98)
- STRAP(0x99)
- STRAP(0x9a)
- STRAP(0x9b)
- STRAP(0x9c)
- STRAP(0x9d)
- STRAP(0x9e)
- STRAP(0x9f)
- STRAP(0xa0)
- STRAP(0xa1)
- STRAP(0xa2)
- STRAP(0xa3)
- STRAP(0xa4)
- STRAP(0xa5)
- STRAP(0xa6)
- STRAP(0xa7)
- STRAP(0xa8)
- STRAP(0xa9)
- STRAP(0xaa)
- STRAP(0xab)
- STRAP(0xac)
- STRAP(0xad)
- STRAP(0xae)
- STRAP(0xaf)
- STRAP(0xb0)
- STRAP(0xb1)
- STRAP(0xb2)
- STRAP(0xb3)
- STRAP(0xb4)
- STRAP(0xb5)
- STRAP(0xb6)
- STRAP(0xb7)
- STRAP(0xb8)
- STRAP(0xb9)
- STRAP(0xba)
- STRAP(0xbb)
- STRAP(0xbc)
- STRAP(0xbd)
- STRAP(0xbe)
- STRAP(0xbf)
- STRAP(0xc0)
- STRAP(0xc1)
- STRAP(0xc2)
- STRAP(0xc3)
- STRAP(0xc4)
- STRAP(0xc5)
- STRAP(0xc6)
- STRAP(0xc7)
- STRAP(0xc8)
- STRAP(0xc9)
- STRAP(0xca)
- STRAP(0xcb)
- STRAP(0xcc)
- STRAP(0xcd)
- STRAP(0xce)
- STRAP(0xcf)
- STRAP(0xd0)
- STRAP(0xd1)
- STRAP(0xd2)
- STRAP(0xd3)
- STRAP(0xd4)
- STRAP(0xd5)
- STRAP(0xd6)
- STRAP(0xd7)
- STRAP(0xd8)
- STRAP(0xd9)
- STRAP(0xda)
- STRAP(0xdb)
- STRAP(0xdc)
- STRAP(0xdd)
- STRAP(0xde)
- STRAP(0xdf)
- STRAP(0xe0)
- STRAP(0xe1)
- STRAP(0xe2)
- STRAP(0xe3)
- STRAP(0xe4)
- STRAP(0xe5)
- STRAP(0xe6)
- STRAP(0xe7)
- STRAP(0xe8)
- STRAP(0xe9)
- STRAP(0xea)
- STRAP(0xeb)
- STRAP(0xec)
- STRAP(0xed)
- STRAP(0xee)
- STRAP(0xef)
- STRAP(0xf0)
- STRAP(0xf1)
- STRAP(0xf2)
- STRAP(0xf3)
- STRAP(0xf4)
- STRAP(0xf5)
- STRAP(0xf6)
- STRAP(0xf7)
- STRAP(0xf8)
- STRAP(0xf9)
- STRAP(0xfa)
- STRAP(0xfb)
- STRAP(0xfc)
- STRAP(0xfd)
- STRAP(0xfe)
- STRAP(0xff)
-
-/*
- * Pad the trap table to max page size.
- * Trap table size is 0x100 * 4instr * 4byte/instr = 4096 bytes only.
- */
- .align PAGE_SIZE
-
-#ifdef DEBUG
-/*
- * A hardware red zone is impossible. We simulate one in software by
- * keeping a `red zone' pointer; if %sp becomes less than this, we panic.
- * This is expensive and is only enabled when debugging.
- */
-#define REDSIZE (8*96) /* some room for bouncing */
-#define REDSTACK 2048 /* size of `panic: stack overflow' region */
- .data
-_C_LABEL(redzone):
- .word _C_LABEL(idle_u) + REDSIZE
-_C_LABEL(redstack):
- .skip REDSTACK
- .text
-Lpanic_red:
- .asciz "stack overflow"
- _ALIGN
-
- /* set stack pointer redzone to base+minstack; alters base */
-#define SET_SP_REDZONE(base, tmp) \
- add base, REDSIZE, base; \
- sethi %hi(_C_LABEL(redzone)), tmp; \
- st base, [tmp + %lo(_C_LABEL(redzone))]
-
- /* variant with a constant */
-#define SET_SP_REDZONE_CONST(const, tmp1, tmp2) \
- set (const) + REDSIZE, tmp1; \
- sethi %hi(_C_LABEL(redzone)), tmp2; \
- st tmp1, [tmp2 + %lo(_C_LABEL(redzone))]
-
- /* check stack pointer against redzone (uses two temps) */
-#define CHECK_SP_REDZONE(t1, t2) \
- sethi %hi(_C_LABEL(redzone)), t1; \
- ld [t1 + %lo(_C_LABEL(redzone))], t2; \
- cmp %sp, t2; /* if sp >= t2, not in red zone */ \
- bgeu 7f; nop; /* and can continue normally */ \
- /* move to panic stack */ \
- st %g0, [t1 + %lo(_C_LABEL(redzone))]; \
- set _C_LABEL(redstack) + REDSTACK - 96, %sp; \
- /* prevent panic() from lowering ipl */ \
- sethi %hi(_C_LABEL(panicstr)), t2; \
- set Lpanic_red, t2; \
- st t2, [t1 + %lo(_C_LABEL(panicstr))]; \
- rd %psr, t1; /* t1 = splhigh() */ \
- or t1, PSR_PIL, t2; \
- wr t2, 0, %psr; \
- nop; nop; nop; \
- wr t2, PSR_ET, %psr; /* turn on traps */ \
- nop; nop; nop; \
- save %sp, -CCFSZ, %sp; /* preserve current window */ \
- sethi %hi(Lpanic_red), %o0; \
- call _C_LABEL(panic); or %o0, %lo(Lpanic_red), %o0; \
-7:
-
-#else
-
-#define SET_SP_REDZONE(base, tmp)
-#define SET_SP_REDZONE_CONST(const, t1, t2)
-#define CHECK_SP_REDZONE(t1, t2)
-#endif
-
-/*
- * The window code must verify user stack addresses before using them.
- * A user stack pointer is invalid if:
- * - it is not on an 8 byte boundary;
- * - its pages (a register window, being 64 bytes, can occupy
- * two pages) are not readable or writable.
- * We define three separate macros here for testing user stack addresses.
- *
- * PTE_OF_ADDR locates a PTE, branching to a `bad address'
- * handler if the stack pointer does not have a valid mapping;
- * CMP_PTE_USER_READ compares the located PTE against `user read' mode;
- * CMP_PTE_USER_WRITE compares the located PTE against `user write' mode.
- * The compares give `equal' if read or write is OK.
- *
- * Note that the user stack pointer usually points into high addresses
- * (top 3 bits all 1), so that is what we check first.
- *
- * The code below also assumes that PTE_OF_ADDR is safe in a delay
- * slot; it is, at it merely sets its `pte' register to a temporary value.
- */
-
- /* input: addr, output: pte; aux: bad address label */
-#define PTE_OF_ADDR(addr, pte, tmp, bad) \
- srl addr, PDT_INDEX_SHIFT, pte; /* get segment */ \
- lda [%g0] ASI_PDBR, tmp; \
- nop; nop; /* XXX */ \
- sll pte, 3, pte; \
- add tmp, pte, tmp; /* get PT pointer */ \
- lda [tmp] ASI_PHYS_CACHED, pte; \
- tst pte; \
- be bad; /* bail if no PT */ \
- srl addr, (PT_INDEX_SHIFT - 2), tmp; \
- and tmp, ((1 << PT_INDEX_SIZE) -1) << 2, tmp; \
- add pte, tmp, pte; /* get PTE */ \
- lda [pte] ASI_PHYS_CACHED, pte; \
- nop; nop /* XXX */
-
- /* input: pte; output: condition codes */
-#define CMP_PTE_USER_READ(pte, tmp, label) \
- and pte, PG_V | PG_S, pte; \
- cmp pte, PG_V
-
- /* input: pte; output: condition codes */
-#define CMP_PTE_USER_WRITE(pte, tmp, label) \
- and pte, PG_V | PG_S | PG_RO, pte; \
- cmp pte, PG_V
-
-#define INSERT_PTE(addr, pte) \
- sta addr, [%g0] ASI_FVAR; \
- sta pte, [%g0] ASI_GTLB_RANDOM
-
-/*
- * The calculations in PTE_OF_ADDR and CMP_PTE_USER_* are rather slow:
- * in particular, according to Gordon Irlam of the University of Adelaide
- * in Australia, these consume at least 18 cycles on an SS1 and 37 on an
- * SS2. Hence, we try to avoid them in the common case.
- *
- * A chunk of 64 bytes is on a single page if and only if:
- *
- * ((base + 64 - 1) & ~(NBPG-1)) == (base & ~(NBPG-1))
- *
- * Equivalently (and faster to test), the low order bits (base & 4095) must
- * be small enough so that the sum (base + 63) does not carry out into the
- * upper page-address bits, i.e.,
- *
- * (base & (NBPG-1)) < (NBPG - 63)
- *
- * so we allow testing that here. This macro is also assumed to be safe
- * in a delay slot (modulo overwriting its temporary).
- */
-#define SLT_IF_1PAGE_RW(addr, tmp, tmp1) \
- sethi %hi(~PAGE_MASK), tmp1; \
- andn addr, tmp1, tmp; \
- set PAGE_MASK - 62, tmp1; \
- cmp tmp, tmp1
-
-/*
- * Every trap that enables traps must set up stack space.
- * If the trap is from user mode, this involves switching to the kernel
- * stack for the current process, and we must also set cpcb->pcb_uw
- * so that the window overflow handler can tell user windows from kernel
- * windows.
- *
- * The number of user windows is:
- *
- * cpcb->pcb_uw = (cpcb->pcb_wim - 1 - CWP) % nwindows
- *
- * (where pcb_wim = log2(current %wim) and CWP = low 5 bits of %psr).
- * We compute this expression by table lookup in uwtab[CWP - pcb_wim],
- * which has been set up as:
- *
- * for i in [-nwin+1 .. nwin-1]
- * uwtab[i] = (nwin - 1 - i) % nwin;
- *
- * (If you do not believe this works, try it for yourself.)
- *
- * We also keep one or two more tables:
- *
- * for i in 0..nwin-1
- * wmask[i] = 1 << ((i + 1) % nwindows);
- *
- * wmask[CWP] tells whether a `rett' would return into the invalid window.
- */
- .data
- .skip 32 ! alignment byte & negative indices
-uwtab: .skip 32 ! u_char uwtab[-31..31];
-wmask: .skip 32 ! u_char wmask[0..31];
-
- .text
-/*
- * Things begin to grow uglier....
- *
- * Each trap handler may (always) be running in the trap window.
- * If this is the case, it cannot enable further traps until it writes
- * the register windows into the stack (or, if the stack is no good,
- * the current pcb).
- *
- * ASSUMPTIONS: TRAP_SETUP() is called with:
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l3 = (some value that must not be altered)
- * which means we have 4 registers to work with.
- *
- * The `stackspace' argument is the number of stack bytes to allocate
- * for register-saving, and must be at least -64 (and typically more,
- * for global registers and %y).
- *
- * Trapframes should use -CCFSZ-80. (80 = sizeof(struct trapframe);
- * see trap.h. This basically means EVERYONE. Interrupt frames could
- * get away with less, but currently do not.)
- *
- * The basic outline here is:
- *
- * if (trap came from kernel mode) {
- * if (we are in the trap window)
- * save it away;
- * %sp = %fp - stackspace;
- * } else {
- * compute the number of user windows;
- * if (we are in the trap window)
- * save it away;
- * %sp = (top of kernel stack) - stackspace;
- * }
- *
- * Again, the number of user windows is:
- *
- * cpcb->pcb_uw = (cpcb->pcb_wim - 1 - CWP) % nwindows
- *
- * (where pcb_wim = log2(current %wim) and CWP is the low 5 bits of %psr),
- * and this is computed as `uwtab[CWP - pcb_wim]'.
- *
- * NOTE: if you change this code, you will have to look carefully
- * at the window overflow and underflow handlers and make sure they
- * have similar changes made as needed.
- */
-#define CALL_CLEAN_TRAP_WINDOW \
- sethi %hi(clean_trap_window), %l7; \
- jmpl %l7 + %lo(clean_trap_window), %l4; \
- mov %g7, %l7 /* save %g7 in %l7 for clean_trap_window */
-
-#define TRAP_SETUP(stackspace) \
- rd %wim, %l4; \
- mov 1, %l5; \
- sll %l5, %l0, %l5; \
- btst PSR_PS, %l0; \
- bz 1f; \
- btst %l5, %l4; \
- /* came from kernel mode; cond codes indicate trap window */ \
- bz,a 3f; \
- add %fp, stackspace, %sp; /* want to just set %sp */ \
- CALL_CLEAN_TRAP_WINDOW; /* but maybe need to clean first */ \
- b 3f; \
- add %fp, stackspace, %sp; \
-1: \
- /* came from user mode: compute pcb_nw */ \
- sethi %hi(_C_LABEL(cpcb)), %l6; \
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6; \
- ld [%l6 + PCB_WIM], %l5; \
- and %l0, 31, %l4; \
- sub %l4, %l5, %l5; \
- set uwtab, %l4; \
- ldub [%l4 + %l5], %l5; \
- st %l5, [%l6 + PCB_UW]; \
- /* cond codes still indicate whether in trap window */ \
- bz,a 2f; \
- sethi %hi(USPACE+(stackspace)), %l5; \
- /* yes, in trap window; must clean it */ \
- CALL_CLEAN_TRAP_WINDOW; \
- sethi %hi(_C_LABEL(cpcb)), %l6; \
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6; \
- sethi %hi(USPACE+(stackspace)), %l5; \
-2: \
- /* trap window is (now) clean: set %sp */ \
- or %l5, %lo(USPACE+(stackspace)), %l5; \
- add %l6, %l5, %sp; \
- SET_SP_REDZONE(%l6, %l5); \
-3: \
- CHECK_SP_REDZONE(%l6, %l5)
-
-/*
- * Interrupt setup is almost exactly like trap setup, but we need to
- * go to the interrupt stack if (a) we came from user mode or (b) we
- * came from kernel mode on the kernel stack.
- */
-#define INTR_SETUP(stackspace) \
- rd %wim, %l4; \
- mov 1, %l5; \
- sll %l5, %l0, %l5; \
- btst PSR_PS, %l0; \
- bz 1f; \
- btst %l5, %l4; \
- /* came from kernel mode; cond codes still indicate trap window */ \
- bz,a 0f; \
- sethi %hi(_C_LABEL(eintstack)), %l7; \
- CALL_CLEAN_TRAP_WINDOW; \
- sethi %hi(_C_LABEL(eintstack)), %l7; \
-0: /* now if %fp >= eintstack, we were on the kernel stack */ \
- cmp %fp, %l7; \
- bge,a 3f; \
- add %l7, stackspace, %sp; /* so switch to intstack */ \
- b 4f; \
- add %fp, stackspace, %sp; /* else stay on intstack */ \
-1: \
- /* came from user mode: compute pcb_nw */ \
- sethi %hi(_C_LABEL(cpcb)), %l6; \
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6; \
- ld [%l6 + PCB_WIM], %l5; \
- and %l0, 31, %l4; \
- sub %l4, %l5, %l5; \
- set uwtab, %l4; \
- ldub [%l4 + %l5], %l5; \
- st %l5, [%l6 + PCB_UW]; \
- /* cond codes still indicate whether in trap window */ \
- bz,a 2f; \
- sethi %hi(_C_LABEL(eintstack)), %l7; \
- /* yes, in trap window; must save regs */ \
- CALL_CLEAN_TRAP_WINDOW; \
- sethi %hi(_C_LABEL(eintstack)), %l7; \
-2: \
- add %l7, stackspace, %sp; \
-3: \
- SET_SP_REDZONE_CONST(_C_LABEL(intstack), %l6, %l5); \
-4: \
- CHECK_SP_REDZONE(%l6, %l5)
-
-/*
- * Handler for making the trap window shiny clean.
- *
- * On entry:
- * cpcb->pcb_nw = number of user windows
- * %l0 = %psr
- * %l1 must not be clobbered
- * %l2 must not be clobbered
- * %l3 must not be clobbered
- * %l4 = address for `return'
- * %l7 = saved %g7 (we put this in a delay slot above, to save work)
- *
- * On return:
- * %wim has changed, along with cpcb->pcb_wim
- * %g7 has been restored
- *
- * Normally, we push only one window.
- */
-clean_trap_window:
- mov %g5, %l5 ! save %g5
- mov %g6, %l6 ! ... and %g6
-/* mov %g7, %l7 ! ... and %g7 (already done for us) */
- sethi %hi(_C_LABEL(cpcb)), %g6 ! get current pcb
- ld [%g6 + %lo(_C_LABEL(cpcb))], %g6
-
- /* Figure out whether it is a user window (cpcb->pcb_uw > 0). */
- ld [%g6 + PCB_UW], %g7
- deccc %g7
- bge ctw_user
- save %g0, %g0, %g0 ! in any case, enter window to save
-
- /* The window to be pushed is a kernel window. */
- std %i6, [%sp + (7*8)]
- std %l0, [%sp + (0*8)]
-
-ctw_merge:
- !! std %l0, [%sp + (0*8)] ! Done by delay slot or above
- std %l2, [%sp + (1*8)]
- std %l4, [%sp + (2*8)]
- std %l6, [%sp + (3*8)]
- std %i0, [%sp + (4*8)]
- std %i2, [%sp + (5*8)]
- std %i4, [%sp + (6*8)]
- !! std %i6, [%sp + (7*8)] ! Done above or by StackGhost
-
- /* Set up new window invalid mask, and update cpcb->pcb_wim. */
- rd %psr, %g7 ! g7 = (junk << 5) + new_cwp
- mov 1, %g5 ! g5 = 1 << new_cwp;
- sll %g5, %g7, %g5
- wr %g5, 0, %wim ! setwim(g5);
- and %g7, 31, %g7 ! cpcb->pcb_wim = g7 & 31;
- sethi %hi(_C_LABEL(cpcb)), %g6 ! re-get current pcb
- ld [%g6 + %lo(_C_LABEL(cpcb))], %g6
- st %g7, [%g6 + PCB_WIM]
- nop
- restore ! back to trap window
-
- mov %l5, %g5 ! restore g5
- mov %l6, %g6 ! ... and g6
- jmp %l4 + 8 ! return to caller
- mov %l7, %g7 ! ... and g7
- /* NOTREACHED */
-
-
-ctw_stackghost:
- !! StackGhost Encrypt
- sethi %hi(_C_LABEL(cpcb)), %g6 ! get current *pcb
- ld [%g6 + %lo(_C_LABEL(cpcb))], %g6 ! dereference *pcb
- ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
- xor %l0, %i7, %i7 ! mix in cookie
- b ctw_merge
- std %i6, [%sp + (7*8)]
-
-ctw_user:
- /*
- * The window to be pushed is a user window.
- * We must verify the stack pointer (alignment & permissions).
- * See comments above definition of PTE_OF_ADDR.
- */
- st %g7, [%g6 + PCB_UW] ! cpcb->pcb_uw--;
- btst 7, %sp ! if not aligned,
- bne ctw_invalid ! choke on it
- EMPTY
-
- PTE_OF_ADDR(%sp, %g7, %g6, ctw_invalid)
- CMP_PTE_USER_WRITE(%g7, %g5, NOP_ON_4M_2) ! likewise if not writable
- bne ctw_invalid
- nop
- INSERT_PTE(%sp, %g7)
- SLT_IF_1PAGE_RW(%sp, %g7, %g6)
- bl,a ctw_stackghost ! all ok if only 1
- std %l0, [%sp]
- add %sp, 7 * 8, %g5 ! check last addr too
- PTE_OF_ADDR(%g5, %g7, %g6, ctw_invalid)
- CMP_PTE_USER_WRITE(%g7, %g6, NOP_ON_4M_4)
- INSERT_PTE(%g5, %g7)
- be,a ctw_stackghost ! all ok: store <l0,l1> and merge
- std %l0, [%sp]
-
- /*
- * The window we wanted to push could not be pushed.
- * Instead, save ALL user windows into the pcb.
- * We will notice later that we did this, when we
- * get ready to return from our trap or syscall.
- *
- * The code here is run rarely and need not be optimal.
- */
-ctw_invalid:
- /*
- * Reread cpcb->pcb_uw. We decremented this earlier,
- * so it is off by one.
- */
- sethi %hi(_C_LABEL(cpcb)), %g6 ! re-get current pcb
- ld [%g6 + %lo(_C_LABEL(cpcb))], %g6
-
- ld [%g6 + PCB_UW], %g7 ! (number of user windows) - 1
- add %g6, PCB_RW, %g5
-
- /* save g7+1 windows, starting with the current one */
-1: ! do {
- std %l0, [%g5 + (0*8)] ! rw->rw_local[0] = l0;
- std %l2, [%g5 + (1*8)] ! ...
- std %l4, [%g5 + (2*8)]
- std %l6, [%g5 + (3*8)]
- std %i0, [%g5 + (4*8)]
- std %i2, [%g5 + (5*8)]
- std %i4, [%g5 + (6*8)]
-
- !! StackGhost Encrypt (PCP)
- ! pcb already dereferenced in %g6
- ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
- xor %l0, %i7, %i7 ! mix in cookie
- std %i6, [%g5 + (7*8)]
-
- deccc %g7 ! if (n > 0) save(), rw++;
- bge,a 1b ! } while (--n >= 0);
- save %g5, 64, %g5
-
- /* stash sp for bottommost window */
- st %sp, [%g5 + 64 + (7*8)]
-
- /* set up new wim */
- rd %psr, %g7 ! g7 = (junk << 5) + new_cwp;
- mov 1, %g5 ! g5 = 1 << new_cwp;
- sll %g5, %g7, %g5
- wr %g5, 0, %wim ! wim = g5;
- and %g7, 31, %g7
- st %g7, [%g6 + PCB_WIM] ! cpcb->pcb_wim = new_cwp;
-
- /* fix up pcb fields */
- ld [%g6 + PCB_UW], %g7 ! n = cpcb->pcb_uw;
- add %g7, 1, %g5
- st %g5, [%g6 + PCB_NSAVED] ! cpcb->pcb_nsaved = n + 1;
- st %g0, [%g6 + PCB_UW] ! cpcb->pcb_uw = 0;
-
- /* return to trap window */
-1: deccc %g7 ! do {
- bge 1b ! restore();
- restore ! } while (--n >= 0);
-
- mov %l5, %g5 ! restore g5, g6, & g7, and return
- mov %l6, %g6
- jmp %l4 + 8
- mov %l7, %g7
- /* NOTREACHED */
-
-/*
- * TLB miss handlers
- *
- * For now, they are the same - we simply extract the faulting PTE, and
- * insert it at a random place into the TLB cache.
- */
-
-dtlb_miss:
-itlb_miss:
- lda [%g0] ASI_PDER, %l3
- lda [%g0] ASI_PTOR, %l4
- lda [%g0] ASI_PDBR, %l5
- lda [%l3] ASI_PHYS_CACHED, %l3 ! get PDE
- add %l3, %l4, %l3
- lda [%l3] ASI_PHYS_CACHED, %l4 ! get PTE
-#if 0
- or %l4, PG_U, %l4 ! set PG_U
- sta %l4, [%l3] ASI_PHYS_CACHED ! and write modified PTE back
-#endif
- sta %l4, [%g0] ASI_GTLB_RANDOM ! insert into tlb
- mov %l0, %psr ! restore PSR_CC
- nop
- RETT
-
-/*
- * Double trap
- *
- * This usually happens during a TLB miss with traps disabled.
- * We save a few registers to help debugging, and reset the machine.
- */
-
-double_trap:
- set PROM_DATA_PA + SB_REGS, %l3
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %l1, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %l2, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_FCR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_FVAR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_FPAR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_FPSR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_PDER, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_PTOR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_PDBR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- lda [%g0] ASI_MMCR, %l0
- sta %l0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g1, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g2, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g3, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g4, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g5, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g6, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %g7, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o0, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o1, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o2, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o3, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o4, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o5, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o6, [%l3] ASI_PHYS_BW
- add %l3, 4, %l3
- sta %o7, [%l3] ASI_PHYS_BW
-
- wr %g0, %wim
- nop; nop; nop
- restore
-
- set GLU_RESET, %o0
- sta %g0, [%o0] ASI_PHYS_IO
-1: b 1b
- nop
-
-/*
- * Each memory access (text or data) fault, from user or kernel mode,
- * comes here. We read the error register and figure out what has
- * happened.
- *
- * This cannot be done from C code since we must not enable traps (and
- * hence may not use the `save' instruction) until we have decided that
- * the error is or is not an asynchronous one that showed up after a
- * synchronous error, but which must be handled before the sync err.
- *
- * Most memory faults are user mode text or data faults, which can cause
- * signal delivery or ptracing, for which we must build a full trapframe.
- * It does not seem worthwhile to work to avoid this in the other cases,
- * so we store all the %g registers on the stack immediately.
- *
- * On entry:
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l3 = T_TEXTFAULT or T_DATAFAULT
- *
- * Internal:
- * %l4 = %y, until we call mem_access_fault (then onto trapframe)
- * %l5 = IE_reg_addr, if async mem error
- *
- */
-
-mem_fault:
- /*
- * This ends up close to slowtrap (except for ECC errors),
- * but we don't invoke trap() in the end.
- */
-
- TRAP_SETUP(-CCFSZ-80)
-
- st %g1, [%sp + CCFSZ + 20] ! save g1
- rd %y, %l4 ! save y
-
- std %g2, [%sp + CCFSZ + 24] ! save g2, g3
- lda [%g0] ASI_FCR, %o1 ! fault cause reg
- std %g4, [%sp + CCFSZ + 32] ! (sneak g4,g5 in here)
- lda [%g0] ASI_FVAR, %o2 ! virt addr
- btst FCR_ECC_SINGLE | FCR_ECC_MULTIPLE, %o1 ! ECC memory error?
- std %g6, [%sp + CCFSZ + 40]
- CLEAR_FCR
- bz normal_mem_fault ! no, just a regular fault
- wr %l0, PSR_ET, %psr ! (and reenable traps)
-
- /*
- * We got an ECC memory error.
- */
- clr %o3
- clr %o4
- call _C_LABEL(ecc_fault) ! ecc_fault(0, fcr, va, 0, 0)
- clr %o0
-
- b mem_fault_return
- wr %l4, 0, %y
-
-normal_mem_fault:
- /*
- * call C code to deal with the trap.
- * Must finish trap frame (psr,pc,npc,%y,%o0..%o7) in case
- * we decide to deliver a signal or ptrace the process.
- * %g1..%g7 were already set up above.
- */
- std %l0, [%sp + CCFSZ + 0] ! set tf.tf_psr, tf.tf_pc
- mov %l3, %o0 ! (argument: type)
- st %l2, [%sp + CCFSZ + 8] ! set tf.tf_npc
- st %l4, [%sp + CCFSZ + 12] ! set tf.tf_y
- mov %l1, %o3 ! (argument: pc)
- std %i0, [%sp + CCFSZ + 48] ! tf.tf_out[0], etc
- std %i2, [%sp + CCFSZ + 56]
- mov %l0, %o4 ! (argument: psr)
- std %i4, [%sp + CCFSZ + 64]
- std %i6, [%sp + CCFSZ + 72]
- call _C_LABEL(mem_access_fault) ! mem_access_fault(type, fcr,
- ! va, pc, psr, &tf);
- add %sp, CCFSZ, %o5 ! (argument: &tf)
-
- ldd [%sp + CCFSZ + 0], %l0 ! load new values
- ldd [%sp + CCFSZ + 8], %l2
- wr %l4, 0, %y
- ldd [%sp + CCFSZ + 48], %i0
- ldd [%sp + CCFSZ + 56], %i2
- ldd [%sp + CCFSZ + 64], %i4
- ldd [%sp + CCFSZ + 72], %i6
-mem_fault_return:
- ld [%sp + CCFSZ + 20], %g1
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
-
- b return_from_trap ! go return
- wr %l0, 0, %psr ! (but first disable traps again)
-
-
-/*
- * fp_exception has to check to see if we are trying to save
- * the FP state, and if so, continue to save the FP state.
- *
- * We do not even bother checking to see if we were in kernel mode,
- * since users have no access to the special_fp_store instruction.
- *
- * This whole idea was stolen from Sprite.
- */
-fp_exception:
- set special_fp_store, %l4 ! see if we came from the special one
- cmp %l1, %l4 ! pc == special_fp_store?
- bne slowtrap ! no, go handle per usual
- EMPTY
- sethi %hi(savefpcont), %l4 ! yes, "return" to the special code
- or %lo(savefpcont), %l4, %l4
- jmp %l4
- rett %l4 + 4
-
-/*
- * slowtrap() builds a trap frame and calls trap().
- * This is called `slowtrap' because it *is*....
- * We have to build a full frame for ptrace(), for instance.
- *
- * Registers:
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l3 = trap code
- */
-slowtrap:
- TRAP_SETUP(-CCFSZ-80)
- /*
- * Phew, ready to enable traps and call C code.
- */
- mov %l3, %o0 ! put type in %o0 for later
-Lslowtrap_reenter:
- wr %l0, PSR_ET, %psr ! traps on again
- std %l0, [%sp + CCFSZ] ! tf.tf_psr = psr; tf.tf_pc = ret_pc;
- rd %y, %l3
- std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc = return_npc; tf.tf_y = %y;
- st %g1, [%sp + CCFSZ + 20]
- std %g2, [%sp + CCFSZ + 24]
- std %g4, [%sp + CCFSZ + 32]
- std %g6, [%sp + CCFSZ + 40]
- std %i0, [%sp + CCFSZ + 48]
- mov %l0, %o1 ! (psr)
- std %i2, [%sp + CCFSZ + 56]
- mov %l1, %o2 ! (pc)
- std %i4, [%sp + CCFSZ + 64]
- add %sp, CCFSZ, %o3 ! (&tf)
- call _C_LABEL(trap) ! trap(type, psr, pc, &tf)
- std %i6, [%sp + CCFSZ + 72]
-
- ldd [%sp + CCFSZ], %l0 ! load new values
- ldd [%sp + CCFSZ + 8], %l2
- wr %l3, 0, %y
- ld [%sp + CCFSZ + 20], %g1
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
- ldd [%sp + CCFSZ + 48], %i0
- ldd [%sp + CCFSZ + 56], %i2
- ldd [%sp + CCFSZ + 64], %i4
- ldd [%sp + CCFSZ + 72], %i6
- b return_from_trap
- wr %l0, 0, %psr
-
-/*
- * Do a `software' trap by re-entering the trap code, possibly first
- * switching from interrupt stack to kernel stack. This is used for
- * scheduling and signal ASTs (which generally occur from softclock or
- * tty or net interrupts) and register window saves (which might occur
- * from anywhere).
- *
- * The current window is the trap window, and it is by definition clean.
- * We enter with the trap type in %o0. All we have to do is jump to
- * Lslowtrap_reenter above, but maybe after switching stacks....
- */
-softtrap:
- sethi %hi(_C_LABEL(eintstack)), %l7
- cmp %sp, %l7
- bge Lslowtrap_reenter
- EMPTY
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- set USPACE-CCFSZ-80, %l5
- add %l6, %l5, %l7
- SET_SP_REDZONE(%l6, %l5)
- b Lslowtrap_reenter
- mov %l7, %sp
-
-#ifdef KGDB
-/*
- * bpt is entered on all breakpoint traps.
- * If this is a kernel breakpoint, we do not want to call trap().
- * Among other reasons, this way we can set breakpoints in trap().
- */
-bpt:
- btst PSR_PS, %l0 ! breakpoint from kernel?
- bz slowtrap ! no, go do regular trap
- nop
-
- /*
- * Build a trap frame for kgdb_trap_glue to copy.
- * Enable traps but set ipl high so that we will not
- * see interrupts from within breakpoints.
- */
- TRAP_SETUP(-CCFSZ-80)
- or %l0, PSR_PIL, %l4 ! splhigh()
- wr %l4, 0, %psr ! the manual claims that this
- nop; nop; nop
- wr %l4, PSR_ET, %psr ! song and dance is necessary
- std %l0, [%sp + CCFSZ + 0] ! tf.tf_psr, tf.tf_pc
- mov %l3, %o0 ! trap type arg for kgdb_trap_glue
- rd %y, %l3
- std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc, tf.tf_y
- rd %wim, %l3
- st %l3, [%sp + CCFSZ + 16] ! tf.tf_wim (a kgdb-only r/o field)
- st %g1, [%sp + CCFSZ + 20] ! tf.tf_global[1]
- std %g2, [%sp + CCFSZ + 24] ! etc
- std %g4, [%sp + CCFSZ + 32]
- std %g6, [%sp + CCFSZ + 40]
- std %i0, [%sp + CCFSZ + 48] ! tf.tf_in[0..1]
- std %i2, [%sp + CCFSZ + 56] ! etc
- std %i4, [%sp + CCFSZ + 64]
- std %i6, [%sp + CCFSZ + 72]
-
- /*
- * Now call kgdb_trap_glue(); if it returns, call trap().
- */
- mov %o0, %l3 ! gotta save trap type
- call _C_LABEL(kgdb_trap_glue) ! kgdb_trap_glue(type, &trapframe)
- add %sp, CCFSZ, %o1 ! (&trapframe)
-
- /*
- * Use slowtrap to call trap---but first erase our tracks
- * (put the registers back the way they were).
- */
- mov %l3, %o0 ! slowtrap will need trap type
- ld [%sp + CCFSZ + 12], %l3
- wr %l3, 0, %y
- ld [%sp + CCFSZ + 20], %g1
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- b Lslowtrap_reenter
- ldd [%sp + CCFSZ + 40], %g6
-
-/*
- * Enter kernel breakpoint. Write all the windows (not including the
- * current window) into the stack, so that backtrace works. Copy the
- * supplied trap frame to the kgdb stack and switch stacks.
- *
- * kgdb_trap_glue(type, tf0)
- * int type;
- * struct trapframe *tf0;
- */
- .globl _C_LABEL(kgdb_trap_glue)
-_C_LABEL(kgdb_trap_glue):
- save %sp, -CCFSZ, %sp
-
- call _C_LABEL(write_all_windows)
- mov %sp, %l4 ! %l4 = current %sp
-
- /* copy trapframe to top of kgdb stack */
- set _C_LABEL(kgdb_stack) + KGDB_STACK_SIZE - 80, %l0
- ! %l0 = tfcopy -> end_of_kgdb_stack
- mov 80, %l1
-1: ldd [%i1], %l2
- inc 8, %i1
- deccc 8, %l1
- std %l2, [%l0]
- bg 1b
- inc 8, %l0
-
-#ifdef DEBUG
- /* save old red zone and then turn it off */
- sethi %hi(_C_LABEL(redzone)), %l7
- ld [%l7 + %lo(_C_LABEL(redzone))], %l6
- st %g0, [%l7 + %lo(_C_LABEL(redzone))]
-#endif
- /* switch to kgdb stack */
- add %l0, -CCFSZ-80, %sp
-
- /* if (kgdb_trap(type, tfcopy)) kgdb_rett(tfcopy); */
- mov %i0, %o0
- call _C_LABEL(kgdb_trap)
- add %l0, -80, %o1
- tst %o0
- bnz,a kgdb_rett
- add %l0, -80, %g1
-
- /*
- * kgdb_trap() did not handle the trap at all so the stack is
- * still intact. A simple `restore' will put everything back,
- * after we reset the stack pointer.
- */
- mov %l4, %sp
-#ifdef DEBUG
- st %l6, [%l7 + %lo(_C_LABEL(redzone))] ! restore red zone
-#endif
- ret
- restore
-
-/*
- * Return from kgdb trap. This is sort of special.
- *
- * We know that kgdb_trap_glue wrote the window above it, so that we will
- * be able to (and are sure to have to) load it up. We also know that we
- * came from kernel land and can assume that the %fp (%i6) we load here
- * is proper. We must also be sure not to lower ipl (it is at splhigh())
- * until we have traps disabled, due to the SPARC taking traps at the
- * new ipl before noticing that PSR_ET has been turned off. We are on
- * the kgdb stack, so this could be disastrous.
- *
- * Note that the trapframe argument in %g1 points into the current stack
- * frame (current window). We abandon this window when we move %g1->tf_psr
- * into %psr, but we will not have loaded the new %sp yet, so again traps
- * must be disabled.
- */
-kgdb_rett:
- rd %psr, %g4 ! turn off traps
- wr %g4, PSR_ET, %psr
- /* use the three-instruction delay to do something useful */
- ld [%g1], %g2 ! pick up new %psr
- ld [%g1 + 12], %g3 ! set %y
- wr %g3, 0, %y
-#ifdef DEBUG
- st %l6, [%l7 + %lo(_C_LABEL(redzone))] ! and restore red zone
-#endif
- wr %g0, 0, %wim ! enable window changes
- nop; nop; nop
- /* now safe to set the new psr (changes CWP, leaves traps disabled) */
- wr %g2, 0, %psr ! set rett psr (including cond codes)
- /* 3 instruction delay before we can use the new window */
-/*1*/ ldd [%g1 + 24], %g2 ! set new %g2, %g3
-/*2*/ ldd [%g1 + 32], %g4 ! set new %g4, %g5
-/*3*/ ldd [%g1 + 40], %g6 ! set new %g6, %g7
-
- /* now we can use the new window */
- mov %g1, %l4
- ld [%l4 + 4], %l1 ! get new pc
- ld [%l4 + 8], %l2 ! get new npc
- ld [%l4 + 20], %g1 ! set new %g1
-
- /* set up returnee's out registers, including its %sp */
- ldd [%l4 + 48], %i0
- ldd [%l4 + 56], %i2
- ldd [%l4 + 64], %i4
- ldd [%l4 + 72], %i6
-
- /* load returnee's window, making the window above it be invalid */
- restore
- restore %g0, 1, %l1 ! move to inval window and set %l1 = 1
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0, %wim ! %wim = 1 << (%psr & 31)
- sethi %hi(_C_LABEL(cpcb)), %l1
- ld [%l1 + %lo(_C_LABEL(cpcb))], %l1
- and %l0, 31, %l0 ! CWP = %psr & 31;
- st %l0, [%l1 + PCB_WIM] ! cpcb->pcb_wim = CWP;
- save %g0, %g0, %g0 ! back to window to reload
- LOADWIN(%sp)
- save %g0, %g0, %g0 ! back to trap window
- /* note, we have not altered condition codes; safe to just rett */
- RETT
-#endif
-
-/*
- * syscall() builds a trap frame and calls syscall().
- * sun_syscall is same but delivers sun system call number
- * XXX should not have to save&reload ALL the registers just for
- * ptrace...
- */
-_C_LABEL(_syscall):
- TRAP_SETUP(-CCFSZ-80)
- wr %l0, PSR_ET, %psr
- std %l0, [%sp + CCFSZ + 0] ! tf_psr, tf_pc
- rd %y, %l3
- std %l2, [%sp + CCFSZ + 8] ! tf_npc, tf_y
- st %g1, [%sp + CCFSZ + 20] ! tf_g[1]
- std %g2, [%sp + CCFSZ + 24] ! tf_g[2], tf_g[3]
- std %g4, [%sp + CCFSZ + 32] ! etc
- std %g6, [%sp + CCFSZ + 40]
- mov %g1, %o0 ! (code)
- std %i0, [%sp + CCFSZ + 48]
- add %sp, CCFSZ, %o1 ! (&tf)
- std %i2, [%sp + CCFSZ + 56]
- mov %l1, %o2 ! (pc)
- std %i4, [%sp + CCFSZ + 64]
- call _C_LABEL(syscall) ! syscall(code, &tf, pc, suncompat)
- std %i6, [%sp + CCFSZ + 72]
- ! now load em all up again, sigh
- ldd [%sp + CCFSZ + 0], %l0 ! new %psr, new pc
- ldd [%sp + CCFSZ + 8], %l2 ! new npc, new %y
- wr %l3, 0, %y
- /* see `proc_trampoline' for the reason for this label */
-return_from_syscall:
- ld [%sp + CCFSZ + 20], %g1
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
- ldd [%sp + CCFSZ + 48], %i0
- ldd [%sp + CCFSZ + 56], %i2
- ldd [%sp + CCFSZ + 64], %i4
- ldd [%sp + CCFSZ + 72], %i6
- b return_from_trap
- wr %l0, 0, %psr
-
-/*
- * Interrupts. Software interrupts must be cleared from the software
- * interrupt enable register. Rather than calling ienab_bic for each,
- * we do them in-line before enabling traps.
- *
- * After preliminary setup work, the interrupt is passed to each
- * registered handler in turn. These are expected to return 1 if they
- * took care of the interrupt, 0 if they didn't, and -1 if the device
- * isn't sure. If a handler claims the interrupt, we exit
- * (hardware interrupts are latched in the requestor so we'll
- * just take another interrupt in the unlikely event of simultaneous
- * interrupts from two different devices at the same level). If we go
- * through all the registered handlers and no one claims it, we report a
- * stray interrupt. This is more or less done as:
- *
- * for (ih = intrhand[intlev]; ih; ih = ih->ih_next)
- * if ((*ih->ih_fun)(ih->ih_arg ? ih->ih_arg : &frame))
- * return;
- * strayintr(&frame);
- *
- * Software interrupts are almost the same with three exceptions:
- * (1) we clear the interrupt from the software interrupt enable
- * register before calling any handler (we have to clear it first
- * to avoid an interrupt-losing race),
- * (2) we always call all the registered handlers (there is no way
- * to tell if the single bit in the software interrupt register
- * represents one or many requests)
- * (3) we never announce a stray interrupt (because of (1), another
- * interrupt request can come in while we're in the handler. If
- * the handler deals with everything for both the original & the
- * new request, we'll erroneously report a stray interrupt when
- * we take the software interrupt for the new request.
- *
- * Inputs:
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l3 = interrupt level
- * (software interrupt only) %l4 = bits to clear in interrupt register
- *
- * Internal:
- * %l4, %l5: local variables
- * %l6 = %y
- * %l7 = %g1
- * %g2..%g7 go to stack
- *
- * An interrupt frame is built in the space for a full trapframe;
- * this contains the psr, pc, npc, and interrupt level.
- */
-softintr_kap:
- sethi %hi(_C_LABEL(kap_sir)), %l6
- mov 1, %l5
- sll %l5, %l4, %l5 ! l5 = 1 << (intno - 1)
- ld [%l6 + %lo(_C_LABEL(kap_sir))], %l4
- andn %l4, %l5, %l4 ! clear bit
- /* skip loop if kap_sir becomes zero */
- clr %l5 ! intnum = 0;
- cmp %l4, 0
- be 2f
- st %l4, [%l6 + %lo(_C_LABEL(kap_sir))]
- /* now find out the topmost bit set in kap_sir */
-1: srl %l4, 1, %l4 ! while (sir >>= 1)
- cmp %l4, 0
- bne 1b
- inc %l5 ! intnum++;
-2: set GLU_ICR, %l6
- lda [%l6] ASI_PHYS_IO, %l4 ! read icr
- srl %l4, 24, %l4
- andn %l4, GICR_DISPATCH_MASK, %l4 ! clear softintr bits
- or %l4, %l5, %l4 ! put our number
- sll %l4, 24, %l4
- sta %l4, [%l6] ASI_PHYS_IO ! write back icr
-
-softintr_common:
- INTR_SETUP(-CCFSZ-80)
- std %g2, [%sp + CCFSZ + 24] ! save registers
- INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1)
- mov %g1, %l7
- rd %y, %l6
- std %g4, [%sp + CCFSZ + 32]
- andn %l0, PSR_PIL, %l4 ! %l4 = psr & ~PSR_PIL |
- sll %l3, 8, %l5 ! intlev << IPLSHIFT
- std %g6, [%sp + CCFSZ + 40]
- or %l5, %l4, %l4 ! ;
- wr %l4, 0, %psr ! the manual claims this
- nop; nop; nop
- wr %l4, PSR_ET, %psr ! song and dance is necessary
- std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe
- sll %l3, 2, %l5
- std %l2, [%sp + CCFSZ + 8]
- set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev];
- ld [%l4 + %l5], %l4
- b 3f
- st %fp, [%sp + CCFSZ + 16]
-
-1: rd %psr, %o1
- ld [%l4 + IH_IPL], %o0
- and %o1, ~PSR_PIL, %o1
- wr %o1, %o0, %psr
- ld [%l4 + IH_ARG], %o0
- ld [%l4 + IH_FUN], %o1
- tst %o0
- bz,a 2f
- add %sp, CCFSZ, %o0
-2: jmpl %o1, %o7 ! (void)(*ih->ih_fun)(...)
- nop
- mov %l4, %l3
- ldd [%l3 + IH_COUNT], %l4
- inccc %l5
- addx %l4, 0, %l4
- std %l4, [%l3 + IH_COUNT]
- ld [%l3 + IH_NEXT], %l4 ! and ih = ih->ih_next
-3: tst %l4 ! while ih != NULL
- bnz 1b
- nop
- mov %l7, %g1
- wr %l6, 0, %y
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
- b return_from_trap
- wr %l0, 0, %psr
-
- /*
- * _sparc_interrupt{44c,4m} is exported for paranoia checking
- * (see intr.c).
- */
- .globl _C_LABEL(sparc_interrupt44c)
-_C_LABEL(sparc_interrupt44c):
-_C_LABEL(sparc_interrupt_common):
-sparc_interruptkap:
- INTR_SETUP(-CCFSZ-80)
- std %g2, [%sp + CCFSZ + 24] ! save registers
- INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1)
- mov %g1, %l7
- rd %y, %l6
- std %g4, [%sp + CCFSZ + 32]
- andn %l0, PSR_PIL, %l4 ! %l4 = psr & ~PSR_PIL |
- sll %l3, 8, %l5 ! intlev << IPLSHIFT
- std %g6, [%sp + CCFSZ + 40]
- or %l5, %l4, %l4 ! ;
- wr %l4, 0, %psr ! the manual claims this
- nop; nop; nop
- wr %l4, PSR_ET, %psr ! song and dance is necessary
- std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe
- sll %l3, 2, %l5
- std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe
- set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev];
- ld [%l4 + %l5], %l4
- clr %l5 ! %l5 = 0
- b 3f
- st %fp, [%sp + CCFSZ + 16]
-
-1: rd %psr, %o1
- ld [%l4 + IH_IPL], %o0
- and %o1, ~PSR_PIL, %o1
- wr %o1, %o0, %psr
- ld [%l4 + IH_ARG], %o0
- ld [%l4 + IH_FUN], %o1
- tst %o0
- bz,a 2f
- add %sp, CCFSZ, %o0
-2: jmpl %o1, %o7 ! handled = (*ih->ih_fun)(...)
- nop
- cmp %o0, 1
- bge 4f ! if (handled >= 1) break
- or %o0, %l5, %l5 ! and %l5 |= handled
- ld [%l4 + IH_NEXT], %l4 ! and ih = ih->ih_next
-3: tst %l4
- bnz 1b ! while (ih)
- nop
- tst %l5 ! if (handled) break
- bnz 5f
- nop
- call _C_LABEL(strayintr) ! strayintr(&intrframe)
- add %sp, CCFSZ, %o0
-5: /* all done: restore registers and go return */
- mov %l7, %g1
- wr %l6, 0, %y
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
- b return_from_trap
- wr %l0, 0, %psr
-4:
- mov %l4, %l3
- ldd [%l3 + IH_COUNT], %l4
- inccc %l5
- addx %l4, 0, %l4
- b 5b
- std %l4, [%l3 + IH_COUNT]
-
-/*
- * Level 15 interrupt. An async memory error has occurred;
- * take care of it (typically by panicking, but hey...).
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l3 = 15 * 4 (why? just because!)
- *
- * Internal:
- * %l4 = %y
- * %l5 = %g1
- * %l6 = %g6
- * %l7 = %g7
- * g2, g3, g4, g5 go to stack
- *
- * This code is almost the same as that in mem_access_fault,
- * except that we already know the problem is not a `normal' fault,
- * and that we must be extra-careful with interrupt enables.
- */
-
-nmi:
- INTR_SETUP(-CCFSZ-80)
- INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1)
- /* XXX
- * We should check for NMI set in the iGLU BSR, and clear it if set.
- */
-
- /*
- * Level 15 interrupts are nonmaskable, so with traps off,
- * disable all interrupts to prevent recursion.
- */
- wr %l0, PSR_ET, %psr ! okay, turn traps on again
-
- std %g2, [%sp + CCFSZ + 0] ! save g2, g3
- rd %y, %l4 ! save y
-
- std %g4, [%sp + CCFSZ + 8] ! save g4,g5
- mov %g1, %l5 ! save g1,g6,g7
- mov %g6, %l6
- mov %g7, %l7
-
-nmi_common:
- ! and call C code
- call _C_LABEL(ecc_fault)
- clr %o0
-
- mov %l5, %g1 ! restore g1 through g7
- ldd [%sp + CCFSZ + 0], %g2
- ldd [%sp + CCFSZ + 8], %g4
- wr %l0, 0, %psr ! re-disable traps
- mov %l6, %g6
- mov %l7, %g7
-
- b return_from_trap
- wr %l4, 0, %y ! restore y
-
-#ifdef GPROF
- .globl window_of, winof_user
- .globl window_uf, winuf_user, winuf_ok, winuf_invalid
- .globl return_from_trap, rft_kernel, rft_user, rft_invalid
- .globl softtrap, slowtrap
- .globl clean_trap_window, _C_LABEL(_syscall)
-#endif
-
-/*
- * Window overflow trap handler.
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- */
-window_of:
-#ifdef TRIVIAL_WINDOW_OVERFLOW_HANDLER
- /* a trivial version that assumes %sp is ok */
- /* (for testing only!) */
- save %g0, %g0, %g0
- std %l0, [%sp + (0*8)]
- rd %psr, %l0
- mov 1, %l1
- sll %l1, %l0, %l0
- wr %l0, 0, %wim
- std %l2, [%sp + (1*8)]
- std %l4, [%sp + (2*8)]
- std %l6, [%sp + (3*8)]
- std %i0, [%sp + (4*8)]
- std %i2, [%sp + (5*8)]
- std %i4, [%sp + (6*8)]
- std %i6, [%sp + (7*8)]
- restore
- RETT
-#else
- /*
- * This is similar to TRAP_SETUP, but we do not want to spend
- * a lot of time, so we have separate paths for kernel and user.
- * We also know for sure that the window has overflowed.
- */
- btst PSR_PS, %l0
- bz winof_user
- sethi %hi(clean_trap_window), %l7
-
- /*
- * Overflow from kernel mode. Call clean_trap_window to
- * do the dirty work, then just return, since we know prev
- * window is valid. clean_trap_windows might dump all *user*
- * windows into the pcb, but we do not care: there is at
- * least one kernel window (a trap or interrupt frame!)
- * above us.
- */
- jmpl %l7 + %lo(clean_trap_window), %l4
- mov %g7, %l7 ! for clean_trap_window
-
- wr %l0, 0, %psr ! put back the @%*! cond. codes
- nop; nop; nop ! (let them settle in)
- RETT
-
-winof_user:
- /*
- * Overflow from user mode.
- * If clean_trap_window dumps the registers into the pcb,
- * rft_user will need to call trap(), so we need space for
- * a trap frame. We also have to compute pcb_nw.
- *
- * SHOULD EXPAND IN LINE TO AVOID BUILDING TRAP FRAME ON
- * `EASY' SAVES
- */
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- ld [%l6 + PCB_WIM], %l5
- and %l0, 31, %l3
- sub %l3, %l5, %l5 /* l5 = CWP - pcb_wim */
- set uwtab, %l4
- ldub [%l4 + %l5], %l5 /* l5 = uwtab[l5] */
- st %l5, [%l6 + PCB_UW]
- jmpl %l7 + %lo(clean_trap_window), %l4
- mov %g7, %l7 ! for clean_trap_window
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- set USPACE-CCFSZ-80, %l5
- add %l6, %l5, %sp /* over to kernel stack */
- CHECK_SP_REDZONE(%l6, %l5)
-
- /*
- * Copy return_from_trap far enough to allow us
- * to jump directly to rft_user_or_recover_pcb_windows
- * (since we know that is where we are headed).
- */
-! and %l0, 31, %l3 ! still set (clean_trap_window
- ! leaves this register alone)
- set wmask, %l6
- ldub [%l6 + %l3], %l5 ! %l5 = 1 << ((CWP + 1) % nwindows)
- b rft_user_or_recover_pcb_windows
- rd %wim, %l4 ! (read %wim first)
-#endif /* end `real' version of window overflow trap handler */
-
-/*
- * Window underflow trap handler.
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- *
- * A picture:
- *
- * T R I X
- * 0 0 0 1 0 0 0 (%wim)
- * [bit numbers increase towards the right;
- * `restore' moves right & `save' moves left]
- *
- * T is the current (Trap) window, R is the window that attempted
- * a `Restore' instruction, I is the Invalid window, and X is the
- * window we want to make invalid before we return.
- *
- * Since window R is valid, we cannot use rft_user to restore stuff
- * for us. We have to duplicate its logic. YUCK.
- *
- * Incidentally, TRIX are for kids. Silly rabbit!
- */
-window_uf:
-#ifdef TRIVIAL_WINDOW_UNDERFLOW_HANDLER
- wr %g0, 0, %wim ! allow us to enter I
- restore ! to R
- nop
- nop
- restore ! to I
- restore %g0, 1, %l1 ! to X
- rd %psr, %l0
- sll %l1, %l0, %l0
- wr %l0, 0, %wim
- save %g0, %g0, %g0 ! back to I
- LOADWIN(%sp)
- save %g0, %g0, %g0 ! back to R
- save %g0, %g0, %g0 ! back to T
- RETT
-#else
- wr %g0, 0, %wim ! allow us to enter I
- btst PSR_PS, %l0
- restore ! enter window R
- bz winuf_user
- restore ! enter window I
-
- /*
- * Underflow from kernel mode. Just recover the
- * registers and go (except that we have to update
- * the blasted user pcb fields).
- */
- restore %g0, 1, %l1 ! enter window X, then set %l1 to 1
- rd %psr, %l0 ! cwp = %psr & 31;
- and %l0, 31, %l0
- sll %l1, %l0, %l1 ! wim = 1 << cwp;
- wr %l1, 0, %wim ! setwim(wim);
- sethi %hi(_C_LABEL(cpcb)), %l1
- ld [%l1 + %lo(_C_LABEL(cpcb))], %l1
- st %l0, [%l1 + PCB_WIM] ! cpcb->pcb_wim = cwp;
- save %g0, %g0, %g0 ! back to window I
- LOADWIN(%sp)
- save %g0, %g0, %g0 ! back to R
- save %g0, %g0, %g0 ! and then to T
- wr %l0, 0, %psr ! fix those cond codes....
- nop; nop; nop ! (let them settle in)
- RETT
-
-winuf_user:
- /*
- * Underflow from user mode.
- *
- * We cannot use rft_user (as noted above) because
- * we must re-execute the `restore' instruction.
- * Since it could be, e.g., `restore %l0,0,%l0',
- * it is not okay to touch R's registers either.
- *
- * We are now in window I.
- */
- btst 7, %sp ! if unaligned, it is invalid
- bne winuf_invalid
- EMPTY
-
- PTE_OF_ADDR(%sp, %l7, %l4, winuf_invalid)
- CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_6) ! if first page not readable,
- bne winuf_invalid ! it is invalid
- nop
- INSERT_PTE(%sp, %l7)
- SLT_IF_1PAGE_RW(%sp, %l7, %l4) ! first page is readable
- bl,a winuf_ok ! if only one page, enter window X
- restore %g0, 1, %l1 ! and goto ok, & set %l1 to 1
- add %sp, 7 * 8, %l5
- PTE_OF_ADDR(%l5, %l7, %l4, winuf_invalid)
- CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_8) ! check second page too
- INSERT_PTE(%l5, %l7)
- be,a winuf_ok ! enter window X and goto ok
- restore %g0, 1, %l1 ! (and then set %l1 to 1)
-
-winuf_invalid:
- /*
- * We were unable to restore the window because %sp
- * is invalid or paged out. Return to the trap window
- * and call trap(T_WINUF). This will save R to the user
- * stack, then load both R and I into the pcb rw[] area,
- * and return with pcb_nsaved set to -1 for success, 0 for
- * failure. `Failure' indicates that someone goofed with the
- * trap registers (e.g., signals), so that we need to return
- * from the trap as from a syscall (probably to a signal handler)
- * and let it retry the restore instruction later. Note that
- * window R will have been pushed out to user space, and thus
- * be the invalid window, by the time we get back here. (We
- * continue to label it R anyway.) We must also set %wim again,
- * and set pcb_uw to 1, before enabling traps. (Window R is the
- * only window, and it is a user window).
- */
- save %g0, %g0, %g0 ! back to R
- save %g0, 1, %l4 ! back to T, then %l4 = 1
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- st %l4, [%l6 + PCB_UW] ! pcb_uw = 1
- ld [%l6 + PCB_WIM], %l5 ! get log2(%wim)
- sll %l4, %l5, %l4 ! %l4 = old %wim
- wr %l4, 0, %wim ! window I is now invalid again
- set USPACE-CCFSZ-80, %l5
- add %l6, %l5, %sp ! get onto kernel stack
- nop
- CHECK_SP_REDZONE(%l6, %l5)
-
- /*
- * Okay, call trap(T_WINUF, psr, pc, &tf).
- * See `slowtrap' above for operation.
- */
- wr %l0, PSR_ET, %psr
- std %l0, [%sp + CCFSZ + 0] ! tf.tf_psr, tf.tf_pc
- rd %y, %l3
- std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc, tf.tf_y
- mov T_WINUF, %o0
- st %g1, [%sp + CCFSZ + 20] ! tf.tf_global[1]
- mov %l0, %o1
- std %g2, [%sp + CCFSZ + 24] ! etc
- mov %l1, %o2
- std %g4, [%sp + CCFSZ + 32]
- add %sp, CCFSZ, %o3
- std %g6, [%sp + CCFSZ + 40]
- std %i0, [%sp + CCFSZ + 48] ! tf.tf_out[0], etc
- std %i2, [%sp + CCFSZ + 56]
- std %i4, [%sp + CCFSZ + 64]
- call _C_LABEL(trap) ! trap(T_WINUF, pc, psr, &tf)
- std %i6, [%sp + CCFSZ + 72] ! tf.tf_out[6]
-
- ldd [%sp + CCFSZ + 0], %l0 ! new psr, pc
- ldd [%sp + CCFSZ + 8], %l2 ! new npc, %y
- wr %l3, 0, %y
- ld [%sp + CCFSZ + 20], %g1
- ldd [%sp + CCFSZ + 24], %g2
- ldd [%sp + CCFSZ + 32], %g4
- ldd [%sp + CCFSZ + 40], %g6
- ldd [%sp + CCFSZ + 48], %i0 ! %o0 for window R, etc
- ldd [%sp + CCFSZ + 56], %i2
- ldd [%sp + CCFSZ + 64], %i4
- wr %l0, 0, %psr ! disable traps: test must be atomic
- ldd [%sp + CCFSZ + 72], %i6
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- ld [%l6 + PCB_NSAVED], %l7 ! if nsaved is -1, we have our regs
- tst %l7
- bl,a 1f ! got them
- wr %g0, 0, %wim ! allow us to enter windows R, I
- b,a return_from_trap
-
- /*
- * Got 'em. Load 'em up.
- */
-1:
- mov %g6, %l3 ! save %g6; set %g6 = cpcb
- mov %l6, %g6
- st %g0, [%g6 + PCB_NSAVED] ! and clear magic flag
- restore ! from T to R
- restore ! from R to I
- restore %g0, 1, %l1 ! from I to X, then %l1 = 1
- rd %psr, %l0 ! cwp = %psr;
- sll %l1, %l0, %l1
- wr %l1, 0, %wim ! make window X invalid
- and %l0, 31, %l0
- st %l0, [%g6 + PCB_WIM] ! cpcb->pcb_wim = cwp;
- nop ! unnecessary? old wim was 0...
- save %g0, %g0, %g0 ! back to I
-
- !!LOADWIN(%g6 + PCB_RW + 64) ! load from rw[1]
-
- !! StackGhost Decrypt (PCP)
- ! pcb already dereferenced in %g6
- ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
- ldd [%g6 + PCB_RW + 64 + 56], %i6
- xor %l0, %i7, %i7 ! remove cookie
-
- ldd [%g6 + PCB_RW + 64], %l0 ! load from rw[1]
- ldd [%g6 + PCB_RW + 64 + 8], %l2
- ldd [%g6 + PCB_RW + 64 + 16], %l4
- ldd [%g6 + PCB_RW + 64 + 24], %l6
- ldd [%g6 + PCB_RW + 64 + 32], %i0
- ldd [%g6 + PCB_RW + 64 + 40], %i2
- ldd [%g6 + PCB_RW + 64 + 48], %i4
-
- save %g0, %g0, %g0 ! back to R
-
- !! StackGhost Decrypt (PCP)
- ! pcb already dereferenced in %g6
- ! (If I was sober, I could potentially re-use the cookie from above)
- ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
- ldd [%g6 + PCB_RW + 56], %i6
- xor %l0, %i7, %i7 ! remove cookie
-
- !!LOADWIN(%g6 + PCB_RW) ! load from rw[0]
- ldd [%g6 + PCB_RW], %l0 ! load from rw[0]
- ldd [%g6 + PCB_RW + 8], %l2
- ldd [%g6 + PCB_RW + 16], %l4
- ldd [%g6 + PCB_RW + 24], %l6
- ldd [%g6 + PCB_RW + 32], %i0
- ldd [%g6 + PCB_RW + 40], %i2
- ldd [%g6 + PCB_RW + 48], %i4
-
- save %g0, %g0, %g0 ! back to T
-
- wr %l0, 0, %psr ! restore condition codes
- nop; nop
- mov %l3, %g6 ! fix %g6
- RETT
-
- /*
- * Restoring from user stack, but everything has checked out
- * as good. We are now in window X, and %l1 = 1. Window R
- * is still valid and holds user values.
- */
-winuf_ok:
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0, %wim ! make this one invalid
- sethi %hi(_C_LABEL(cpcb)), %l2
- ld [%l2 + %lo(_C_LABEL(cpcb))], %l2
- and %l0, 31, %l0
- st %l0, [%l2 + PCB_WIM] ! cpcb->pcb_wim = cwp;
- save %g0, %g0, %g0 ! back to I
-
- !! StackGhost Decrypt
- sethi %hi(_C_LABEL(cpcb)), %l0 ! get current *pcb
- ld [%l0 + %lo(_C_LABEL(cpcb))], %l1 ! dereference *pcb
- ld [%l1 + PCB_WCOOKIE], %l0 ! get window cookie
- ldd [%sp + 56], %i6 ! get saved return pointer
- xor %l0, %i7, %i7 ! remove cookie
-
- !!LOADWIN(%sp)
- ldd [%sp], %l0
- ldd [%sp + 8], %l2
- ldd [%sp + 16], %l4
- ldd [%sp + 24], %l6
- ldd [%sp + 32], %i0
- ldd [%sp + 40], %i2
- ldd [%sp + 48], %i4
-
- save %g0, %g0, %g0 ! back to R
- save %g0, %g0, %g0 ! back to T
- wr %l0, 0, %psr ! restore condition codes
- nop; nop; nop ! it takes three to tangle
- RETT
-#endif /* end `real' version of window underflow trap handler */
-
-/*
- * Various return-from-trap routines (see return_from_trap).
- */
-
-/*
- * Return from trap, to kernel.
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l4 = %wim
- * %l5 = bit for previous window
- */
-rft_kernel:
- btst %l5, %l4 ! if (wim & l5)
- bnz 1f ! goto reload;
- wr %l0, 0, %psr ! but first put !@#*% cond codes back
-
- /* previous window is valid; just rett */
- nop; nop; nop ! wait for cond codes to settle in
- RETT
-
- /*
- * Previous window is invalid.
- * Update %wim and then reload l0..i7 from frame.
- *
- * T I X
- * 0 0 1 0 0 (%wim)
- * [see picture in window_uf handler]
- *
- * T is the current (Trap) window, I is the Invalid window,
- * and X is the window we want to make invalid. Window X
- * currently has no useful values.
- */
-1:
- wr %g0, 0, %wim ! allow us to enter window I
- nop; nop; nop ! (it takes a while)
- restore ! enter window I
- restore %g0, 1, %l1 ! enter window X, then %l1 = 1
- rd %psr, %l0 ! CWP = %psr & 31;
- and %l0, 31, %l0
- sll %l1, %l0, %l1 ! wim = 1 << CWP;
- wr %l1, 0, %wim ! setwim(wim);
- sethi %hi(_C_LABEL(cpcb)), %l1
- ld [%l1 + %lo(_C_LABEL(cpcb))], %l1
- st %l0, [%l1 + PCB_WIM] ! cpcb->pcb_wim = l0 & 31;
- save %g0, %g0, %g0 ! back to window I
- LOADWIN(%sp)
- save %g0, %g0, %g0 ! back to window T
- /*
- * Note that the condition codes are still set from
- * the code at rft_kernel; we can simply return.
- */
- RETT
-
-/*
- * Return from trap, to user. Checks for scheduling trap (`ast') first;
- * will re-enter trap() if set. Note that we may have to switch from
- * the interrupt stack to the kernel stack in this case.
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- * %l4 = %wim
- * %l5 = bit for previous window
- * %l6 = cpcb
- * If returning to a valid window, just set psr and return.
- */
-rft_user:
-! sethi %hi(_C_LABEL(want_ast)), %l7 ! (done below)
- ld [%l7 + %lo(_C_LABEL(want_ast))], %l7
- tst %l7 ! want AST trap?
- bne,a softtrap ! yes, re-enter trap with type T_AST
- mov T_AST, %o0
-
- btst %l5, %l4 ! if (wim & l5)
- bnz 1f ! goto reload;
- wr %l0, 0, %psr ! restore cond codes
- nop; nop; nop ! (three instruction delay)
- RETT
-
- /*
- * Previous window is invalid.
- * Before we try to load it, we must verify its stack pointer.
- * This is much like the underflow handler, but a bit easier
- * since we can use our own local registers.
- */
-1:
- btst 7, %fp ! if unaligned, address is invalid
- bne rft_invalid
- EMPTY
-
- PTE_OF_ADDR(%fp, %l7, %l3, rft_invalid)
- CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_10) ! try first page
- bne rft_invalid ! no good
- nop
- INSERT_PTE(%fp, %l7)
- SLT_IF_1PAGE_RW(%fp, %l7, %l3)
- bl,a rft_user_ok ! only 1 page: ok
- wr %g0, 0, %wim
- add %fp, 7*8, %l5
- PTE_OF_ADDR(%l5, %l7, %l3, rft_invalid)
- INSERT_PTE(%l5, %l7)
- CMP_PTE_USER_READ(%l7, %l5, NOP_ON_4M_12) ! check 2nd page too
- be,a rft_user_ok
- wr %g0, 0, %wim
-
- /*
- * The window we wanted to pull could not be pulled. Instead,
- * re-enter trap with type T_RWRET. This will pull the window
- * into cpcb->pcb_rw[0] and set cpcb->pcb_nsaved to -1, which we
- * will detect when we try to return again.
- */
-rft_invalid:
- b softtrap
- mov T_RWRET, %o0
-
- /*
- * The window we want to pull can be pulled directly.
- */
-rft_user_ok:
-! wr %g0, 0, %wim ! allow us to get into it
- wr %l0, 0, %psr ! fix up the cond codes now
- nop; nop; nop
- restore ! enter window I
- restore %g0, 1, %l1 ! enter window X, then %l1 = 1
- rd %psr, %l0 ! l0 = (junk << 5) + CWP;
- sll %l1, %l0, %l1 ! %wim = 1 << CWP;
- wr %l1, 0, %wim
- sethi %hi(_C_LABEL(cpcb)), %l1
- ld [%l1 + %lo(_C_LABEL(cpcb))], %l1
- and %l0, 31, %l0
- st %l0, [%l1 + PCB_WIM] ! cpcb->pcb_wim = l0 & 31;
- save %g0, %g0, %g0 ! back to window I
-
- !! StackGhost Decrypt
- sethi %hi(_C_LABEL(cpcb)), %l0 ! get current *pcb
- ld [%l0 + %lo(_C_LABEL(cpcb))], %l1 ! dereference *pcb
- ld [%l1 + PCB_WCOOKIE], %l0 ! get window cookie
- ldd [%sp + 56], %i6 ! get saved return pointer
- xor %l0, %i7, %i7 ! remove cookie
-
- !!LOADWIN(%sp) ! suck hard
- ldd [%sp], %l0
- ldd [%sp + 8], %l2
- ldd [%sp + 16], %l4
- ldd [%sp + 24], %l6
- ldd [%sp + 32], %i0
- ldd [%sp + 40], %i2
- ldd [%sp + 48], %i4
-
- save %g0, %g0, %g0 ! back to window T
- RETT
-
-/*
- * Return from trap. Entered after a
- * wr %l0, 0, %psr
- * which disables traps so that we can rett; registers are:
- *
- * %l0 = %psr
- * %l1 = return pc
- * %l2 = return npc
- *
- * (%l3..%l7 anything).
- *
- * If we are returning to user code, we must:
- * 1. Check for register windows in the pcb that belong on the stack.
- * If there are any, reenter trap with type T_WINOF.
- * 2. Make sure the register windows will not underflow. This is
- * much easier in kernel mode....
- */
-return_from_trap:
-! wr %l0, 0, %psr ! disable traps so we can rett
-! (someone else did this already)
- and %l0, 31, %l5
- set wmask, %l6
- ldub [%l6 + %l5], %l5 ! %l5 = 1 << ((CWP + 1) % nwindows)
- btst PSR_PS, %l0 ! returning to userland?
- bnz rft_kernel ! no, go return to kernel
- rd %wim, %l4 ! (read %wim in any case)
-
-rft_user_or_recover_pcb_windows:
- /*
- * (entered with %l4=%wim, %l5=wmask[cwp]; %l0..%l2 as usual)
- *
- * check cpcb->pcb_nsaved:
- * if 0, do a `normal' return to user (see rft_user);
- * if > 0, cpcb->pcb_rw[] holds registers to be copied to stack;
- * if -1, cpcb->pcb_rw[0] holds user registers for rett window
- * from an earlier T_RWRET pseudo-trap.
- */
- sethi %hi(_C_LABEL(cpcb)), %l6
- ld [%l6 + %lo(_C_LABEL(cpcb))], %l6
- ld [%l6 + PCB_NSAVED], %l7
- tst %l7
- bz,a rft_user
- sethi %hi(_C_LABEL(want_ast)), %l7 ! first instr of rft_user
-
- bg,a softtrap ! if (pcb_nsaved > 0)
- mov T_WINOF, %o0 ! trap(T_WINOF);
-
- /*
- * To get here, we must have tried to return from a previous
- * trap and discovered that it would cause a window underflow.
- * We then must have tried to pull the registers out of the
- * user stack (from the address in %fp==%i6) and discovered
- * that it was either unaligned or not loaded in memory, and
- * therefore we ran a trap(T_RWRET), which loaded one set of
- * registers into cpcb->pcb_pcb_rw[0] (if it had killed the
- * process due to a bad stack, we would not be here).
- *
- * We want to load pcb_rw[0] into the previous window, which
- * we know is currently invalid. In other words, we want
- * %wim to be 1 << ((cwp + 2) % nwindows).
- */
- wr %g0, 0, %wim ! enable restores
- mov %g6, %l3 ! save g6 in l3
- mov %l6, %g6 ! set g6 = &u
- st %g0, [%g6 + PCB_NSAVED] ! clear cpcb->pcb_nsaved
- restore ! enter window I
- restore %g0, 1, %l1 ! enter window X, then %l1 = 1
- rd %psr, %l0
- sll %l1, %l0, %l1 ! %wim = 1 << CWP;
- wr %l1, 0, %wim
- and %l0, 31, %l0
- st %l0, [%g6 + PCB_WIM] ! cpcb->pcb_wim = CWP;
- nop ! unnecessary? old wim was 0...
- save %g0, %g0, %g0 ! back to window I
-
- !! StackGhost Decrypt (PCB)
- ! pcb already deferenced in %g6
- ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
- ldd [%g6 + PCB_RW + 56], %i6 ! get saved return pointer
- xor %l0, %i7, %i7 ! remove cookie
-
- !LOADWIN(%g6 + PCB_RW)
- ldd [%g6 + PCB_RW], %l0
- ldd [%g6 + PCB_RW + 8], %l2
- ldd [%g6 + PCB_RW + 16], %l4
- ldd [%g6 + PCB_RW + 24], %l6
- ldd [%g6 + PCB_RW + 32], %i0
- ldd [%g6 + PCB_RW + 40], %i2
- ldd [%g6 + PCB_RW + 48], %i4
-
- save %g0, %g0, %g0 ! back to window T (trap window)
- wr %l0, 0, %psr ! cond codes, cond codes everywhere
- nop; nop
- mov %l3, %g6 ! restore g6
- RETT
-
-! exported end marker for kernel gdb
- .globl _C_LABEL(endtrapcode)
-_C_LABEL(endtrapcode):
-
-/*
- * init_tables(nwin) int nwin;
- *
- * Set up the uwtab and wmask tables.
- * We know nwin > 1.
- */
-init_tables:
- /*
- * for (i = -nwin, j = nwin - 2; ++i < 0; j--)
- * uwtab[i] = j;
- * (loop runs at least once)
- */
- set uwtab, %o3
- sub %g0, %o0, %o1 ! i = -nwin + 1
- inc %o1
- add %o0, -2, %o2 ! j = nwin - 2;
-0:
- stb %o2, [%o3 + %o1] ! uwtab[i] = j;
-1:
- inccc %o1 ! ++i < 0?
- bl 0b ! yes, continue loop
- dec %o2 ! in any case, j--
-
- /*
- * (i now equals 0)
- * for (j = nwin - 1; i < nwin; i++, j--)
- * uwtab[i] = j;
- * (loop runs at least twice)
- */
- sub %o0, 1, %o2 ! j = nwin - 1
-0:
- stb %o2, [%o3 + %o1] ! uwtab[i] = j
- inc %o1 ! i++
-1:
- cmp %o1, %o0 ! i < nwin?
- bl 0b ! yes, continue
- dec %o2 ! in any case, j--
-
- /*
- * We observe that, for i in 0..nwin-2, (i+1)%nwin == i+1;
- * for i==nwin-1, (i+1)%nwin == 0.
- * To avoid adding 1, we run i from 1 to nwin and set
- * wmask[i-1].
- *
- * for (i = j = 1; i < nwin; i++) {
- * j <<= 1; (j now == 1 << i)
- * wmask[i - 1] = j;
- * }
- * (loop runs at least once)
- */
- set wmask - 1, %o3
- mov 1, %o1 ! i = 1;
- mov 2, %o2 ! j = 2;
-0:
- stb %o2, [%o3 + %o1] ! (wmask - 1)[i] = j;
- inc %o1 ! i++
- cmp %o1, %o0 ! i < nwin?
- bl,a 0b ! yes, continue
- sll %o2, 1, %o2 ! (and j <<= 1)
-
- /*
- * Now i==nwin, so we want wmask[i-1] = 1.
- */
- mov 1, %o2 ! j = 1;
- retl
- stb %o2, [%o3 + %o1] ! (wmask - 1)[i] = j;
-
-/* ========================================================================== */
-
- .align 8 /* to be sure we won't cross a page boundary */
-ENTRY(masktest)
- ret
- nop
-
-#define BLINK(how) \
- call blink; \
- mov how, %o0
-
-ENTRY(blink)
- save %sp, -64, %sp
- set GLU_BSR, %l1
- lda [%l1] ASI_PHYS_IO, %l2
- srl %l2, 24, %l2
- andn %l2, GBSR_LED_MASK, %l2
- or %l2, %i0, %l2
- sll %l2, 24, %l2
- sta %l2, [%l1] ASI_PHYS_IO
- ret
- restore
-
-dostart:
- /*
- * Startup.
- *
- * We have been loaded in high RAM, in the virtual window 0xfd, but
- * physical window 0xf0, which is also the segment we are linked at.
- */
-
- BLINK(GBSR_LED_AMBER)
-
-#if defined(DDB) || NKSYMS > 0
- /*
- * Initialize esym to a non-dangerous value for now.
- */
- set _C_LABEL(end), %l0
- sethi %hi(_C_LABEL(esym)), %l1
- st %l0, [%l1 + %lo(_C_LABEL(esym))]
-#endif
-
- /*
- * We are invoked with a regular frame on stack.
- */
- ld [%sp + FRAME_ARGC], %g5 ! argc
- ld [%sp + FRAME_ARGC + 4], %g6 ! argv
- ld [%sp + FRAME_ARGC + 8], %g7 ! environ
-
- /*
- * Here, we should make sure we are really running on an idt
- * machine. But we won't, because if we could be loaded correctly,
- * and did not fault earlier, chances are good we are running on
- * the adequate hardware...
- */
-
- /* disable external interrupts - this also disables soft interrupts */
- set GLU_ICR, %o0
- mov GICR_DISABLE_ALL, %o1
- sll %o1, 24, %o1
- sta %o1, [%o0] ASI_PHYS_IO
- nop
-
- CLEAR_FCR
-
- /* disable interrupts, and enable traps */
- rd %psr, %o0
- or %o0, PSR_PIL, %o0
- wr %o0, %psr
- nop; nop; nop;
- or %o0, PSR_ET, %o0
- wr %o0, %psr
- nop; nop; nop
-
- /*
- * Step 1: Reset the MMU to sane defaults.
- * We do not disable it because we will be playing with the stack,
- * which will not be addressable if translations are disabled.
- */
-
- sta %g0, [%g0] ASI_PIID
- sta %g0, [%g0] ASI_GTLB_INVAL_PID
- nop; nop; nop
- lda [%g0] ASI_FVAR, %g0
- lda [%g0] ASI_FPAR, %g0
- lda [%g0] ASI_FPSR, %g0
- sta %g0, [%g0] ASI_PID
-
- rd %psr, %g3 ! paranoia: make sure ...
- andn %g3, PSR_ET, %g3 ! we have traps off
- wr %g3, 0, %psr ! so that we can fiddle safely
- nop; nop; nop
-
- wr %g0, 0, %wim ! make sure we can set psr
- nop; nop; nop
- wr %g0, PSR_S|PSR_PS|PSR_PIL, %psr ! set initial psr
- nop; nop; nop
-
- wr %g0, 2, %wim ! set initial %wim (w1 invalid)
- mov 1, %g1 ! set pcb_wim (log2(%wim) = 1)
- sethi %hi(_C_LABEL(u0) + PCB_WIM), %g2
- st %g1, [%g2 + %lo(_C_LABEL(u0) + PCB_WIM)]
-
- set VM_MIN_KERNEL_ADDRESS - CCFSZ, %fp ! as if called from user code
- set estack0 - CCFSZ - 80, %sp ! via syscall(boot_me_up) or somesuch
- rd %psr, %l0
- wr %l0, PSR_ET, %psr
- nop; nop; nop
-
- /*
- * Step 2: clear BSS. This may just be paranoia; the boot
- * loader might already do it for us; but what the hell.
- */
- set _C_LABEL(edata), %o0 ! bzero(edata, end - edata)
- set _C_LABEL(end), %o1
- call _C_LABEL(bzero)
- sub %o1, %o0, %o1
-
- /*
- * Stash prom variables now, after bzero, as they live in bss
- * (which we just zeroed).
- * This depends on the fact that bzero does not use %g5-%g7.
- */
- sethi %hi(_C_LABEL(prom_argc)), %o0
- st %g5, [%o0 + %lo(_C_LABEL(prom_argc))]
- sethi %hi(_C_LABEL(prom_argv)), %o0
- st %g6, [%o0 + %lo(_C_LABEL(prom_argv))]
- sethi %hi(_C_LABEL(prom_environ)), %o0
- st %g7, [%o0 + %lo(_C_LABEL(prom_environ))]
-
- /*
- * Step 3: compute number of windows and set up tables.
- * We could do some of this later.
- */
- save %sp, -64, %sp
- rd %psr, %g1
- restore
- and %g1, 31, %g1 ! want just the CWP bits
- add %g1, 1, %o0 ! compute nwindows
- sethi %hi(_C_LABEL(nwindows)), %o1 ! may as well tell everyone
- call init_tables
- st %o0, [%o1 + %lo(_C_LABEL(nwindows))]
-
- /*
- * Invoke early C code, still using the PROM trap, so that it can
- * do proper TLB insertion for us while we are accessing various
- * onboard devices.
- */
-
- call _C_LABEL(bootstrap)
- nop
-
- /*
- * Step 4: change the trap base register, now that our trap handlers
- * will function (they need the tables we just set up).
- */
- set trapbase_kap, %g6
- wr %g6, 0, %tbr
- nop; nop; nop ! paranoia
-
- /*
- * Step 5: activate our translations...
- */
- set _C_LABEL(kernel_pmap_store), %o0
- ld [%o0 + PMAP_PSEGTAB], %o1
- sta %o1, [%g0] ASI_PDBR
- nop; nop; nop
-
- /*
- * ... and unmap ROM code.
- */
- set PTW0_DEFAULT & ~PTW_V, %o1
- sta %o1, [%g0] ASI_PTW0
-#if 0
- set PTW1_DEFAULT, %o1
- sta %o1, [%g0] ASI_PTW1
- set PTW2_DEFAULT, %o1
- sta %o1, [%g0] ASI_PTW2
-#endif
-
- sta %g0, [%g0] ASI_PIID
- sta %g0, [%g0] ASI_GTLB_INVAL_PID
- nop; nop; nop
-
- /*
- * Call main.
- */
- call _C_LABEL(main)
- clr %o0 ! our frame arg is ignored
- /*NOTREACHED*/
-
-
-/*
- * The following code is copied to the top of the user stack when each
- * process is exec'ed, and signals are `trampolined' off it.
- *
- * When this code is run, the stack looks like:
- * [%sp] 64 bytes to which registers can be dumped
- * [%sp + 64] signal number (goes in %o0)
- * [%sp + 64 + 4] siginfo_t pointer (goes in %o1)
- * [%sp + 64 + 8] sigcontext pointer (goes in %o2)
- * [%sp + 64 + 12] argument for %o3, currently unsupported (always 0)
- * [%sp + 64 + 16] first word of saved state (sigcontext)
- * .
- * .
- * .
- * [%sp + NNN] last word of saved state
- * (followed by previous stack contents or top of signal stack).
- * The address of the function to call is in %g1; the old %g1 and %o0
- * have already been saved in the sigcontext. We are running in a clean
- * window, all previous windows now being saved to the stack.
- *
- * Note that [%sp + 64 + 8] == %sp + 64 + 16. The copy at %sp+64+8
- * will eventually be removed, with a hole left in its place, if things
- * work out.
- */
- .globl _C_LABEL(sigcode)
- .globl _C_LABEL(esigcode)
-_C_LABEL(sigcode):
- /*
- * XXX the `save' and `restore' below are unnecessary: should
- * replace with simple arithmetic on %sp
- *
- * Make room on the stack for 32 %f registers + %fsr. This comes
- * out to 33*4 or 132 bytes, but this must be aligned to a multiple
- * of 8, or 136 bytes.
- */
- save %sp, -CCFSZ - 136, %sp
- mov %g2, %l2 ! save globals in %l registers
- mov %g3, %l3
- mov %g4, %l4
- mov %g5, %l5
- mov %g6, %l6
- mov %g7, %l7
- /*
- * Saving the fpu registers is expensive, so do it iff the fsr
- * stored in the sigcontext shows that the fpu is enabled.
- */
- ld [%fp + 64 + 16 + SC_PSR_OFFSET], %l0
- sethi %hi(PSR_EF), %l1 ! FPU enable bit is too high for andcc
- andcc %l0, %l1, %l0 ! %l0 = fpu enable bit
- be 1f ! if not set, skip the saves
- rd %y, %l1 ! in any case, save %y
-
- ! fpu is enabled, oh well
- st %fsr, [%sp + CCFSZ + 0]
- std %f0, [%sp + CCFSZ + 8]
- std %f2, [%sp + CCFSZ + 16]
- std %f4, [%sp + CCFSZ + 24]
- std %f6, [%sp + CCFSZ + 32]
- std %f8, [%sp + CCFSZ + 40]
- std %f10, [%sp + CCFSZ + 48]
- std %f12, [%sp + CCFSZ + 56]
- std %f14, [%sp + CCFSZ + 64]
- std %f16, [%sp + CCFSZ + 72]
- std %f18, [%sp + CCFSZ + 80]
- std %f20, [%sp + CCFSZ + 88]
- std %f22, [%sp + CCFSZ + 96]
- std %f24, [%sp + CCFSZ + 104]
- std %f26, [%sp + CCFSZ + 112]
- std %f28, [%sp + CCFSZ + 120]
- std %f30, [%sp + CCFSZ + 128]
-
-1:
- ldd [%fp + 64], %o0 ! sig, sip
- ld [%fp + 76], %o3 ! arg3
-#ifdef SIG_DEBUG
- subcc %o0, 32, %g0 ! signals are 1-32
- bgu _C_LABEL(suicide)
- nop
-#endif
- call %g1 ! (*sa->sa_handler)(sig,sip,scp,arg3)
- add %fp, 64 + 16, %o2 ! scp
-
- /*
- * Now that the handler has returned, re-establish all the state
- * we just saved above, then do a sigreturn.
- */
- tst %l0 ! reload fpu registers?
- be 1f ! if not, skip the loads
- wr %l1, %g0, %y ! in any case, restore %y
-
- ld [%sp + CCFSZ + 0], %fsr
- ldd [%sp + CCFSZ + 8], %f0
- ldd [%sp + CCFSZ + 16], %f2
- ldd [%sp + CCFSZ + 24], %f4
- ldd [%sp + CCFSZ + 32], %f6
- ldd [%sp + CCFSZ + 40], %f8
- ldd [%sp + CCFSZ + 48], %f10
- ldd [%sp + CCFSZ + 56], %f12
- ldd [%sp + CCFSZ + 64], %f14
- ldd [%sp + CCFSZ + 72], %f16
- ldd [%sp + CCFSZ + 80], %f18
- ldd [%sp + CCFSZ + 88], %f20
- ldd [%sp + CCFSZ + 96], %f22
- ldd [%sp + CCFSZ + 104], %f24
- ldd [%sp + CCFSZ + 112], %f26
- ldd [%sp + CCFSZ + 120], %f28
- ldd [%sp + CCFSZ + 128], %f30
-
-1:
- mov %l2, %g2
- mov %l3, %g3
- mov %l4, %g4
- mov %l5, %g5
- mov %l6, %g6
- mov %l7, %g7
-
- restore %g0, SYS_sigreturn, %g1 ! get registers back & set syscall #
- add %sp, 64 + 16, %o0 ! compute scp
- t ST_SYSCALL ! sigreturn(scp)
- ! sigreturn does not return unless it fails
- mov SYS_exit, %g1 ! exit(errno)
- t ST_SYSCALL
-
-#ifdef SIG_DEBUG
- .globl _C_LABEL(suicide)
-_C_LABEL(suicide):
- mov 139, %g1 ! obsolete syscall, puke...
- t ST_SYSCALL
-#endif
-_C_LABEL(esigcode):
-
-/*
- * Primitives
- */
-#if 0
-#ifdef GPROF
- .globl mcount
-#define ENTRY(x) \
- .globl _C_LABEL(x); _C_LABEL(x): ; \
- save %sp, -CCFSZ, %sp; \
- call mcount; \
- nop; \
- restore
-#else
-#define ENTRY(x) .globl _C_LABEL(x); _C_LABEL(x):
-#endif
-#endif
-#define ALTENTRY(x) .globl _C_LABEL(x); _C_LABEL(x):
-
-/*
- * General-purpose NULL routine.
- */
-ENTRY(sparc_noop)
- retl
- nop
-
-/*
- * getfp() - get stack frame pointer
- */
-ENTRY(getfp)
- retl
- mov %fp, %o0
-
-/*
- * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
- *
- * Copy a null terminated string from the user address space into
- * the kernel address space.
- */
-ENTRY(copyinstr)
- ! %o0 = fromaddr, %o1 = toaddr, %o2 = maxlen, %o3 = &lencopied
- mov %o1, %o5 ! save = toaddr;
- tst %o2 ! maxlen == 0?
- beq,a Lcstoolong0 ! yes, return ENAMETOOLONG
- sethi %hi(_C_LABEL(cpcb)), %o4
-
- set VM_MIN_KERNEL_ADDRESS, %o4
- cmp %o0, %o4 ! fromaddr < VM_MIN_KERNEL_ADDRESS?
- blu Lcsdocopyi ! yes, go do it
- sethi %hi(_C_LABEL(cpcb)), %o4 ! (first instr of copy)
-
- b Lcsdone ! no, return EFAULT
- mov EFAULT, %o0
-
-/*
- * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
- *
- * Copy a null terminated string from the kernel
- * address space to the user address space.
- */
-ENTRY(copyoutstr)
- ! %o0 = fromaddr, %o1 = toaddr, %o2 = maxlen, %o3 = &lencopied
- mov %o1, %o5 ! save = toaddr;
- tst %o2 ! maxlen == 0?
- beq,a Lcstoolong0 ! yes, return ENAMETOOLONG
- sethi %hi(_C_LABEL(cpcb)), %o4
-
- set VM_MIN_KERNEL_ADDRESS, %o4
- cmp %o1, %o4 ! toaddr < VM_MIN_KERNEL_ADDRESS?
- blu Lcsdocopyo ! yes, go do it
- sethi %hi(_C_LABEL(cpcb)), %o4 ! (first instr of copy)
-
- b Lcsdone ! no, return EFAULT
- mov EFAULT, %o0
-
-Lcsdocopyi:
-! sethi %hi(_C_LABEL(cpcb)), %o4 ! (done earlier)
- ld [%o4 + %lo(_C_LABEL(cpcb))], %o4 ! catch faults
- set Lcsfaulti, %g1
- b 0f
- st %g1, [%o4 + PCB_ONFAULT]
-
-Lcsdocopyo:
-! sethi %hi(_C_LABEL(cpcb)), %o4 ! (done earlier)
- ld [%o4 + %lo(_C_LABEL(cpcb))], %o4 ! catch faults
- set Lcsfaulto, %g1
- st %g1, [%o4 + PCB_ONFAULT]
-
-! XXX should do this in bigger chunks when possible
-0: ! loop:
- ldsb [%o0], %g1 ! c = *fromaddr;
- tst %g1
- stb %g1, [%o1] ! *toaddr++ = c;
- be 1f ! if (c == NULL)
- inc %o1 ! goto ok;
- deccc %o2 ! if (--len > 0) {
- bgu 0b ! fromaddr++;
- inc %o0 ! goto loop;
- ! }
-Lcstoolong: !
- deccc %o1
- stb %g0, [%o1] ! *--toaddr = '\0';
-Lcstoolong0: !
- b Lcsdone ! error = ENAMETOOLONG;
- mov ENAMETOOLONG, %o0 ! goto done;
-1: ! ok:
- clr %o0 ! error = 0;
-Lcsdone: ! done:
- sub %o1, %o5, %o1 ! len = to - save;
- tst %o3 ! if (lencopied)
- bnz,a 3f
- st %o1, [%o3] ! *lencopied = len;
-3:
- retl ! cpcb->pcb_onfault = 0;
- st %g0, [%o4 + PCB_ONFAULT]! return (error);
-
-Lcsfaulti:
- cmp %o1, %o5 ! did we write to the string?
- be 1f
- nop
- deccc %o1 ! --toaddr
-1:
- stb %g0, [%o1] ! *toaddr = '\0';
- b Lcsdone ! error = EFAULT;
- mov EFAULT, %o0 ! goto ret;
-
-Lcsfaulto:
- cmp %o1, %o5 ! did we write to the string?
- be 1f
- nop
- deccc %o1
- stb %g0, [%o1] ! *--toaddr = '\0';
-1:
- b Lcsdone ! error = EFAULT;
- mov EFAULT, %o0 ! goto ret;
-
-/*
- * copystr(fromaddr, toaddr, maxlength, &lencopied)
- *
- * Copy a null terminated string from one point to another in
- * the kernel address space. (This is a leaf procedure, but
- * it does not seem that way to the C compiler.)
- */
-ENTRY(copystr)
- mov %o1, %o5 ! to0 = to;
- tst %o2 ! if (maxlength == 0)
- beq,a 2f !
- mov ENAMETOOLONG, %o0 ! ret = ENAMETOOLONG; goto done;
-
-0: ! loop:
- ldsb [%o0], %o4 ! c = *from;
- tst %o4
- stb %o4, [%o1] ! *to++ = c;
- be 1f ! if (c == 0)
- inc %o1 ! goto ok;
- deccc %o2 ! if (--len > 0) {
- bgu,a 0b ! from++;
- inc %o0 ! goto loop;
- b 2f ! }
- mov ENAMETOOLONG, %o0 ! ret = ENAMETOOLONG; goto done;
-1: ! ok:
- clr %o0 ! ret = 0;
-2:
- sub %o1, %o5, %o1 ! len = to - to0;
- tst %o3 ! if (lencopied)
- bnz,a 3f
- st %o1, [%o3] ! *lencopied = len;
-3:
- retl
- nop
-
-/*
- * Copyin(src, dst, len)
- *
- * Copy specified amount of data from user space into the kernel.
- */
-ENTRY(copyin)
- set VM_MIN_KERNEL_ADDRESS, %o3
- cmp %o0, %o3 ! src < VM_MIN_KERNEL_ADDRESS?
- blu,a Ldocopy ! yes, can try it
- sethi %hi(_C_LABEL(cpcb)), %o3
-
- /* source address points into kernel space: return EFAULT */
- retl
- mov EFAULT, %o0
-
-/*
- * Copyout(src, dst, len)
- *
- * Copy specified amount of data from kernel to user space.
- * Just like copyin, except that the `dst' addresses are user space
- * rather than the `src' addresses.
- */
-ENTRY(copyout)
- set VM_MIN_KERNEL_ADDRESS, %o3
- cmp %o1, %o3 ! dst < VM_MIN_KERNEL_ADDRESS?
- blu,a Ldocopy
- sethi %hi(_C_LABEL(cpcb)), %o3
-
- /* destination address points into kernel space: return EFAULT */
- retl
- mov EFAULT, %o0
-
- /*
- * ******NOTE****** this depends on bcopy() not using %g7
- */
-Ldocopy:
-! sethi %hi(_C_LABEL(cpcb)), %o3
- ld [%o3 + %lo(_C_LABEL(cpcb))], %o3
- set Lcopyfault, %o4
- mov %o7, %g7 ! save return address
- call _C_LABEL(bcopy) ! bcopy(src, dst, len)
- st %o4, [%o3 + PCB_ONFAULT]
-
- sethi %hi(_C_LABEL(cpcb)), %o3
- ld [%o3 + %lo(_C_LABEL(cpcb))], %o3
- st %g0, [%o3 + PCB_ONFAULT]
- jmp %g7 + 8
- clr %o0 ! return 0
-
-! Copyin or copyout fault. Clear cpcb->pcb_onfault and return EFAULT.
-! Note that although we were in bcopy, there is no state to clean up;
-! the only special thing is that we have to return to [g7 + 8] rather than
-! [o7 + 8].
-Lcopyfault:
- sethi %hi(_C_LABEL(cpcb)), %o3
- ld [%o3 + %lo(_C_LABEL(cpcb))], %o3
- st %g0, [%o3 + PCB_ONFAULT]
- jmp %g7 + 8
- mov EFAULT, %o0
-
-
-/*
- * Write all user windows presently in the CPU back to the user's stack.
- * We just do `save' instructions until pcb_uw == 0.
- *
- * p = cpcb;
- * nsaves = 0;
- * while (p->pcb_uw > 0)
- * save(), nsaves++;
- * while (--nsaves >= 0)
- * restore();
- */
-ENTRY(write_user_windows)
- sethi %hi(_C_LABEL(cpcb)), %g6
- ld [%g6 + %lo(_C_LABEL(cpcb))], %g6
- b 2f
- clr %g5
-1:
- save %sp, -64, %sp
-2:
- ld [%g6 + PCB_UW], %g7
- tst %g7
- bg,a 1b
- inc %g5
-3:
- deccc %g5
- bge,a 3b
- restore
- retl
- nop
-
-
- .comm _C_LABEL(want_resched),4
-/*
- * Masterpaddr is the p->p_addr of the last process on the processor.
- * XXX masterpaddr is almost the same as cpcb
- * XXX should delete this entirely
- */
- .comm _C_LABEL(masterpaddr), 4
-
-/*
- * cpu_switchto(struct proc *oldproc, struct proc *newproc)
- */
-ENTRY(cpu_switchto)
- sethi %hi(_C_LABEL(cpcb)), %g6
- sethi %hi(_C_LABEL(curproc)), %g7
- ld [%g6 + %lo(_C_LABEL(cpcb))], %o2
- std %o6, [%o2 + PCB_SP] ! cpcb->pcb_<sp,pc> = <sp,pc>;
- rd %psr, %g1 ! oldpsr = %psr;
- st %g1, [%o2 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
- andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
-
- /*
- * REGISTER USAGE:
- * %g1 = oldpsr (excluding ipl bits)
- * %g2 = newpsr
- * %g5 = newpcb
- * %g6 = %hi(_C_LABEL(cpcb))
- * %g7 = %hi(_C_LABEL(curproc))
- * %o0 = oldproc
- * %o1 = newproc
- * %o2 = tmp 3
- * %o3 = vm
- * %o4 = sswap
- * %o5 = <free>
- */
-
- /*
- * Committed to running process p (in o1).
- */
- mov %o1, %g3
-
- mov SONPROC, %o0 ! p->p_stat = SONPROC
- stb %o0, [%g3 + P_STAT]
- ld [%g3 + P_ADDR], %g5 ! newpcb = p->p_addr;
- ld [%g5 + PCB_PSR], %g2 ! newpsr = newpcb->pcb_psr;
- st %g3, [%g7 + %lo(_C_LABEL(curproc))] ! curproc = p;
-
- /*
- * Save the old process, if any; then load p.
- */
- tst %o0
- be,a Lsw_load ! if no old process, go load
-#if 0
- wr %g1, (IPL_SCHED << 8) | PSR_ET, %psr
-#else
- wr %g1, (IPL_SCHED << 8), %psr
-#endif
-
- /*
- * save: write back all windows (including the current one).
- * XXX crude; knows nwindows <= 8
- */
-#define SAVE save %sp, -64, %sp
-wb1: SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE /* 7 of each: */
- restore; restore; restore; restore; restore; restore; restore
-
- /*
- * Load the new process. To load, we must change stacks and
- * alter cpcb and %wim, hence we must disable traps. %psr is
- * currently equal to oldpsr (%g1) ^ (IPL_SCHED << 8);
- * this means that PSR_ET is on. Likewise, PSR_ET is on
- * in newpsr (%g2), although we do not know newpsr's ipl.
- *
- * We also must load up the `in' and `local' registers.
- */
-#if 0
- wr %g1, (IPL_SCHED << 8) | PSR_ET, %psr
-#else
- wr %g1, (IPL_SCHED << 8), %psr
-#endif
-Lsw_load:
-#if 0
-! wr %g1, (IPL_SCHED << 8) | PSR_ET, %psr ! done above
-#else
-! wr %g1, (IPL_SCHED << 8), %psr ! done above
-#endif
-
- /*
- * Access the new pcb while we still enable traps. This is
- * simpler (for us) than doing manual TLB insertion, and
- * is faster if this is a TLB hit.
- */
- ld [%g5 + PCB_SP], %o1 ! access pcb
- ld [%g3 + P_VMSPACE], %o3 ! access p
- ld [%o3 + VM_PMAP], %o3 ! access p->p_vmspace
- ld [%o3 + PMAP_PSEGTAB], %o3 ! access pmap
-
- /*
- * Disable traps now.
- */
- wr %g1, PSR_ET, %psr
-
- /* compute new wim */
- ld [%g5 + PCB_WIM], %o0
- mov 1, %o1
- sll %o1, %o0, %o0
- wr %o0, 0, %wim ! %wim = 1 << newpcb->pcb_wim;
- /* now must not change %psr for 3 more instrs */
-/*1*/ set PSR_EF|PSR_EC, %o0
-/*2*/ andn %g2, %o0, %g2 ! newpsr &= ~(PSR_EF|PSR_EC);
-/*3*/ nop
- /* set new psr, but with traps disabled */
- wr %g2, PSR_ET, %psr ! %psr = newpsr ^ PSR_ET;
- /* set new cpcb */
- st %g5, [%g6 + %lo(_C_LABEL(cpcb))] ! cpcb = newpcb;
-
- /*
- * Now we need to set up the new translations; but we have to be
- * careful not to fault (TLB miss) while dereferencing the proper
- * structures.
- */
-
- ld [%g3 + P_VMSPACE], %o3 ! vm = p->p_vmspace;
-#if 0
- PTE_OF_ADDR(%o3, %o1, %o2, badstack)
- INSERT_PTE(%o3, %o1)
-#endif
-
- ld [%o3 + VM_PMAP], %o3 ! pm = vm->vm_map.pmap;
- add %o3, PMAP_PSEGTAB, %o3
-#if 0
- PTE_OF_ADDR(%o3, %o1, %o2, badstack)
- INSERT_PTE(%o3, %o1)
-#endif
-
- ld [%o3], %o3 ! pmap->pm_psegtab
- lda [%g0] ASI_PDBR, %o4 ! get old psegtab
- ldd [%g5 + PCB_SP], %o6 ! <sp,pc> = newpcb->pcb_<sp,pc>
-
- /* skip flushes if no PDBR change */
- cmp %o3, %o4
- be 9f
- clr %o0
-
- /* flush cache */
- lda [%g0] ASI_MMCR, %o2
- andn %o2, MMCR_DSET0 | MMCR_DSET1, %o2
-
- or %o2, MMCR_DSET0, %o1 ! flush DSET 0
- sta %o1, [%g0] ASI_MMCR
- mov DCACHE_LINE(DCACHE_LINES - 1), %o1
-1: lda [%o0] ASI_DCACHE_FLUSH, %g0
- cmp %o0, %o1
- bl 1b
- add %o0, DCACHE_INCR, %o0
-
- or %o2, MMCR_DSET1, %o2 ! flush DSET 1
- clr %o0
- sta %o2, [%g0] ASI_MMCR
-1: lda [%o0] ASI_DCACHE_FLUSH, %g0
- cmp %o0, %o1
- bl 1b
- add %o0, DCACHE_INCR, %o0
-
- /* invalidate caches */
- sta %g0, [%g0] ASI_DCACHE_INVAL
- sta %g0, [%g0] ASI_ICACHE_INVAL
-
- /* invalidate TLBs */
- sta %g0, [%g0] ASI_PID
- sta %g0, [%g0] ASI_PIID
- sta %g0, [%g0] ASI_GTLB_INVAL_PID
- nop; nop; nop
-
- /* set up new page tables */
- sta %o3, [%g0] ASI_PDBR
- nop; nop; nop
-
- sta %g0, [%g0] ASI_GTLB_INVALIDATE
- nop
-
- /*
- * Before we restore the window from the stack, we have to make
- * sure it is in the TLB...
- */
- mov %o6, %o3
- PTE_OF_ADDR(%o3, %o1, %o2, badstack)
- INSERT_PTE(%o3, %o1)
-
- SLT_IF_1PAGE_RW(%o3, %o1, %o2)
- bl 9f
- add %o3, 7 * 8, %o3
- PTE_OF_ADDR(%o3, %o1, %o2, badstack)
- INSERT_PTE(%o3, %o1)
- /* b 9f; nop */
-
-badstack:
- /*
- * If control goes there, the stack we are restoring does not have
- * a valid mapping. We can't recover and will double fault very quickly.
- */
-
-9:
- /* load window */
- ldd [%sp + (0*8)], %l0
- ldd [%sp + (1*8)], %l2
- ldd [%sp + (2*8)], %l4
- ldd [%sp + (3*8)], %l6
- ldd [%sp + (4*8)], %i0
- ldd [%sp + (5*8)], %i2
- ldd [%sp + (6*8)], %i4
- ldd [%sp + (7*8)], %i6
-#ifdef DEBUG
- mov %g5, %o0
- SET_SP_REDZONE(%o0, %o1)
- CHECK_SP_REDZONE(%o0, %o1)
-#endif
- /* finally, enable traps */
- wr %g2, 0, %psr ! psr = newpsr;
-
- /*
- * Now running p. Make sure it has a context so that it
- * can talk about user space stuff. (Its pcb_uw is currently
- * zero so it is safe to have interrupts going here.)
- */
-
- retl
- nop
-
-ENTRY(cpu_idle_enter)
- retl
- nop
-
-ENTRY(cpu_idle_cycle)
- retl
- nop
-
-ENTRY(cpu_idle_leave)
- retl
- nop
-
-
-/*
- * Snapshot the current process so that stack frames are up to date.
- * Only used just before a crash dump.
- */
-ENTRY(snapshot)
- std %o6, [%o0 + PCB_SP] ! save sp
- rd %psr, %o1 ! save psr
- st %o1, [%o0 + PCB_PSR]
-
- /*
- * Just like switch(); same XXX comments apply.
- * 7 of each. Minor tweak: the 7th restore is
- * done after a ret.
- */
- SAVE; SAVE; SAVE; SAVE; SAVE; SAVE; SAVE
- restore; restore; restore; restore; restore; restore; ret; restore
-
-
-/*
- * cpu_set_kpc() and cpu_fork() arrange for proc_trampoline() to run
- * after after a process gets chosen in switch(). The stack frame will
- * contain a function pointer in %l0, and an argument to pass to it in %l2.
- *
- * If the function *(%l0) returns, we arrange for an immediate return
- * to user mode. This happens in two known cases: after execve(2) of init,
- * and when returning a child to user mode after a fork(2).
- */
-ENTRY(proc_trampoline)
- /* Reset interrupt level */
- rd %psr, %o0
- andn %o0, PSR_PIL, %o0 ! psr &= ~PSR_PIL;
- wr %o0, 0, %psr ! (void) spl0();
- nop ! psr delay; the next 2 instructions
- ! can safely be made part of the
- ! required 3 instructions psr delay
- call %l0 ! re-use current frame
- mov %l1, %o0
-
- /*
- * Here we finish up as in syscall, but simplified. We need to
- * fiddle pc and npc a bit, as execve() / setregs() /cpu_set_kpc()
- * have only set npc, in anticipation that trap.c will advance past
- * the trap instruction; but we bypass that, so we must do it manually.
- */
- mov PSR_S, %l0 ! user psr (no need to load it)
- !?wr %g0, 2, %wim ! %wim = 2
- ld [%sp + CCFSZ + 4], %l1 ! pc
- b return_from_syscall
- ld [%sp + CCFSZ + 8], %l2 ! npc
-
-/* probeget is meant to be used during autoconfiguration */
-
-/*
- * probeget(addr, size) caddr_t addr; int size;
- *
- * Read a (byte,short,int) from the given address.
- * Like copyin but our caller is supposed to know what he is doing...
- * the address can be anywhere.
- *
- * We optimize for space, rather than time, here.
- */
-ENTRY(probeget)
- ! %o0 = addr, %o1 = (1,2,4)
- sethi %hi(_C_LABEL(cpcb)), %o2
- ld [%o2 + %lo(_C_LABEL(cpcb))], %o2 ! cpcb->pcb_onfault = Lfserr;
- set Lfserr, %o5
- st %o5, [%o2 + PCB_ONFAULT]
- btst 1, %o1
- bnz,a 0f ! if (len & 1)
- ldub [%o0], %o0 ! value = *(char *)addr;
-0: btst 2, %o1
- bnz,a 0f ! if (len & 2)
- lduh [%o0], %o0 ! value = *(short *)addr;
-0: btst 4, %o1
- bnz,a 0f ! if (len & 4)
- ld [%o0], %o0 ! value = *(int *)addr;
-0: retl ! made it, clear onfault and return
- st %g0, [%o2 + PCB_ONFAULT]
-
-Lfserr:
- st %g0, [%o2 + PCB_ONFAULT]! error in r/w, clear pcb_onfault
- retl ! and return error indicator
- mov -1, %o0
-
-/*
- * copywords(src, dst, nbytes)
- *
- * Copy `nbytes' bytes from src to dst, both of which are word-aligned;
- * nbytes is a multiple of four. It may, however, be zero, in which case
- * nothing is to be copied.
- */
-ENTRY(copywords)
- ! %o0 = src, %o1 = dst, %o2 = nbytes
- b 1f
- deccc 4, %o2
-0:
- st %o3, [%o1 + %o2]
- deccc 4, %o2 ! while ((n -= 4) >= 0)
-1:
- bge,a 0b ! *(int *)(dst+n) = *(int *)(src+n);
- ld [%o0 + %o2], %o3
- retl
- nop
-
-/*
- * qcopy(src, dst, nbytes)
- *
- * (q for `quad' or `quick', as opposed to b for byte/block copy)
- *
- * Just like copywords, but everything is multiples of 8.
- */
-ENTRY(qcopy)
- b 1f
- deccc 8, %o2
-0:
- std %o4, [%o1 + %o2]
- deccc 8, %o2
-1:
- bge,a 0b
- ldd [%o0 + %o2], %o4
- retl
- nop
-
-/*
- * qzero(addr, nbytes)
- *
- * Zeroes `nbytes' bytes of a quad-aligned virtual address,
- * where nbytes is itself a multiple of 8.
- */
-ENTRY(qzero)
- ! %o0 = addr, %o1 = len (in bytes)
- clr %g1
-0:
- deccc 8, %o1 ! while ((n =- 8) >= 0)
- bge,a 0b
- std %g0, [%o0 + %o1] ! *(quad *)(addr + n) = 0;
- retl
- nop
-
-/*
- * kernel bcopy/memcpy
- * Assumes regions do not overlap; has no useful return value.
- *
- * Must not use %g7 (see copyin/copyout above).
- */
-
-#define BCOPY_SMALL 32 /* if < 32, copy by bytes */
-
-ENTRY(memcpy)
- /*
- * Swap args for bcopy. Gcc generates calls to memcpy for
- * structure assignments.
- */
- mov %o0, %o3
- mov %o1, %o0
- mov %o3, %o1
-Lbcopy_old:
- cmp %o2, BCOPY_SMALL
-Lbcopy_start:
- bge,a Lbcopy_fancy ! if >= this many, go be fancy.
- btst 7, %o0 ! (part of being fancy)
-
- /*
- * Not much to copy, just do it a byte at a time.
- */
- deccc %o2 ! while (--len >= 0)
- bl 1f
- EMPTY
-0:
- inc %o0
- ldsb [%o0 - 1], %o4 ! (++dst)[-1] = *src++;
- stb %o4, [%o1]
- deccc %o2
- bge 0b
- inc %o1
-1:
- retl
- nop
- /* NOTREACHED */
-
- /*
- * Plenty of data to copy, so try to do it optimally.
- */
-Lbcopy_fancy:
- ! check for common case first: everything lines up.
-! btst 7, %o0 ! done already
- bne 1f
- EMPTY
- btst 7, %o1
- be,a Lbcopy_doubles
- dec 8, %o2 ! if all lined up, len -= 8, goto bcopy_doubes
-
- ! If the low bits match, we can make these line up.
-1:
- xor %o0, %o1, %o3 ! t = src ^ dst;
- btst 1, %o3 ! if (t & 1) {
- be,a 1f
- btst 1, %o0 ! [delay slot: if (src & 1)]
-
- ! low bits do not match, must copy by bytes.
-0:
- ldsb [%o0], %o4 ! do {
- inc %o0 ! (++dst)[-1] = *src++;
- inc %o1
- deccc %o2
- bnz 0b ! } while (--len != 0);
- stb %o4, [%o1 - 1]
- retl
- nop
- /* NOTREACHED */
-
- ! lowest bit matches, so we can copy by words, if nothing else
-1:
- be,a 1f ! if (src & 1) {
- btst 2, %o3 ! [delay slot: if (t & 2)]
-
- ! although low bits match, both are 1: must copy 1 byte to align
- ldsb [%o0], %o4 ! *dst++ = *src++;
- stb %o4, [%o1]
- inc %o0
- inc %o1
- dec %o2 ! len--;
- btst 2, %o3 ! } [if (t & 2)]
-1:
- be,a 1f ! if (t & 2) {
- btst 2, %o0 ! [delay slot: if (src & 2)]
- dec 2, %o2 ! len -= 2;
-0:
- ldsh [%o0], %o4 ! do {
- sth %o4, [%o1] ! *(short *)dst = *(short *)src;
- inc 2, %o0 ! dst += 2, src += 2;
- deccc 2, %o2 ! } while ((len -= 2) >= 0);
- bge 0b
- inc 2, %o1
- b Lbcopy_mopb ! goto mop_up_byte;
- btst 1, %o2 ! } [delay slot: if (len & 1)]
- /* NOTREACHED */
-
- ! low two bits match, so we can copy by longwords
-1:
- be,a 1f ! if (src & 2) {
- btst 4, %o3 ! [delay slot: if (t & 4)]
-
- ! although low 2 bits match, they are 10: must copy one short to align
- ldsh [%o0], %o4 ! (*short *)dst = *(short *)src;
- sth %o4, [%o1]
- inc 2, %o0 ! dst += 2;
- inc 2, %o1 ! src += 2;
- dec 2, %o2 ! len -= 2;
- btst 4, %o3 ! } [if (t & 4)]
-1:
- be,a 1f ! if (t & 4) {
- btst 4, %o0 ! [delay slot: if (src & 4)]
- dec 4, %o2 ! len -= 4;
-0:
- ld [%o0], %o4 ! do {
- st %o4, [%o1] ! *(int *)dst = *(int *)src;
- inc 4, %o0 ! dst += 4, src += 4;
- deccc 4, %o2 ! } while ((len -= 4) >= 0);
- bge 0b
- inc 4, %o1
- b Lbcopy_mopw ! goto mop_up_word_and_byte;
- btst 2, %o2 ! } [delay slot: if (len & 2)]
- /* NOTREACHED */
-
- ! low three bits match, so we can copy by doublewords
-1:
- be 1f ! if (src & 4) {
- dec 8, %o2 ! [delay slot: len -= 8]
- ld [%o0], %o4 ! *(int *)dst = *(int *)src;
- st %o4, [%o1]
- inc 4, %o0 ! dst += 4, src += 4, len -= 4;
- inc 4, %o1
- dec 4, %o2 ! }
-1:
-Lbcopy_doubles:
- ldd [%o0], %o4 ! do {
- std %o4, [%o1] ! *(double *)dst = *(double *)src;
- inc 8, %o0 ! dst += 8, src += 8;
- deccc 8, %o2 ! } while ((len -= 8) >= 0);
- bge Lbcopy_doubles
- inc 8, %o1
-
- ! check for a usual case again (save work)
- btst 7, %o2 ! if ((len & 7) == 0)
- be Lbcopy_done ! goto bcopy_done;
-
- btst 4, %o2 ! if ((len & 4) == 0)
- be,a Lbcopy_mopw ! goto mop_up_word_and_byte;
- btst 2, %o2 ! [delay slot: if (len & 2)]
- ld [%o0], %o4 ! *(int *)dst = *(int *)src;
- st %o4, [%o1]
- inc 4, %o0 ! dst += 4;
- inc 4, %o1 ! src += 4;
- btst 2, %o2 ! } [if (len & 2)]
-
-1:
- ! mop up trailing word (if present) and byte (if present).
-Lbcopy_mopw:
- be Lbcopy_mopb ! no word, go mop up byte
- btst 1, %o2 ! [delay slot: if (len & 1)]
- ldsh [%o0], %o4 ! *(short *)dst = *(short *)src;
- be Lbcopy_done ! if ((len & 1) == 0) goto done;
- sth %o4, [%o1]
- ldsb [%o0 + 2], %o4 ! dst[2] = src[2];
- retl
- stb %o4, [%o1 + 2]
- /* NOTREACHED */
-
- ! mop up trailing byte (if present).
-Lbcopy_mopb:
- bne,a 1f
- ldsb [%o0], %o4
-
-Lbcopy_done:
- retl
- nop
-
-1:
- retl
- stb %o4,[%o1]
-/*
- * bcopy(src, dst, len): regions may overlap.
- */
-ENTRY(bcopy)
- cmp %o0, %o1 ! src < dst?
- bgeu Lbcopy_start ! no, go copy forwards as via bcopy
- cmp %o2, BCOPY_SMALL! (check length for doublecopy first)
-
- /*
- * Since src comes before dst, and the regions might overlap,
- * we have to do the copy starting at the end and working backwards.
- */
- add %o2, %o0, %o0 ! src += len
- add %o2, %o1, %o1 ! dst += len
- bge,a Lback_fancy ! if len >= BCOPY_SMALL, go be fancy
- btst 3, %o0
-
- /*
- * Not much to copy, just do it a byte at a time.
- */
- deccc %o2 ! while (--len >= 0)
- bl 1f
- EMPTY
-0:
- dec %o0 ! *--dst = *--src;
- ldsb [%o0], %o4
- dec %o1
- deccc %o2
- bge 0b
- stb %o4, [%o1]
-1:
- retl
- nop
-
- /*
- * Plenty to copy, try to be optimal.
- * We only bother with word/halfword/byte copies here.
- */
-Lback_fancy:
-! btst 3, %o0 ! done already
- bnz 1f ! if ((src & 3) == 0 &&
- btst 3, %o1 ! (dst & 3) == 0)
- bz,a Lback_words ! goto words;
- dec 4, %o2 ! (done early for word copy)
-
-1:
- /*
- * See if the low bits match.
- */
- xor %o0, %o1, %o3 ! t = src ^ dst;
- btst 1, %o3
- bz,a 3f ! if (t & 1) == 0, can do better
- btst 1, %o0
-
- /*
- * Nope; gotta do byte copy.
- */
-2:
- dec %o0 ! do {
- ldsb [%o0], %o4 ! *--dst = *--src;
- dec %o1
- deccc %o2 ! } while (--len != 0);
- bnz 2b
- stb %o4, [%o1]
- retl
- nop
-
-3:
- /*
- * Can do halfword or word copy, but might have to copy 1 byte first.
- */
-! btst 1, %o0 ! done earlier
- bz,a 4f ! if (src & 1) { /* copy 1 byte */
- btst 2, %o3 ! (done early)
- dec %o0 ! *--dst = *--src;
- ldsb [%o0], %o4
- dec %o1
- stb %o4, [%o1]
- dec %o2 ! len--;
- btst 2, %o3 ! }
-
-4:
- /*
- * See if we can do a word copy ((t&2) == 0).
- */
-! btst 2, %o3 ! done earlier
- bz,a 6f ! if (t & 2) == 0, can do word copy
- btst 2, %o0 ! (src&2, done early)
-
- /*
- * Gotta do halfword copy.
- */
- dec 2, %o2 ! len -= 2;
-5:
- dec 2, %o0 ! do {
- ldsh [%o0], %o4 ! src -= 2;
- dec 2, %o1 ! dst -= 2;
- deccc 2, %o2 ! *(short *)dst = *(short *)src;
- bge 5b ! } while ((len -= 2) >= 0);
- sth %o4, [%o1]
- b Lback_mopb ! goto mop_up_byte;
- btst 1, %o2 ! (len&1, done early)
-
-6:
- /*
- * We can do word copies, but we might have to copy
- * one halfword first.
- */
-! btst 2, %o0 ! done already
- bz 7f ! if (src & 2) {
- dec 4, %o2 ! (len -= 4, done early)
- dec 2, %o0 ! src -= 2, dst -= 2;
- ldsh [%o0], %o4 ! *(short *)dst = *(short *)src;
- dec 2, %o1
- sth %o4, [%o1]
- dec 2, %o2 ! len -= 2;
- ! }
-
-7:
-Lback_words:
- /*
- * Do word copies (backwards), then mop up trailing halfword
- * and byte if any.
- */
-! dec 4, %o2 ! len -= 4, done already
-0: ! do {
- dec 4, %o0 ! src -= 4;
- dec 4, %o1 ! src -= 4;
- ld [%o0], %o4 ! *(int *)dst = *(int *)src;
- deccc 4, %o2 ! } while ((len -= 4) >= 0);
- bge 0b
- st %o4, [%o1]
-
- /*
- * Check for trailing shortword.
- */
- btst 2, %o2 ! if (len & 2) {
- bz,a 1f
- btst 1, %o2 ! (len&1, done early)
- dec 2, %o0 ! src -= 2, dst -= 2;
- ldsh [%o0], %o4 ! *(short *)dst = *(short *)src;
- dec 2, %o1
- sth %o4, [%o1] ! }
- btst 1, %o2
-
- /*
- * Check for trailing byte.
- */
-1:
-Lback_mopb:
-! btst 1, %o2 ! (done already)
- bnz,a 1f ! if (len & 1) {
- ldsb [%o0 - 1], %o4 ! b = src[-1];
- retl
- nop
-1:
- retl ! dst[-1] = b;
- stb %o4, [%o1 - 1] ! }
-
-/*
- * kcopy() is exactly like old bcopy except that it set pcb_onfault such that
- * when a fault occurs, it is able to return EFAULT to indicate this to the
- * caller.
- */
-ENTRY(kcopy)
- sethi %hi(_C_LABEL(cpcb)), %o5 ! cpcb->pcb_onfault = Lkcerr;
- ld [%o5 + %lo(_C_LABEL(cpcb))], %o5
- set Lkcerr, %o3
- ld [%o5 + PCB_ONFAULT], %g1! save current onfault handler
- st %o3, [%o5 + PCB_ONFAULT]
-
- cmp %o2, BCOPY_SMALL
-Lkcopy_start:
- bge,a Lkcopy_fancy ! if >= this many, go be fancy.
- btst 7, %o0 ! (part of being fancy)
-
- /*
- * Not much to copy, just do it a byte at a time.
- */
- deccc %o2 ! while (--len >= 0)
- bl 1f
- EMPTY
-0:
- ldsb [%o0], %o4 ! *dst++ = *src++;
- inc %o0
- stb %o4, [%o1]
- deccc %o2
- bge 0b
- inc %o1
-1:
- st %g1, [%o5 + PCB_ONFAULT] ! restore onfault
- retl
- mov 0, %o0 ! delay slot: return success
- /* NOTREACHED */
-
- /*
- * Plenty of data to copy, so try to do it optimally.
- */
-Lkcopy_fancy:
- ! check for common case first: everything lines up.
-! btst 7, %o0 ! done already
- bne 1f
- EMPTY
- btst 7, %o1
- be,a Lkcopy_doubles
- dec 8, %o2 ! if all lined up, len -= 8, goto bcopy_doubes
-
- ! If the low bits match, we can make these line up.
-1:
- xor %o0, %o1, %o3 ! t = src ^ dst;
- btst 1, %o3 ! if (t & 1) {
- be,a 1f
- btst 1, %o0 ! [delay slot: if (src & 1)]
-
- ! low bits do not match, must copy by bytes.
-0:
- ldsb [%o0], %o4 ! do {
- inc %o0 ! *dst++ = *src++;
- stb %o4, [%o1]
- deccc %o2
- bnz 0b ! } while (--len != 0);
- inc %o1
- st %g1, [%o5 + PCB_ONFAULT] ! restore onfault
- retl
- mov 0, %o0 ! delay slot: return success
- /* NOTREACHED */
-
- ! lowest bit matches, so we can copy by words, if nothing else
-1:
- be,a 1f ! if (src & 1) {
- btst 2, %o3 ! [delay slot: if (t & 2)]
-
- ! although low bits match, both are 1: must copy 1 byte to align
- ldsb [%o0], %o4 ! *dst++ = *src++;
- inc %o0
- stb %o4, [%o1]
- dec %o2 ! len--;
- inc %o1
- btst 2, %o3 ! } [if (t & 2)]
-1:
- be,a 1f ! if (t & 2) {
- btst 2, %o0 ! [delay slot: if (src & 2)]
- dec 2, %o2 ! len -= 2;
-0:
- ldsh [%o0], %o4 ! do {
- inc 2, %o0 ! dst += 2, src += 2;
- sth %o4, [%o1] ! *(short *)dst = *(short *)src;
- deccc 2, %o2 ! } while ((len -= 2) >= 0);
- bge 0b
- inc 2, %o1
- b Lkcopy_mopb ! goto mop_up_byte;
- btst 1, %o2 ! } [delay slot: if (len & 1)]
- /* NOTREACHED */
-
- ! low two bits match, so we can copy by longwords
-1:
- be,a 1f ! if (src & 2) {
- btst 4, %o3 ! [delay slot: if (t & 4)]
-
- ! although low 2 bits match, they are 10: must copy one short to align
- ldsh [%o0], %o4 ! (*short *)dst = *(short *)src;
- inc 2, %o0 ! dst += 2;
- sth %o4, [%o1]
- dec 2, %o2 ! len -= 2;
- inc 2, %o1 ! src += 2;
- btst 4, %o3 ! } [if (t & 4)]
-1:
- be,a 1f ! if (t & 4) {
- btst 4, %o0 ! [delay slot: if (src & 4)]
- dec 4, %o2 ! len -= 4;
-0:
- ld [%o0], %o4 ! do {
- inc 4, %o0 ! dst += 4, src += 4;
- st %o4, [%o1] ! *(int *)dst = *(int *)src;
- deccc 4, %o2 ! } while ((len -= 4) >= 0);
- bge 0b
- inc 4, %o1
- b Lkcopy_mopw ! goto mop_up_word_and_byte;
- btst 2, %o2 ! } [delay slot: if (len & 2)]
- /* NOTREACHED */
-
- ! low three bits match, so we can copy by doublewords
-1:
- be 1f ! if (src & 4) {
- dec 8, %o2 ! [delay slot: len -= 8]
- ld [%o0], %o4 ! *(int *)dst = *(int *)src;
- inc 4, %o0 ! dst += 4, src += 4, len -= 4;
- st %o4, [%o1]
- dec 4, %o2 ! }
- inc 4, %o1
-1:
-Lkcopy_doubles:
- ! swap %o4 with %o2 during doubles copy, since %o5 is verboten
- mov %o2, %o4
-Lkcopy_doubles2:
- ldd [%o0], %o2 ! do {
- inc 8, %o0 ! dst += 8, src += 8;
- std %o2, [%o1] ! *(double *)dst = *(double *)src;
- deccc 8, %o4 ! } while ((len -= 8) >= 0);
- bge Lkcopy_doubles2
- inc 8, %o1
- mov %o4, %o2 ! restore len
-
- ! check for a usual case again (save work)
- btst 7, %o2 ! if ((len & 7) == 0)
- be Lkcopy_done ! goto bcopy_done;
-
- btst 4, %o2 ! if ((len & 4) == 0)
- be,a Lkcopy_mopw ! goto mop_up_word_and_byte;
- btst 2, %o2 ! [delay slot: if (len & 2)]
- ld [%o0], %o4 ! *(int *)dst = *(int *)src;
- inc 4, %o0 ! dst += 4;
- st %o4, [%o1]
- inc 4, %o1 ! src += 4;
- btst 2, %o2 ! } [if (len & 2)]
-
-1:
- ! mop up trailing word (if present) and byte (if present).
-Lkcopy_mopw:
- be Lkcopy_mopb ! no word, go mop up byte
- btst 1, %o2 ! [delay slot: if (len & 1)]
- ldsh [%o0], %o4 ! *(short *)dst = *(short *)src;
- be Lkcopy_done ! if ((len & 1) == 0) goto done;
- sth %o4, [%o1]
- ldsb [%o0 + 2], %o4 ! dst[2] = src[2];
- stb %o4, [%o1 + 2]
- st %g1, [%o5 + PCB_ONFAULT]! restore onfault
- retl
- mov 0, %o0 ! delay slot: return success
- /* NOTREACHED */
-
- ! mop up trailing byte (if present).
-Lkcopy_mopb:
- bne,a 1f
- ldsb [%o0], %o4
-
-Lkcopy_done:
- st %g1, [%o5 + PCB_ONFAULT] ! restore onfault
- retl
- mov 0, %o0 ! delay slot: return success
- /* NOTREACHED */
-
-1:
- stb %o4, [%o1]
- st %g1, [%o5 + PCB_ONFAULT] ! restore onfault
- retl
- mov 0, %o0 ! delay slot: return success
- /* NOTREACHED */
-
-Lkcerr:
- st %g1, [%o5 + PCB_ONFAULT] ! restore onfault
- retl
- mov EFAULT, %o0 ! delay slot: return error indicator
- /* NOTREACHED */
-
-/*
- * savefpstate(f) struct fpstate *f;
- *
- * Store the current FPU state. The first `st %fsr' may cause a trap;
- * our trap handler knows how to recover (by `returning' to savefpcont).
- */
-ENTRY(savefpstate)
- rd %psr, %o1 ! enable FP before we begin
- set PSR_EF, %o2
- or %o1, %o2, %o1
- wr %o1, 0, %psr
- /* do some setup work while we wait for PSR_EF to turn on */
- set FSR_QNE, %o5 ! QNE = 0x2000, too big for immediate
- clr %o3 ! qsize = 0;
- nop ! (still waiting for PSR_EF)
-special_fp_store:
- st %fsr, [%o0 + FS_FSR] ! f->fs_fsr = getfsr();
- /*
- * Even if the preceding instruction did not trap, the queue
- * is not necessarily empty: this state save might be happening
- * because user code tried to store %fsr and took the FPU
- * from `exception pending' mode to `exception' mode.
- * So we still have to check the blasted QNE bit.
- * With any luck it will usually not be set.
- */
- ld [%o0 + FS_FSR], %o4 ! if (f->fs_fsr & QNE)
- btst %o5, %o4
- bnz Lfp_storeq ! goto storeq;
- std %f0, [%o0 + FS_REGS + (4*0)] ! f->fs_f0 = etc;
-Lfp_finish:
- st %o3, [%o0 + FS_QSIZE] ! f->fs_qsize = qsize;
- std %f2, [%o0 + FS_REGS + (4*2)]
- std %f4, [%o0 + FS_REGS + (4*4)]
- std %f6, [%o0 + FS_REGS + (4*6)]
- std %f8, [%o0 + FS_REGS + (4*8)]
- std %f10, [%o0 + FS_REGS + (4*10)]
- std %f12, [%o0 + FS_REGS + (4*12)]
- std %f14, [%o0 + FS_REGS + (4*14)]
- std %f16, [%o0 + FS_REGS + (4*16)]
- std %f18, [%o0 + FS_REGS + (4*18)]
- std %f20, [%o0 + FS_REGS + (4*20)]
- std %f22, [%o0 + FS_REGS + (4*22)]
- std %f24, [%o0 + FS_REGS + (4*24)]
- std %f26, [%o0 + FS_REGS + (4*26)]
- std %f28, [%o0 + FS_REGS + (4*28)]
- retl
- std %f30, [%o0 + FS_REGS + (4*30)]
-
-/*
- * Store the (now known nonempty) FP queue.
- * We have to reread the fsr each time in order to get the new QNE bit.
- */
-Lfp_storeq:
- add %o0, FS_QUEUE, %o1 ! q = &f->fs_queue[0];
-1:
- std %fq, [%o1 + %o3] ! q[qsize++] = fsr_qfront();
- st %fsr, [%o0 + FS_FSR] ! reread fsr
- ld [%o0 + FS_FSR], %o4 ! if fsr & QNE, loop
- btst %o5, %o4
- bnz 1b
- inc 8, %o3
- b Lfp_finish ! set qsize and finish storing fregs
- srl %o3, 3, %o3 ! (but first fix qsize)
-
-/*
- * The fsr store trapped. Do it again; this time it will not trap.
- * We could just have the trap handler return to the `st %fsr', but
- * if for some reason it *does* trap, that would lock us into a tight
- * loop. This way we panic instead. Whoopee.
- */
-savefpcont:
- b special_fp_store + 4 ! continue
- st %fsr, [%o0 + FS_FSR] ! but first finish the %fsr store
-
-/*
- * Load FPU state.
- */
-ENTRY(loadfpstate)
- rd %psr, %o1 ! enable FP before we begin
- set PSR_EF, %o2
- or %o1, %o2, %o1
- wr %o1, 0, %psr
- nop; nop; nop ! paranoia
- ldd [%o0 + FS_REGS + (4*0)], %f0
- ldd [%o0 + FS_REGS + (4*2)], %f2
- ldd [%o0 + FS_REGS + (4*4)], %f4
- ldd [%o0 + FS_REGS + (4*6)], %f6
- ldd [%o0 + FS_REGS + (4*8)], %f8
- ldd [%o0 + FS_REGS + (4*10)], %f10
- ldd [%o0 + FS_REGS + (4*12)], %f12
- ldd [%o0 + FS_REGS + (4*14)], %f14
- ldd [%o0 + FS_REGS + (4*16)], %f16
- ldd [%o0 + FS_REGS + (4*18)], %f18
- ldd [%o0 + FS_REGS + (4*20)], %f20
- ldd [%o0 + FS_REGS + (4*22)], %f22
- ldd [%o0 + FS_REGS + (4*24)], %f24
- ldd [%o0 + FS_REGS + (4*26)], %f26
- ldd [%o0 + FS_REGS + (4*28)], %f28
- ldd [%o0 + FS_REGS + (4*30)], %f30
- retl
- ld [%o0 + FS_FSR], %fsr ! setfsr(f->fs_fsr);
-
-/*
- * ffs(), using table lookup.
- * The process switch code shares the table, so we just put the
- * whole thing here.
- */
-ffstab:
- .byte -24,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 00-0f */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-1f */
- .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 20-2f */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 30-3f */
- .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 40-4f */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 50-5f */
- .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 60-6f */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 70-7f */
- .byte 8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 80-8f */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* 10-9f */
- .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* a0-af */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* b0-bf */
- .byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* c0-cf */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* d0-df */
- .byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* e0-ef */
- .byte 5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 /* f0-ff */
-
-/*
- * We use a table lookup on each byte.
- *
- * In each section below, %o1 is the current byte (0, 1, 2, or 3).
- * The last byte is handled specially: for the first three,
- * if that byte is nonzero, we return the table value
- * (plus 0, 8, or 16 for the byte number), but for the last
- * one, we just return the table value plus 24. This means
- * that ffstab[0] must be -24 so that ffs(0) will return 0.
- */
-ENTRY(ffs)
- set ffstab, %o2
- andcc %o0, 0xff, %o1 ! get low byte
- bz,a 1f ! try again if 0
- srl %o0, 8, %o0 ! delay slot, get ready for next byte
-
- retl ! return ffstab[%o1]
- ldsb [%o2 + %o1], %o0
-
-1:
- andcc %o0, 0xff, %o1 ! byte 1 like byte 0...
- bz,a 2f
- srl %o0, 8, %o0 ! (use delay to prepare for byte 2)
-
- ldsb [%o2 + %o1], %o0
- retl ! return ffstab[%o1] + 8
- add %o0, 8, %o0
-
-2:
- andcc %o0, 0xff, %o1
- bz,a 3f
- srl %o0, 8, %o0 ! (prepare for byte 3)
-
- ldsb [%o2 + %o1], %o0
- retl ! return ffstab[%o1] + 16
- add %o0, 16, %o0
-
-3: ! just return ffstab[%o0] + 24
- ldsb [%o2 + %o0], %o0
- retl
- add %o0, 24, %o0
-
-/*
- * V8 sparc .{,u}{mul,div,rem} replacements.
- * We try to mimic them 100%. Full 64 bit sources or outputs, and
- * these routines are required to update the condition codes.
- */
-.globl _C_LABEL(_mulreplace), _C_LABEL(_mulreplace_end)
-_C_LABEL(_mulreplace):
- smulcc %o0, %o1, %o0
- retl
- rd %y, %o1
-_C_LABEL(_mulreplace_end):
-
-.globl _C_LABEL(_umulreplace), _C_LABEL(_umulreplace_end)
-_C_LABEL(_umulreplace):
- umulcc %o0, %o1, %o0
- retl
- rd %y, %o1
-_C_LABEL(_umulreplace_end):
-
-.globl _C_LABEL(_divreplace), _C_LABEL(_divreplace_end)
-_C_LABEL(_divreplace):
- sra %o0, 31, %g1
- wr %g1, 0, %y
- nop
- nop
- nop
- retl
- sdivcc %o0, %o1, %o0
-_C_LABEL(_divreplace_end):
-
-.globl _C_LABEL(_udivreplace), _C_LABEL(_udivreplace_end)
-_C_LABEL(_udivreplace):
- wr %g0, 0, %y
- nop
- nop
- nop
- retl
- udivcc %o0, %o1, %o0
-_C_LABEL(_udivreplace_end):
-
-.globl _C_LABEL(_remreplace), _C_LABEL(_remreplace_end)
-_C_LABEL(_remreplace):
- sra %o0, 31, %g1
- wr %g1, 0, %y
- nop
- nop
- nop
- sdiv %o0, %o1, %o2
- smul %o1, %o2, %o2
- retl
- subcc %o0, %o2, %o0
-_C_LABEL(_remreplace_end):
-
-.globl _C_LABEL(_uremreplace), _C_LABEL(_uremreplace_end)
-_C_LABEL(_uremreplace):
- wr %g0, 0, %y
- nop
- nop
- nop
- udiv %o0, %o1, %o2
- umul %o1, %o2, %o2
- retl
- subcc %o0, %o2, %o0
-_C_LABEL(_uremreplace_end):
-
-/*
- * Signed multiply, from Appendix E of the Sparc Version 8
- * Architecture Manual.
- *
- * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of
- * the 64-bit product).
- *
- * This code optimizes short (less than 13-bit) multiplies.
- */
-.globl .mul, _C_LABEL(_mul)
-.mul:
-_C_LABEL(_mul):
- mov %o0, %y ! multiplier -> Y
- andncc %o0, 0xfff, %g0 ! test bits 12..31
- be Lmul_shortway ! if zero, can do it the short way
- andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
-
- /*
- * Long multiply. 32 steps, followed by a final shift step.
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %o1, %o4 ! 13
- mulscc %o4, %o1, %o4 ! 14
- mulscc %o4, %o1, %o4 ! 15
- mulscc %o4, %o1, %o4 ! 16
- mulscc %o4, %o1, %o4 ! 17
- mulscc %o4, %o1, %o4 ! 18
- mulscc %o4, %o1, %o4 ! 19
- mulscc %o4, %o1, %o4 ! 20
- mulscc %o4, %o1, %o4 ! 21
- mulscc %o4, %o1, %o4 ! 22
- mulscc %o4, %o1, %o4 ! 23
- mulscc %o4, %o1, %o4 ! 24
- mulscc %o4, %o1, %o4 ! 25
- mulscc %o4, %o1, %o4 ! 26
- mulscc %o4, %o1, %o4 ! 27
- mulscc %o4, %o1, %o4 ! 28
- mulscc %o4, %o1, %o4 ! 29
- mulscc %o4, %o1, %o4 ! 30
- mulscc %o4, %o1, %o4 ! 31
- mulscc %o4, %o1, %o4 ! 32
- mulscc %o4, %g0, %o4 ! final shift
-
- ! If %o0 was negative, the result is
- ! (%o0 * %o1) + (%o1 << 32))
- ! We fix that here.
-
- tst %o0
- bge 1f
- rd %y, %o0
-
- ! %o0 was indeed negative; fix upper 32 bits of result by subtracting
- ! %o1 (i.e., return %o4 - %o1 in %o1).
- retl
- sub %o4, %o1, %o1
-
-1:
- retl
- mov %o4, %o1
-
-Lmul_shortway:
- /*
- * Short multiply. 12 steps, followed by a final shift step.
- * The resulting bits are off by 12 and (32-12) = 20 bit positions,
- * but there is no problem with %o0 being negative (unlike above).
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %g0, %o4 ! final shift
-
- /*
- * %o4 has 20 of the bits that should be in the low part of the
- * result; %y has the bottom 12 (as %y's top 12). That is:
- *
- * %o4 %y
- * +----------------+----------------+
- * | -12- | -20- | -12- | -20- |
- * +------(---------+------)---------+
- * --hi-- ----low-part----
- *
- * The upper 12 bits of %o4 should be sign-extended to form the
- * high part of the product (i.e., highpart = %o4 >> 20).
- */
-
- rd %y, %o5
- sll %o4, 12, %o0 ! shift middle bits left 12
- srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left
- or %o5, %o0, %o0 ! construct low part of result
- retl
- sra %o4, 20, %o1 ! ... and extract high part of result
-
-/*
- * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the
- * upper 32 bits of the 64-bit product).
- *
- * This code optimizes short (less than 13-bit) multiplies. Short
- * multiplies require 25 instruction cycles, and long ones require
- * 45 instruction cycles.
- *
- * On return, overflow has occurred (%o1 is not zero) if and only if
- * the Z condition code is clear, allowing, e.g., the following:
- *
- * call .umul
- * nop
- * bnz overflow (or tnz)
- */
-.globl .umul, _C_LABEL(_umul)
-.umul:
-_C_LABEL(_umul):
- or %o0, %o1, %o4
- mov %o0, %y ! multiplier -> Y
- andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
- be Lumul_shortway ! if zero, can do it the short way
- andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
-
- /*
- * Long multiply. 32 steps, followed by a final shift step.
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %o1, %o4 ! 13
- mulscc %o4, %o1, %o4 ! 14
- mulscc %o4, %o1, %o4 ! 15
- mulscc %o4, %o1, %o4 ! 16
- mulscc %o4, %o1, %o4 ! 17
- mulscc %o4, %o1, %o4 ! 18
- mulscc %o4, %o1, %o4 ! 19
- mulscc %o4, %o1, %o4 ! 20
- mulscc %o4, %o1, %o4 ! 21
- mulscc %o4, %o1, %o4 ! 22
- mulscc %o4, %o1, %o4 ! 23
- mulscc %o4, %o1, %o4 ! 24
- mulscc %o4, %o1, %o4 ! 25
- mulscc %o4, %o1, %o4 ! 26
- mulscc %o4, %o1, %o4 ! 27
- mulscc %o4, %o1, %o4 ! 28
- mulscc %o4, %o1, %o4 ! 29
- mulscc %o4, %o1, %o4 ! 30
- mulscc %o4, %o1, %o4 ! 31
- mulscc %o4, %o1, %o4 ! 32
- mulscc %o4, %g0, %o4 ! final shift
-
-
- /*
- * Normally, with the shift-and-add approach, if both numbers are
- * positive you get the correct result. WIth 32-bit two's-complement
- * numbers, -x is represented as
- *
- * x 32
- * ( 2 - ------ ) mod 2 * 2
- * 32
- * 2
- *
- * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s,
- * we can treat this as if the radix point were just to the left
- * of the sign bit (multiply by 2^32), and get
- *
- * -x = (2 - x) mod 2
- *
- * Then, ignoring the `mod 2's for convenience:
- *
- * x * y = xy
- * -x * y = 2y - xy
- * x * -y = 2x - xy
- * -x * -y = 4 - 2x - 2y + xy
- *
- * For signed multiplies, we subtract (x << 32) from the partial
- * product to fix this problem for negative multipliers (see mul.s).
- * Because of the way the shift into the partial product is calculated
- * (N xor V), this term is automatically removed for the multiplicand,
- * so we don't have to adjust.
- *
- * But for unsigned multiplies, the high order bit wasn't a sign bit,
- * and the correction is wrong. So for unsigned multiplies where the
- * high order bit is one, we end up with xy - (y << 32). To fix it
- * we add y << 32.
- */
- tst %o1
- bl,a 1f ! if %o1 < 0 (high order bit = 1),
- add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
-1: rd %y, %o0 ! get lower half of product
- retl
- addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
-
-Lumul_shortway:
- /*
- * Short multiply. 12 steps, followed by a final shift step.
- * The resulting bits are off by 12 and (32-12) = 20 bit positions,
- * but there is no problem with %o0 being negative (unlike above),
- * and overflow is impossible (the answer is at most 24 bits long).
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %g0, %o4 ! final shift
-
- /*
- * %o4 has 20 of the bits that should be in the result; %y has
- * the bottom 12 (as %y's top 12). That is:
- *
- * %o4 %y
- * +----------------+----------------+
- * | -12- | -20- | -12- | -20- |
- * +------(---------+------)---------+
- * -----result-----
- *
- * The 12 bits of %o4 left of the `result' area are all zero;
- * in fact, all top 20 bits of %o4 are zero.
- */
-
- rd %y, %o5
- sll %o4, 12, %o0 ! shift middle bits left 12
- srl %o5, 20, %o5 ! shift low bits right 20
- or %o5, %o0, %o0
- retl
- addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
-
-/*
- * delay function
- *
- * void delay(N) -- delay N microseconds
- *
- * Register usage: %o0 = "N" number of usecs to go (counts down to zero)
- * %o1 = "timerblurb" (stays constant)
- * %o2 = counter for 1 usec (counts down from %o1 to zero)
- *
- */
-
-ENTRY(delay) ! %o0 = n
- subcc %o0, %g0, %g0
- be 2f
-
- sethi %hi(_C_LABEL(timerblurb)), %o1
- ld [%o1 + %lo(_C_LABEL(timerblurb))], %o1 ! %o1 = timerblurb
-
- addcc %o1, %g0, %o2 ! %o2 = cntr (start @ %o1), clear CCs
- ! first time through only
-
- ! delay 1 usec
-1: bne 1b ! come back here if not done
- subcc %o2, 1, %o2 ! %o2 = %o2 - 1 [delay slot]
-
- subcc %o0, 1, %o0 ! %o0 = %o0 - 1
- bne 1b ! done yet?
- addcc %o1, %g0, %o2 ! reinit %o2 and CCs [delay slot]
- ! harmless if not branching
-2:
- retl ! return
- nop ! [delay slot]
-
-#if defined(KGDB) || defined(DDB) || defined(DIAGNOSTIC)
-/*
- * Write all windows (user or otherwise), except the current one.
- *
- * THIS COULD BE DONE IN USER CODE
- */
-ENTRY(write_all_windows)
- /*
- * g2 = g1 = nwindows - 1;
- * while (--g1 > 0) save();
- * while (--g2 > 0) restore();
- */
- sethi %hi(_C_LABEL(nwindows)), %g1
- ld [%g1 + %lo(_C_LABEL(nwindows))], %g1
- dec %g1
- mov %g1, %g2
-
-1: deccc %g1
- bg,a 1b
- save %sp, -64, %sp
-
-2: deccc %g2
- bg,a 2b
- restore
-
- retl
- nop
-#endif /* KGDB */
-
-ENTRY(setjmp)
- std %sp, [%o0+0] ! stack pointer & return pc
- st %fp, [%o0+8] ! frame pointer
- retl
- clr %o0
-
-Lpanic_ljmp:
- .asciz "longjmp botch"
- _ALIGN
-
-ENTRY(longjmp)
- mov 1, %g6
- mov %o0, %g1 ! save a in another global register
- ld [%g1+8], %g7 /* get caller's frame */
-1:
- cmp %fp, %g7 ! compare against desired frame
- bl,a 1b ! if below,
- restore ! pop frame and loop
- be,a 2f ! if there,
- ldd [%g1+0], %o2 ! fetch return %sp and pc, and get out
-
-Llongjmpbotch:
- ! otherwise, went too far; bomb out
- save %sp, -CCFSZ, %sp /* preserve current window */
- sethi %hi(Lpanic_ljmp), %o0
- call _C_LABEL(panic)
- or %o0, %lo(Lpanic_ljmp), %o0;
- unimp 0
-
-2:
- cmp %o2, %sp ! %sp must not decrease
- bge,a 3f
- mov %o2, %sp ! it is OK, put it in place
- b,a Llongjmpbotch
-3:
- jmp %o3 + 8 ! success, return %g6
- mov %g6, %o0
-
-/*
- * Early console code. Ugly, but works.
- */
-ENTRY(earlycnputc)
- save %sp, -64, %sp
- sethi %hi(ZS0_BASE), %l1
-1: ldub [%l1 + %lo(ZS0_BASE) + 0x10], %l2
- btst ZSRR0_TX_READY, %l2
- be 1b
- nop
- stb %i1, [%l1 + %lo(ZS0_BASE) + 0x18]
- set 0x2000, %l1
-1: cmp %l1, 0
- bne 1b
- dec %l1
- ret
- restore
-
-ENTRY(earlycngetc)
- save %sp, -64, %sp
- sethi %hi(ZS0_BASE), %l1
-1: ldub [%l1 + %lo(ZS0_BASE) + 0x10], %l2
- btst ZSRR0_RX_READY, %l2
- be 1b
- nop
- ldub [%l1 + %lo(ZS0_BASE) + 0x18], %i0
- set 0x2000, %l1
-1: cmp %l1, 0
- bne 1b
- dec %l1
- ret
- restore
-
- .data
-#if defined(DDB) || NKSYMS > 0
- .globl _C_LABEL(esym)
-_C_LABEL(esym):
- .word 0
-#endif
- .globl _C_LABEL(cold)
-_C_LABEL(cold):
- .word 1 ! cold start flag
-
- .globl _C_LABEL(proc0paddr)
-_C_LABEL(proc0paddr):
- .word _C_LABEL(u0) ! KVA of proc0 uarea
-
-! StackGhost: added 2 symbols to ease debugging
- .globl slowtrap
- .globl winuf_invalid
-
- .comm _C_LABEL(nwindows), 4
diff --git a/sys/arch/solbourne/solbourne/machdep.c b/sys/arch/solbourne/solbourne/machdep.c
deleted file mode 100644
index cc6b2c4d4a1..00000000000
--- a/sys/arch/solbourne/solbourne/machdep.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/* $OpenBSD: machdep.c,v 1.46 2015/01/16 20:17:07 kettenis Exp $ */
-/* OpenBSD: machdep.c,v 1.105 2005/04/11 15:13:01 deraadt Exp */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. 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.
- *
- * @(#)machdep.c 8.6 (Berkeley) 1/14/94
- */
-
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <sys/signalvar.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/buf.h>
-#include <sys/device.h>
-#include <sys/reboot.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/timeout.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/mount.h>
-#include <sys/msgbuf.h>
-#include <sys/syscallargs.h>
-#include <sys/exec.h>
-#include <sys/sysctl.h>
-#include <sys/extent.h>
-
-#include <net/if.h>
-#include <uvm/uvm.h>
-
-#include <dev/rndvar.h>
-
-#include <machine/autoconf.h>
-#include <machine/frame.h>
-#include <machine/cpu.h>
-#include <machine/pmap.h>
-#include <machine/oldmon.h>
-#include <machine/bsd_openprom.h>
-
-#include <machine/idt.h>
-#include <machine/kap.h>
-#include <machine/prom.h>
-
-#include <sparc/sparc/asm.h>
-#include <sparc/sparc/cache.h>
-#include <sparc/sparc/cpuvar.h>
-
-#include "auxreg.h"
-
-#include <sparc/sparc/intreg.h>
-
-struct vm_map *exec_map = NULL;
-struct vm_map *phys_map = NULL;
-
-int physmem;
-
-/* sysctl settable */
-int sparc_led_blink = 1;
-
-/*
- * safepri is a safe priority for sleep to set for a spin-wait
- * during autoconfiguration or after a panic.
- */
-int safepri = 0;
-
-/*
- * dvmamap is used to manage DVMA memory. Note: this coincides with
- * the memory range in `phys_map' (which is mostly a place-holder).
- */
-vaddr_t dvma_base, dvma_end;
-struct extent *dvmamap_extent;
-
-void dumpsys(void);
-static int kap_maskcheck(void);
-
-/*
- * Machine-dependent startup code
- */
-void
-cpu_startup()
-{
-#ifdef DEBUG
- extern int pmapdebug;
- int opmapdebug = pmapdebug;
-#endif
- vaddr_t minaddr, maxaddr;
- extern struct user *proc0paddr;
-
-#ifdef DEBUG
- pmapdebug = 0;
-#endif
-
- /*
- * fix message buffer mapping
- */
- pmap_map(MSGBUF_VA, MSGBUF_PA, MSGBUF_PA + MSGBUFSIZE,
- PROT_READ | PROT_WRITE);
- initmsgbuf((caddr_t)(MSGBUF_VA + (CPU_ISSUN4 ? 4096 : 0)), MSGBUFSIZE);
-
- proc0.p_addr = proc0paddr;
-
- /* I would print this earlier, but I want it in the message buffer */
- if (kap_maskcheck() == 0) {
- printf("WARNING: KAP M2C3 or earlier mask detected.\n"
-"THE PROCESSOR IN THIS MACHINE SUFFERS FROM SEVERE HARDWARE ISSUES.\n"
-"M2C3 PROCESSORS MAY RUN RELIABLY ENOUGH, OLDER WILL DEFINITELY NOT.\n\n");
- }
-
- /*
- * Good {morning,afternoon,evening,night}.
- */
- printf(version);
- /*identifycpu();*/
- printf("real mem = %d (%dMB)\n", ptoa(physmem),
- ptoa(physmem) / 1024 / 1024);
-
- /*
- * Allocate a submap for exec arguments. This map effectively
- * limits the number of processes exec'ing at any time.
- */
- minaddr = vm_map_min(kernel_map);
- exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
- 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
-
- /*
- * Allocate a map for physio. Others use a submap of the kernel
- * map, but we want one completely separate, even though it uses
- * the same pmap.
- */
- dvma_base = CPU_ISSUN4M ? DVMA4M_BASE : DVMA_BASE;
- dvma_end = CPU_ISSUN4M ? DVMA4M_END : DVMA_END;
- phys_map = uvm_map_create(pmap_kernel(), dvma_base, dvma_end,
- VM_MAP_INTRSAFE);
- if (phys_map == NULL)
- panic("unable to create DVMA map");
-
- /*
- * Allocate DVMA space and dump into a privately managed
- * extent for double mappings which is usable from
- * interrupt contexts.
- */
- if (uvm_km_valloc_wait(phys_map, (dvma_end-dvma_base)) != dvma_base)
- panic("unable to allocate from DVMA map");
- dvmamap_extent = extent_create("dvmamap", dvma_base, dvma_end,
- M_DEVBUF, NULL, 0, EX_NOWAIT);
- if (dvmamap_extent == 0)
- panic("unable to allocate extent for dvma");
-
-#ifdef DEBUG
- pmapdebug = opmapdebug;
-#endif
- printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
- ptoa(uvmexp.free) / 1024 / 1024);
-
- /*
- * Set up buffers, so they can be used to read disk labels.
- */
- bufinit();
-
- /* Early interrupt handlers initialization */
- intr_init();
-}
-
-/*
- * Set up registers on exec.
- *
- * XXX this entire mess must be fixed
- */
-/* ARGSUSED */
-void
-setregs(p, pack, stack, retval)
- struct proc *p;
- struct exec_package *pack;
- u_long stack;
- register_t *retval;
-{
- struct trapframe *tf = p->p_md.md_tf;
- struct fpstate *fs;
- int psr;
-
- /*
- * Setup the process StackGhost cookie which will be XORed into
- * the return pointer as register windows are over/underflowed
- */
- p->p_addr->u_pcb.pcb_wcookie = arc4random();
-
- /* The cookie needs to guarantee invalid alignment after the XOR */
- switch (p->p_addr->u_pcb.pcb_wcookie % 3) {
- case 0: /* Two lsb's already both set except if the cookie is 0 */
- p->p_addr->u_pcb.pcb_wcookie |= 0x3;
- break;
- case 1: /* Set the lsb */
- p->p_addr->u_pcb.pcb_wcookie = 1 |
- (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
- break;
- case 2: /* Set the second most lsb */
- p->p_addr->u_pcb.pcb_wcookie = 2 |
- (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
- break;
- }
-
- /* Don't allow misaligned code by default */
- p->p_md.md_flags &= ~MDP_FIXALIGN;
-
- /*
- * The syscall will ``return'' to npc or %g7 or %g2; set them all.
- * Set the rest of the registers to 0 except for %o6 (stack pointer,
- * built in exec()) and psr (retain CWP and PSR_S bits).
- */
- psr = tf->tf_psr & (PSR_S | PSR_CWP);
- if ((fs = p->p_md.md_fpstate) != NULL) {
- /*
- * We hold an FPU state. If we own *the* FPU chip state
- * we must get rid of it, and the only way to do that is
- * to save it. In any case, get rid of our FPU state.
- */
- if (p == cpuinfo.fpproc) {
- savefpstate(fs);
- cpuinfo.fpproc = NULL;
- }
- free((void *)fs, M_SUBPROC, 0);
- p->p_md.md_fpstate = NULL;
- }
- bzero((caddr_t)tf, sizeof *tf);
- tf->tf_psr = psr;
- tf->tf_npc = pack->ep_entry & ~3;
- tf->tf_global[2] = tf->tf_global[7] = tf->tf_npc;
- /* XXX exec of init(8) returns via proc_trampoline() */
- if (p->p_pid == 1) {
- tf->tf_pc = tf->tf_npc;
- tf->tf_npc += 4;
- }
- stack -= sizeof(struct rwindow);
- tf->tf_out[6] = stack;
- retval[1] = 0;
-}
-
-#ifdef DEBUG
-int sigdebug = 0;
-pid_t sigpid = 0;
-#define SDB_FOLLOW 0x01
-#define SDB_KSTACK 0x02
-#define SDB_FPSTATE 0x04
-#endif
-
-struct sigframe {
- int sf_signo; /* signal number */
- siginfo_t *sf_sip; /* points to siginfo_t */
- int sf_xxx; /* placeholder */
- caddr_t sf_addr; /* SunOS compat */
- struct sigcontext sf_sc; /* actual sigcontext */
- siginfo_t sf_si;
-};
-
-/*
- * machine dependent system variables.
- */
-int
-cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
- int *name;
- u_int namelen;
- void *oldp;
- size_t *oldlenp;
- void *newp;
- size_t newlen;
- struct proc *p;
-{
-#if (NLED > 0) || (NAUXREG > 0) || (NSCF > 0)
- int oldval;
- int ret;
-#endif
- extern int v8mul;
-
- /* all sysctl names are this level are terminal */
- if (namelen != 1)
- return (ENOTDIR); /* overloaded */
-
- switch (name[0]) {
- case CPU_LED_BLINK:
-#if (NLED > 0) || (NAUXREG > 0) || (NSCF > 0)
- oldval = sparc_led_blink;
- ret = sysctl_int(oldp, oldlenp, newp, newlen,
- &sparc_led_blink);
-
- /*
- * If we were false and are now true, call led_blink().
- * led_blink() itself will catch the other case.
- */
- if (!oldval && sparc_led_blink > oldval) {
-#if NAUXREG > 0
- led_blink((caddr_t *)0);
-#endif
-#if NLED > 0
- led_cycle((caddr_t *)led_sc);
-#endif
-#if NSCF > 0
- scfblink((caddr_t *)0);
-#endif
- }
-
- return (ret);
-#else
- return (EOPNOTSUPP);
-#endif
- case CPU_CPUTYPE:
- return (sysctl_rdint(oldp, oldlenp, newp, cputyp));
- case CPU_V8MUL:
- return (sysctl_rdint(oldp, oldlenp, newp, v8mul));
- default:
- return (EOPNOTSUPP);
- }
- /* NOTREACHED */
-}
-
-/*
- * Send an interrupt to process.
- */
-void
-sendsig(catcher, sig, mask, code, type, val)
- sig_t catcher;
- int sig, mask;
- u_long code;
- int type;
- union sigval val;
-{
- struct proc *p = curproc;
- struct sigacts *psp = p->p_p->ps_sigacts;
- struct sigframe *fp;
- struct trapframe *tf;
- int caddr, oldsp, newsp;
- struct sigframe sf;
-
- tf = p->p_md.md_tf;
- oldsp = tf->tf_out[6];
-
- /*
- * Compute new user stack addresses, subtract off
- * one signal frame, and align.
- */
- if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
- !sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig)))
- fp = (struct sigframe *)(p->p_sigstk.ss_sp +
- p->p_sigstk.ss_size);
- else
- fp = (struct sigframe *)oldsp;
- fp = (struct sigframe *)((int)(fp - 1) & ~7);
-
-#ifdef DEBUG
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig: %s[%d] sig %d newusp %p scp %p\n",
- p->p_comm, p->p_pid, sig, fp, &fp->sf_sc);
-#endif
- /*
- * Now set up the signal frame. We build it in kernel space
- * and then copy it out. We probably ought to just build it
- * directly in user space....
- */
- bzero(&sf, sizeof(sf));
- sf.sf_signo = sig;
- sf.sf_sip = NULL;
-
- /*
- * Build the signal context to be used by sigreturn.
- */
- sf.sf_sc.sc_mask = mask;
- sf.sf_sc.sc_sp = oldsp;
- sf.sf_sc.sc_pc = tf->tf_pc;
- sf.sf_sc.sc_npc = tf->tf_npc;
- sf.sf_sc.sc_psr = tf->tf_psr;
- sf.sf_sc.sc_g1 = tf->tf_global[1];
- sf.sf_sc.sc_o0 = tf->tf_out[0];
-
- if (psp->ps_siginfo & sigmask(sig)) {
- sf.sf_sip = &fp->sf_si;
- initsiginfo(&sf.sf_si, sig, code, type, val);
- }
-
- /*
- * Put the stack in a consistent state before we whack away
- * at it. Note that write_user_windows may just dump the
- * registers into the pcb; we need them in the process's memory.
- * We also need to make sure that when we start the signal handler,
- * its %i6 (%fp), which is loaded from the newly allocated stack area,
- * joins seamlessly with the frame it was in when the signal occurred,
- * so that the debugger and _longjmp code can back up through it.
- */
- newsp = (int)fp - sizeof(struct rwindow);
- write_user_windows();
- /* XXX do not copyout siginfo if not needed */
- if (rwindow_save(p) || copyout((caddr_t)&sf, (caddr_t)fp, sizeof sf) ||
- copyout(&oldsp, &((struct rwindow *)newsp)->rw_in[6],
- sizeof(register_t)) != 0) {
- /*
- * Process has trashed its stack; give it an illegal
- * instruction to halt it in its tracks.
- */
-#ifdef DEBUG
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig: window save or copyout error\n");
-#endif
- sigexit(p, SIGILL);
- /* NOTREACHED */
- }
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW)
- printf("sendsig: %s[%d] sig %d scp %p\n",
- p->p_comm, p->p_pid, sig, &fp->sf_sc);
-#endif
- /*
- * Arrange to continue execution at the code copied out in exec().
- * It needs the function to call in %g1, and a new stack pointer.
- */
- caddr = p->p_p->ps_sigcode;
- tf->tf_global[1] = (int)catcher;
- tf->tf_pc = caddr;
- tf->tf_npc = caddr + 4;
- tf->tf_out[6] = newsp;
-#ifdef DEBUG
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig: about to return to catcher\n");
-#endif
-}
-
-/*
- * System call to cleanup state after a signal
- * has been taken. Reset signal mask and
- * stack state from context left by sendsig (above),
- * and return to the given trap frame (if there is one).
- * Check carefully to make sure that the user has not
- * modified the state to gain improper privileges or to cause
- * a machine fault.
- */
-/* ARGSUSED */
-int
-sys_sigreturn(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
-{
- struct sys_sigreturn_args /* {
- syscallarg(struct sigcontext *) sigcntxp;
- } */ *uap = v;
- struct sigcontext ksc;
- struct trapframe *tf;
- int error;
-
- /* First ensure consistent stack state (see sendsig). */
- write_user_windows();
- if (rwindow_save(p))
- sigexit(p, SIGILL);
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW)
- printf("sigreturn: %s[%d], sigcntxp %p\n",
- p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
-#endif
- if ((error = copyin(SCARG(uap, sigcntxp), &ksc, sizeof(ksc))) != 0)
- return (error);
- tf = p->p_md.md_tf;
- /*
- * Only the icc bits in the psr are used, so it need not be
- * verified. pc and npc must be multiples of 4. This is all
- * that is required; if it holds, just do it.
- */
- if (((ksc.sc_pc | ksc.sc_npc) & 3) != 0)
- return (EINVAL);
- /* take only psr ICC field */
- tf->tf_psr = (tf->tf_psr & ~PSR_ICC) | (ksc.sc_psr & PSR_ICC);
- tf->tf_pc = ksc.sc_pc;
- tf->tf_npc = ksc.sc_npc;
- tf->tf_global[1] = ksc.sc_g1;
- tf->tf_out[0] = ksc.sc_o0;
- tf->tf_out[6] = ksc.sc_sp;
- p->p_sigmask = ksc.sc_mask & ~sigcantmask;
- return (EJUSTRETURN);
-}
-
-int waittime = -1;
-
-__dead void
-boot(int howto)
-{
- int i;
- static char str[4]; /* room for "-sd\0" */
-
- if (cold) {
- if ((howto & RB_USERREQ) == 0)
- howto |= RB_HALT;
- goto haltsys;
- }
-
- fb_unblank();
- boothowto = howto;
- if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
- waittime = 0;
- vfs_shutdown();
-
- if ((howto & RB_TIMEBAD) == 0) {
- resettodr();
- } else {
- printf("WARNING: not updating battery clock\n");
- }
- }
- if_downall();
-
- uvm_shutdown();
- splhigh();
- cold = 1;
-
- if ((howto & RB_DUMP) != 0)
- dumpsys();
-
-haltsys:
- config_suspend_all(DVACT_POWERDOWN);
-
- if ((howto & RB_HALT) != 0 || (howto & RB_POWERDOWN) != 0) {
- printf("halted\n\n");
- romhalt();
- }
-
- printf("rebooting\n\n");
- i = 1;
- if ((howto & RB_SINGLE) != 0)
- str[i++] = 's';
- if ((howto & RB_KDB) != 0)
- str[i++] = 'd';
- if (i > 1) {
- str[0] = '-';
- str[i] = 0;
- } else
- str[0] = 0;
- romboot(str);
- for (;;) ;
- /* NOTREACHED */
-}
-
-/* XXX - needs to be written */
-void
-dumpconf(void)
-{
-}
-
-/*
- * Write a crash dump.
- */
-void
-dumpsys()
-{
- printf("dump: TBD\n");
-}
-
-/*
- * Map an I/O device given physical address and size in bytes, e.g.,
- *
- * mydev = (struct mydev *)mapdev(myioaddr, 0,
- * 0, sizeof(struct mydev));
- *
- * See also machine/autoconf.h.
- *
- * XXXART - verify types (too tired now).
- */
-void *
-mapdev(phys, virt, offset, size)
- struct rom_reg *phys;
- int offset, virt, size;
-{
- vaddr_t va;
- paddr_t pa;
- void *ret;
- static vaddr_t iobase;
- unsigned int pmtype;
-
- if (iobase == NULL)
- iobase = IODEV_BASE;
-
- size = round_page(size);
- if (size == 0)
- panic("mapdev: zero size");
-
- if (virt)
- va = trunc_page(virt);
- else {
- va = iobase;
- iobase += size;
- if (iobase > IODEV_END) /* unlikely */
- panic("mapiodev");
- }
- ret = (void *)(va | (((u_long)phys->rr_paddr + offset) & PGOFSET));
- /* note: preserve page offset */
-
- pa = trunc_page((vaddr_t)phys->rr_paddr + offset);
- pmtype = PMAP_IOENC(phys->rr_iospace);
-
- do {
- pmap_kenter_pa(va, pa | pmtype | PMAP_NC,
- PROT_READ | PROT_WRITE);
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- } while ((size -= PAGE_SIZE) > 0);
- pmap_update(pmap_kernel());
- return (ret);
-}
-
-/*
- * Soft interrupt handling
- */
-
-int kap_sir;
-
-void
-ienab_bis(int bis)
-{
- int s;
- int mask = 1 << (bis - 1);
- u_int32_t icr;
-
- s = splhigh();
- if (kap_sir < mask) {
- /*
- * We become the most important bit in kap_sir. Reprogram
- * the GLU_ICR soft interrupt dispatcher.
- */
- icr = lda(GLU_ICR, ASI_PHYS_IO) >> 24;
- icr = (icr & ~GICR_DISPATCH_MASK) | bis;
- sta(GLU_ICR, ASI_PHYS_IO, icr << 24);
- }
- kap_sir |= mask;
- splx(s);
-}
-
-/*
- * minimal console routines
- */
-
-#include <sys/conf.h>
-#include <dev/cons.h>
-
-cons_decl(early);
-
-struct consdev consdev_early = {
- earlycnprobe,
- earlycninit,
- earlycngetc,
- earlycnputc,
- nullcnpollc
-};
-
-struct consdev *cn_tab = &consdev_early;
-
-void
-earlycnprobe(struct consdev *cn)
-{
- cn->cn_dev = makedev(0, 0);
- cn->cn_pri = CN_MIDPRI;
-}
-
-void
-earlycninit(struct consdev *cn)
-{
-}
-
-/* getc, putc in locore.s */
-
-int kapmask_m2c4;
-static void kap_maskfault(void);
-
-void
-kap_maskfault()
-{
- kapmask_m2c4 = 1;
-}
-
-/*
- * This routine checks whether we are running on a M2C4 or later mask, by
- * checking for M2C4 behaviour.
- *
- * After mapping a kernel text page with the ``byte-writeable shared''
- * memory attribute, we will attempt to execute code from the new mapping.
- *
- * On M2C4 and later masks, this will cause a text fault, supposedly for
- * us to be able to invalidate the instruction cache first, before resuming
- * execution; while M2C3 and earlier masks will not fault.
- *
- * Since OpenBSD does not use BWS pages and does explicit instruction cache
- * invalidation in ddb and the ptrace interface, this fault never happens in
- * real life. mem_access_fault() in trap.c knows this and will direct
- * execution to kap_maskfault(). Since the test code we have been invoking
- * is a simple empty function, kap_maskfault() will return here.
- *
- * XXX Find some way to identify M2C3, which _should_ run.
- */
-int
-kap_maskcheck()
-{
- extern void masktest(void);
- void (*test)(void);
-
- pmap_enter(pmap_kernel(), TMPMAP_VA,
- trunc_page((vaddr_t)masktest) | PMAP_BWS, PROT_READ, 0);
- test = (void (*)(void))(TMPMAP_VA + ((vaddr_t)masktest & PAGE_MASK));
-
- cpcb->pcb_onfault = (caddr_t)kap_maskfault;
- (*test)();
- cpcb->pcb_onfault = NULL;
-
- pmap_remove(pmap_kernel(), TMPMAP_VA, TMPMAP_VA + PAGE_SIZE);
-
- return (kapmask_m2c4);
-}
diff --git a/sys/arch/solbourne/solbourne/mem.c b/sys/arch/solbourne/solbourne/mem.c
deleted file mode 100644
index 22e06376d92..00000000000
--- a/sys/arch/solbourne/solbourne/mem.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* $OpenBSD: mem.c,v 1.5 2015/02/10 22:44:35 miod Exp $ */
-/* OpenBSD: mem.c,v 1.21 2003/06/02 23:27:55 millert Exp */
-
-/*
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1982, 1986, 1990, 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. 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.
- *
- * @(#)mem.c 8.3 (Berkeley) 1/12/94
- */
-
-/*
- * Memory special file
- */
-
-#include <sys/param.h>
-#include <sys/buf.h>
-#include <sys/systm.h>
-#include <sys/uio.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-
-#include <machine/eeprom.h>
-#include <machine/conf.h>
-
-#include <uvm/uvm_extern.h>
-
-extern vaddr_t prom_vstart;
-extern vaddr_t prom_vend;
-caddr_t zeropage;
-vaddr_t mem_page;
-
-/*ARGSUSED*/
-int
-mmopen(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
-{
-
- switch (minor(dev)) {
- case 0:
- case 1:
- case 2:
- case 11:
- case 12:
- return (0);
- default:
- return (ENXIO);
- }
-}
-
-/*ARGSUSED*/
-int
-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;
- int flags;
-{
- paddr_t pa;
- vaddr_t va;
- size_t c, o;
- struct iovec *iov;
- int error = 0;
- static int physlock;
-
- if (minor(dev) == 0) {
- /* lock against other uses of shared mem_page */
- while (physlock > 0) {
- physlock++;
- error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
- "mmrw", 0);
- if (error)
- return (error);
- }
- physlock = 1;
- if (mem_page == 0)
- mem_page = uvm_km_valloc_wait(kernel_map, NBPG);
- if (mem_page == 0)
- panic("mmrw: out of space in kernel_map");
- }
- while (uio->uio_resid > 0 && error == 0) {
- iov = uio->uio_iov;
- if (iov->iov_len == 0) {
- uio->uio_iov++;
- uio->uio_iovcnt--;
- if (uio->uio_iovcnt < 0)
- panic("mmrw");
- continue;
- }
- switch (minor(dev)) {
-
- /* minor device 0 is physical memory */
- case 0:
- pa = (paddr_t)uio->uio_offset;
- if (!pmap_pa_exists(pa)) {
- error = EFAULT;
- goto unlock;
- }
- pmap_enter(pmap_kernel(), mem_page,
- trunc_page(pa), uio->uio_rw == UIO_READ ?
- PROT_READ : PROT_WRITE, PMAP_WIRED);
- pmap_update(pmap_kernel());
- o = uio->uio_offset & PGOFSET;
- c = ulmin(uio->uio_resid, NBPG - o);
- error = uiomove((caddr_t)mem_page + o, c, uio);
- pmap_remove(pmap_kernel(), mem_page, mem_page + NBPG);
- pmap_update(pmap_kernel());
- continue;
-
- /* minor device 1 is kernel memory */
- case 1:
- va = (vaddr_t)uio->uio_offset;
- if (va >= MSGBUF_VA && va < MSGBUF_VA+MSGBUFSIZE) {
- c = ulmin(iov->iov_len, MSGBUFSIZE);
-#if 0
- } else if (va >= prom_vstart && va < prom_vend &&
- uio->uio_rw == UIO_READ) {
- /* Allow read-only access to the PROM */
- c = ulmin(iov->iov_len, prom_vend - prom_vstart);
-#endif
- } else {
- c = ulmin(iov->iov_len, MAXPHYS);
- if (!uvm_kernacc((caddr_t)va, c,
- uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
- return (EFAULT);
- }
- error = uiomove((caddr_t)va, c, uio);
- continue;
-
- /* minor device 2 is EOF/RATHOLE */
- case 2:
- if (uio->uio_rw == UIO_WRITE)
- uio->uio_resid = 0;
- return (0);
-
-/* XXX should add sbus, etc */
-
-/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
- case 12:
- if (uio->uio_rw == UIO_WRITE) {
- uio->uio_resid = 0;
- return 0;
- }
- if (zeropage == NULL)
- zeropage = malloc(PAGE_SIZE, M_TEMP,
- M_WAITOK | M_ZERO);
- c = ulmin(iov->iov_len, PAGE_SIZE);
- error = uiomove(zeropage, c, uio);
- continue;
-
- default:
- return (ENXIO);
- }
- }
- if (minor(dev) == 0) {
-unlock:
- if (physlock > 1)
- wakeup((caddr_t)&physlock);
- physlock = 0;
- }
- return (error);
-}
-
-paddr_t
-mmmmap(dev, off, prot)
- dev_t dev;
- off_t off;
- int prot;
-{
-
- return (-1);
-}
-
-/*ARGSUSED*/
-int
-mmioctl(dev, cmd, data, flags, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flags;
- struct proc *p;
-{
- return (EOPNOTSUPP);
-}
diff --git a/sys/arch/solbourne/solbourne/pmap.c b/sys/arch/solbourne/solbourne/pmap.c
deleted file mode 100644
index 131c99cc016..00000000000
--- a/sys/arch/solbourne/solbourne/pmap.c
+++ /dev/null
@@ -1,1625 +0,0 @@
-/* $OpenBSD: pmap.c,v 1.12 2015/09/08 21:28:36 kettenis Exp $ */
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * KAP physical memory management code.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/pool.h>
-#include <sys/proc.h>
-
-#include <uvm/uvm.h>
-
-#include <machine/idt.h>
-#include <machine/kap.h>
-#include <machine/prom.h>
-
-#include <sparc/sparc/asm.h>
-#include <sparc/sparc/cache.h>
-#include <sparc/sparc/cpuvar.h>
-
-#include <sparc/dev/if_lereg.h>
-
-#ifdef PMAPDEBUG
-#define PDB_ACTIVATE 0x000001
-#define PDB_CLEAR_M 0x000002
-#define PDB_CLEAR_U 0x000004
-#define PDB_COLLECT 0x000008
-#define PDB_COPY 0x000010
-#define PDB_CREATE 0x000020
-#define PDB_DESTROY 0x000040
-#define PDB_ENTER 0x000080
-#define PDB_EXTRACT 0x000100
-#define PDB_IS_M 0x000200
-#define PDB_IS_U 0x000400
-#define PDB_KENTER 0x000800
-#define PDB_KREMOVE 0x001000
-#define PDB_PROTECT 0x002000
-#define PDB_REFERENCE 0x004000
-#define PDB_RELEASE 0x008000
-#define PDB_REMOVE 0x010000
-#define PDB_UNWIRE 0x020000
-#define PDB_ZERO 0x040000
-
-#define DPRINTF(flg,stmt) \
-do { \
- if (pmapdebug & (flg)) \
- printf stmt; \
-} while (0)
-
-u_int _pmapdebug_cold = 0;
-u_int _pmapdebug = -1;
-#define pmapdebug ((cold) ? _pmapdebug_cold : _pmapdebug)
-#else
-#define DPRINTF(flg,stmt) do { } while (0)
-#endif
-
-/* pmap and pde/pte pool allocators */
-struct pool pmappool, pvpool;
-
-struct pmap kernel_pmap_store;
-
-pt_entry_t *pmap_grow_pte(struct pmap *, vaddr_t);
-static pd_entry_t *pmap_pde(pmap_t, vaddr_t);
-static pt_entry_t *pde_pte(pd_entry_t *, vaddr_t);
-pt_entry_t *pmap_pte(pmap_t, vaddr_t);
-
-void pg_flushcache(struct vm_page *);
-
-void tlb_flush(vaddr_t);
-void tlb_flush_all(void);
-
-vaddr_t virtual_avail;
-vaddr_t virtual_end;
-
-vaddr_t vreserve; /* two reserved pages for copy and zero operations... */
-pt_entry_t *ptereserve; /* ...and their PTEs */
-
-vaddr_t lance_va; /* a fixed buffer for the on-board lance */
-
-/*
- * Attribute caching
- */
-
-typedef struct pvlist *pv_entry_t;
-
-static pv_entry_t pg_to_pvl(struct vm_page *);
-
-static __inline__
-pv_entry_t
-pg_to_pvl(struct vm_page *pg)
-{
- return (&pg->mdpage.pv_head);
-}
-
-/*
- * TLB operations
- */
-
-void
-tlb_flush(vaddr_t va)
-{
-#if 0
- u_int32_t fvar;
-
- fvar = lda(0, ASI_FVAR);
-#endif
-
- sta(0, ASI_PID, 0);
- sta(0, ASI_FVAR, va);
- sta(0, ASI_GTLB_INVAL_ENTRY, 0);
-#if 0
- sta(0, ASI_FVAR, fvar);
-#endif
-}
-
-void
-tlb_flush_all()
-{
- /*
- * Note that loaded TLB for PTEs with PG_G do NOT get invalidated
- * by this command (because they are common to all PID), and need
- * to be invalidated with ASI_GTLB_INVAL_ENTRY.
- * This does not matter to us, as we don't use PG_G for now.
- */
- sta(0, ASI_PID, 0);
- sta(0, ASI_GTLB_INVALIDATE, 0);
-}
-
-/*
- * Simple pde and pte access routines.
- */
-
-#define trunc_seg(va) ((va) & PDT_INDEX_MASK)
-
-static __inline__
-pd_entry_t *
-pmap_pde(pmap_t pmap, vaddr_t va)
-{
- return (&pmap->pm_segtab[va >> PDT_INDEX_SHIFT]);
-}
-
-static __inline__
-pt_entry_t *
-pde_pte(pd_entry_t *pde, vaddr_t va)
-{
- pt_entry_t *pte;
-
- pte = (pt_entry_t *)pde->pde_va;
- pte += (va & PT_INDEX_MASK) >> PT_INDEX_SHIFT;
-
- return (pte);
-}
-
-pt_entry_t *
-pmap_pte(pmap_t pmap, vaddr_t va)
-{
- pd_entry_t *pde;
-
- pde = pmap_pde(pmap, va);
- if (pde->pde_va == NULL)
- return (NULL);
-
- return (pde_pte(pde, va));
-}
-
-/*
- * Setup virtual memory for the kernel. The new tables are not activated yet,
- * they will be in locore.s after bootstrap() returns.
- */
-void
-pmap_bootstrap(size_t promdata)
-{
- extern caddr_t end;
- extern vaddr_t esym;
- u_int32_t icuconf;
- u_int8_t imcmcr;
- vaddr_t ekern;
- vaddr_t va, eva;
- paddr_t pa;
- unsigned int tabidx;
- pd_entry_t *pde;
- pt_entry_t *pte;
- struct sb_prom *sp;
- paddr_t prompa;
- psize_t promlen;
- extern vaddr_t prom_data;
-
- /*
- * Compute memory size by checking the iCU for the number of iMC,
- * then each iMC for its status.
- */
-
- icuconf = lda(ICU_CONF, ASI_PHYS_IO);
- physmem = 0;
-
-#if 0
- imcmcr = lduba(MC0_MCR, ASI_PHYS_IO);
-#else
- imcmcr = *(u_int8_t *)MC0_MCR;
-#endif
- if (imcmcr & MCR_BANK0_AVAIL)
- physmem += (imcmcr & MCR_BANK0_32M) ? 32 : 8;
- if (imcmcr & MCR_BANK1_AVAIL)
- physmem += (imcmcr & MCR_BANK1_32M) ? 32 : 8;
-
- if ((icuconf & CONF_NO_EXTRA_MEMORY) == 0) {
-#if 0
- imcmcr = lduba(MC1_MCR, ASI_PHYS_IO);
-#else
- imcmcr = *(u_int8_t *)MC1_MCR;
-#endif
- if (imcmcr & MCR_BANK0_AVAIL)
- physmem += (imcmcr & MCR_BANK0_32M) ? 32 : 8;
- if (imcmcr & MCR_BANK1_AVAIL)
- physmem += (imcmcr & MCR_BANK1_32M) ? 32 : 8;
- }
-
- /* scale to pages */
- physmem <<= (20 - PAGE_SHIFT);
-
- /*
- * Get a grip on the PROM communication area.
- */
- sp = (struct sb_prom *)PROM_DATA_VA;
-
- /*
- * Set virtual page size.
- */
- uvmexp.pagesize = PAGE_SIZE;
- uvm_setpagesize();
-
- /*
- * Initialize kernel pmap.
- */
- pmap_kernel()->pm_refcount = 1;
-
- /*
- * Compute kernel fixed memory usage.
- */
- ekern = (vaddr_t)&end;
-#if defined(DDB) || NKSYMS > 0
- if (esym != 0)
- ekern = esym;
-#endif
-
- /*
- * Reserve room for the prom data we're interested in.
- */
- prom_data = ekern;
- ekern += promdata;
-
- /*
- * From then on, all allocations will be multiples of the
- * page size.
- */
- ekern = round_page(ekern);
-
- /*
- * Reserve buffers for the on-board Lance chip - the whole buffer
- * must be in the same 128KB segment.
- * This should disappear once iCU is tamed...
- */
- if ((ekern >> 17) != ((ekern + MEMSIZE) >> 17))
- ekern = roundup(ekern, 1 << 17);
- lance_va = ekern;
- ekern += MEMSIZE;
-
- /*
- * Initialize fixed mappings.
- * We want to keep the PTW mapping the kernel for now, but all
- * devices needed during early bootstrap needs to have their own
- * mappings.
- */
-
- /*
- * Step 1: reserve memory for the kernel pde.
- */
-
- bzero((caddr_t)ekern, PDT_SIZE);
- pmap_kernel()->pm_segtab = (pd_entry_t *)ekern;
- pmap_kernel()->pm_psegtab = PTW1_TO_PHYS(ekern);
- ekern += PDT_SIZE; /* not rounded anymore ! */
-
- /*
- * Step 2: create as many pages tables as necessary.
- * We'll provide page tables for the kernel virtual memory range
- * and the top of memory (i.e. PTW1, PTW2 and I/O maps), so that
- * we can invoke mapdev() early in the boot process.
- *
- * For the early console, we will also provide an 1:1 mapping
- * of the I/O space.
- */
-
- tabidx = 0;
-
- va = VM_MIN_KERNEL_ADDRESS;
- while (va != 0) {
- pde = pmap_pde(pmap_kernel(), va);
-
- pde->pde_va = (pt_entry_t *)(ekern + tabidx * PT_SIZE);
- pde->pde_pa = PTW1_TO_PHYS((vaddr_t)pde->pde_va);
-
- tabidx++;
- va += NBSEG;
- }
-
- va = (vaddr_t)OBIO_PA_START;
- while (va < (vaddr_t)OBIO_PA_END) {
- pde = pmap_pde(pmap_kernel(), va);
-
- pde->pde_va = (pt_entry_t *)(ekern + tabidx * PT_SIZE);
- pde->pde_pa = PTW1_TO_PHYS((vaddr_t)pde->pde_va);
-
- tabidx++;
- va += NBSEG;
- }
-
- va = IOSPACE_BASE;
- while (va < IOSPACE_BASE + IOSPACE_LEN) {
- pde = pmap_pde(pmap_kernel(), va);
-
- pde->pde_va = (pt_entry_t *)(ekern + tabidx * PT_SIZE);
- pde->pde_pa = PTW1_TO_PHYS((vaddr_t)pde->pde_va);
-
- tabidx++;
- /* watch out for wraparound! */
- if ((va += NBSEG) == 0)
- break;
- }
-
- bzero((caddr_t)ekern, tabidx * PT_SIZE);
- ekern += tabidx * PT_SIZE;
- ekern = round_page(ekern);
-
- /*
- * Step 3: fill them. We fill the page tables backing PTW1 and
- * PTW2 to simplify pmap_extract(), by not having to check if
- * the va is in a PTW.
- */
-
- va = PTW1_BASE;
- pa = PHYSMEM_BASE;
- while (va < PTW1_BASE + PTW_WINDOW_SIZE) {
- pde = pmap_pde(pmap_kernel(), va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > PTW1_BASE + PTW_WINDOW_SIZE)
- eva = PTW1_BASE + PTW_WINDOW_SIZE;
- pte = pde_pte(pde, va);
- while (va < eva) {
- *pte++ = pa | PG_V | PG_S | PG_U | PG_CACHE;
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
- }
-
- va = PTW2_BASE;
- pa = PHYSMEM_BASE;
- while (va < PTW2_BASE + PTW_WINDOW_SIZE) {
- pde = pmap_pde(pmap_kernel(), va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > PTW2_BASE + PTW_WINDOW_SIZE)
- eva = PTW2_BASE + PTW_WINDOW_SIZE;
- pte = pde_pte(pde, va);
- while (va < eva) {
- *pte++ = pa | PG_V | PG_S | PG_U | PG_SHARED;
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
- }
-
- va = (vaddr_t)OBIO_PA_START;
- while (va < (vaddr_t)OBIO_PA_END) {
- pde = pmap_pde(pmap_kernel(), va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > OBIO_PA_END)
- eva = OBIO_PA_END;
- pte = pde_pte(pde, va);
- for (; va < eva; va += PAGE_SIZE)
- *pte++ = va | PG_V | PG_S | PG_U | PG_IO;
- }
-
- /*
- * Compute the virtual memory space.
- * Note that the kernel is mapped by PTW1 and PTW2, and is outside
- * this range.
- */
-
- virtual_avail = VM_MIN_KERNEL_ADDRESS;
- virtual_end = VM_MAX_KERNEL_ADDRESS;
-
- /*
- * Reserve two _virtual_ pages for copy and zero operations.
- * Since we need to be able to tweak their PTE, they need to be
- * outside PTW1 and PTW2. We'll steal them from the top of the
- * virtual space; thus we are sure they will be in the same
- * segment as well.
- */
-
- virtual_end -= 2* PAGE_SIZE;
- vreserve = virtual_end;
- ptereserve = pmap_pte(pmap_kernel(), vreserve);
-
- /*
- * Tell the VM system about the available memory.
- * Physical memory starts at PHYSMEM_BASE; kernel uses space
- * from PTW1_TO_PHYS(KERNBASE) to ekern at this point.
- *
- * The physical memory below the kernel is reserved for the PROM
- * data and bss, and need to be left intact when invoking it, so
- * we do not upload (manage) it.
- *
- * The PROM communication area may claim another area, way above
- * the kernel (usually less than 200 KB, immediately under 8MB
- * physical).
- */
-
- if (sp->sp_interface >= PROM_INTERFACE) {
- prompa = atop(PHYSMEM_BASE) + sp->sp_reserve_start;
- promlen = sp->sp_reserve_len;
- } else
- promlen = 0;
-
- if (promlen != 0) {
-#ifdef DIAGNOSTIC
- if (PTW1_TO_PHYS(ekern) > ptoa(prompa))
- panic("kernel overlaps PROM reserved area");
-#endif
- uvm_page_physload(
- atop(PTW1_TO_PHYS(ekern)), prompa,
- atop(PTW1_TO_PHYS(ekern)), prompa, 0);
- uvm_page_physload(
- prompa + promlen, atop(PHYSMEM_BASE) + physmem,
- prompa + promlen, atop(PHYSMEM_BASE) + physmem, 0);
- } else {
- uvm_page_physload(
- atop(PTW1_TO_PHYS(ekern)), atop(PHYSMEM_BASE) + physmem,
- atop(PTW1_TO_PHYS(ekern)), atop(PHYSMEM_BASE) + physmem, 0);
- }
-}
-
-/*
- * Return the virtual area range available to the kernel.
- */
-void
-pmap_virtual_space(vaddr_t *v_start, vaddr_t *v_end)
-{
- *v_start = virtual_avail;
- *v_end = virtual_end;
-}
-
-/*
- * Secondary initialization, at uvm_init() time.
- * We can now create the pools we'll use for pmap and pvlist allocations.
- */
-void
-pmap_init()
-{
- pool_init(&pmappool, sizeof(struct pmap), 0, 0, 0, "pmappl",
- &pool_allocator_single);
- pool_init(&pvpool, sizeof(struct pvlist), 0, 0, 0, "pvpl", NULL);
-}
-
-/*
- * Create a new pmap.
- *
- * We initialize pmaps with an empty pde, and a shadow of the kernel
- * space (VM_MIN_KERNEL_ADDRESS onwards).
- */
-pmap_t
-pmap_create()
-{
- pmap_t pmap;
- u_int pde;
-
- DPRINTF(PDB_CREATE, ("pmap_create()"));
-
- pmap = pool_get(&pmappool, PR_WAITOK | PR_ZERO);
-
- pmap->pm_refcount = 1;
-
- /*
- * Allocate the page directory.
- */
- pmap->pm_segtab = (pd_entry_t *)uvm_km_zalloc(kernel_map, PDT_SIZE);
- if (pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_segtab,
- &pmap->pm_psegtab) == FALSE)
- panic("pmap_create: pmap_extract failed!");
-
- /*
- * Shadow the kernel map in all user pmaps.
- */
- for (pde = (VM_MIN_KERNEL_ADDRESS >> PDT_INDEX_SHIFT);
- pde < NBR_PDE; pde++) {
- pmap->pm_segtab[pde].pde_pa =
- pmap_kernel()->pm_segtab[pde].pde_pa;
- pmap->pm_segtab[pde].pde_va =
- pmap_kernel()->pm_segtab[pde].pde_va;
- }
-
- DPRINTF(PDB_CREATE, (" -> %p\n", pmap));
-
- return (pmap);
-}
-
-/*
- * Destroy a pmap.
- * Its mappings will not actually be removed until the reference count
- * drops to zero.
- */
-void
-pmap_destroy(struct pmap *pmap)
-{
- int count;
-
- DPRINTF(PDB_DESTROY, ("pmap_destroy(%p)\n", pmap));
-
- count = --pmap->pm_refcount;
- if (count == 0) {
- pmap_release(pmap);
- pool_put(&pmappool, pmap);
- }
-}
-
-/*
- * Release all mappings and resources associated to a given pmap.
- */
-void
-pmap_release(struct pmap *pmap)
-{
- u_int pde;
- pt_entry_t *pdeva;
-#ifdef DIAGNOSTIC
- u_int pte;
-#endif
-
- DPRINTF(PDB_RELEASE, ("pmap_release(%p)\n", pmap));
-
- /*
- * Free all page tables.
- */
- for (pde = 0; pde < (VM_MIN_KERNEL_ADDRESS >> PDT_INDEX_SHIFT); pde++) {
- if ((pdeva = pmap->pm_segtab[pde].pde_va) != NULL) {
-#ifdef DIAGNOSTIC
- for (pte = 0; pte < NBR_PTE; pte++)
- if (pdeva[pte] & PG_V) {
- DPRINTF(PDB_RELEASE,
- ("pmap_release: unreleased pte "
- "%p (%08x)\n",
- pdeva + pte, pdeva[pte]));
- }
-#endif
- uvm_km_free(kernel_map, (vaddr_t)pdeva, PT_SIZE);
- }
- }
-
- /*
- * Free the page directory.
- */
- uvm_km_free(kernel_map, (vaddr_t)pmap->pm_segtab, PDT_SIZE);
-}
-
-/*
- * Returns a preferred virtual address for the given address, which
- * does not cause a VAC aliasing situation.
- */
-vaddr_t
-pmap_prefer(vaddr_t foff, vaddr_t va)
-{
- /* XXX assume no cache aliasing yet */
- return va;
-}
-
-/*
- * Activate the pmap associated to a given process.
- * Called from the scheduler.
- */
-void
-pmap_activate(struct proc *p)
-{
- pmap_t pmap = p->p_vmspace->vm_map.pmap;
- int s;
-
- DPRINTF(PDB_ACTIVATE,
- ("pmap_activate(%p/pmap %p/segtab pa %08x va %08x)\n",
- p, pmap, pmap->pm_psegtab, (vaddr_t)pmap->pm_segtab));
-
- s = splvm();
-
- if (p == curproc) {
- write_user_windows();
- cache_flush_context();
- sta(0, ASI_PID, 0);
- sta(0, ASI_PDBR, pmap->pm_psegtab);
- tlb_flush_all();
- }
-
- splx(s);
-}
-
-/*
- * Increment the pmap reference counter.
- */
-void
-pmap_reference(struct pmap *pmap)
-{
- DPRINTF(PDB_REFERENCE, ("pmap_reference(%p)\n", pmap));
-
- pmap->pm_refcount++;
-}
-
-/*
- * Remove a range of virtual addresses from the given pmap.
- * Addresses are expected to be page-aligned.
- */
-void
-pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t e)
-{
- vaddr_t va, eva;
- paddr_t pa;
- pd_entry_t *pde;
- pt_entry_t *pte, opte;
- struct vm_page *pg;
- struct pvlist *pvl, *prev, *cur;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_REMOVE, ("pmap_remove(%p,%08x,%08x)\n", pmap, sva, e));
-
- va = sva;
- while (va != e) {
- pde = pmap_pde(pmap, va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > e || eva == 0)
- eva = e;
-
- if (pde == NULL) {
- va = eva;
- continue;
- }
-
- pte = pde_pte(pde, va);
- for (; va != eva; va += PAGE_SIZE, pte++) {
- opte = *pte;
- if ((opte & PG_V) == 0)
- continue;
-
- pmap->pm_stats.resident_count--;
-
- pa = opte & PG_FRAME;
-
-#ifdef DIAGNOSTIC
- if (opte & PG_W) {
- printf("pmap_remove(%p): wired mapping for %08x",
- pmap, va);
- pmap->pm_stats.wired_count--;
- }
-#endif
-
- *pte = PG_NV;
- tlb_flush(va);
-
- pg = PHYS_TO_VM_PAGE(pa);
- if (pg == NULL)
- continue;
-
- /*
- * Remove the mapping from the pvlist for this
- * physical page.
- */
- pvl = pg_to_pvl(pg);
-#ifdef DIAGNOSTIC
- if (pvl->pv_pmap == NULL)
- panic("pmap_remove: NULL pmap in pvlist");
-#endif
- prev = NULL;
- for (cur = pvl; cur != NULL; cur = cur->pv_next) {
- if (cur->pv_va == va && cur->pv_pmap == pmap)
- break;
- prev = cur;
- }
-#ifdef DIAGNOSTIC
- if (cur == NULL) {
- panic("pmap_remove: va not in pvlist");
- }
-#endif
- if (prev == NULL) {
- cur = cur->pv_next;
- if (cur != NULL) {
- cur->pv_flags = pvl->pv_flags;
- *pvl = *cur;
- pool_put(&pvpool, cur);
- } else {
- pvl->pv_pmap = NULL;
- }
- } else {
- prev->pv_next = cur->pv_next;
- pool_put(&pvpool, cur);
- }
-
- /* update saved attributes for managed page */
- pvl->pv_flags |= (opte & (PG_U | PG_M));
- }
- }
-
- splx(s);
-}
-
-/*
- * Release any unnecessary management resources for the given pmap,
- * before swapping it out.
- */
-void
-pmap_collect(struct pmap *pmap)
-{
- u_int pde, pte;
- pt_entry_t *pdeva;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_COLLECT, ("pmap_collect(%p)\n", pmap));
-
- /*
- * Free all empty page tables.
- */
- for (pde = 0; pde < (VM_MIN_KERNEL_ADDRESS >> PDT_INDEX_SHIFT); pde++) {
- if ((pdeva = pmap->pm_segtab[pde].pde_va) == NULL)
- continue;
- for (pte = 0; pte < NBR_PTE; pte++)
- if (pdeva[pte] & PG_V)
- break;
- if (pte != NBR_PTE)
- continue;
-
- /*
- * Free the unused page table.
- */
- pmap->pm_segtab[pde].pde_va = NULL;
- pmap->pm_segtab[pde].pde_pa = 0;
- uvm_km_free(kernel_map, (vaddr_t)pdeva, PT_SIZE);
- }
-
- splx(s);
-}
-
-/*
- * Change the protection for a given vm_page. The protection can only
- * become more strict, i.e. protection rights get removed.
- *
- * Note that this pmap does not manage execution protection yet.
- */
-void
-pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
-{
- struct pvlist *pvl;
- int s;
-
- if ((prot & PROT_READ) == PROT_NONE) { /* remove all */
- s = splvm();
- pvl = pg_to_pvl(pg);
-
- DPRINTF(PDB_REMOVE, ("pmap_page_protect(%p/pmap %p,%x)\n",
- pg, pvl->pv_pmap, prot));
-
- while (pvl->pv_pmap != NULL) {
- pmap_remove(pvl->pv_pmap, pvl->pv_va,
- pvl->pv_va + PAGE_SIZE);
- }
-
- splx(s);
- } else if ((prot & PROT_WRITE) == PROT_NONE) {
- s = splvm();
- pvl = pg_to_pvl(pg);
-
- DPRINTF(PDB_REMOVE, ("pmap_page_protect(%p/pmap %p,%x)\n",
- pg, pvl->pv_pmap, prot));
-
- if (pvl->pv_pmap != NULL)
- for (; pvl != NULL; pvl = pvl->pv_next)
- pmap_protect(pvl->pv_pmap, pvl->pv_va,
- pvl->pv_va + PAGE_SIZE, prot);
-
- splx(s);
- } else {
- DPRINTF(PDB_REMOVE, ("pmap_page_protect(%p,%x)\n", pg, prot));
- }
-}
-
-/*
- * Set the protection for a virtual address range in the given pmap.
- *
- * Note that this pmap does not manage execution protection yet.
- */
-void
-pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t e, vm_prot_t prot)
-{
- vaddr_t va, eva;
- pd_entry_t *pde;
- pt_entry_t *pte, opte, npte;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_PROTECT,
- ("pmap_protect(%p,%08x,%08x,%x)\n", pmap, sva, e, prot));
-
- if ((prot & PROT_READ) == PROT_NONE) {
- pmap_remove(pmap, sva, e);
- splx(s);
- return;
- }
-
- va = sva;
- while (va != e) {
- pde = pmap_pde(pmap, va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > e || eva == 0)
- eva = e;
-
- if (pde == NULL) {
- va = eva;
- continue;
- }
-
- pte = pde_pte(pde, va);
- for (; va != eva; va += PAGE_SIZE, pte++) {
- opte = *pte;
- if ((opte & PG_V) == 0)
- continue;
-
- npte = (opte & ~PG_RO) |
- (prot & PROT_WRITE) ? PG_RW : PG_RO;
- if (opte != npte) {
- *pte = npte;
- tlb_flush(va);
- }
- }
- }
-
- splx(s);
-}
-
-/*
- * Expand a pmap, if necessary, to include a pte.
- */
-pt_entry_t *
-pmap_grow_pte(struct pmap *pmap, vaddr_t va)
-{
- pd_entry_t *pde;
-
- pde = pmap_pde(pmap, va);
- if (pde->pde_va == NULL) {
- pde->pde_va = (pt_entry_t *)uvm_km_zalloc(kernel_map, PT_SIZE);
- if (pde->pde_va == NULL)
- return (NULL);
- if (pmap_extract(pmap_kernel(), (vaddr_t)pde->pde_va,
- (paddr_t *)&pde->pde_pa) == FALSE)
- panic("pmap_grow_pte: pmap_extract on PT failed!");
- tlb_flush((vaddr_t)pmap->pm_segtab);
- }
-
- return (pde_pte(pde, va));
-}
-
-/*
- * Create or update a mapping for the page at the given physical and
- * virtual addresses, for the given pmap.
- */
-int
-pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
-{
- pt_entry_t *pte, opte, npte;
- struct vm_page *pg;
- struct pvlist *pvl, *cur;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_ENTER,
- ("pmap_enter(%p,%08x,%08x,%x,%x)", pmap, va, pa, prot, flags));
-
- if ((pte = pmap_grow_pte(pmap, va)) == NULL) {
- DPRINTF(PDB_ENTER, (" -> pmap_grow_pte failed\n"));
- if (flags & PMAP_CANFAIL) {
- splx(s);
- return (ENOMEM);
- } else
- panic("pmap_enter: unable to allocate PT");
- }
-
- opte = *pte;
- DPRINTF(PDB_ENTER, (" opte %08x", opte));
-
- /*
- * Enable cache, by default, if on physical memory, unless
- * PMAP_NC has been passed in pa.
- */
- switch (pa & PAGE_MASK) {
- case PMAP_NC:
- npte = PG_IO;
- break;
- case PMAP_BWS:
- npte = PG_BYTE_SHARED;
- break;
- default:
- if (pa >= PHYSMEM_BASE && pa < PHYSMEM_BASE + ptoa(physmem))
- npte = PG_CACHE;
- else
- npte = PG_IO;
- break;
- }
-
- pa = trunc_page(pa);
- npte |= pa | PG_V | (prot & PROT_WRITE ? PG_RW : PG_RO);
-
- pg = PHYS_TO_VM_PAGE(pa);
- if (pg != NULL) {
- /*
- * For a managed page, enter the mapping in the pvlist.
- */
- pvl = pg_to_pvl(pg);
-
- if (pvl->pv_pmap == NULL) {
- /*
- * We are the first mapping.
- */
- pvl->pv_pmap = pmap;
- pvl->pv_va = va;
- pvl->pv_next = NULL;
- } else {
- /*
- * Add ourselves to the list.
- * Note that, if we are only changing attributes
- * and/or protection, we are already in the list!
- */
- for (cur = pvl; cur != NULL; cur = cur->pv_next) {
- if (pmap == cur->pv_pmap && va == cur->pv_va)
- break;
- }
-
- if (cur == NULL) {
- cur = pool_get(&pvpool, PR_NOWAIT);
- if (cur == NULL) {
- if (flags & PMAP_CANFAIL) {
- splx(s);
- return (ENOMEM);
- } else
- panic("pmap_enter: "
- "pvlist pool exhausted");
- }
- /*
- * Add the new entry after the header.
- */
- cur->pv_pmap = pmap;
- cur->pv_va = va;
- cur->pv_flags = 0;
- cur->pv_next = pvl->pv_next;
- pvl->pv_next = cur;
- }
- }
- }
-
- if (flags & PMAP_WIRED) {
- npte |= PG_W;
- if ((opte & PG_W) == 0)
- pmap->pm_stats.wired_count++;
- } else {
- if ((opte & PG_W) != 0)
- pmap->pm_stats.wired_count--;
- }
- if ((opte & PG_V) == 0)
- pmap->pm_stats.resident_count++;
- if (pa >= VM_MIN_KERNEL_ADDRESS)
- npte |= PG_S;
-
- /*
- * Now update the pte.
- */
- if (opte != npte) {
- DPRINTF(PDB_ENTER, (" -> npte %08x", npte));
- *pte = npte;
- tlb_flush(va);
- }
-
- DPRINTF(PDB_ENTER, ("\n"));
-
- splx(s);
-
- return (0);
-}
-
-/*
- * Specific flavour of pmap_enter() for unmanaged wired mappings in the
- * kernel pmap.
- */
-void
-pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
-{
- pt_entry_t *pte, opte, npte;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_KENTER,
- ("pmap_kenter_pa(%08x,%08x,%x)", va, pa, prot));
-
- if ((pte = pmap_grow_pte(pmap_kernel(), va)) == NULL) {
- DPRINTF(PDB_KENTER, (" -> pmap_grow_pte failed\n"));
- panic("pmap_kenter_pa: unable to allocate PT");
- }
-
- opte = *pte;
- DPRINTF(PDB_KENTER, (" opte %08x", opte));
-
- /*
- * Enable cache, by default, if on physical memory, unless
- * PMAP_NC has been passed in pa.
- */
- switch (pa & PAGE_MASK) {
- case PMAP_NC:
- npte = PG_IO;
- break;
- case PMAP_BWS:
- npte = PG_BYTE_SHARED;
- break;
- default:
- if (pa >= PHYSMEM_BASE && pa < PHYSMEM_BASE + ptoa(physmem))
- npte = PG_CACHE;
- else
- npte = PG_IO;
- break;
- }
-
- pa = trunc_page(pa);
- npte |= pa | PG_V | PG_W | (prot & PROT_WRITE ? PG_RW : PG_RO);
-
- if ((opte & PG_W) == 0)
- pmap_kernel()->pm_stats.wired_count++;
- if ((opte & PG_V) == 0)
- pmap_kernel()->pm_stats.resident_count++;
- if (pa >= VM_MIN_KERNEL_ADDRESS)
- npte |= PG_S;
-
- /*
- * Now update the pte.
- */
- if (opte != npte) {
- DPRINTF(PDB_KENTER, (" -> npte %08x", npte));
- *pte = npte;
- tlb_flush(va);
- }
-
- DPRINTF(PDB_KENTER, ("\n"));
-
- splx(s);
-}
-
-/*
- * Specific flavour of pmap_remove for unmanaged wired mappings in the
- * kernel pmap.
- */
-void
-pmap_kremove(vaddr_t va, vsize_t len)
-{
- vaddr_t e, eva;
- pd_entry_t *pde;
- pt_entry_t *pte, opte;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_KREMOVE, ("pmap_kremove(%08x,%08x)\n", va, len));
-
- e = va + len;
- while (va != e) {
- pde = pmap_pde(pmap_kernel(), va);
- eva = trunc_seg(va) + NBSEG;
- if (eva > e || eva == 0)
- eva = e;
-
- if (pde == NULL) {
- va = eva;
- continue;
- }
-
- pte = pde_pte(pde, va);
- for (; va != eva; va += PAGE_SIZE, pte++) {
- opte = *pte;
- if ((opte & PG_V) == 0)
- continue;
-
- pmap_kernel()->pm_stats.resident_count--;
-
-#ifdef DIAGNOSTIC
- if (!(opte & PG_W)) {
- printf("pmap_kremove: non-wired mapping for %08x",
- va);
- } else
-#endif
- pmap_kernel()->pm_stats.wired_count--;
-
- *pte = PG_NV;
- tlb_flush(va);
- }
- }
-
- splx(s);
-}
-
-/*
- * Remove the wiring state of a page in the given pmap.
- */
-void
-pmap_unwire(struct pmap *pmap, vaddr_t va)
-{
- pt_entry_t *pte;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_UNWIRE, ("pmap_unwire(%p,%08x)\n", pmap, va));
-
- pte = pmap_pte(pmap, va);
-
- if (*pte & PG_V)
- if (*pte & PG_W) {
- pmap->pm_stats.wired_count--;
- /* No need to flush TLB, it's a software flag */
- *pte &= ~PG_W;
- }
-
- splx(s);
-}
-
-/*
- * Compute the physical address of a given virtual address in the given pmap.
- * If the physical address is not mapped by this pmap, FALSE is returned.
- */
-boolean_t
-pmap_extract(struct pmap *pmap, vaddr_t va, paddr_t *pap)
-{
- pt_entry_t *pte;
- paddr_t pa;
- boolean_t rv;
- int s;
-
- DPRINTF(PDB_EXTRACT, ("pmap_extract(%p,%08x)", pmap, va));
-
- s = splvm();
-
- pte = pmap_pte(pmap, va);
- if (pte != NULL && (*pte & PG_V) != 0) {
- rv = TRUE;
- pa = (*pte & PG_FRAME) | (va & PAGE_MASK);
- DPRINTF(PDB_EXTRACT, (" -> %08x\n", pa));
- if (pap != NULL)
- *pap = pa;
- } else {
- DPRINTF(PDB_EXTRACT, (" -> FALSE\n"));
- rv = FALSE;
- }
-
- splx(s);
-
- return (rv);
-}
-
-/*
- * Walk a vm_page and flush all existing mappings.
- */
-void
-pg_flushcache(struct vm_page *pg)
-{
- struct pvlist *pvl;
- int s;
-
- s = splvm();
-
- pvl = pg_to_pvl(pg);
- if (pvl->pv_pmap == NULL) {
- splx(s);
- return;
- }
-
- /*
- * Since cache_flush_page() causes the whole cache to be flushed,
- * there is no need to loop - flush once.
- */
- /* for (; pvl != NULL; pvl = pvl->pv_next) */
- cache_flush_page(pvl->pv_va);
-
- splx(s);
-}
-
-/*
- * Fill a vm_page with zeroes.
- */
-void
-pmap_zero_page(struct vm_page *pg)
-{
- paddr_t pa;
- vaddr_t va;
- pt_entry_t *pte;
- int s;
-
- s = splvm();
-
- pa = VM_PAGE_TO_PHYS(pg);
- va = vreserve;
- pte = ptereserve;
-
- DPRINTF(PDB_ZERO, ("pmap_zero_page(%p/pa %x) pte %p\n", pg, pa, pte));
-
- pg_flushcache(pg);
-
- *pte = PG_V | PG_S | (pa & PG_FRAME);
- tlb_flush(va);
-
- qzero((caddr_t)va, PAGE_SIZE);
- cache_flush_page(va);
-
- /* paranoia */
- *pte = PG_NV;
- tlb_flush(va);
-
- splx(s);
-}
-
-/*
- * Copy the contents of a vm_page to another.
- */
-void
-pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg)
-{
- paddr_t srcpa, dstpa;
- vaddr_t srcva, dstva;
- pt_entry_t *srcpte, *dstpte;
- int s;
-
- s = splvm();
-
- DPRINTF(PDB_COPY, ("pmap_copy_page(%p,%p)\n", srcpg, dstpg));
-
- srcpa = VM_PAGE_TO_PHYS(srcpg);
- dstpa = VM_PAGE_TO_PHYS(dstpg);
- srcva = vreserve;
- dstva = srcva + PAGE_SIZE;
-
- dstpte = ptereserve;
- srcpte = dstpte++;
-
- pg_flushcache(srcpg);
- /*
- * Since pg_flushcache() causes the whole cache to be flushed,
- * there is no need flush dstpg.
- */
- /* pg_flushcache(dstpg); */
-
- *srcpte = PG_V | PG_S | PG_RO | (srcpa & PG_FRAME);
- *dstpte = PG_V | PG_S | (dstpa & PG_FRAME);
-
- tlb_flush(srcva);
- tlb_flush(dstva);
-
- qcopy((caddr_t)srcva, (caddr_t)dstva, PAGE_SIZE);
- cache_flush_page(srcva);
-
- *srcpte = *dstpte = PG_NV;
- tlb_flush(srcva);
- tlb_flush(dstva);
-
- splx(s);
-}
-
-/*
- * Clear the modify bits on all mappings associated to the given vm_page.
- */
-boolean_t
-pmap_clear_modify(struct vm_page *pg)
-{
- struct pvlist *pvl;
- pt_entry_t *pte;
- boolean_t rv;
- int s;
- int flushed;
-
- s = splvm();
-
- pvl = pg_to_pvl(pg);
-
- DPRINTF(PDB_CLEAR_M,
- ("pmap_clear_modify(%p/pmap %p)\n", pg, pvl->pv_pmap));
-
- if (pvl->pv_flags & PG_M) {
- pvl->pv_flags &= ~PG_M;
- rv = TRUE;
- }
-
- if (pvl->pv_pmap != NULL) {
- flushed = 0;
- for (; pvl != NULL; pvl = pvl->pv_next) {
- pte = pmap_pte(pvl->pv_pmap, pvl->pv_va);
- if ((*pte & PG_V) != 0 && (*pte & PG_M) != 0) {
- /*
- * Since cache_flush_page() causes the whole
- * cache to be flushed, only flush once.
- */
- if (flushed == 0) {
- cache_flush_page(pvl->pv_va);
- flushed = 1;
- }
-
- rv = TRUE;
- /* No need to flush TLB, it's a software flag */
- *pte &= ~PG_M;
- }
- }
- }
-
- splx(s);
-
- return (rv);
-}
-
-/*
- * Clear the reference bits on all mappings associated to the given vm_page.
- */
-boolean_t
-pmap_clear_reference(struct vm_page *pg)
-{
- struct pvlist *pvl;
- pt_entry_t *pte;
- boolean_t rv;
- int s;
-
- s = splvm();
-
- pvl = pg_to_pvl(pg);
-
- DPRINTF(PDB_CLEAR_U,
- ("pmap_clear_reference(%p/pmap %p)\n", pg, pvl->pv_pmap));
-
- if (pvl->pv_flags & PG_U) {
- pvl->pv_flags &= ~PG_U;
- rv = TRUE;
- }
-
- if (pvl->pv_pmap != NULL)
- for (; pvl != NULL; pvl = pvl->pv_next) {
- pte = pmap_pte(pvl->pv_pmap, pvl->pv_va);
- if ((*pte & PG_V) != 0 && (*pte & PG_U) != 0) {
- rv = TRUE;
- /* No need to flush TLB, it's a software flag */
- *pte &= ~PG_U;
- }
- }
-
- splx(s);
-
- return (rv);
-}
-
-/*
- * Check the reference bit attribute for the given vm_page.
- */
-boolean_t
-pmap_is_referenced(struct vm_page *pg)
-{
- struct pvlist *pvl;
- boolean_t rv;
- int s;
-
- s = splvm();
-
- pvl = pg_to_pvl(pg);
- rv = (pvl->pv_flags & PG_U) != 0;
-
- DPRINTF(PDB_IS_U,
- ("pmap_is_referenced(%p/pmap %p) -> %d\n", pg, pvl->pv_pmap, rv));
-
- splx(s);
-
- return (rv);
-}
-
-/*
- * Check the modify bit attribute for the given vm_page.
- */
-boolean_t
-pmap_is_modified(struct vm_page *pg)
-{
- struct pvlist *pvl;
- boolean_t rv;
- int s;
-
- s = splvm();
-
- pvl = pg_to_pvl(pg);
- rv = (pvl->pv_flags & PG_M) != 0;
-
- DPRINTF(PDB_IS_M,
- ("pmap_is_modified(%p/pmap %p) -> %d\n", pg, pvl->pv_pmap, rv));
-
- splx(s);
-
- return (rv);
-}
-
-/*
- * Flush instruction cache on the given dirty area.
- *
- * The KAP is the only sparc implementation OpenBSD runs on with independent
- * instruction and data caches; for now, we won't add a function pointer
- * to the cpu structure, but will directly invoke the necessary operation.
- */
-void
-pmap_proc_iflush(struct proc *p, vaddr_t va, vsize_t len)
-{
- /* There is no way to invalidate a subset of the icache */
- sta(0, ASI_ICACHE_INVAL, 0);
-}
-
-/*
- * The following routines are not part of the MI pmap API, but are
- * necessary to use the common sparc code.
- */
-
-/*
- * Enable caching of the page tables if necessary.
- */
-void
-pmap_cache_enable()
-{
- /* nothing to do */
-}
-
-/*
- * Change the protection for a specific kernel mapping.
- * Used by machdep.c only.
- */
-void
-pmap_changeprot(struct pmap *pmap, vaddr_t va, vm_prot_t prot, int wired)
-{
- pt_entry_t *pte, npte;
- int s;
-
- s = splvm();
-
- npte = PG_S | (prot & PROT_WRITE ? PG_RW : PG_RO);
-
- pte = pmap_pte(pmap, va);
- if ((*pte & PG_PROT) != npte) {
- *pte = (*pte & ~PG_PROT) | npte;
- tlb_flush(va);
- }
-
- splx(s);
-}
-
-/*
- * Set a ``red zone'' below the kernel.
- */
-void
-pmap_redzone()
-{
-}
-
-/*
- * Write a given byte in a protected page; used by the ddb breakpoints.
- */
-void
-pmap_writetext(unsigned char *dst, int ch)
-{
- pt_entry_t *pte, opte;
- int s;
-
- /*
- * Check for a PTW hit first.
- */
- switch ((vaddr_t)dst >> PTW_WINDOW_SHIFT) {
- case PTW1_WINDOW:
- case PTW2_WINDOW:
- *dst = (unsigned char)ch;
- cpuinfo.cache_flush(dst, 1);
- return;
- }
-
- s = splvm();
-
- pte = pmap_pte(pmap_kernel(), (vaddr_t)dst);
- if (pte != NULL) {
- opte = *pte;
- if ((opte & PG_V) != 0) {
- cpuinfo.cache_flush(dst, 1);
-
- if ((opte & PG_RO) != 0) {
- *pte &= ~PG_RO;
- tlb_flush(trunc_page((vaddr_t)dst));
- }
-
- *dst = (unsigned char)ch;
-
- if ((opte & PG_RO) != 0) {
- *pte = opte;
- tlb_flush(trunc_page((vaddr_t)dst));
- }
-
- cpuinfo.cache_flush(dst, 1);
- }
- }
-
- splx(s);
-}
-
-/*
- * Enable or disable cache for the given number of pages at the given
- * virtual address.
- */
-void
-kvm_setcache(caddr_t addr, int npages, int cached)
-{
- pt_entry_t *pte, opte;
- vaddr_t va = (vaddr_t)addr;
- int s;
- int flushed;
-
-#ifdef DIAGNOSTIC
- if (va & PAGE_MASK) {
- printf("kvm_setcache: unaligned va %08x\n", va);
- va = trunc_page(va);
- }
-#endif
-
-#ifdef DIAGNOSTIC
- /*
- * Check for a PTW hit first.
- */
- switch (va >> PTW_WINDOW_SHIFT) {
- case PTW1_WINDOW:
- case PTW2_WINDOW:
- printf("kvm_setcache(%08x, %08x, %d) in a PTW\n",
- va, npages << PAGE_SHIFT, cached);
- return;
- }
-#endif
-
- s = splvm();
-
- pte = pmap_pte(pmap_kernel(), va);
- flushed = 0;
- for (; --npages >= 0; va += PAGE_SIZE, pte++) {
- opte = *pte & ~PG_MA;
-
- if (cached)
- opte |= PG_CACHE;
- else
- opte |= PG_IO;
-
- *pte = opte;
- tlb_flush(va);
-
- /*
- * Since cache_flush_page() causes the whole
- * cache to be flushed, only flush once.
- */
- if (flushed == 0) {
- cache_flush_page(va);
- flushed = 1;
- }
- }
-
- splx(s);
-}
-
-/*
- * Simple wrapper around pmap_kenter_pa() for multiple pages.
- */
-vaddr_t
-pmap_map(vaddr_t va, paddr_t pa, paddr_t epa, int prot)
-{
- while (pa < epa) {
- pmap_kenter_pa(va, pa, (vm_prot_t)prot);
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- }
- return (va);
-}
-
-/*
- * Checks whether a given physical address is in physical memory or
- * in device space.
- * Used by mem.c.
- */
-int
-pmap_pa_exists(paddr_t pa)
-{
- return (pa >= PHYSMEM_BASE && pa < PHYSMEM_BASE + ptoa(physmem));
-}
diff --git a/sys/arch/solbourne/solbourne/prom_machdep.c b/sys/arch/solbourne/solbourne/prom_machdep.c
deleted file mode 100644
index 25eb21d8a63..00000000000
--- a/sys/arch/solbourne/solbourne/prom_machdep.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* $OpenBSD: prom_machdep.c,v 1.1 2005/04/19 21:30:18 miod Exp $ */
-/*
- * Copyright (c) 2005, Miodrag Vallat
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Routines to hide the Solbourne PROM specifics.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <machine/autoconf.h>
-#include <machine/bsd_openprom.h> /* romboot() prototype */
-#include <machine/idt.h>
-#include <machine/kap.h>
-#include <machine/prom.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <sparc/sparc/asm.h>
-
-int sysmodel;
-
-void myetheraddr(u_char *);
-void prom_map(void);
-void prom_unmap(void);
-
-extern void tlb_flush_all(void);
-
-/*
- * Lookup a variable in the environment strings.
- */
-const char *
-prom_getenv(const char *var)
-{
- u_int i;
- const char *eq, *env;
- size_t len;
- extern char **prom_environ;
-
- len = strlen(var);
-
- for (i = 0; (env = prom_environ[i]) != NULL; i++) {
- eq = strchr(env, '=');
-#ifdef DIAGNOSTIC
- if (eq == NULL)
- continue; /* can't happen */
-#endif
- if (eq - env != len)
- continue;
-
- if (strncasecmp(var, env, len) == 0) {
- return (eq + 1);
- }
- }
-
- return (NULL);
-}
-
-void
-myetheraddr(u_char *cp)
-{
- const char *enetaddr;
- int i;
-
- enetaddr = prom_getenv(ENV_ETHERADDR);
- if (enetaddr == NULL) {
- cp[0] = cp[1] = cp[2] = cp[3] = cp[4] = cp[5] = 0xff;
- } else {
- for (i = 0; i < 6; i++) {
- cp[i] = 0;
- for (;;) {
- if (*enetaddr >= '0' && *enetaddr <= '9')
- cp[i] = cp[i] * 0x10 +
- (*enetaddr - '0');
- else if (*enetaddr >= 'A' && *enetaddr <= 'F')
- cp[i] = cp[i] * 0x10 +
- (*enetaddr + 10 - 'A');
- else if (*enetaddr >= 'a' && *enetaddr <= 'f')
- cp[i] = cp[i] * 0x10 +
- (*enetaddr + 10 - 'a');
- else
- break;
-
- enetaddr++;
- }
- if (*enetaddr++ != ':')
- break;
- }
- /* fill remaining digits if necessary */
- while (i++ < 6)
- cp[i] = 0;
- }
-}
-
-/*
- * Set up PROM-friendly mappings
- */
-
-void
-prom_map(void)
-{
- sta(0, ASI_PTW0, PTW0_DEFAULT);
- tlb_flush_all();
-}
-
-void
-prom_unmap(void)
-{
- sta(0, ASI_PTW0, 0);
- tlb_flush_all();
-}
-
-/*
- * Prom property access
- *
- * Note that if we are passed addresses in the fd va window, we need to
- * temporarily copy these pointers to a ``safe'' address (in this case,
- * a global variable, thus in the f0 or f1 window).
- */
-
-int
-getprop(int node, char *name, void *buf, int bufsiz)
-{
- struct prom_node *n = (struct prom_node *)node;
- struct prom_prop *p;
- char *propname, *eq;
- int len, proplen;
-
- len = strlen(name);
-
-#ifdef DIAGNOSTIC
- if (node == 0)
-#if 0
- node = findroot();
-#else
- panic("getprop(%s) invoked on invalid node", name);
-#endif
-#endif
-
- for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
- propname = p->pp_data;
- eq = strchr(propname, '=');
-#ifdef DIAGNOSTIC
- if (eq == NULL)
- continue; /* can't happen */
-#endif
- if (eq - propname != len)
- continue;
-
- if (strncmp(name, propname, len) == 0) {
- proplen = p->pp_size;
- if (proplen > bufsiz) {
- printf("node %p property %s length %d > %d",
- node, name, proplen, bufsiz);
-#ifdef DEBUG
- panic("getprop");
-#else
- return (0);
-#endif
- } else
- bcopy(eq + 1, buf, proplen);
- break;
- }
- }
-
- if (p == NULL)
- proplen = -1;
-
- return (proplen);
-}
-
-int
-getproplen(int node, char *name)
-{
- struct prom_node *n = (struct prom_node *)node;
- struct prom_prop *p;
- char *propname, *eq;
- int len, proplen;
-
-#ifdef DIAGNOSTIC
- if (node == 0)
- panic("getproplen(%s) invoked on invalid node", name);
-#endif
-
- len = strlen(name);
-
- for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
- propname = p->pp_data;
- eq = strchr(propname, '=');
-#ifdef DIAGNOSTIC
- if (eq == NULL)
- continue; /* can't happen */
-#endif
- if (eq - propname != len)
- continue;
-
- if (strncmp(name, propname, len) == 0) {
- proplen = p->pp_size;
- break;
- }
- }
-
- if (p == NULL)
- proplen = -1;
-
- return (proplen);
-}
-
-int
-firstchild(int node)
-{
- return ((struct prom_node *)node)->pn_child;
-}
-
-int
-nextsibling(int node)
-{
- if (node == 0)
- return (findroot());
- else
- return (((struct prom_node *)node)->pn_sibling);
-}
-
-int
-findroot()
-{
- struct sb_prom *sp;
-
- sp = (struct sb_prom *)PROM_DATA_VA;
- if (sp->sp_interface >= PROM_INTERFACE)
- return (sp->sp_rootnode);
-
- panic("findroot: PROM communication interface is too old (%d)",
- sp->sp_interface);
- /* NOTREACHED */
-}
-
-/*
- * Shutdown and reboot interface
- */
-
-void
-romhalt()
-{
- struct sb_prom *sp;
-
- sp = (struct sb_prom *)PROM_DATA_VA;
- if (sp->sp_interface >= PROM_INTERFACE) {
- prom_map();
- (*sp->sp_interp)("reset " PROM_RESET_HALT);
- prom_unmap();
- }
-
- panic("PROM exit failed");
-}
-
-void
-romboot(char *str)
-{
- char command[256];
- struct sb_prom *sp;
-
- if (*str != '\0') {
- strlcpy(command, "boot ", sizeof command);
- strlcat(command, str, sizeof command);
- } else {
- strlcpy(command, "reset ", sizeof command);
- strlcat(command, PROM_RESET_WARM, sizeof command);
- }
-
- sp = (struct sb_prom *)PROM_DATA_VA;
- if (sp->sp_interface >= PROM_INTERFACE) {
- prom_map();
- (*sp->sp_interp)(command);
- prom_unmap();
- }
-
- panic("PROM boot failed");
-}
diff --git a/sys/arch/solbourne/solbourne/trap.c b/sys/arch/solbourne/solbourne/trap.c
deleted file mode 100644
index 798773463aa..00000000000
--- a/sys/arch/solbourne/solbourne/trap.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/* $OpenBSD: trap.c,v 1.22 2014/11/16 12:30:58 deraadt Exp $ */
-/* OpenBSD: trap.c,v 1.42 2004/12/06 20:12:25 miod Exp */
-
-/*
- * Copyright (c) 1996
- * The President and Fellows of Harvard College. All rights reserved.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- * This product includes software developed by Harvard University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * This product includes software developed by Harvard University.
- * 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.
- *
- * @(#)trap.c 8.4 (Berkeley) 9/23/93
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/user.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/resource.h>
-#include <sys/signal.h>
-#include <sys/wait.h>
-#include <sys/syscall.h>
-#include <sys/syscall_mi.h>
-#include <sys/syslog.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <sparc/sparc/asm.h>
-#include <machine/cpu.h>
-#include <machine/ctlreg.h>
-#include <machine/trap.h>
-#include <machine/instr.h>
-#include <machine/pmap.h>
-
-#include <machine/idt.h>
-#include <machine/kap.h>
-
-#ifdef DDB
-#include <machine/db_machdep.h>
-#else
-#include <machine/frame.h>
-#endif
-
-#include <sparc/fpu/fpu_extern.h>
-#include <sparc/sparc/memreg.h>
-#include <sparc/sparc/cpuvar.h>
-
-#ifdef DEBUG
-int rwindow_debug = 0;
-#endif
-
-/*
- * Initial FPU state is all registers == all 1s, everything else == all 0s.
- * This makes every floating point register a signalling NaN, with sign bit
- * set, no matter how it is interpreted. Appendix N of the Sparc V8 document
- * seems to imply that we should do this, and it does make sense.
- */
-struct fpstate initfpstate = {
- { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
- ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 }
-};
-
-/*
- * There are more than 100 trap types, but most are unused.
- *
- * Trap type 0 is taken over as an `Asynchronous System Trap'.
- * This is left-over Vax emulation crap that should be fixed.
- *
- * Note that some of the Sparc v8 traps are actually handled by
- * the corresponding v7 routine, but listed here for completeness.
- * The Fujitsu Turbo-Sparc Guide also alludes to several more
- * unimplemented trap types, but doesn't give the nominal coding.
- */
-static const char T[] = "trap";
-const char *trap_type[] = {
- /* non-user vectors */
- "ast", /* 0 */
- "text fault", /* 1 */
- "illegal instruction", /* 2 */
- "privileged instruction",/*3 */
- "fp disabled", /* 4 */
- "window overflow", /* 5 */
- "window underflow", /* 6 */
- "alignment fault", /* 7 */
- "fp exception", /* 8 */
- "data fault", /* 9 */
- "tag overflow", /* 0a */
- "watchpoint", /* 0b */
- T, T, T, T, T, /* 0c..10 */
- "level 1 int", /* 11 */
- "level 2 int", /* 12 */
- "level 3 int", /* 13 */
- "level 4 int", /* 14 */
- "level 5 int", /* 15 */
- "level 6 int", /* 16 */
- "level 7 int", /* 17 */
- "level 8 int", /* 18 */
- "level 9 int", /* 19 */
- "level 10 int", /* 1a */
- "level 11 int", /* 1b */
- "level 12 int", /* 1c */
- "level 13 int", /* 1d */
- "level 14 int", /* 1e */
- "level 15 int", /* 1f */
- "double trap", /* 20 */
- "v8 text error", /* 21 */
- T, T, /* 22..23 */
- "v8 cp disabled", /* 24 */
- "v8 unimp flush", /* 25 */
- T, T, /* 26..27 */
- "v8 cp exception", /* 28 */
- "v8 data error", /* 29 */
- "v8 idiv by zero", /* 2a */
- "v8 store error", /* 2b */
- "dtlb miss", /* 2c */
- T, T, T, /* 2d..2f */
- T, T, T, T, T, T, T, T, /* 30..37 */
- T, T, T, T, /* 38..3b */
- "itlb miss", /* 3c */
- T, T, T, /* 3d..3f */
- T, T, T, T, T, T, T, T, /* 40..48 */
- T, T, T, T, T, T, T, T, /* 48..4f */
- T, T, T, T, T, T, T, T, /* 50..57 */
- T, T, T, T, T, T, T, T, /* 58..5f */
- T, T, T, T, T, T, T, T, /* 60..67 */
- T, T, T, T, T, T, T, T, /* 68..6f */
- T, T, T, T, T, T, T, T, /* 70..77 */
- T, T, T, T, T, T, T, T, /* 78..7f */
-
- /* user (software trap) vectors */
- "syscall", /* 80 */
- "breakpoint", /* 81 */
- "zero divide", /* 82 */
- "flush windows", /* 83 */
- "clean windows", /* 84 */
- "range check", /* 85 */
- "fix align", /* 86 */
- "integer overflow", /* 87 */
- "svr4 syscall", /* 88 */
- "4.4 syscall", /* 89 */
- "kgdb exec", /* 8a */
- T, T, T, T, T, /* 8b..8f */
- T, T, T, T, T, T, T, T, /* 9a..97 */
- T, T, T, T, T, T, T, T, /* 98..9f */
- "svr4 getcc", /* a0 */
- "svr4 setcc", /* a1 */
- "svr4 getpsr", /* a2 */
- "svr4 setpsr", /* a3 */
- "svr4 gethrtime", /* a4 */
- "svr4 gethrvtime", /* a5 */
- T, /* a6 */
- "svr4 gethrestime", /* a7 */
-};
-
-#define N_TRAP_TYPES (sizeof trap_type / sizeof *trap_type)
-
-void trap(unsigned, int, int, struct trapframe *);
-static __inline void share_fpu(struct proc *, struct trapframe *);
-void mem_access_fault(unsigned, int, u_int, int, int, struct trapframe *);
-void ecc_fault(unsigned, int, u_int, int, int, struct trapframe *);
-void syscall(register_t, struct trapframe *, register_t);
-
-int ignore_bogus_traps = 0;
-
-int want_ast = 0;
-
-/*
- * If someone stole the FPU while we were away, do not enable it
- * on return. This is not done in userret() above as it must follow
- * the ktrsysret() in syscall(). Actually, it is likely that the
- * ktrsysret should occur before the call to userret.
- */
-static __inline void share_fpu(p, tf)
- struct proc *p;
- struct trapframe *tf;
-{
- if ((tf->tf_psr & PSR_EF) != 0 && cpuinfo.fpproc != p)
- tf->tf_psr &= ~PSR_EF;
-}
-
-/*
- * Called from locore.s trap handling, for non-MMU-related traps.
- * (MMU-related traps go through mem_access_fault, below.)
- */
-void
-trap(type, psr, pc, tf)
- unsigned type;
- int psr, pc;
- struct trapframe *tf;
-{
- struct proc *p;
- struct pcb *pcb;
- int n;
- union sigval sv;
-
- sv.sival_int = pc; /* XXX fix for parm five of trapsignal() */
-
- /* This steps the PC over the trap. */
-#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
-
- uvmexp.traps++;
- /*
- * Generally, kernel traps cause a panic. Any exceptions are
- * handled early here.
- */
- if (psr & PSR_PS) {
-#ifdef DDB
- if (type == T_BREAKPOINT) {
- write_all_windows();
- if (kdb_trap(type, tf)) {
- return;
- }
- }
-#endif
-#ifdef DIAGNOSTIC
- /*
- * Currently, we allow DIAGNOSTIC kernel code to
- * flush the windows to record stack traces.
- */
- if (type == T_FLUSHWIN) {
- write_all_windows();
- ADVANCE;
- return;
- }
-#endif
- /*
- * Storing %fsr in cpu_attach will cause this trap
- * even though the fpu has been enabled, if and only
- * if there is no FPU.
- */
- if (type == T_FPDISABLED && cold) {
- ADVANCE;
- return;
- }
- dopanic:
- printf("trap type 0x%x: pc=0x%x npc=0x%x psr=%b\n",
- type, pc, tf->tf_npc, psr, PSR_BITS);
- if (type == T_RREGERROR) /* 0x20 double fault */
- printf("fcr %b fvar %08x fpar %08x fpsr %08x pdbr %08x\n",
- lda(0, ASI_FCR), FCR_BITS, lda(0, ASI_FPAR),
- lda(0, ASI_FPSR), lda(0, ASI_PDBR));
- panic(type < N_TRAP_TYPES ? trap_type[type] : T);
- /* NOTREACHED */
- }
- if ((p = curproc) == NULL)
- p = &proc0;
- pcb = &p->p_addr->u_pcb;
- p->p_md.md_tf = tf; /* for ptrace/signals */
- refreshcreds(p);
-
- switch (type) {
-
- default:
- if (type < 0x80) {
- if (!ignore_bogus_traps)
- goto dopanic;
- printf("trap type 0x%x: pc=0x%x npc=0x%x psr=%b\n",
- type, pc, tf->tf_npc, psr, PSR_BITS);
- trapsignal(p, SIGILL, type, ILL_ILLOPC, sv);
- break;
- }
- /* the following message is gratuitous */
- /* ... but leave it in until we find anything */
- printf("%s[%d]: unimplemented software trap 0x%x\n",
- p->p_comm, p->p_pid, type);
- trapsignal(p, SIGILL, type, ILL_ILLOPC, sv);
- break;
-
- case T_AST:
- want_ast = 0;
- uvmexp.softs++;
- mi_ast(p, want_resched);
- break;
-
- case T_ILLINST:
- if ((n = emulinstr(pc, tf)) == 0) {
- ADVANCE;
- break;
- }
- trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv);
- break;
-
- case T_PRIVINST:
- trapsignal(p, SIGILL, 0, ILL_PRVOPC, sv);
- break;
-
- case T_FPDISABLED: {
- struct fpstate *fs = p->p_md.md_fpstate;
-
- if (fs == NULL) {
- fs = malloc(sizeof *fs, M_SUBPROC, M_WAITOK);
- *fs = initfpstate;
- p->p_md.md_fpstate = fs;
- }
- /*
- * If we have not found an FPU, we have to emulate it.
- */
- if (!foundfpu) {
-#ifdef notyet
- fpu_emulate(p, tf, fs);
- break;
-#else
- trapsignal(p, SIGFPE, 0, FPE_FLTINV, sv);
- break;
-#endif
- }
- /*
- * We may have more FPEs stored up and/or ops queued.
- * If they exist, handle them and get out. Otherwise,
- * resolve the FPU state, turn it on, and try again.
- */
- if (fs->fs_qsize) {
- fpu_cleanup(p, fs);
- break;
- }
- if (cpuinfo.fpproc != p) { /* we do not have it */
- if (cpuinfo.fpproc != NULL) /* someone else had it */
- savefpstate(cpuinfo.fpproc->p_md.md_fpstate);
- loadfpstate(fs);
- cpuinfo.fpproc = p; /* now we do have it */
- uvmexp.fpswtch++;
- }
- tf->tf_psr |= PSR_EF;
- break;
- }
-
- case T_WINOF:
- if (rwindow_save(p))
- sigexit(p, SIGILL);
- break;
-
-#define read_rw(src, dst) \
- copyin((caddr_t)(src), (caddr_t)(dst), sizeof(struct rwindow))
-
- case T_RWRET:
- /*
- * T_RWRET is a window load needed in order to rett.
- * It simply needs the window to which tf->tf_out[6]
- * (%sp) points. There are no user or saved windows now.
- * Copy the one from %sp into pcb->pcb_rw[0] and set
- * nsaved to -1. If we decide to deliver a signal on
- * our way out, we will clear nsaved.
- */
- if (pcb->pcb_uw || pcb->pcb_nsaved)
- panic("trap T_RWRET 1");
-#ifdef DEBUG
- if (rwindow_debug)
- printf("%s[%d]: rwindow: pcb<-stack: 0x%x\n",
- p->p_comm, p->p_pid, tf->tf_out[6]);
-#endif
- if (read_rw(tf->tf_out[6], &pcb->pcb_rw[0]))
- sigexit(p, SIGILL);
- if (pcb->pcb_nsaved)
- panic("trap T_RWRET 2");
- pcb->pcb_nsaved = -1; /* mark success */
- break;
-
- case T_WINUF:
- /*
- * T_WINUF is a real window underflow, from a restore
- * instruction. It needs to have the contents of two
- * windows---the one belonging to the restore instruction
- * itself, which is at its %sp, and the one belonging to
- * the window above, which is at its %fp or %i6---both
- * in the pcb. The restore's window may still be in
- * the cpu; we need to force it out to the stack.
- */
-#ifdef DEBUG
- if (rwindow_debug)
- printf("%s[%d]: rwindow: T_WINUF 0: pcb<-stack: 0x%x\n",
- p->p_comm, p->p_pid, tf->tf_out[6]);
-#endif
- write_user_windows();
- if (rwindow_save(p) || read_rw(tf->tf_out[6], &pcb->pcb_rw[0]))
- sigexit(p, SIGILL);
-#ifdef DEBUG
- if (rwindow_debug)
- printf("%s[%d]: rwindow: T_WINUF 1: pcb<-stack: 0x%x\n",
- p->p_comm, p->p_pid, pcb->pcb_rw[0].rw_in[6]);
-#endif
- if (read_rw(pcb->pcb_rw[0].rw_in[6], &pcb->pcb_rw[1]))
- sigexit(p, SIGILL);
- if (pcb->pcb_nsaved)
- panic("trap T_WINUF");
- pcb->pcb_nsaved = -1; /* mark success */
- break;
-
- case T_ALIGN:
- if ((p->p_md.md_flags & MDP_FIXALIGN) != 0 &&
- fixalign(p, tf) == 0) {
- ADVANCE;
- break;
- }
- trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv);
- break;
-
- case T_FPE:
- /*
- * Clean up after a floating point exception.
- * fpu_cleanup can (and usually does) modify the
- * state we save here, so we must `give up' the FPU
- * chip context. (The software and hardware states
- * will not match once fpu_cleanup does its job, so
- * we must not save again later.)
- */
- if (p != cpuinfo.fpproc)
- panic("fpe without being the FP user");
- savefpstate(p->p_md.md_fpstate);
- cpuinfo.fpproc = NULL;
- /* tf->tf_psr &= ~PSR_EF; */ /* share_fpu will do this */
- fpu_cleanup(p, p->p_md.md_fpstate);
- /* fpu_cleanup posts signals if needed */
-#if 0 /* ??? really never??? */
- ADVANCE;
-#endif
- break;
-
- case T_TAGOF:
- trapsignal(p, SIGEMT, 0, EMT_TAGOVF, sv);
- break;
-
- case T_CPDISABLED:
- uprintf("coprocessor instruction\n"); /* XXX */
- trapsignal(p, SIGILL, 0, ILL_COPROC, sv);
- break;
-
- case T_BREAKPOINT:
- trapsignal(p, SIGTRAP, 0, TRAP_BRKPT, sv);
- break;
-
- case T_DIV0:
- case T_IDIV0:
- ADVANCE;
- trapsignal(p, SIGFPE, 0, FPE_INTDIV, sv);
- break;
-
- case T_FLUSHWIN:
- write_user_windows();
-#ifdef probably_slower_since_this_is_usually_false
- if (pcb->pcb_nsaved && rwindow_save(p))
- sigexit(p, SIGILL);
-#endif
- ADVANCE;
- break;
-
- case T_CLEANWIN:
- uprintf("T_CLEANWIN\n"); /* XXX */
- ADVANCE;
- break;
-
- case T_RANGECHECK:
- uprintf("T_RANGECHECK\n"); /* XXX */
- ADVANCE;
- trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv);
- break;
-
- case T_FIXALIGN:
-#ifdef DEBUG_ALIGN
- uprintf("T_FIXALIGN\n");
-#endif
- /* User wants us to fix alignment faults */
- p->p_md.md_flags |= MDP_FIXALIGN;
- ADVANCE;
- break;
-
- case T_INTOF:
- uprintf("T_INTOF\n"); /* XXX */
- ADVANCE;
- trapsignal(p, SIGFPE, FPE_INTOVF_TRAP, FPE_INTOVF, sv);
- break;
- }
- userret(p);
- share_fpu(p, tf);
-#undef ADVANCE
-}
-
-/*
- * Save windows from PCB into user stack, and return 0. This is used on
- * window overflow pseudo-traps (from locore.s, just before returning to
- * user mode) and when ptrace or sendsig needs a consistent state.
- * As a side effect, rwindow_save() always sets pcb_nsaved to 0,
- * clobbering the `underflow restore' indicator if it was -1.
- *
- * If the windows cannot be saved, pcb_nsaved is restored and we return -1.
- */
-int
-rwindow_save(p)
- struct proc *p;
-{
- struct pcb *pcb = &p->p_addr->u_pcb;
- struct rwindow *rw = &pcb->pcb_rw[0];
- int i;
-
- i = pcb->pcb_nsaved;
- if (i < 0) {
- pcb->pcb_nsaved = 0;
- return (0);
- }
- if (i == 0)
- return (0);
-#ifdef DEBUG
- if (rwindow_debug)
- printf("%s[%d]: rwindow: pcb->stack:", p->p_comm, p->p_pid);
-#endif
- do {
-#ifdef DEBUG
- if (rwindow_debug)
- printf(" 0x%x", rw[1].rw_in[6]);
-#endif
- if (copyout((caddr_t)rw, (caddr_t)rw[1].rw_in[6],
- sizeof *rw))
- return (-1);
- rw++;
- } while (--i > 0);
-#ifdef DEBUG
- if (rwindow_debug)
- printf("\n");
-#endif
- pcb->pcb_nsaved = 0;
- return (0);
-}
-
-/*
- * Kill user windows (before exec) by writing back to stack or pcb
- * and then erasing any pcb tracks. Otherwise we might try to write
- * the registers into the new process after the exec.
- */
-void
-pmap_unuse_final(p)
- struct proc *p;
-{
-
- write_user_windows();
- p->p_addr->u_pcb.pcb_nsaved = 0;
-}
-
-/*
- * Called from locore.s trap handling, for synchronous memory faults.
- *
- * This duplicates a lot of logic in trap() and perhaps should be
- * moved there; but the bus-error-register parameters are unique to
- * this routine.
- *
- * Since synchronous errors accumulate during prefetch, we can have
- * more than one `cause'. But we do not care what the cause, here;
- * we just want to page in the page and try again.
- */
-void
-mem_access_fault(type, ser, v, pc, psr, tf)
- unsigned type;
- int ser;
- u_int v;
- int pc, psr;
- struct trapframe *tf;
-{
- struct proc *p;
- struct vmspace *vm;
- vaddr_t va;
- int rv;
- vm_prot_t ftype;
- int onfault;
- union sigval sv;
- u_int isr;
-
- uvmexp.traps++;
- if ((p = curproc) == NULL) /* safety check */
- p = &proc0;
-
- if (type == T_DATAFAULT && (ser & FCR_EXTERNAL) != 0) {
- /*
- * For external faults, check the iCU status.
- */
-
- isr = lda(ICU_ISR, ASI_PHYS_IO);
-
- /*
- * Sometimes the interrupt register is empty... and I have
- * no idea what we are supposed to do in such situations.
- */
- if (isr == 0) {
-#ifdef DEBUG
- printf("external data fault, fcr %b pc %08x fvar %08x fpar %08x fpsr %08x pdbr %08x\n",
- ser, FCR_BITS, pc, v, lda(0, ASI_FPAR), lda(0, ASI_FPSR), lda(0, ASI_PDBR));
-#ifdef DDB
- Debugger();
-#endif
-#endif
- ser &= ~FCR_EXTERNAL;
- if (ser == 0)
- goto out;
- } else {
- /*
- * This is either an unrecoverable DMA or ECC error,
- * or a bus timeout.
- * XXX should restart the operation if retry timeout.
- */
- panic("data fault: fcr %b isr %b pc %08x addr %08x fpar %08x fpsr %08x",
- ser, FCR_BITS, isr, ISR_BITS,
- pc, v, lda(0, ASI_FPAR), lda(0, ASI_FPSR));
- }
- }
-
- /*
- * Figure out what to pass the VM code, and ignore the sva register
- * value in v on text faults (text faults are always at pc).
- * Kernel faults are somewhat different: text faults are always
- * illegal, and data faults are extra complex. User faults must
- * set p->p_md.md_tf, in case we decide to deliver a signal. Check
- * for illegal virtual addresses early since those can induce more
- * faults.
- */
- if (type == T_TEXTFAULT)
- v = pc;
- ftype = ser & FCR_RO ? PROT_WRITE : PROT_READ;
- va = trunc_page(v);
- if (psr & PSR_PS) {
- if (type == T_TEXTFAULT) {
- /*
- * If we are trying to figure on which processor mask
- * we run, we might trigger a text fault with
- * pcb_onfault set.
- * This is normal; don't panic there.
- */
- if (cold && p->p_addr->u_pcb.pcb_onfault != NULL)
- goto kfault;
- (void) splhigh();
- printf("text fault: pc=0x%x fcr=%b\n", pc,
- ser, FCR_BITS);
- panic("kernel fault");
- /* NOTREACHED */
- }
-
- /*
- * During autoconfiguration, faults are never OK unless
- * pcb_onfault is set. Once running normally we must allow
- * exec() to cause copy-on-write faults to kernel addresses.
- */
- if (cold)
- goto kfault;
- if (va >= VM_MIN_KERNEL_ADDRESS) {
- if (uvm_fault(kernel_map, va, 0, ftype) == 0)
- return;
- goto kfault;
- }
- } else
- p->p_md.md_tf = tf;
-
- vm = p->p_vmspace;
- rv = uvm_fault(&vm->vm_map, (vaddr_t)va, 0, ftype);
-
- /*
- * 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 ((caddr_t)va >= vm->vm_maxsaddr) {
- if (rv == 0)
- uvm_grow(p, va);
- else if (rv == EACCES)
- rv = EFAULT;
- }
- if (rv != 0) {
- /*
- * If doing copyin/out, return to onfault address. Any
- * other page fault in kernel, die; if user fault, deliver
- * SIGSEGV.
- */
- if (psr & PSR_PS) {
-kfault:
- onfault = p->p_addr ?
- (int)p->p_addr->u_pcb.pcb_onfault : 0;
- if (!onfault) {
- (void) splhigh();
- printf("data fault: pc=0x%x addr=0x%x fcr=%b\n",
- pc, v, ser, FCR_BITS);
- panic("kernel fault");
- /* NOTREACHED */
- }
- tf->tf_pc = onfault;
- tf->tf_npc = onfault + 4;
- return;
- }
-
- sv.sival_int = v;
- trapsignal(p, SIGSEGV, (ser & FCR_RO) ? PROT_WRITE :
- PROT_READ, SEGV_MAPERR, sv);
- }
-out:
- if ((psr & PSR_PS) == 0) {
- userret(p);
- share_fpu(p, tf);
- }
-}
-
-void
-ecc_fault(type, ser, v, pc, psr, tf)
- unsigned type;
- int ser;
- u_int v;
- int pc, psr;
- struct trapframe *tf;
-{
- /* XXX */
- panic("ecc_fault");
-}
-
-/*
- * System calls. `pc' is just a copy of tf->tf_pc.
- *
- * Note that the things labelled `out' registers in the trapframe were the
- * `in' registers within the syscall trap code (because of the automatic
- * `save' effect of each trap). They are, however, the %o registers of the
- * thing that made the system call, and are named that way here.
- */
-void
-syscall(code, tf, pc)
- register_t code;
- struct trapframe *tf;
- register_t pc;
-{
- int i, nsys, *ap, nap;
- struct sysent *callp;
- struct proc *p;
- int error, new;
- struct args {
- register_t i[8];
- } args;
- register_t rval[2];
-#ifdef DIAGNOSTIC
- extern struct pcb *cpcb;
-#endif
-
- uvmexp.syscalls++;
- p = curproc;
-#ifdef DIAGNOSTIC
- if (tf->tf_psr & PSR_PS)
- panic("syscall");
- if (cpcb != &p->p_addr->u_pcb)
- panic("syscall cpcb/ppcb");
- if (tf != (struct trapframe *)((caddr_t)cpcb + USPACE) - 1)
- panic("syscall trapframe");
-#endif
- p->p_md.md_tf = tf;
- new = code & (SYSCALL_G7RFLAG | SYSCALL_G2RFLAG);
- code &= ~(SYSCALL_G7RFLAG | SYSCALL_G2RFLAG);
-
- callp = p->p_p->ps_emul->e_sysent;
- nsys = p->p_p->ps_emul->e_nsysent;
-
- /*
- * The first six system call arguments are in the six %o registers.
- * Any arguments beyond that are in the `argument extension' area
- * of the user's stack frame (see <machine/frame.h>).
- *
- * Check for ``special'' codes that alter this, namely syscall and
- * __syscall. The latter takes a quad syscall number, so that other
- * arguments are at their natural alignments. Adjust the number
- * of ``easy'' arguments as appropriate; we will copy the hard
- * ones later as needed.
- */
- ap = &tf->tf_out[0];
- nap = 6;
-
- switch (code) {
- case SYS_syscall:
- code = *ap++;
- nap--;
- break;
- case SYS___syscall:
- if (callp != sysent)
- break;
- code = ap[_QUAD_LOWWORD];
- ap += 2;
- nap -= 2;
- break;
- }
-
- if (code < 0 || code >= nsys)
- callp += p->p_p->ps_emul->e_nosys;
- else {
- callp += code;
- i = callp->sy_argsize / sizeof(register_t);
- if (i > nap) { /* usually false */
- if (i > 8)
- panic("syscall nargs");
- if ((error = copyin((caddr_t)tf->tf_out[6] +
- offsetof(struct frame, fr_argx),
- &args.i[nap], (i - nap) * sizeof(register_t))))
- goto bad;
- i = nap;
- }
- if (error == 0)
- copywords(ap, args.i, i * sizeof(register_t));
- }
-
- rval[0] = 0;
- rval[1] = tf->tf_out[1];
-
- error = mi_syscall(p, code, callp, args.i, rval);
-
- switch (error) {
- case 0:
- /* Note: fork() does not return here in the child */
- tf->tf_out[0] = rval[0];
- tf->tf_out[1] = rval[1];
- if (new) {
- /* jmp %g2 (or %g7, deprecated) on success */
- i = tf->tf_global[new & SYSCALL_G2RFLAG ? 2 : 7];
- if (i & 3) {
- error = EINVAL;
- goto bad;
- }
- } else {
- /* old system call convention: clear C on success */
- tf->tf_psr &= ~PSR_C; /* success */
- i = tf->tf_npc;
- }
- tf->tf_pc = i;
- tf->tf_npc = i + 4;
- break;
-
- case ERESTART:
- case EJUSTRETURN:
- /* nothing to do */
- break;
-
- default:
- bad:
- tf->tf_out[0] = error;
- tf->tf_psr |= PSR_C; /* fail */
- i = tf->tf_npc;
- tf->tf_pc = i;
- tf->tf_npc = i + 4;
- break;
- }
-
- mi_syscall_return(p, code, error, rval);
-
- share_fpu(p, tf);
-}
-
-/*
- * Process the tail end of a fork() for the child.
- */
-void
-child_return(arg)
- void *arg;
-{
- struct proc *p = arg;
- struct trapframe *tf = p->p_md.md_tf;
-
- /*
- * Return values in the frame set by cpu_fork().
- */
- tf->tf_out[0] = 0;
- tf->tf_out[1] = 0;
- tf->tf_psr &= ~PSR_C;
-
- mi_child_return(p);
-}