aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/autoconf.c109
-rw-r--r--sys/alpha/alpha/clock.c355
-rw-r--r--sys/alpha/alpha/cons.c448
-rw-r--r--sys/alpha/alpha/cpuconf.c161
-rw-r--r--sys/alpha/alpha/db_disasm.c1095
-rw-r--r--sys/alpha/alpha/db_instruction.h672
-rw-r--r--sys/alpha/alpha/db_interface.c536
-rw-r--r--sys/alpha/alpha/db_trace.c25
-rw-r--r--sys/alpha/alpha/dec_kn8ae.c89
-rw-r--r--sys/alpha/alpha/diskslice_machdep.c461
-rw-r--r--sys/alpha/alpha/divrem.m4197
-rw-r--r--sys/alpha/alpha/exception.s200
-rw-r--r--sys/alpha/alpha/genassym.c212
-rw-r--r--sys/alpha/alpha/gensetdefs.c313
-rw-r--r--sys/alpha/alpha/in_cksum.c216
-rw-r--r--sys/alpha/alpha/interrupt.c264
-rw-r--r--sys/alpha/alpha/ipl_funcs.c52
-rw-r--r--sys/alpha/alpha/mem.c443
-rw-r--r--sys/alpha/alpha/pal.s350
-rw-r--r--sys/alpha/alpha/pmap.c3081
-rw-r--r--sys/alpha/alpha/procfs_machdep.c146
-rw-r--r--sys/alpha/alpha/prom.c361
-rw-r--r--sys/alpha/alpha/prom_disp.s116
-rw-r--r--sys/alpha/alpha/promcons.c249
-rw-r--r--sys/alpha/alpha/setdef0.c49
-rw-r--r--sys/alpha/alpha/setdef1.c41
-rw-r--r--sys/alpha/alpha/support.s626
-rw-r--r--sys/alpha/alpha/swtch.s388
-rw-r--r--sys/alpha/alpha/symbols.raw81
-rw-r--r--sys/alpha/alpha/sys_machdep.c76
-rw-r--r--sys/alpha/alpha/trap.c1010
-rw-r--r--sys/alpha/conf/GENERIC74
-rw-r--r--sys/alpha/conf/Makefile.alpha272
-rw-r--r--sys/alpha/conf/NOTES74
-rw-r--r--sys/alpha/conf/SIMOS84
-rw-r--r--sys/alpha/conf/devices.alpha18
-rw-r--r--sys/alpha/conf/files.alpha80
-rw-r--r--sys/alpha/conf/majors.alpha141
-rw-r--r--sys/alpha/conf/options.alpha18
-rw-r--r--sys/alpha/include/alpha_cpu.h14
-rw-r--r--sys/alpha/include/asm.h6
-rw-r--r--sys/alpha/include/bootinfo.h21
-rw-r--r--sys/alpha/include/bus.h620
-rw-r--r--sys/alpha/include/chipset.h76
-rw-r--r--sys/alpha/include/clock.h22
-rw-r--r--sys/alpha/include/conf.h11
-rw-r--r--sys/alpha/include/cons.h110
-rw-r--r--sys/alpha/include/cpu.h20
-rw-r--r--sys/alpha/include/cpuconf.h118
-rw-r--r--sys/alpha/include/cpufunc.h46
-rw-r--r--sys/alpha/include/db_machdep.h112
-rw-r--r--sys/alpha/include/elf.h55
-rw-r--r--sys/alpha/include/in_cksum.h78
-rw-r--r--sys/alpha/include/ipl.h75
-rw-r--r--sys/alpha/include/lock.h6
-rw-r--r--sys/alpha/include/md_var.h50
-rw-r--r--sys/alpha/include/param.h51
-rw-r--r--sys/alpha/include/pmap.h255
-rw-r--r--sys/alpha/include/proc.h2
-rw-r--r--sys/alpha/include/prom.h104
-rw-r--r--sys/alpha/include/psl.h32
-rw-r--r--sys/alpha/include/pte.h4
-rw-r--r--sys/alpha/include/ptrace.h53
-rw-r--r--sys/alpha/include/reg.h5
-rw-r--r--sys/alpha/include/rpb.h393
-rw-r--r--sys/alpha/include/vmparam.h34
-rw-r--r--sys/alpha/pci/pcibus.c89
-rw-r--r--sys/alpha/pci/pcibus.h41
-rw-r--r--sys/alpha/tlsb/dwlpx.c291
-rw-r--r--sys/alpha/tlsb/dwlpxreg.h237
-rw-r--r--sys/alpha/tlsb/gbus.c155
-rw-r--r--sys/alpha/tlsb/gbusreg.h46
-rw-r--r--sys/alpha/tlsb/gbusvar.h64
-rw-r--r--sys/alpha/tlsb/kftxx.c192
-rw-r--r--sys/alpha/tlsb/kftxxreg.h74
-rw-r--r--sys/alpha/tlsb/kftxxvar.h59
-rw-r--r--sys/alpha/tlsb/mcclock_tlsb.c126
-rw-r--r--sys/alpha/tlsb/tlsb.c329
-rw-r--r--sys/alpha/tlsb/tlsbmem.c91
-rw-r--r--sys/alpha/tlsb/tlsbreg.h318
-rw-r--r--sys/alpha/tlsb/tlsbvar.h75
-rw-r--r--sys/alpha/tlsb/zs_tlsb.c473
-rw-r--r--sys/alpha/tlsb/zsreg.h30
-rw-r--r--sys/conf/Makefile.alpha272
-rw-r--r--sys/conf/files5
-rw-r--r--sys/conf/files.alpha80
-rw-r--r--sys/conf/options.alpha18
-rw-r--r--sys/ddb/db_examine.c4
-rw-r--r--sys/ddb/db_print.c4
-rw-r--r--sys/ddb/db_sym.c6
-rw-r--r--sys/dev/dec/clockvar.h62
-rw-r--r--sys/dev/dec/mc146818reg.h194
-rw-r--r--sys/dev/dec/mcclock.c141
-rw-r--r--sys/dev/dec/mcclockvar.h41
-rw-r--r--sys/dev/mc146818/mc146818reg.h194
-rw-r--r--sys/kern/subr_bus.c854
-rw-r--r--sys/libkern/alpha/byte_swap_2.S47
-rw-r--r--sys/libkern/alpha/byte_swap_4.S53
-rw-r--r--sys/libkern/alpha/htonl.S32
-rw-r--r--sys/libkern/alpha/htons.S32
-rw-r--r--sys/libkern/alpha/ntohl.S32
-rw-r--r--sys/libkern/alpha/ntohs.S32
-rw-r--r--sys/pci/simos.c312
-rw-r--r--sys/pci/simos.h74
-rw-r--r--sys/powerpc/include/bootinfo.h21
-rw-r--r--sys/powerpc/include/clock.h22
-rw-r--r--sys/powerpc/include/md_var.h50
-rw-r--r--sys/powerpc/powerpc/genassym.c212
-rw-r--r--sys/powerpc/powerpc/procfs_machdep.c146
-rw-r--r--sys/sys/bus.h229
-rw-r--r--sys/sys/bus_private.h71
-rw-r--r--sys/sys/elf64.h312
-rw-r--r--sys/sys/module.h5
113 files changed, 21627 insertions, 176 deletions
diff --git a/sys/alpha/alpha/autoconf.c b/sys/alpha/alpha/autoconf.c
new file mode 100644
index 000000000000..f70e85d26272
--- /dev/null
+++ b/sys/alpha/alpha/autoconf.c
@@ -0,0 +1,109 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h> /* for BASE_SLICE, MAX_SLICES */
+#include <sys/reboot.h>
+#include <sys/kernel.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/bus.h>
+
+#include <machine/cons.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#include <machine/cpuconf.h>
+
+#include "scbus.h"
+#if NSCBUS > 0
+#include <scsi/scsiconf.h>
+#endif
+
+static void configure __P((void *));
+SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL)
+
+static void configure_finish __P((void));
+static void configure_start __P((void));
+
+static void
+configure_start()
+{
+#if NSCBUS > 0
+ scsi_configure_start();
+#endif
+}
+
+static void
+configure_finish()
+{
+#if NSCBUS > 0
+ scsi_configure_finish();
+#endif
+}
+
+/*
+ * Determine i/o configuration for a machine.
+ */
+static void
+configure(void *dummy)
+{
+ configure_start();
+
+ bus_add_device(root_bus, platform.iobus, 0, 0);
+ root_bus_configure();
+
+ pci_configure();
+
+ configure_finish();
+
+ cninit_finish();
+
+ /*
+ * Now we're ready to handle (pending) interrupts.
+ * XXX this is slightly misplaced.
+ */
+ spl0();
+
+ cold = 0;
+}
+
+void
+cpu_rootconf()
+{
+ mountrootfsname = "ufs";
+ rootdevs[0] = makedev(4, dkmakeminor(0, COMPATIBILITY_SLICE, 0));
+ rootdevnames[0] = "sd0c";
+}
+
+void
+cpu_dumpconf()
+{
+}
diff --git a/sys/alpha/alpha/clock.c b/sys/alpha/alpha/clock.c
new file mode 100644
index 000000000000..24eb3c80c4a5
--- /dev/null
+++ b/sys/alpha/alpha/clock.c
@@ -0,0 +1,355 @@
+/* $Id$ */
+/* $NetBSD: clock.c,v 1.20 1998/01/31 10:32:47 ross Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1992, 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 and Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah Hdr: clock.c 1.18 91/01/21
+ *
+ * @(#)clock.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/cpuconf.h>
+
+#include <dev/dec/clockvar.h>
+
+#define SECMIN ((unsigned)60) /* seconds per minute */
+#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
+#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */
+#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */
+
+#define LEAPYEAR(year) (((year) % 4) == 0)
+
+device_t clockdev;
+const struct clockfns *clockfns;
+int clockinitted;
+int tickfix;
+int tickfixinterval;
+int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+
+extern cycles_per_sec;
+
+static timecounter_get_t alpha_get_timecount;
+static timecounter_pps_t alpha_poll_pps;
+
+static struct timecounter alpha_timecounter[3] = {
+ alpha_get_timecount, /* get_timecount */
+ 0, /* no poll_pps */
+ ~0u, /* counter_mask */
+ 0, /* frequency */
+ "alpha" /* name */
+};
+
+SYSCTL_OPAQUE(_debug, OID_AUTO, alpha_timecounter, CTLFLAG_RD,
+ alpha_timecounter, sizeof(alpha_timecounter), "S,timecounter", "");
+
+/*
+ * Algorithm for missed clock ticks from Linux/alpha.
+ */
+
+/*
+ * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting
+ * by 48 gives us 16 bits for HZ while keeping the accuracy good even
+ * for large CPU clock rates.
+ */
+#define FIX_SHIFT 48
+
+static u_int64_t scaled_ticks_per_cycle;
+static u_int32_t max_cycles_per_tick;
+static u_int32_t last_time;
+
+static void handleclock(void* arg);
+
+void
+clockattach(dev, fns)
+ struct device *dev;
+ const struct clockfns *fns;
+{
+
+ /*
+ * Just bookkeeping.
+ */
+ if (clockfns != NULL)
+ panic("clockattach: multiple clocks");
+ clockdev = dev;
+ clockfns = fns;
+#ifdef EVCNT_COUNTERS
+ evcnt_attach(dev, "intr", &clock_intr_evcnt);
+#endif
+}
+
+/*
+ * Machine-dependent clock routines.
+ *
+ * Startrtclock restarts the real-time clock, which provides
+ * hardclock interrupts to kern_clock.c.
+ *
+ * Inittodr initializes the time of day hardware which provides
+ * date functions. Its primary function is to use some file
+ * system information in case the hardare clock lost state.
+ *
+ * Resettodr restores the time of day hardware after a time change.
+ */
+
+/*
+ * Start the real-time and statistics clocks. Leave stathz 0 since there
+ * are no other timers available.
+ */
+void
+cpu_initclocks()
+{
+ if (clockfns == NULL)
+ panic("cpu_initclocks: no clock attached");
+
+ tick = 1000000 / hz; /* number of microseconds between interrupts */
+ tickfix = 1000000 - (hz * tick);
+ if (tickfix) {
+ int ftp;
+
+ ftp = min(ffs(tickfix), ffs(hz));
+ tickfix >>= (ftp - 1);
+ tickfixinterval = hz >> (ftp - 1);
+ }
+
+ /*
+ * Establish the clock interrupt; it's a special case.
+ *
+ * We establish the clock interrupt this late because if
+ * we do it at clock attach time, we may have never been at
+ * spl0() since taking over the system. Some versions of
+ * PALcode save a clock interrupt, which would get delivered
+ * when we spl0() in autoconf.c. If established the clock
+ * interrupt handler earlier, that interrupt would go to
+ * hardclock, which would then fall over because p->p_stats
+ * isn't set at that time.
+ */
+ last_time = alpha_rpcc();
+ scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / cycles_per_sec;
+ max_cycles_per_tick = 2*cycles_per_sec / hz;
+
+ alpha_timecounter[0].tc_frequency = cycles_per_sec;
+ init_timecounter(alpha_timecounter);
+
+ platform.clockintr = (void (*) __P((void *))) handleclock;
+
+ /*
+ * Get the clock started.
+ */
+ (*clockfns->cf_init)(clockdev);
+}
+
+static void
+handleclock(void* arg)
+{
+ u_int32_t now = alpha_rpcc();
+ u_int32_t delta = now - last_time;
+ last_time = now;
+
+ if (delta > max_cycles_per_tick) {
+ int i, missed_ticks;
+ missed_ticks = (delta * scaled_ticks_per_cycle) >> FIX_SHIFT;
+ for (i = 0; i < missed_ticks; i++)
+ hardclock(arg);
+ }
+ hardclock(arg);
+}
+
+/*
+ * We assume newhz is either stathz or profhz, and that neither will
+ * change after being set up above. Could recalculate intervals here
+ * but that would be a drag.
+ */
+void
+setstatclockrate(newhz)
+ int newhz;
+{
+
+ /* nothing we can do */
+}
+
+/*
+ * This code is defunct after 2099.
+ * Will Unix still be here then??
+ */
+static short dayyr[12] = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
+/*
+ * Initialze the time of day register, based on the time base which is, e.g.
+ * from a filesystem. Base provides the time to within six months,
+ * and the time of year clock (if any) provides the rest.
+ */
+void
+inittodr(base)
+ time_t base;
+{
+ register int days, yr;
+ struct clocktime ct;
+ time_t deltat;
+ int badbase;
+ int s;
+ struct timespec ts;
+
+ if (base < 5*SECYR) {
+ printf("WARNING: preposterous time in file system");
+ /* read the system clock anyway */
+ base = 6*SECYR + 186*SECDAY + SECDAY/2;
+ badbase = 1;
+ } else
+ badbase = 0;
+
+ (*clockfns->cf_get)(clockdev, base, &ct);
+ clockinitted = 1;
+
+ /* simple sanity checks */
+ if (ct.year < 70 || ct.mon < 1 || ct.mon > 12 || ct.day < 1 ||
+ ct.day > 31 || ct.hour > 23 || ct.min > 59 || ct.sec > 59) {
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the TODR.
+ */
+ s = splclock();
+ ts.tv_sec = base;
+ ts.tv_nsec = 0;
+ set_timecounter(&ts);
+ splx(s);
+ if (!badbase) {
+ printf("WARNING: preposterous clock chip time\n");
+ resettodr();
+ }
+ goto bad;
+ }
+ days = 0;
+ for (yr = 70; yr < ct.year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[ct.mon - 1] + ct.day - 1;
+ if (LEAPYEAR(yr) && ct.mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ s = splclock();
+ ts.tv_sec =
+ days * SECDAY + ct.hour * SECHOUR + ct.min * SECMIN + ct.sec;
+ ts.tv_nsec = 0;
+ set_timecounter(&ts);
+ splx(s);
+
+ if (!badbase) {
+ /*
+ * See if we gained/lost two or more days;
+ * if so, assume something is amiss.
+ */
+ deltat = ts.tv_sec - base;
+ if (deltat < 0)
+ deltat = -deltat;
+ if (deltat < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %d days",
+ ts.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
+ }
+bad:
+ printf(" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * Reset the TODR based on the time value; used when the TODR
+ * has a preposterous value and also when the time is reset
+ * by the stime system call. Also called when the TODR goes past
+ * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
+ * to wrap the TODR around.
+ */
+void
+resettodr()
+{
+ register int t, t2, s;
+ struct clocktime ct;
+ unsigned long tm;
+
+ s = splclock();
+ tm = time_second;
+ splx(s);
+
+ if (!clockinitted)
+ return;
+
+ /* compute the day of week. */
+ t2 = tm / SECDAY;
+ ct.dow = (t2 + 4) % 7; /* 1/1/1970 was thursday */
+
+ /* compute the year */
+ ct.year = 69;
+ t = t2; /* XXX ? */
+ while (t2 >= 0) { /* whittle off years */
+ t = t2;
+ ct.year++;
+ t2 -= LEAPYEAR(ct.year) ? 366 : 365;
+ }
+
+ /* t = month + day; separate */
+ t2 = LEAPYEAR(ct.year);
+ for (ct.mon = 1; ct.mon < 12; ct.mon++)
+ if (t < dayyr[ct.mon] + (t2 && ct.mon > 1))
+ break;
+
+ ct.day = t - dayyr[ct.mon - 1] + 1;
+ if (t2 && ct.mon > 2)
+ ct.day--;
+
+ /* the rest is easy */
+ t = tm % SECDAY;
+ ct.hour = t / SECHOUR;
+ t %= 3600;
+ ct.min = t / SECMIN;
+ ct.sec = t % SECMIN;
+
+ (*clockfns->cf_set)(clockdev, &ct);
+}
+
+static unsigned
+alpha_get_timecount(struct timecounter* tc)
+{
+ return alpha_rpcc();
+}
+
diff --git a/sys/alpha/alpha/cons.c b/sys/alpha/alpha/cons.c
new file mode 100644
index 000000000000..511f370e6506
--- /dev/null
+++ b/sys/alpha/alpha/cons.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)cons.c 7.2 (Berkeley) 5/9/91
+ * $Id: cons.c,v 1.57 1998/03/28 10:32:56 bde Exp $
+ */
+
+#include "opt_devfs.h"
+
+#include <sys/param.h>
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#endif /*DEVFS*/
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/reboot.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/uio.h>
+
+#include <machine/cpu.h>
+#include <machine/cons.h>
+
+/* XXX this should be config(8)ed. */
+#if 0
+#include "sc.h"
+#include "vt.h"
+#include "sio.h"
+#endif
+static struct consdev constab[] = {
+#if NSC > 0
+ { sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc },
+#endif
+#if NVT > 0
+ { pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc },
+#endif
+#if NSIO > 0
+ { siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc },
+#endif
+ { 0 },
+};
+
+static d_open_t cnopen;
+static d_close_t cnclose;
+static d_read_t cnread;
+static d_write_t cnwrite;
+static d_ioctl_t cnioctl;
+static d_poll_t cnpoll;
+
+#define CDEV_MAJOR 0
+static struct cdevsw cn_cdevsw =
+ { cnopen, cnclose, cnread, cnwrite, /*0*/
+ cnioctl, nullstop, nullreset, nodevtotty,/* console */
+ cnpoll, nommap, NULL, "console", NULL, -1 };
+
+static dev_t cn_dev_t; /* seems to be never really used */
+SYSCTL_OPAQUE(_machdep, CPU_CONSDEV, consdev, CTLTYPE_OPAQUE|CTLFLAG_RD,
+ &cn_dev_t, sizeof cn_dev_t, "T,dev_t", "");
+
+static int cn_mute;
+
+int cons_unavail = 0; /* XXX:
+ * physical console not available for
+ * input (i.e., it is in graphics mode)
+ */
+
+static u_char cn_is_open; /* nonzero if logical console is open */
+static int openmode, openflag; /* how /dev/console was openned */
+static u_char cn_phys_is_open; /* nonzero if physical device is open */
+static d_close_t *cn_phys_close; /* physical device close function */
+static d_open_t *cn_phys_open; /* physical device open function */
+struct consdev *cn_tab; /* physical console device info */
+static struct tty *cn_tp; /* physical console tty struct */
+#ifdef DEVFS
+static void *cn_devfs_token; /* represents the devfs entry */
+#endif /* DEVFS */
+
+void
+cninit()
+{
+ struct consdev *best_cp, *cp;
+
+ /*
+ * Find the first console with the highest priority.
+ */
+ best_cp = NULL;
+ for (cp = constab; cp->cn_probe; cp++) {
+ (*cp->cn_probe)(cp);
+ if (cp->cn_pri > CN_DEAD &&
+ (best_cp == NULL || cp->cn_pri > best_cp->cn_pri))
+ best_cp = cp;
+ }
+
+ /*
+ * Check if we should mute the console (for security reasons perhaps)
+ * It can be changes dynamically using sysctl kern.consmute
+ * once we are up and going.
+ *
+ */
+ cn_mute = ((boothowto & (RB_MUTE
+ |RB_SINGLE
+ |RB_VERBOSE
+ |RB_ASKNAME
+ |RB_CONFIG)) == RB_MUTE);
+
+ /*
+ * If no console, give up.
+ */
+ if (best_cp == NULL) {
+ cn_tab = best_cp;
+ return;
+ }
+
+ /*
+ * Initialize console, then attach to it. This ordering allows
+ * debugging using the previous console, if any.
+ * XXX if there was a previous console, then its driver should
+ * be informed when we forget about it.
+ */
+ (*best_cp->cn_init)(best_cp);
+ cn_tab = best_cp;
+}
+
+void
+cninit_finish()
+{
+ struct cdevsw *cdp;
+
+ if ((cn_tab == NULL) || cn_mute)
+ return;
+
+ /*
+ * Hook the open and close functions.
+ */
+ cdp = cdevsw[major(cn_tab->cn_dev)];
+ cn_phys_close = cdp->d_close;
+ cdp->d_close = cnclose;
+ cn_phys_open = cdp->d_open;
+ cdp->d_open = cnopen;
+ cn_tp = (*cdp->d_devtotty)(cn_tab->cn_dev);
+ cn_dev_t = cn_tp->t_dev;
+}
+
+static void
+cnuninit(void)
+{
+ struct cdevsw *cdp;
+
+ if (cn_tab == NULL)
+ return;
+
+ /*
+ * Unhook the open and close functions.
+ */
+ cdp = cdevsw[major(cn_tab->cn_dev)];
+ cdp->d_close = cn_phys_close;
+ cn_phys_close = NULL;
+ cdp->d_open = cn_phys_open;
+ cn_phys_open = NULL;
+ cn_tp = NULL;
+ cn_dev_t = 0;
+}
+
+/*
+ * User has changed the state of the console muting.
+ * This may require us to open or close the device in question.
+ */
+static int
+sysctl_kern_consmute SYSCTL_HANDLER_ARGS
+{
+ int error;
+ int ocn_mute;
+
+ ocn_mute = cn_mute;
+ error = sysctl_handle_int(oidp, &cn_mute, 0, req);
+ if((error == 0) && (cn_tab != NULL) && (req->newptr != NULL)) {
+ if(ocn_mute && !cn_mute) {
+ /*
+ * going from muted to unmuted.. open the physical dev
+ * if the console has been openned
+ */
+ cninit_finish();
+ if(cn_is_open)
+ /* XXX curproc is not what we want really */
+ error = cnopen(cn_dev_t, openflag,
+ openmode, curproc);
+ /* if it failed, back it out */
+ if ( error != 0) cnuninit();
+ } else if (!ocn_mute && cn_mute) {
+ /*
+ * going from unmuted to muted.. close the physical dev
+ * if it's only open via /dev/console
+ */
+ if(cn_is_open)
+ error = cnclose(cn_dev_t, openflag,
+ openmode, curproc);
+ if ( error == 0) cnuninit();
+ }
+ if (error != 0) {
+ /*
+ * back out the change if there was an error
+ */
+ cn_mute = ocn_mute;
+ }
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,
+ 0, sizeof cn_mute, sysctl_kern_consmute, "I", "");
+
+static int
+cnopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ dev_t cndev, physdev;
+ int retval = 0;
+
+ if (cn_tab == NULL)
+ return (0);
+ cndev = cn_tab->cn_dev;
+ physdev = (major(dev) == major(cndev) ? dev : cndev);
+ /*
+ * If mute is active, then non console opens don't get here
+ * so we don't need to check for that. They
+ * bypass this and go straight to the device.
+ */
+ if(!cn_mute)
+ retval = (*cn_phys_open)(physdev, flag, mode, p);
+ if (retval == 0) {
+ /*
+ * check if we openned it via /dev/console or
+ * via the physical entry (e.g. /dev/sio0).
+ */
+ if (dev == cndev)
+ cn_phys_is_open = 1;
+ else if (physdev == cndev) {
+ openmode = mode;
+ openflag = flag;
+ cn_is_open = 1;
+ }
+ }
+ return (retval);
+}
+
+static int
+cnclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ dev_t cndev;
+
+ if (cn_tab == NULL)
+ return (0);
+ cndev = cn_tab->cn_dev;
+ /*
+ * act appropriatly depending on whether it's /dev/console
+ * or the pysical device (e.g. /dev/sio) that's being closed.
+ * in either case, don't actually close the device unless
+ * both are closed.
+ */
+ if (dev == cndev) {
+ /* the physical device is about to be closed */
+ cn_phys_is_open = 0;
+ if (cn_is_open) {
+ if (cn_tp) {
+ /* perform a ttyhalfclose() */
+ /* reset session and proc group */
+ cn_tp->t_pgrp = NULL;
+ cn_tp->t_session = NULL;
+ }
+ return (0);
+ }
+ } else if (major(dev) != major(cndev)) {
+ /* the logical console is about to be closed */
+ cn_is_open = 0;
+ if (cn_phys_is_open)
+ return (0);
+ dev = cndev;
+ }
+ if(cn_phys_close)
+ return ((*cn_phys_close)(dev, flag, mode, p));
+ return (0);
+}
+
+static int
+cnread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ if ((cn_tab == NULL) || cn_mute)
+ return (0);
+ dev = cn_tab->cn_dev;
+ return ((*cdevsw[major(dev)]->d_read)(dev, uio, flag));
+}
+
+static int
+cnwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ if ((cn_tab == NULL) || cn_mute) {
+ uio->uio_resid = 0; /* dump the data */
+ return (0);
+ }
+ if (constty)
+ dev = constty->t_dev;
+ else
+ dev = cn_tab->cn_dev;
+ return ((*cdevsw[major(dev)]->d_write)(dev, uio, flag));
+}
+
+static int
+cnioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int error;
+
+ if ((cn_tab == NULL) || cn_mute)
+ return (0);
+ /*
+ * Superuser can always use this to wrest control of console
+ * output from the "virtual" console.
+ */
+ if (cmd == TIOCCONS && constty) {
+ error = suser(p->p_ucred, (u_short *) NULL);
+ if (error)
+ return (error);
+ constty = NULL;
+ return (0);
+ }
+ dev = cn_tab->cn_dev;
+ return ((*cdevsw[major(dev)]->d_ioctl)(dev, cmd, data, flag, p));
+}
+
+static int
+cnpoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
+{
+ if ((cn_tab == NULL) || cn_mute)
+ return (1);
+
+ dev = cn_tab->cn_dev;
+
+ return ((*cdevsw[major(dev)]->d_poll)(dev, events, p));
+}
+
+int
+cngetc()
+{
+ int c;
+ if ((cn_tab == NULL) || cn_mute)
+ return (-1);
+ c = (*cn_tab->cn_getc)(cn_tab->cn_dev);
+ if (c == '\r') c = '\n'; /* console input is always ICRNL */
+ return (c);
+}
+
+int
+cncheckc()
+{
+ if ((cn_tab == NULL) || cn_mute)
+ return (-1);
+ return ((*cn_tab->cn_checkc)(cn_tab->cn_dev));
+}
+
+void
+cnputc(c)
+ register int c;
+{
+ if ((cn_tab == NULL) || cn_mute)
+ return;
+ if (c) {
+ if (c == '\n')
+ (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
+ (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
+ }
+}
+
+static cn_devsw_installed = 0;
+
+static void
+cn_drvinit(void *unused)
+{
+ dev_t dev;
+
+ if( ! cn_devsw_installed ) {
+ dev = makedev(CDEV_MAJOR,0);
+ cdevsw_add(&dev,&cn_cdevsw,NULL);
+ cn_devsw_installed = 1;
+#ifdef DEVFS
+ cn_devfs_token = devfs_add_devswf(&cn_cdevsw, 0, DV_CHR,
+ UID_ROOT, GID_WHEEL, 0600,
+ "console");
+#endif
+ }
+}
+
+SYSINIT(cndev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,cn_drvinit,NULL)
+
+
diff --git a/sys/alpha/alpha/cpuconf.c b/sys/alpha/alpha/cpuconf.c
new file mode 100644
index 000000000000..9e395ae37145
--- /dev/null
+++ b/sys/alpha/alpha/cpuconf.c
@@ -0,0 +1,161 @@
+/* $Id$ */
+/* $NetBSD: cpuconf.c,v 1.10 1998/03/20 21:48:21 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <machine/cpuconf.h>
+#include <machine/rpb.h>
+
+#include "opt_cpu.h"
+
+#ifdef DEC_3000_500
+extern void dec_3000_500_init __P((int));
+#else
+#define dec_3000_500_init platform_not_configured
+#endif
+
+#ifdef DEC_3000_300
+extern void dec_3000_300_init __P((int));
+#else
+#define dec_3000_300_init platform_not_configured
+#endif
+
+#ifdef DEC_AXPPCI_33
+extern void dec_axppci_33_init __P((int));
+#else
+#define dec_axppci_33_init platform_not_configured
+#endif
+
+#ifdef DEC_KN8AE
+extern void dec_kn8ae_init __P((int));
+#else
+#define dec_kn8ae_init platform_not_configured
+#endif
+
+#ifdef DEC_2100_A50
+extern void dec_2100_a50_init __P((int));
+#else
+#define dec_2100_a50_init platform_not_configured
+#endif
+
+#ifdef DEC_KN20AA
+extern void dec_kn20aa_init __P((int));
+#else
+#define dec_kn20aa_init platform_not_configured
+#endif
+
+#ifdef DEC_EB64PLUS
+extern void dec_eb64plus_init __P((int));
+#else
+#define dec_eb64plus_init platform_not_configured
+#endif
+
+#ifdef DEC_EB164
+extern void dec_eb164_init __P((int));
+#else
+#define dec_eb164_init platform_not_configured
+#endif
+
+#ifdef AVALON_A12
+extern void avalon_a12_init __P((int));
+#else
+#define avalon_a12_init platform_not_configured
+#endif
+
+struct cpuinit cpuinit[] = {
+ cpu_notsupp("???"), /* 0: ??? */
+ cpu_notsupp("ST_ADU"), /* 1: ST_ADU */
+ cpu_notsupp("ST_DEC_4000"), /* 2: ST_DEC_4000 */
+ cpu_notsupp("ST_DEC_7000"), /* 3: ST_DEC_7000 */
+ cpu_init(dec_3000_500_init,"DEC_3000_500"), /* 4: ST_DEC_3000_500 */
+ cpu_notsupp("???"), /* 5: ??? */
+ cpu_notsupp("ST_DEC_2000_300"), /* 6: ST_DEC_2000_300 */
+ cpu_init(dec_3000_300_init,"DEC_3000_300"), /* 7: ST_DEC_3000_300 */
+ cpu_init(avalon_a12_init,"ST_AVALON_A12"), /* 8: ST_AVALON_A12 */
+ cpu_notsupp("ST_DEC_2100_A500"), /* 9: ST_DEC_2100_A500 */
+ cpu_notsupp("ST_DEC_APXVME_64"), /* 10: ST_DEC_APXVME_64 */
+ cpu_init(dec_axppci_33_init,"DEC_AXPPCI_33"),/* 11: ST_DEC_AXPPCI_33 */
+ cpu_init(dec_kn8ae_init,"DEC_KN8AE"), /* 12: ST_DEC_21000 */
+ cpu_init(dec_2100_a50_init,"DEC_2100_A50"), /* 13: ST_DEC_2100_A50 */
+ cpu_notsupp("ST_DEC_MUSTANG"), /* 14: ST_DEC_MUSTANG */
+ cpu_init(dec_kn20aa_init,"DEC_KN20AA"), /* 15: ST_DEC_KN20AA */
+ cpu_notsupp("???"), /* 16: ??? */
+ cpu_notsupp("ST_DEC_1000"), /* 17: ST_DEC_1000 */
+ cpu_notsupp("???"), /* 18: ??? */
+ cpu_notsupp("ST_EB66"), /* 19: ST_EB66 */
+ cpu_init(dec_eb64plus_init,"DEC_EB64PLUS"), /* 20: ST_EB64P */
+ cpu_notsupp("ST_ALPHABOOK1"), /* 21: ST_ALPHABOOK1 */
+ cpu_notsupp("ST_DEC_4100"), /* 22: ST_DEC_4100 */
+ cpu_notsupp("ST_DEC_EV45_PBP"), /* 23: ST_DEC_EV45_PBP */
+ cpu_notsupp("ST_DEC_2100A_A500"), /* 24: ST_DEC_2100A_A500 */
+ cpu_notsupp("???"), /* 25: ??? */
+ cpu_init(dec_eb164_init,"DEC_EB164"), /* 26: ST_EB164 */
+ cpu_notsupp("ST_DEC_1000A"), /* 27: ST_DEC_1000A */
+ cpu_notsupp("ST_DEC_ALPHAVME_224"), /* 28: ST_DEC_ALPHAVME_224 */
+ cpu_notsupp("???"), /* 29: ??? */
+ cpu_notsupp("???"), /* 30: ??? */
+ cpu_notsupp("???"), /* 31: ??? */
+ cpu_notsupp("ST_DEC_EV56_PBP"), /* 32: ST_DEC_EV56_PBP */
+ cpu_notsupp("ST_DEC_ALPHAVME_320"), /* 33: ST_DEC_ALPHAVME_320 */
+};
+int ncpuinit = (sizeof(cpuinit) / sizeof(cpuinit[0]));
+
+void
+platform_not_configured(int cputype)
+{
+ printf("\n");
+ printf("Support for system type %d is not present in this kernel.\n",
+ cputype);
+ printf("Please build a kernel with \"options %s\" and reboot.\n",
+ cpuinit[cputype].option);
+ printf("\n");
+ panic("platform not configured\n");
+}
+
+void
+platform_not_supported(int cputype)
+{
+ const char *typestr;
+
+ if (cputype >= ncpuinit)
+ typestr = "???";
+ else
+ typestr = cpuinit[cputype].option;
+
+ printf("\n");
+ printf("NetBSD does not yet support system type %d (%s).\n", cputype,
+ typestr);
+ printf("\n");
+ panic("platform not supported");
+}
diff --git a/sys/alpha/alpha/db_disasm.c b/sys/alpha/alpha/db_disasm.c
new file mode 100644
index 000000000000..94df6fa70dcc
--- /dev/null
+++ b/sys/alpha/alpha/db_disasm.c
@@ -0,0 +1,1095 @@
+/* $NetBSD: db_disasm.c,v 1.4 1997/09/16 22:52:40 thorpej Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * File: db_disasm.c
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 11/91
+ *
+ * Disassembler for Alpha
+ *
+ * Modified for NetBSD/alpha by:
+ *
+ * Christopher G. Demetriou, Carnegie Mellon University
+ *
+ * Jason R. Thorpe, Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center
+ *
+ * This code was derived exclusively from information available in
+ * "Alpha Architecture Reference Manual", Richard L. Sites ed.
+ * Digital Press, Burlington, MA 01803
+ * ISBN 1-55558-098-X, Order no. EY-L520E-DP
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+/* __KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.4 1997/09/16 22:52:40 thorpej Exp $"); */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <machine/db_machdep.h>
+#include <alpha/alpha/db_instruction.h>
+
+#include <machine/pal.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_output.h>
+
+/*
+ * This would belong in a header file, except noone else needs it
+ */
+typedef union {
+ /*
+ * All instructions are 32 bits wide, PAL included
+ */
+ unsigned int bits;
+
+ /*
+ * Internal processor register access instrs
+ * specify the IPR index, doubly specify the
+ * (same) GP register as src/dest, and qualifiers
+ * for the IPR set involved (abox/ibox/tmp)
+ */
+ struct {
+ unsigned index : 5,
+ regset : 3, /* a,i,p */
+ xxx : 8,
+ rs : 5,
+ rd : 5,
+ opcode : 6;
+ } mXpr_format;
+
+ /*
+ * Load/store instructions have a 12 bit displacement,
+ * and two register specifiers just as normal ld/st.
+ * Four bits have special meanings:
+ * phy: bypass the MMU (physical access)
+ * alt: use mode in ALT register for checks,
+ * or if PHY is also on locked/linked access
+ * rwc: read-with-write-check (probew)
+ * qw: quadword access
+ */
+ struct {
+ signed int displacement : 12;
+ unsigned qw : 1,
+ qualif : 3,
+ rs : 5,
+ rd : 5,
+ opcode : 6;
+ } mem_format;
+
+ /*
+ * Return from exception or interrupt has
+ * a branch-like encoding, but only one
+ * instantiation is actually usable.
+ */
+ struct {
+ unsigned xxx : 14,
+ zero : 1, /* branch prediction! */
+ one : 1,
+ rb : 5, /* r31 or stall */
+ ra : 5, /* r31 or stall */
+ opcode : 6;
+ } rei_format;
+
+} pal_instruction;
+
+
+/*
+ * Major opcodes
+ */
+static char *op_name[64] = {
+/* 0 */ "call_pal", "op1", "op2", "op3", "op4", "op5", "op6", "op7",
+/* 8 */ "lda", "ldah", "ldbu", "ldq_u","ldwu", "stw", "stb", "stq_u",
+/*16 */ "arit", "logical","bit","mul", "op20", "vaxf", "ieeef","anyf",
+/*24 */ "spec", "hw_mfpr","jump","hw_ld","intmisc","hw_mtpr","hw_rei","hw_st",
+/*32 */ "ldf", "ldg", "lds", "ldt", "stf", "stg", "sts", "stt",
+/*40 */ "ldl", "ldq", "ldl_l","ldq_l","stl", "stq", "stl_c","stq_c",
+/*48 */ "br", "fbeq", "fblt", "fble", "bsr", "fbne", "fbge", "fbgt",
+/*56 */ "blbc", "beq", "blt", "ble", "blbs", "bne", "bge", "bgt"
+};
+
+/*
+ * The function field is too big (7 or 11 bits), so the sub-tables
+ * are addressed in a somewhat complicated manner to save
+ * space. After all, alu operations is what RISCs are good at.
+ */
+
+struct tbl {
+ const char *name;
+ int code;
+};
+
+static const struct tbl pal_op_tbl[] = {
+ /* Common PAL function codes. */
+ { "halt", PAL_halt },
+ { "cflush", PAL_cflush },
+ { "draina", PAL_draina },
+ { "cserve", PAL_cserve, },
+ { "swppal", PAL_swppal },
+ { "ipir", PAL_ipir },
+ { "bpt", PAL_bpt },
+ { "bugchk", PAL_bugchk },
+ { "imb", PAL_imb },
+ { "rdunique", PAL_rdunique },
+ { "wrunique", PAL_wrunique },
+ { "gentrap", PAL_gentrap },
+
+ /* OSF/1 PAL function codes. */
+ { "osf1_rdmces", PAL_OSF1_rdmces },
+ { "osf1_wrmces", PAL_OSF1_wrmces },
+ { "osf1_wrfen", PAL_OSF1_wrfen },
+ { "osf1_wrvptptr", PAL_OSF1_wrvptptr },
+ { "osf1_swpctx", PAL_OSF1_swpctx },
+ { "osf1_wrval", PAL_OSF1_wrval },
+ { "osf1_rdval", PAL_OSF1_rdval },
+ { "osf1_tbi", PAL_OSF1_tbi },
+ { "osf1_wrent", PAL_OSF1_wrent },
+ { "osf1_swpipl", PAL_OSF1_swpipl },
+ { "osf1_rdps", PAL_OSF1_rdps },
+ { "osf1_wrkgp", PAL_OSF1_wrkgp },
+ { "osf1_wrusp", PAL_OSF1_wrusp },
+ { "osf1_wrperfmon", PAL_OSF1_wrperfmon },
+ { "osf1_rdusp", PAL_OSF1_rdusp },
+ { "osf1_whami", PAL_OSF1_whami },
+ { "osf1_retsys", PAL_OSF1_retsys },
+ { "osf1_rti", PAL_OSF1_rti },
+ { "osf1_callsys", PAL_OSF1_callsys },
+
+ { NULL, -1 },
+};
+
+static const char *pal_opname __P((int));
+
+static const char *
+pal_opname(op)
+ int op;
+{
+ static char unk[8];
+ int i;
+
+ for (i = 0; pal_op_tbl[i].name != NULL; i++) {
+ if (pal_op_tbl[i].code == op)
+ return (pal_op_tbl[i].name);
+ }
+
+ sprintf(unk, "0x%x", op);
+ return (unk);
+}
+
+/* HW (PAL) instruction qualifiers, stright tables */
+static const char *mXpr_name[8] = {
+ "", "/i", "/a", "/ai", "/p", "/pi", "/pa", "/pai"
+};
+static const char *hwlds_name[8] = {
+ "", "/r", "/a", "/ar", "/p", "/p?r", "_l-c", "_l-c/?r"
+};
+
+/*
+ * For this one we take the low nibble (valid values 0/2/9/b/d)
+ * and shift it down one to get the row index. Within a row
+ * we can just take the high nibble deprived of the high bit
+ * (valid values 0/1/2/3/4/6). We could have used a flat 64
+ * entry array, but in this way we use just 48 pointers.
+ * BUGFIX: the 'cmpbge 0x0f' opcode fits in here too
+ */
+static const char *arit_c0[8] = {
+ "addl", 0, "addq", 0, "addl/v", 0, "addq/v",
+};
+static const char *arit_c2[8] = {
+ "s4addl", "s8addl", "s4addq", "s8addq",
+};
+static const char *arit_c9[8] = {
+ "subl", 0, "subq", 0, "subl/v", 0, "subq/v",
+};
+static const char *arit_cB[8] = {
+ "s4subl", "s8subl", "s4subq", "s8subq",
+};
+static const char *arit_cD[8] = {
+ 0, "cmpult", "cmpeq", "cmpule", "cmplt", 0, "cmple",
+};
+static const char *arit_cF[1] = {
+ "cmpbge"
+};
+static const char **arit_opname[8] = {
+ arit_c0, arit_c2, 0, 0, arit_c9, arit_cB, arit_cD, arit_cF
+};
+
+static __inline const char *arit_name __P((int));
+static __inline const char *
+arit_name(op)
+ int op;
+{
+ static char unk[32];
+ const char *name = NULL;
+
+ if (arit_opname[((op)&0xe)>>1])
+ name = arit_opname[((op)&0xe)>>1][((op)&0x70)>>4];
+
+ if (name != NULL)
+ return (name);
+
+ sprintf(unk, "?arit 0x%x?", op);
+ return (unk);
+}
+
+/*
+ * Something similar for this one, except there are only
+ * 16 entries so the row indexing is done by enumeration
+ * of the low nibble (valid values 0/4/6/8). Then we can
+ * just shift the high nibble to index inside the row
+ * (valid values are 0/2/4 or 1/2/4/6)
+ *
+ * There are two functions that don't play by these simple rules,
+ * so we special-case them.
+ */
+static const char *logical_c0[4] = {
+ "and", "or", "xor", 0
+};
+static const char *logical_c4[4] = {
+ "cmovlbs", "cmoveq", "cmovlt", "cmovle"
+};
+static const char *logical_c6[4] = {
+ "cmovlbc", "cmovne", "cmovge", "cmovgt"
+};
+static const char *logical_c8[4] = {
+ "andnot", "ornot", "xornot", 0
+};
+
+static __inline const char *logical_name __P((int));
+static __inline const char *
+logical_name(op)
+ int op;
+{
+ static char unk[32];
+ const char *name = NULL;
+
+ if (op == op_amask)
+ return ("amask");
+ else if (op == op_implver)
+ return ("implver");
+
+ switch (op & 0xf) {
+ case 0: name = logical_c0[((op)>>5)&3]; break;
+ case 4: name = logical_c4[((op)>>5)&3]; break;
+ case 6: name = logical_c6[((op)>>5)&3]; break;
+ case 8: name = logical_c8[((op)>>5)&3]; break;
+ }
+
+ if (name != NULL)
+ return (name);
+
+ sprintf(unk, "?logical 0x%x?", op);
+ return (unk);
+}
+
+/*
+ * This is the messy one. First, we single out the dense
+ * case of a 3 in the high nibble (valid values 0/1/2/4/6/9/b/c).
+ * Then the case of a 2 in the low nibble (valid values 0/1/2/5/6/7).
+ * For the remaining codes (6/7/a/b) we do as above: high
+ * nibble has valid values 0/1/2 or 5/6/7. The low nibble
+ * can be used as row index picking bits 0 and 2, for the
+ * high one just the lower two bits.
+ */
+static const char *bitop_c3[8] = {
+ "zapnot", "mskql", "srl", "extql", "sll", "insql", "sra", 0
+};
+static const char *bitop_c2[8] = {
+ "mskbl", "mskwl", "mskll", 0/*mskql*/, 0, "mskwh", "msklh", "mskqh"
+};
+static const char *bitop_c67ab[4][4] = {
+/* a */ { 0, "extwh", "extlh", "extqh"},
+/* b */ { "insbl", "inswl", "insll", 0 },
+/* 6 */ { "extbl", "extwl", "extll", 0 },
+/* 7 */ { 0, "inswh", "inslh", "insqh" },
+};
+
+static __inline const char *bitop_name __P((int));
+static __inline const char *
+bitop_name(op)
+ int op;
+{
+ static char unk[32];
+ const char *name = NULL;
+
+ if ((op & 0x70) == 0x30)
+ name = (op == op_zap) ? "zap" : bitop_c3[((op)&0xe)>>1];
+ else if ((op & 0xf) == 0x02)
+ name = bitop_c2[(op)>>4];
+ else
+ name =
+ bitop_c67ab[(((op)&1)|(((op)&0x4)>>1))][(((op)&0x30)>>4)];
+
+ if (name != NULL)
+ return (name);
+
+ sprintf(unk, "?bit 0x%x?", op);
+ return (unk);
+}
+
+/*
+ * Only 5 entries in this one
+ */
+static const char *mul_opname[4] = {
+ "mull", "mulq", "mull/v", "mulq/v"
+};
+
+static __inline const char *mul_name __P((int));
+static __inline const char *
+mul_name(op)
+ int op;
+{
+ static char unk[32];
+ const char *name = NULL;
+
+ name = (op == op_umulh) ? "umulh" : mul_opname[((op)>>5)&3];
+
+ if (name != NULL)
+ return (name);
+
+ sprintf(unk, "?mul 0x%x?", op);
+ return (unk);
+}
+
+/*
+ * These are few, the high nibble is enough to dispatch.
+ * We single out the "f" case to halve the table size.
+ */
+static const char *special_opname[8] = {
+ "drain_t", 0, "mb", 0, "fetch", "fetch_m", "rpcc", "rc"
+};
+
+static __inline const char *special_name __P((int));
+static __inline const char *
+special_name(op)
+ int op;
+{
+ static char unk[32];
+ const char *name;
+
+ name = (op == op_rs) ? "rs" : special_opname[(op)>>13];
+
+ if (name != NULL)
+ return (name);
+
+ sprintf(unk, "?special 0x%x?", op);
+ return (unk);
+}
+
+/*
+ * This is trivial
+ */
+static const char *jump_opname[4] = {
+ "jmp", "jsr", "ret", "jcr"
+};
+#define jump_name(ix) jump_opname[ix]
+
+/*
+ * For all but 4 of these, we can dispatch on the lower nibble of
+ * the "function".
+ */
+static const char *intmisc_opname_3x[16] = {
+ "ctpop", "perr", "ctlz", "cttz", "unpkbw", "unpkbl", "pkwb",
+ "pklb", "minsb8", "minsw4", "minub8", "minuw4", "maxub8",
+ "maxuw4", "maxsb8", "maxsw4",
+};
+
+static __inline const char *intmisc_name __P((int));
+static __inline const char *
+intmisc_name(op)
+ int op;
+{
+ static char unk[32];
+
+ if ((op & 0xf0) == 0x30)
+ return (intmisc_opname_3x[op & 0x0f]);
+
+ switch (op) {
+ case op_sextb: return ("sextb");
+ case op_sextw: return ("sextw");
+ case op_ftoit: return ("ftoit");
+ case op_ftois: return ("ftois");
+ }
+
+ sprintf(unk, "?intmisc 0x%x?", op);
+ return (unk);
+}
+
+static const char *float_name __P((const struct tbl[], int, const char *type));
+
+static const char *
+float_name(tbl, op, type)
+ const struct tbl tbl[];
+ int op;
+ const char *type;
+{
+ static char unk[32];
+ int i;
+
+ for (i = 0; tbl[i].name != NULL; i++) {
+ if (tbl[i].code == op)
+ return (tbl[i].name);
+ }
+
+ sprintf(unk, "?%s 0x%x?", type, op);
+ return (unk);
+}
+
+#define vaxf_name(op) float_name(vaxf_tbl, op, "vaxfl")
+#define ieeef_name(op) float_name(ieeef_tbl, op, "ieeefl")
+#define anyf_name(op) float_name(anyf_tbl, op, "anyfl")
+
+static const struct tbl anyf_tbl[] = {
+ { "cvtlq", 0x010},
+ { "cpys", 0x020},
+ { "cpysn", 0x021},
+ { "cpyse", 0x022},
+ { "mt_fpcr", 0x024},
+ { "mf_fpcr", 0x025},
+ { "fcmoveq", 0x02a},
+ { "fcmovne", 0x02b},
+ { "fcmovlt", 0x02c},
+ { "fcmovge", 0x02d},
+ { "fcmovle", 0x02e},
+ { "fcmovgt", 0x02f},
+ { "cvtql", 0x030},
+ { "cvtql/v", 0x130},
+ { "cvtql/sv", 0x330},
+ { 0, 0},
+};
+
+static const struct tbl ieeef_tbl[] = {
+ { "adds/c", 0x000},
+ { "subs/c", 0x001},
+ { "muls/c", 0x002},
+ { "divs/c", 0x003},
+ { "addt/c", 0x020},
+ { "subt/c", 0x021},
+ { "mult/c", 0x022},
+ { "divt/c", 0x023},
+ { "cvtts/c", 0x02c},
+ { "cvttq/c", 0x02f},
+ { "cvtqs/c", 0x03c},
+ { "cvtqt/c", 0x03e},
+ { "adds/m", 0x040},
+ { "subs/m", 0x041},
+ { "muls/m", 0x042},
+ { "divs/m", 0x043},
+ { "addt/m", 0x060},
+ { "subt/m", 0x061},
+ { "mult/m", 0x062},
+ { "divt/m", 0x063},
+ { "cvtts/m", 0x06c},
+ { "cvtqs/m", 0x07c},
+ { "cvtqt/m", 0x07e},
+ { "adds", 0x080},
+ { "subs", 0x081},
+ { "muls", 0x082},
+ { "divs", 0x083},
+ { "addt", 0x0a0},
+ { "subt", 0x0a1},
+ { "mult", 0x0a2},
+ { "divt", 0x0a3},
+ { "cmptun", 0x0a4},
+ { "cmpteq", 0x0a5},
+ { "cmptlt", 0x0a6},
+ { "cmptle", 0x0a7},
+ { "cvtts", 0x0ac},
+ { "cvttq", 0x0af},
+ { "cvtqs", 0x0bc},
+ { "cvtqt", 0x0be},
+ { "adds/d", 0x0c0},
+ { "subs/d", 0x0c1},
+ { "muls/d", 0x0c2},
+ { "divs/d", 0x0c3},
+ { "addt/d", 0x0e0},
+ { "subt/d", 0x0e1},
+ { "mult/d", 0x0e2},
+ { "divt/d", 0x0e3},
+ { "cvtts/d", 0x0ec},
+ { "cvtqs/d", 0x0fc},
+ { "cvtqt/d", 0x0fe},
+ { "adds/uc", 0x100},
+ { "subs/uc", 0x101},
+ { "muls/uc", 0x102},
+ { "divs/uc", 0x103},
+ { "addt/uc", 0x120},
+ { "subt/uc", 0x121},
+ { "mult/uc", 0x122},
+ { "divt/uc", 0x123},
+ { "cvtts/uc", 0x12c},
+ { "cvttq/vc", 0x12f},
+ { "adds/um", 0x140},
+ { "subs/um", 0x141},
+ { "muls/um", 0x142},
+ { "divs/um", 0x143},
+ { "addt/um", 0x160},
+ { "subt/um", 0x161},
+ { "mult/um", 0x162},
+ { "divt/um", 0x163},
+ { "cvtts/um", 0x16c},
+ { "adds/u", 0x180},
+ { "subs/u", 0x181},
+ { "muls/u", 0x182},
+ { "divs/u", 0x183},
+ { "addt/u", 0x1a0},
+ { "subt/u", 0x1a1},
+ { "mult/u", 0x1a2},
+ { "divt/u", 0x1a3},
+ { "cvtts/u", 0x1ac},
+ { "cvttq/v", 0x1af},
+ { "adds/ud", 0x1c0},
+ { "subs/ud", 0x1c1},
+ { "muls/ud", 0x1c2},
+ { "divs/ud", 0x1c3},
+ { "addt/ud", 0x1e0},
+ { "subt/ud", 0x1e1},
+ { "mult/ud", 0x1e2},
+ { "divt/ud", 0x1e3},
+ { "cvtts/ud", 0x1ec},
+ { "adds/suc", 0x500},
+ { "subs/suc", 0x501},
+ { "muls/suc", 0x502},
+ { "divs/suc", 0x503},
+ { "addt/suc", 0x520},
+ { "subt/suc", 0x521},
+ { "mult/suc", 0x522},
+ { "divt/suc", 0x523},
+ { "cvtts/suc", 0x52c},
+ { "cvttq/svc", 0x52f},
+ { "adds/sum", 0x540},
+ { "subs/sum", 0x541},
+ { "muls/sum", 0x542},
+ { "divs/sum", 0x543},
+ { "addt/sum", 0x560},
+ { "subt/sum", 0x561},
+ { "mult/sum", 0x562},
+ { "divt/sum", 0x563},
+ { "cvtts/sum", 0x56c},
+ { "adds/su", 0x580},
+ { "subs/su", 0x581},
+ { "muls/su", 0x582},
+ { "divs/su", 0x583},
+ { "addt/su", 0x5a0},
+ { "subt/su", 0x5a1},
+ { "mult/su", 0x5a2},
+ { "divt/su", 0x5a3},
+ { "cmptun/su", 0x5a4},
+ { "cmpteq/su", 0x5a5},
+ { "cmptlt/su", 0x5a6},
+ { "cmptle/su", 0x5a7},
+ { "cvtts/su", 0x5ac},
+ { "cvttq/sv", 0x5af},
+ { "adds/sud", 0x5c0},
+ { "subs/sud", 0x5c1},
+ { "muls/sud", 0x5c2},
+ { "divs/sud", 0x5c3},
+ { "addt/sud", 0x5e0},
+ { "subt/sud", 0x5e1},
+ { "mult/sud", 0x5e2},
+ { "divt/sud", 0x5e3},
+ { "cvtts/sud", 0x5ec},
+ { "adds/suic", 0x700},
+ { "subs/suic", 0x701},
+ { "muls/suic", 0x702},
+ { "divs/suic", 0x703},
+ { "addt/suic", 0x720},
+ { "subt/suic", 0x721},
+ { "mult/suic", 0x722},
+ { "divt/suic", 0x723},
+ { "cvtts/suic", 0x72c},
+ { "cvttq/svic", 0x72f},
+ { "cvtqs/suic", 0x73c},
+ { "cvtqt/suic", 0x73e},
+ { "adds/suim", 0x740},
+ { "subs/suim", 0x741},
+ { "muls/suim", 0x742},
+ { "divs/suim", 0x743},
+ { "addt/suim", 0x760},
+ { "subt/suim", 0x761},
+ { "mult/suim", 0x762},
+ { "divt/suim", 0x763},
+ { "cvtts/suim", 0x76c},
+ { "cvtqs/suim", 0x77c},
+ { "cvtqt/suim", 0x77e},
+ { "adds/sui", 0x780},
+ { "subs/sui", 0x781},
+ { "muls/sui", 0x782},
+ { "divs/sui", 0x783},
+ { "addt/sui", 0x7a0},
+ { "subt/sui", 0x7a1},
+ { "mult/sui", 0x7a2},
+ { "divt/sui", 0x7a3},
+ { "cvtts/sui", 0x7ac},
+ { "cvttq/svi", 0x7af},
+ { "cvtqs/sui", 0x7bc},
+ { "cvtqt/sui", 0x7be},
+ { "adds/suid", 0x7c0},
+ { "subs/suid", 0x7c1},
+ { "muls/suid", 0x7c2},
+ { "divs/suid", 0x7c3},
+ { "addt/suid", 0x7e0},
+ { "subt/suid", 0x7e1},
+ { "mult/suid", 0x7e2},
+ { "divt/suid", 0x7e3},
+ { "cvtts/suid", 0x7ec},
+ { "cvtqs/suid", 0x7fc},
+ { "cvtqt/suid", 0x7fe},
+ { 0, 0}
+};
+
+static const struct tbl vaxf_tbl[] = {
+ { "addf/c", 0x000},
+ { "subf/c", 0x001},
+ { "mulf/c", 0x002},
+ { "divf/c", 0x003},
+ { "cvtdg/c", 0x01e},
+ { "addg/c", 0x020},
+ { "subg/c", 0x021},
+ { "mulg/c", 0x022},
+ { "divg/c", 0x023},
+ { "cvtgf/c", 0x02c},
+ { "cvtgd/c", 0x02d},
+ { "cvtgq/c", 0x02f},
+ { "cvtqf/c", 0x03c},
+ { "cvtqg/c", 0x03e},
+ { "addf", 0x080},
+ { "subf", 0x081},
+ { "mulf", 0x082},
+ { "divf", 0x083},
+ { "cvtdg", 0x09e},
+ { "addg", 0x0a0},
+ { "subg", 0x0a1},
+ { "mulg", 0x0a2},
+ { "divg", 0x0a3},
+ { "cmpgeq", 0x0a5},
+ { "cmpglt", 0x0a6},
+ { "cmpgle", 0x0a7},
+ { "cvtgf", 0x0ac},
+ { "cvtgd", 0x0ad},
+ { "cvtgq", 0x0af},
+ { "cvtqf", 0x0bc},
+ { "cvtqg", 0x0be},
+ { "addf/uc", 0x100},
+ { "subf/uc", 0x101},
+ { "mulf/uc", 0x102},
+ { "divf/uc", 0x103},
+ { "cvtdg/uc", 0x11e},
+ { "addg/uc", 0x120},
+ { "subg/uc", 0x121},
+ { "mulg/uc", 0x122},
+ { "divg/uc", 0x123},
+ { "cvtgf/uc", 0x12c},
+ { "cvtgd/uc", 0x12d},
+ { "cvtgq/vc", 0x12f},
+ { "addf/u", 0x180},
+ { "subf/u", 0x181},
+ { "mulf/u", 0x182},
+ { "divf/u", 0x183},
+ { "cvtdg/u", 0x19e},
+ { "addg/u", 0x1a0},
+ { "subg/u", 0x1a1},
+ { "mulg/u", 0x1a2},
+ { "divg/u", 0x1a3},
+ { "cvtgf/u", 0x1ac},
+ { "cvtgd/u", 0x1ad},
+ { "cvtgq/v", 0x1af},
+ { "addf/sc", 0x400},
+ { "subf/sc", 0x401},
+ { "mulf/sc", 0x402},
+ { "divf/sc", 0x403},
+ { "cvtdg/sc", 0x41e},
+ { "addg/sc", 0x420},
+ { "subg/sc", 0x421},
+ { "mulg/sc", 0x422},
+ { "divg/sc", 0x423},
+ { "cvtgf/sc", 0x42c},
+ { "cvtgd/sc", 0x42d},
+ { "cvtgq/sc", 0x42f},
+ { "cvtqf/sc", 0x43c},
+ { "cvtqg/sc", 0x43e},
+ { "addf/s", 0x480},
+ { "subf/s", 0x481},
+ { "mulf/s", 0x482},
+ { "divf/s", 0x483},
+ { "cvtdg/s", 0x49e},
+ { "addg/s", 0x4a0},
+ { "subg/s", 0x4a1},
+ { "mulg/s", 0x4a2},
+ { "divg/s", 0x4a3},
+ { "cmpgeq/s", 0x4a5},
+ { "cmpglt/s", 0x4a6},
+ { "cmpgle/s", 0x4a7},
+ { "cvtgf/s", 0x4ac},
+ { "cvtgd/s", 0x4ad},
+ { "cvtgq/s", 0x4af},
+ { "cvtqf/s", 0x4bc},
+ { "cvtqg/s", 0x4be},
+ { "addf/suc", 0x500},
+ { "subf/suc", 0x501},
+ { "mulf/suc", 0x502},
+ { "divf/suc", 0x503},
+ { "cvtdg/suc", 0x51e},
+ { "addg/suc", 0x520},
+ { "subg/suc", 0x521},
+ { "mulg/suc", 0x522},
+ { "divg/suc", 0x523},
+ { "cvtgf/suc", 0x52c},
+ { "cvtgd/suc", 0x52d},
+ { "cvtgq/svc", 0x52f},
+ { "addf/su", 0x580},
+ { "subf/su", 0x581},
+ { "mulf/su", 0x582},
+ { "divf/su", 0x583},
+ { "cvtdg/su", 0x59e},
+ { "addg/su", 0x5a0},
+ { "subg/su", 0x5a1},
+ { "mulg/su", 0x5a2},
+ { "divg/su", 0x5a3},
+ { "cvtgf/su", 0x5ac},
+ { "cvtgd/su", 0x5ad},
+ { "cvtgq/sv", 0x5af},
+ { 0, 0}
+};
+
+/*
+ * General purpose registers
+ */
+static const char *name_of_register[32] = {
+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6",
+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
+ "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"
+};
+
+static int regcount; /* how many regs used in this inst */
+static int regnum[3]; /* which regs used in this inst */
+
+static const char *register_name __P((int));
+
+static const char *
+register_name (ireg)
+ int ireg;
+{
+ int i;
+
+ for (i = 0; i < regcount; i++)
+ if (regnum[i] == ireg)
+ break;
+ if (i >= regcount)
+ regnum[regcount++] = ireg;
+ return (name_of_register[ireg]);
+}
+
+/*
+ * Disassemble instruction at 'loc'. 'altfmt' specifies an
+ * (optional) alternate format. Return address of start of
+ * next instruction.
+ */
+int alpha_print_instruction __P((db_addr_t, alpha_instruction, boolean_t));
+
+db_addr_t
+db_disasm(loc, altfmt)
+ db_addr_t loc;
+ boolean_t altfmt;
+{
+ alpha_instruction inst;
+
+ inst.bits = db_get_value(loc, 4, 0);
+
+ loc += alpha_print_instruction(loc, inst, altfmt);
+ return (loc);
+}
+
+int
+alpha_print_instruction(iadr, i, showregs)
+ db_addr_t iadr;
+ alpha_instruction i;
+ boolean_t showregs;
+{
+ const char *opcode;
+ int ireg;
+ long signed_immediate;
+ boolean_t fstore;
+ pal_instruction p;
+
+ regcount = 0;
+ fstore = FALSE;
+ opcode = op_name[i.mem_format.opcode];
+
+ /*
+ * Dispatch directly on the opcode, save code
+ * duplication sometimes via "harmless gotos".
+ */
+ switch (i.mem_format.opcode) {
+ case op_pal:
+ /* "call_pal" is a long string; just use a space. */
+ db_printf("%s %s", opcode, pal_opname(i.pal_format.function));
+ break;
+ case op_lda:
+ case op_ldah:
+ case op_ldbu:
+ case op_ldq_u:
+ case op_ldwu:
+ case op_stw:
+ case op_stb:
+ case op_stq_u:
+ /*
+ * These loadstores are here to make compiling the
+ * switch a bit easier. Could embellish the output
+ * someday, too.
+ */
+ goto loadstore;
+ break;
+ case op_arit:
+ /*
+ * For this and the following three groups we
+ * just need different opcode strings
+ */
+ opcode = arit_name(i.operate_lit_format.function);
+ goto operate;
+ break;
+ case op_logical:
+ opcode = logical_name(i.operate_lit_format.function);
+ goto operate;
+ break;
+ case op_bit:
+ opcode = bitop_name(i.operate_lit_format.function);
+ goto operate;
+ break;
+ case op_mul:
+ opcode = mul_name(i.operate_lit_format.function);
+operate:
+ /*
+ * Nice and uniform, just check for literals
+ */
+ db_printf("%s\t%s,", opcode,
+ register_name(i.operate_lit_format.rs));
+ if (i.operate_lit_format.one)
+ db_printf("#0x%x", i.operate_lit_format.literal);
+ else
+ db_printf("%s", register_name(i.operate_reg_format.rt));
+ db_printf(",%s", register_name(i.operate_lit_format.rd));
+ break;
+ case op_vax_float:
+ /*
+ * The three floating point groups are even simpler
+ */
+ opcode = vaxf_name(i.float_format.function);
+ goto foperate;
+ break;
+ case op_ieee_float:
+ opcode = ieeef_name(i.float_format.function);
+ goto foperate;
+ break;
+ case op_any_float:
+ opcode = anyf_name(i.float_format.function);
+foperate:
+ db_printf("%s\tf%d,f%d,f%d", opcode,
+ i.float_format.fs,
+ i.float_format.ft,
+ i.float_format.fd);
+ break;
+ case op_special:
+ /*
+ * Miscellaneous.
+ */
+ {
+ register unsigned int code;
+
+ code = (i.mem_format.displacement)&0xffff;
+ opcode = special_name(code);
+
+ switch (code) {
+ case op_fetch:
+ case op_fetch_m:
+ db_printf("%s\t0(%s)", opcode,
+ register_name(i.mem_format.rs));
+ break;
+ case op_rpcc:
+ case op_rc:
+ case op_rs:
+ db_printf("%s\t%s", opcode,
+ register_name(i.mem_format.rd));
+ break;
+ case op_draint:
+ case op_mb:
+ default:
+ db_printf("%s", opcode);
+ break;
+ }
+ }
+ break;
+ case op_j:
+ /*
+ * Jump instructions really are of two sorts,
+ * depending on the use of the hint info.
+ */
+ opcode = jump_name(i.jump_format.action);
+ switch (i.jump_format.action) {
+ case op_jmp:
+ case op_jsr:
+ db_printf("%s\t%s,(%s),", opcode,
+ register_name(i.jump_format.rd),
+ register_name(i.jump_format.rs));
+ signed_immediate = i.jump_format.hint;
+ goto branch_displacement;
+ break;
+ case op_ret:
+ case op_jcr:
+ db_printf("%s\t%s,(%s)", opcode,
+ register_name(i.jump_format.rd),
+ register_name(i.jump_format.rs));
+ break;
+ }
+ break;
+ case op_intmisc:
+ /*
+ * These are just in "operate" format.
+ */
+ opcode = intmisc_name(i.operate_lit_format.function);
+ goto operate;
+ break;
+ /* HW instructions, possibly chip-specific XXXX */
+ case op_pal19: /* "hw_mfpr" */
+ case op_pal1d: /* "hw_mtpr" */
+ p.bits = i.bits;
+ db_printf("\t%s%s\t%s, %d", opcode,
+ mXpr_name[p.mXpr_format.regset],
+ register_name(p.mXpr_format.rd),
+ p.mXpr_format.index);
+ break;
+ case op_pal1b: /* "hw_ld" */
+ case op_pal1f: /* "hw_st" */
+ p.bits = i.bits;
+ db_printf("\t%s%c%s\t%s,", opcode,
+ (p.mem_format.qw) ? 'q' : 'l',
+ hwlds_name[p.mem_format.qualif],
+ register_name(p.mem_format.rd));
+ signed_immediate = (long)p.mem_format.displacement;
+ goto loadstore_address;
+
+ case op_pal1e: /* "hw_rei" */
+ db_printf("\t%s", opcode);
+ break;
+
+ case op_ldf:
+ case op_ldg:
+ case op_lds:
+ case op_ldt:
+ case op_stf:
+ case op_stg:
+ case op_sts:
+ case op_stt:
+ fstore = TRUE;
+ /* fall through */
+ case op_ldl:
+ case op_ldq:
+ case op_ldl_l:
+ case op_ldq_l:
+ case op_stl:
+ case op_stq:
+ case op_stl_c:
+ case op_stq_c:
+ /*
+ * Memory operations, including floats
+ */
+loadstore:
+ if (fstore)
+ db_printf("%s\tf%d,", opcode, i.mem_format.rd);
+ else
+ db_printf("%s\t%s,", opcode,
+ register_name(i.mem_format.rd));
+ signed_immediate = (long)i.mem_format.displacement;
+loadstore_address:
+ db_printf("%+#lx(%s)", signed_immediate,
+ register_name(i.mem_format.rs));
+ /*
+ * For convenience, do the address computation
+ */
+ if (showregs) {
+ if (i.mem_format.opcode == op_ldah)
+ signed_immediate <<= 16;
+ db_printf(" <0x%x>", signed_immediate +
+ db_register_value(DDB_REGS, i.mem_format.rs));
+ }
+ break;
+ case op_br:
+ case op_fbeq:
+ case op_fblt:
+ case op_fble:
+ case op_bsr:
+ case op_fbne:
+ case op_fbge:
+ case op_fbgt:
+ case op_blbc:
+ case op_beq:
+ case op_blt:
+ case op_ble:
+ case op_blbs:
+ case op_bne:
+ case op_bge:
+ case op_bgt:
+ /*
+ * We want to know where we are branching to
+ */
+ signed_immediate = (long)i.branch_format.displacement;
+ db_printf("%s\t%s,", opcode,
+ register_name(i.branch_format.rd));
+branch_displacement:
+ db_printsym(iadr + sizeof(alpha_instruction) +
+ (signed_immediate << 2), DB_STGY_PROC);
+ break;
+ default:
+ /*
+ * Shouldn't happen
+ */
+ db_printf("? 0x%x ?", i.bits);
+ }
+
+ /*
+ * Print out the registers used in this instruction
+ */
+ if (showregs && regcount > 0) {
+ db_printf("\t<");
+ for (ireg = 0; ireg < regcount; ireg++) {
+ if (ireg != 0)
+ db_printf(",");
+ db_printf("%s=0x%lx",
+ name_of_register[regnum[ireg]],
+ db_register_value(DDB_REGS, regnum[ireg]));
+ }
+ db_printf(">");
+ }
+ db_printf("\n");
+ return (sizeof(alpha_instruction));
+}
diff --git a/sys/alpha/alpha/db_instruction.h b/sys/alpha/alpha/db_instruction.h
new file mode 100644
index 000000000000..54d9d115872e
--- /dev/null
+++ b/sys/alpha/alpha/db_instruction.h
@@ -0,0 +1,672 @@
+/* $NetBSD: db_instruction.h,v 1.4 1997/09/16 22:53:32 thorpej Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1993,1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ * File: alpha_instruction.h
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 11/91
+ *
+ * Alpha Instruction set definition
+ *
+ * Reference: "Alpha System Reference Manual", V4.0, April 1991
+ *
+ */
+
+#ifndef _ALPHA_INSTRUCTION_H_
+#define _ALPHA_INSTRUCTION_H_ 1
+
+#if !defined(ASSEMBLER)
+
+/*
+ * All instructions are in one of five formats:
+ * Memory, Branch, Operate, Floating-point Operate, PAL
+ *
+ * One minor departure from DEC's conventions is we use names
+ * for registers that are more akin their software use, e.g.
+ * rather then bluntly call them Ra/Rb/Rc we make clear which
+ * one is a source (Rs) and which one is a destination (Rd).
+ * When a second source register is defined we call it Rt.
+ */
+
+
+typedef union {
+ /*
+ * All instructions are 32 bits wide
+ */
+ unsigned int bits;
+
+ /*
+ * Memory instructions contain a 16 bit
+ * signed immediate value and two register
+ * specifiers
+ */
+ struct {
+ signed short displacement;
+ unsigned rs : 5,
+ rd : 5,
+ opcode : 6;
+ } mem_format;
+
+ /*
+ * Branch instruction contain a 21 bit offset,
+ * which is sign-extended, shifted and combined
+ * with the PC to form a 64 bit destination address.
+ *
+ * In computed jump instructions the opcode is further
+ * specified in the offset field, the rest of it is
+ * used as branch target hint. The destination of the
+ * jump is the source register.
+ */
+ struct {
+ signed int displacement : 21;
+ unsigned rd : 5,
+ opcode : 6;
+ } branch_format;
+
+ struct {
+ signed int hint : 14;
+ unsigned action : 2,
+ rs : 5,
+ rd : 5,
+ opcode : 6;
+ } jump_format;
+
+
+ /*
+ * Operate instructions are of two types, with
+ * a second source register or with a literal
+ * specifier. Bit 12 sez which is which.
+ */
+ struct {
+ unsigned rd : 5,
+ function : 7,
+ sbz : 4,
+ rt : 5,
+ rs : 5,
+ opcode : 6;
+ } operate_reg_format;
+
+ struct {
+ unsigned rd : 5,
+ function : 7,
+ one : 1,
+ literal : 8,
+ rs : 5,
+ opcode : 6;
+ } operate_lit_format;
+
+
+ /*
+ * Floating point operate instruction are quite
+ * uniform in the encoding. As for the semantics..
+ */
+ struct {
+ unsigned fd : 5,
+ function : 11,
+ ft : 5,
+ fs : 5,
+ opcode : 6;
+ } float_format;
+
+
+ /*
+ * PAL instructions just define the major opcode
+ */
+
+ struct {
+ unsigned function : 26,
+ opcode : 6;
+ } pal_format;
+
+} alpha_instruction;
+
+#endif !defined(ASSEMBLER)
+
+/*
+ *
+ * Encoding of regular instructions (Appendix C op cit)
+ *
+ */
+
+ /* OPCODE, bits 26..31 */
+
+#define op_pal 0x00 /* see PAL sub-table */
+ /* 1..7 reserved */
+#define op_lda 0x08
+#define op_ldah 0x09
+#define op_ldbu 0x0a
+#define op_ldq_u 0x0b
+#define op_ldwu 0x0c
+#define op_stw 0x0d
+#define op_stb 0x0e
+#define op_stq_u 0x0f
+
+#define op_arit 0x10 /* see ARIT sub-table */
+#define op_logical 0x11 /* see LOGICAL sub-table */
+#define op_bit 0x12 /* see BIT sub-table */
+#define op_mul 0x13 /* see MUL sub-table */
+ /* reserved */
+#define op_vax_float 0x15 /* see FLOAT sub-table */
+#define op_ieee_float 0x16 /* see FLOAT sub-table */
+#define op_any_float 0x17 /* see FLOAT sub-table */
+
+#define op_special 0x18 /* see SPECIAL sub-table */
+#define op_pal19 0x19 /* reserved for pal code */
+#define op_j 0x1a /* see JUMP sub-table */
+#define op_pal1b 0x1b /* reserved for pal code */
+#define op_intmisc 0x1c /* see INTMISC sub-table */
+#define op_pal1d 0x1d /* reserved for pal code */
+#define op_pal1e 0x1e /* reserved for pal code */
+#define op_pal1f 0x1f /* reserved for pal code */
+
+#define op_ldf 0x20
+#define op_ldg 0x21
+#define op_lds 0x22
+#define op_ldt 0x23
+#define op_stf 0x24
+#define op_stg 0x25
+#define op_sts 0x26
+#define op_stt 0x27
+#define op_ldl 0x28
+#define op_ldq 0x29
+#define op_ldl_l 0x2a
+#define op_ldq_l 0x2b
+#define op_stl 0x2c
+#define op_stq 0x2d
+#define op_stl_c 0x2e
+#define op_stq_c 0x2f
+#define op_br 0x30
+#define op_fbeq 0x31
+#define op_fblt 0x32
+#define op_fble 0x33
+#define op_bsr 0x34
+#define op_fbne 0x35
+#define op_fbge 0x36
+#define op_fbgt 0x37
+#define op_blbc 0x38
+#define op_beq 0x39
+#define op_blt 0x3a
+#define op_ble 0x3b
+#define op_blbs 0x3c
+#define op_bne 0x3d
+#define op_bge 0x3e
+#define op_bgt 0x3f
+
+
+ /* PAL, "function" opcodes (bits 0..25) */
+/*
+ * What we will implement is TBD. These are the unprivileged ones
+ * that we probably have to support for compat reasons.
+ */
+
+/* See <machine/pal.h> */
+
+ /* ARIT, "function" opcodes (bits 5..11) */
+
+#define op_addl 0x00
+#define op_s4addl 0x02
+#define op_subl 0x09
+#define op_s4subl 0x0b
+#define op_cmpbge 0x0f
+#define op_s8addl 0x12
+#define op_s8subl 0x1b
+#define op_cmpult 0x1d
+#define op_addq 0x20
+#define op_s4addq 0x22
+#define op_subq 0x29
+#define op_s4subq 0x2b
+#define op_cmpeq 0x2d
+#define op_s8addq 0x32
+#define op_s8subq 0x3b
+#define op_cmpule 0x3d
+#define op_addl_v 0x40
+#define op_subl_v 0x49
+#define op_cmplt 0x4d
+#define op_addq_v 0x60
+#define op_subq_v 0x69
+#define op_cmple 0x6d
+
+
+ /* LOGICAL, "function" opcodes (bits 5..11) */
+
+#define op_and 0x00
+#define op_andnot 0x08 /* bic */
+#define op_cmovlbs 0x14
+#define op_cmovlbc 0x16
+#define op_or 0x20 /* bis */
+#define op_cmoveq 0x24
+#define op_cmovne 0x26
+#define op_ornot 0x28
+#define op_xor 0x40
+#define op_cmovlt 0x44
+#define op_cmovge 0x46
+#define op_xornot 0x48 /* eqv */
+#define op_amask 0x61
+#define op_cmovle 0x64
+#define op_cmovgt 0x66
+#define op_implver 0x6c
+
+ /* BIT, "function" opcodes (bits 5..11) */
+
+#define op_mskbl 0x02
+#define op_extbl 0x06
+#define op_insbl 0x0b
+#define op_mskwl 0x12
+#define op_extwl 0x16
+#define op_inswl 0x1b
+#define op_mskll 0x22
+#define op_extll 0x26
+#define op_insll 0x2b
+#define op_zap 0x30
+#define op_zapnot 0x31
+#define op_mskql 0x32
+#define op_srl 0x34
+#define op_extql 0x36
+#define op_sll 0x39
+#define op_insql 0x3b
+#define op_sra 0x3c
+#define op_mskwh 0x52
+#define op_inswh 0x57
+#define op_extwh 0x5a
+#define op_msklh 0x62
+#define op_inslh 0x67
+#define op_extlh 0x6a
+#define op_extqh 0x7a
+#define op_insqh 0x77
+#define op_mskqh 0x72
+
+ /* MUL, "function" opcodes (bits 5..11) */
+
+#define op_mull 0x00
+#define op_mulq_v 0x60
+#define op_mull_v 0x40
+#define op_umulh 0x30
+#define op_mulq 0x20
+
+
+ /* SPECIAL, "displacement" opcodes (bits 0..15) */
+
+#define op_draint 0x0000
+#define op_mb 0x4000
+#define op_fetch 0x8000
+#define op_fetch_m 0xa000
+#define op_rpcc 0xc000
+#define op_rc 0xe000
+#define op_rs 0xf000
+
+ /* JUMP, "action" opcodes (bits 14..15) */
+
+#define op_jmp 0x0
+#define op_jsr 0x1
+#define op_ret 0x2
+#define op_jcr 0x3
+
+ /* INTMISC, "function" opcodes (operate format) */
+
+#define op_sextb 0x00
+#define op_sextw 0x01
+#define op_ctpop 0x30
+#define op_perr 0x31
+#define op_ctlz 0x32
+#define op_cttz 0x33
+#define op_unpkbw 0x34
+#define op_unpkbl 0x35
+#define op_pkwb 0x36
+#define op_pklb 0x37
+#define op_minsb8 0x38
+#define op_minsw4 0x39
+#define op_minub8 0x3a
+#define op_minuw4 0x3b
+#define op_maxub8 0x3c
+#define op_maxuw4 0x3d
+#define op_maxsb8 0x3e
+#define op_maxsw4 0x3f
+#define op_ftoit 0x70
+#define op_ftois 0x78
+
+/*
+ *
+ * Encoding of floating point instructions (pagg. C-5..6 op cit)
+ *
+ * Load and store operations use opcodes op_ldf..op_stt
+ */
+
+ /* any FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_cvtlq 0x010
+#define op_cpys 0x020
+#define op_cpysn 0x021
+#define op_cpyse 0x022
+#define op_mt_fpcr 0x024
+#define op_mf_fpcr 0x025
+#define op_fcmoveq 0x02a
+#define op_fcmovne 0x02b
+#define op_fcmovlt 0x02c
+#define op_fcmovge 0x02d
+#define op_fcmovle 0x02e
+#define op_fcmovgt 0x02f
+#define op_cvtql 0x030
+#define op_cvtql_v 0x130
+#define op_cvtql_sv 0x330
+
+
+ /* ieee FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_adds_c 0x000
+#define op_subs_c 0x001
+#define op_muls_c 0x002
+#define op_divs_c 0x003
+#define op_addt_c 0x020
+#define op_subt_c 0x021
+#define op_mult_c 0x022
+#define op_divt_c 0x023
+#define op_cvtts_c 0x02c
+#define op_cvttq_c 0x02f
+#define op_cvtqs_c 0x03c
+#define op_cvtqt_c 0x03e
+#define op_adds_m 0x040
+#define op_subs_m 0x041
+#define op_muls_m 0x042
+#define op_divs_m 0x043
+#define op_addt_m 0x060
+#define op_subt_m 0x061
+#define op_mult_m 0x062
+#define op_divt_m 0x063
+#define op_cvtts_m 0x06c
+#define op_cvtqs_m 0x07c
+#define op_cvtqt_m 0x07e
+#define op_adds 0x080
+#define op_subs 0x081
+#define op_muls 0x082
+#define op_divs 0x083
+#define op_addt 0x0a0
+#define op_subt 0x0a1
+#define op_mult 0x0a2
+#define op_divt 0x0a3
+#define op_cmptun 0x0a4
+#define op_cmpteq 0x0a5
+#define op_cmptlt 0x0a6
+#define op_cmptle 0x0a7
+#define op_cvtts 0x0ac
+#define op_cvttq 0x0af
+#define op_cvtqs 0x0bc
+#define op_cvtqt 0x0be
+#define op_adds_d 0x0c0
+#define op_subs_d 0x0c1
+#define op_muls_d 0x0c2
+#define op_divs_d 0x0c3
+#define op_addt_d 0x0e0
+#define op_subt_d 0x0e1
+#define op_mult_d 0x0e2
+#define op_divt_d 0x0e3
+#define op_cvtts_d 0x0ec
+#define op_cvtqs_d 0x0fc
+#define op_cvtqt_d 0x0fe
+#define op_adds_uc 0x100
+#define op_subs_uc 0x101
+#define op_muls_uc 0x102
+#define op_divs_uc 0x103
+#define op_addt_uc 0x120
+#define op_subt_uc 0x121
+#define op_mult_uc 0x122
+#define op_divt_uc 0x123
+#define op_cvtts_uc 0x12c
+#define op_cvttq_vc 0x12f
+#define op_adds_um 0x140
+#define op_subs_um 0x141
+#define op_muls_um 0x142
+#define op_divs_um 0x143
+#define op_addt_um 0x160
+#define op_subt_um 0x161
+#define op_mult_um 0x162
+#define op_divt_um 0x163
+#define op_cvtts_um 0x16c
+#define op_adds_u 0x180
+#define op_subs_u 0x181
+#define op_muls_u 0x182
+#define op_divs_u 0x183
+#define op_addt_u 0x1a0
+#define op_subt_u 0x1a1
+#define op_mult_u 0x1a2
+#define op_divt_u 0x1a3
+#define op_cvtts_u 0x1ac
+#define op_cvttq_v 0x1af
+#define op_adds_ud 0x1c0
+#define op_subs_ud 0x1c1
+#define op_muls_ud 0x1c2
+#define op_divs_ud 0x1c3
+#define op_addt_ud 0x1e0
+#define op_subt_ud 0x1e1
+#define op_mult_ud 0x1e2
+#define op_divt_ud 0x1e3
+#define op_cvtts_ud 0x1ec
+#define op_adds_suc 0x500
+#define op_subs_suc 0x501
+#define op_muls_suc 0x502
+#define op_divs_suc 0x503
+#define op_addt_suc 0x520
+#define op_subt_suc 0x521
+#define op_mult_suc 0x522
+#define op_divt_suc 0x523
+#define op_cvtts_suc 0x52c
+#define op_cvttq_svc 0x52f
+#define op_adds_sum 0x540
+#define op_subs_sum 0x541
+#define op_muls_sum 0x542
+#define op_divs_sum 0x543
+#define op_addt_sum 0x560
+#define op_subt_sum 0x561
+#define op_mult_sum 0x562
+#define op_divt_sum 0x563
+#define op_cvtts_sum 0x56c
+#define op_adds_su 0x580
+#define op_subs_su 0x581
+#define op_muls_su 0x582
+#define op_divs_su 0x583
+#define op_addt_su 0x5a0
+#define op_subt_su 0x5a1
+#define op_mult_su 0x5a2
+#define op_divt_su 0x5a3
+#define op_cmptun_su 0x5a4
+#define op_cmpteq_su 0x5a5
+#define op_cmptlt_su 0x5a6
+#define op_cmptle_su 0x5a7
+#define op_cvtts_su 0x5ac
+#define op_cvttq_sv 0x5af
+#define op_adds_sud 0x5c0
+#define op_subs_sud 0x5c1
+#define op_muls_sud 0x5c2
+#define op_divs_sud 0x5c3
+#define op_addt_sud 0x5e0
+#define op_subt_sud 0x5e1
+#define op_mult_sud 0x5e2
+#define op_divt_sud 0x5e3
+#define op_cvtts_sud 0x5ec
+#define op_adds_suic 0x700
+#define op_subs_suic 0x701
+#define op_muls_suic 0x702
+#define op_divs_suic 0x703
+#define op_addt_suic 0x720
+#define op_subt_suic 0x721
+#define op_mult_suic 0x722
+#define op_divt_suic 0x723
+#define op_cvtts_suic 0x72c
+#define op_cvttq_svic 0x72f
+#define op_cvtqs_suic 0x73c
+#define op_cvtqt_suic 0x73e
+#define op_adds_suim 0x740
+#define op_subs_suim 0x741
+#define op_muls_suim 0x742
+#define op_divs_suim 0x743
+#define op_addt_suim 0x760
+#define op_subt_suim 0x761
+#define op_mult_suim 0x762
+#define op_divt_suim 0x763
+#define op_cvtts_suim 0x76c
+#define op_cvtqs_suim 0x77c
+#define op_cvtqt_suim 0x77e
+#define op_adds_sui 0x780
+#define op_subs_sui 0x781
+#define op_muls_sui 0x782
+#define op_divs_sui 0x783
+#define op_addt_sui 0x7a0
+#define op_subt_sui 0x7a1
+#define op_mult_sui 0x7a2
+#define op_divt_sui 0x7a3
+#define op_cvtts_sui 0x7ac
+#define op_cvttq_svi 0x7af
+#define op_cvtqs_sui 0x7bc
+#define op_cvtqt_sui 0x7be
+#define op_adds_suid 0x7c0
+#define op_subs_suid 0x7c1
+#define op_muls_suid 0x7c2
+#define op_divs_suid 0x7c3
+#define op_addt_suid 0x7e0
+#define op_subt_suid 0x7e1
+#define op_mult_suid 0x7e2
+#define op_divt_suid 0x7e3
+#define op_cvtts_suid 0x7ec
+#define op_cvtqs_suid 0x7fc
+#define op_cvtqt_suid 0x7fe
+
+
+ /* vax FLOAT, "function" opcodes (bits 5..11) */
+
+#define op_addf_c 0x000
+#define op_subf_c 0x001
+#define op_mulf_c 0x002
+#define op_divf_c 0x003
+#define op_cvtdg_c 0x01e
+#define op_addg_c 0x020
+#define op_subg_c 0x021
+#define op_mulg_c 0x022
+#define op_divg_c 0x023
+#define op_cvtgf_c 0x02c
+#define op_cvtgd_c 0x02d
+#define op_cvtgqg_c 0x02f
+#define op_cvtqf_c 0x03c
+#define op_cvtqg_c 0x03e
+#define op_addf 0x080
+#define op_subf 0x081
+#define op_mulf 0x082
+#define op_divf 0x083
+#define op_cvtdg 0x09e
+#define op_addg 0x0a0
+#define op_subg 0x0a1
+#define op_mulg 0x0a2
+#define op_divg 0x0a3
+#define op_cmpgeq 0x0a5
+#define op_cmpglt 0x0a6
+#define op_cmpgle 0x0a7
+#define op_cvtgf 0x0ac
+#define op_cvtgd 0x0ad
+#define op_cvtgq 0x0af
+#define op_cvtqf 0x0bc
+#define op_cvtqg 0x0be
+#define op_addf_uc 0x100
+#define op_subf_uc 0x101
+#define op_mulf_uc 0x102
+#define op_divf_uc 0x103
+#define op_cvtdg_uc 0x11e
+#define op_addg_uc 0x120
+#define op_subg_uc 0x121
+#define op_mulg_uc 0x122
+#define op_divg_uc 0x123
+#define op_cvtgf_uc 0x12c
+#define op_cvtgd_uc 0x12d
+#define op_cvtgqg_vc 0x12f
+#define op_addf_u 0x180
+#define op_subf_u 0x181
+#define op_mulf_u 0x182
+#define op_divf_u 0x183
+#define op_cvtdg_u 0x19e
+#define op_addg_u 0x1a0
+#define op_subg_u 0x1a1
+#define op_mulg_u 0x1a2
+#define op_divg_u 0x1a3
+#define op_cvtgf_u 0x1ac
+#define op_cvtgd_u 0x1ad
+#define op_cvtgqg_v 0x1af
+#define op_addf_sc 0x400
+#define op_subf_sc 0x401
+#define op_mulf_sc 0x402
+#define op_divf_sc 0x403
+#define op_cvtdg_sc 0x41e
+#define op_addg_sc 0x420
+#define op_subg_sc 0x421
+#define op_mulg_sc 0x422
+#define op_divg_sc 0x423
+#define op_cvtgf_sc 0x42c
+#define op_cvtgd_sc 0x42d
+#define op_cvtgqg_sc 0x42f
+#define op_cvtqf_sc 0x43c
+#define op_cvtqg_sc 0x43e
+#define op_addf_s 0x480
+#define op_subf_s 0x481
+#define op_mulf_s 0x482
+#define op_divf_s 0x483
+#define op_cvtdg_s 0x49e
+#define op_addg_s 0x4a0
+#define op_subg_s 0x4a1
+#define op_mulg_s 0x4a2
+#define op_divg_s 0x4a3
+#define op_cmpgeq_s 0x4a5
+#define op_cmpglt_s 0x4a6
+#define op_cmpgle_s 0x4a7
+#define op_cvtgf_s 0x4ac
+#define op_cvtgd_s 0x4ad
+#define op_cvtgqg_s 0x4af
+#define op_cvtqf_s 0x4bc
+#define op_cvtqg_s 0x4be
+#define op_addf_suc 0x500
+#define op_subf_suc 0x501
+#define op_mulf_suc 0x502
+#define op_divf_suc 0x503
+#define op_cvtdg_suc 0x51e
+#define op_addg_suc 0x520
+#define op_subg_suc 0x521
+#define op_mulg_suc 0x522
+#define op_divg_suc 0x523
+#define op_cvtgf_suc 0x52c
+#define op_cvtgd_suc 0x52d
+#define op_cvtgqg_svc 0x52f
+#define op_addf_su 0x580
+#define op_subf_su 0x581
+#define op_mulf_su 0x582
+#define op_divf_su 0x583
+#define op_cvtdg_su 0x59e
+#define op_addg_su 0x5a0
+#define op_subg_su 0x5a1
+#define op_mulg_su 0x5a2
+#define op_divg_su 0x5a3
+#define op_cvtgf_su 0x5ac
+#define op_cvtgd_su 0x5ad
+#define op_cvtgqg_sv 0x5af
+
+
+#endif /* _ALPHA_INSTRUCTION_H_ */
diff --git a/sys/alpha/alpha/db_interface.c b/sys/alpha/alpha/db_interface.c
new file mode 100644
index 000000000000..c93e50641578
--- /dev/null
+++ b/sys/alpha/alpha/db_interface.c
@@ -0,0 +1,536 @@
+/* $NetBSD: db_interface.c,v 1.2 1997/09/16 19:07:19 thorpej Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992,1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
+ */
+
+/*
+ * Parts of this file are derived from Mach 3:
+ *
+ * File: alpha_instruction.c
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 6/92
+ */
+
+/*
+ * Interface to DDB.
+ *
+ * Modified for NetBSD/alpha by:
+ *
+ * Christopher G. Demetriou, Carnegie Mellon University
+ *
+ * Jason R. Thorpe, Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+/* __KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.2 1997/09/16 19:07:19 thorpej Exp $"); */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+
+#include <machine/cons.h>
+
+#include <machine/db_machdep.h>
+#include <machine/pal.h>
+#include <machine/prom.h>
+
+#include <alpha/alpha/db_instruction.h>
+
+#include <ddb/ddb.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_variables.h>
+
+extern label_t *db_recover;
+
+#if 0
+extern char *trap_type[];
+extern int trap_types;
+#endif
+
+int db_active = 0;
+
+void ddbprinttrap __P((unsigned long, unsigned long, unsigned long,
+ unsigned long));
+
+struct db_variable db_regs[] = {
+ { "v0", &ddb_regs.tf_regs[FRAME_V0], FCN_NULL },
+ { "t0", &ddb_regs.tf_regs[FRAME_T0], FCN_NULL },
+ { "t1", &ddb_regs.tf_regs[FRAME_T1], FCN_NULL },
+ { "t2", &ddb_regs.tf_regs[FRAME_T2], FCN_NULL },
+ { "t3", &ddb_regs.tf_regs[FRAME_T3], FCN_NULL },
+ { "t4", &ddb_regs.tf_regs[FRAME_T4], FCN_NULL },
+ { "t5", &ddb_regs.tf_regs[FRAME_T5], FCN_NULL },
+ { "t6", &ddb_regs.tf_regs[FRAME_T6], FCN_NULL },
+ { "t7", &ddb_regs.tf_regs[FRAME_T7], FCN_NULL },
+ { "s0", &ddb_regs.tf_regs[FRAME_S0], FCN_NULL },
+ { "s1", &ddb_regs.tf_regs[FRAME_S1], FCN_NULL },
+ { "s2", &ddb_regs.tf_regs[FRAME_S2], FCN_NULL },
+ { "s3", &ddb_regs.tf_regs[FRAME_S3], FCN_NULL },
+ { "s4", &ddb_regs.tf_regs[FRAME_S4], FCN_NULL },
+ { "s5", &ddb_regs.tf_regs[FRAME_S5], FCN_NULL },
+ { "s6", &ddb_regs.tf_regs[FRAME_S6], FCN_NULL },
+ { "a0", &ddb_regs.tf_regs[FRAME_A0], FCN_NULL },
+ { "a1", &ddb_regs.tf_regs[FRAME_A1], FCN_NULL },
+ { "a2", &ddb_regs.tf_regs[FRAME_A2], FCN_NULL },
+ { "a3", &ddb_regs.tf_regs[FRAME_A3], FCN_NULL },
+ { "a4", &ddb_regs.tf_regs[FRAME_A4], FCN_NULL },
+ { "a5", &ddb_regs.tf_regs[FRAME_A5], FCN_NULL },
+ { "t8", &ddb_regs.tf_regs[FRAME_T8], FCN_NULL },
+ { "t9", &ddb_regs.tf_regs[FRAME_T9], FCN_NULL },
+ { "t10", &ddb_regs.tf_regs[FRAME_T10], FCN_NULL },
+ { "t11", &ddb_regs.tf_regs[FRAME_T11], FCN_NULL },
+ { "ra", &ddb_regs.tf_regs[FRAME_RA], FCN_NULL },
+ { "t12", &ddb_regs.tf_regs[FRAME_T12], FCN_NULL },
+ { "at", &ddb_regs.tf_regs[FRAME_AT], FCN_NULL },
+ { "gp", &ddb_regs.tf_regs[FRAME_GP], FCN_NULL },
+ { "sp", &ddb_regs.tf_regs[FRAME_SP], FCN_NULL },
+ { "pc", &ddb_regs.tf_regs[FRAME_PC], FCN_NULL },
+ { "ps", &ddb_regs.tf_regs[FRAME_PS], FCN_NULL },
+ { "ai", &ddb_regs.tf_regs[FRAME_T11], FCN_NULL },
+ { "pv", &ddb_regs.tf_regs[FRAME_T12], FCN_NULL },
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+/*
+ * Print trap reason.
+ */
+void
+ddbprinttrap(a0, a1, a2, entry)
+ unsigned long a0, a1, a2, entry;
+{
+
+ /* XXX Implement. */
+
+ printf("ddbprinttrap(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", a0, a1, a2,
+ entry);
+}
+
+/*
+ * ddb_trap - field a kernel trap
+ */
+int
+ddb_trap(a0, a1, a2, entry, regs)
+ unsigned long a0, a1, a2, entry;
+ db_regs_t *regs;
+{
+ int s;
+
+ /*
+ * Don't bother checking for usermode, since a benign entry
+ * by the kernel (call to Debugger() or a breakpoint) has
+ * already checked for usermode. If neither of those
+ * conditions exist, something Bad has happened.
+ */
+
+ if (entry != ALPHA_KENTRY_IF ||
+ (a0 != ALPHA_IF_CODE_BUGCHK && a0 != ALPHA_IF_CODE_BPT)) {
+ db_printf("ddbprinttrap from 0x%lx\n", /* XXX */
+ regs->tf_regs[FRAME_PC]);
+ ddbprinttrap(a0, a1, a2, entry);
+#if 0
+ if (db_recover != 0) {
+ /*
+ * XXX Sould longjump back into command loop!
+ */
+ db_printf("Faulted in DDB; continuing...\n");
+ alpha_pal_halt(); /* XXX */
+ db_error("Faulted in DDB; continuing...\n");
+ /* NOTREACHED */
+ }
+#endif
+
+ /*
+ * Tell caller "We did NOT handle the trap."
+ * Caller should panic, or whatever.
+ */
+ return (0);
+ }
+
+ /*
+ * XXX Should switch to DDB's own stack, here.
+ */
+
+ ddb_regs = *regs;
+
+ s = splhigh();
+
+ db_active++;
+ cnpollc(TRUE); /* Set polling mode, unblank video */
+
+ db_trap(entry, a0); /* Where the work happens */
+
+ cnpollc(FALSE); /* Resume interrupt mode */
+ db_active--;
+
+ splx(s);
+
+ *regs = ddb_regs;
+
+ /*
+ * Tell caller "We HAVE handled the trap."
+ */
+ return (1);
+}
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+void
+db_read_bytes(addr, size, data)
+ vm_offset_t addr;
+ register size_t size;
+ register char *data;
+{
+ register char *src;
+
+ src = (char *)addr;
+ while (size-- > 0)
+ *data++ = *src++;
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+void
+db_write_bytes(addr, size, data)
+ vm_offset_t addr;
+ register size_t size;
+ register char *data;
+{
+ register char *dst;
+
+ dst = (char *)addr;
+ while (size-- > 0)
+ *dst++ = *data++;
+ alpha_pal_imb();
+}
+
+void
+Debugger(const char* msg)
+{
+ printf("%s\n", msg);
+ __asm("call_pal 0x81"); /* XXX bugchk */
+}
+
+/*
+ * Alpha-specific ddb commands:
+ *
+ * halt set halt bit in rpb and halt
+ * reboot set reboot bit in rpb and halt
+ */
+
+DB_COMMAND(halt, db_mach_halt)
+{
+
+ prom_halt(1);
+}
+
+DB_COMMAND(reboot, db_mach_reboot)
+{
+ prom_halt(0);
+}
+
+/*
+ * Map Alpha register numbers to trapframe/db_regs_t offsets.
+ */
+static int reg_to_frame[32] = {
+ FRAME_V0,
+ FRAME_T0,
+ FRAME_T1,
+ FRAME_T2,
+ FRAME_T3,
+ FRAME_T4,
+ FRAME_T5,
+ FRAME_T6,
+ FRAME_T7,
+
+ FRAME_S0,
+ FRAME_S1,
+ FRAME_S2,
+ FRAME_S3,
+ FRAME_S4,
+ FRAME_S5,
+ FRAME_S6,
+
+ FRAME_A0,
+ FRAME_A1,
+ FRAME_A2,
+ FRAME_A3,
+ FRAME_A4,
+ FRAME_A5,
+
+ FRAME_T8,
+ FRAME_T9,
+ FRAME_T10,
+ FRAME_T11,
+ FRAME_RA,
+ FRAME_T12,
+ FRAME_AT,
+ FRAME_GP,
+ FRAME_SP,
+ -1, /* zero */
+};
+
+u_long
+db_register_value(regs, regno)
+ db_regs_t *regs;
+ int regno;
+{
+
+ if (regno > 31 || regno < 0) {
+ db_printf(" **** STRANGE REGISTER NUMBER %d **** ", regno);
+ return (0);
+ }
+
+ if (regno == 31)
+ return (0);
+
+ return (regs->tf_regs[reg_to_frame[regno]]);
+}
+
+/*
+ * Support functions for software single-step.
+ */
+
+boolean_t
+db_inst_call(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ return ((insn.branch_format.opcode == op_bsr) ||
+ ((insn.jump_format.opcode == op_j) &&
+ (insn.jump_format.action & 1)));
+}
+
+boolean_t
+db_inst_return(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ return ((insn.jump_format.opcode == op_j) &&
+ (insn.jump_format.action == op_ret));
+}
+
+boolean_t
+db_inst_trap_return(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ return ((insn.pal_format.opcode == op_pal) &&
+ (insn.pal_format.function == PAL_OSF1_rti));
+}
+
+boolean_t
+db_inst_branch(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ switch (insn.branch_format.opcode) {
+ case op_j:
+ case op_br:
+ case op_fbeq:
+ case op_fblt:
+ case op_fble:
+ case op_fbne:
+ case op_fbge:
+ case op_fbgt:
+ case op_blbc:
+ case op_beq:
+ case op_blt:
+ case op_ble:
+ case op_blbs:
+ case op_bne:
+ case op_bge:
+ case op_bgt:
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+boolean_t
+db_inst_unconditional_flow_transfer(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ switch (insn.branch_format.opcode) {
+ case op_j:
+ case op_br:
+ return (TRUE);
+
+ case op_pal:
+ switch (insn.pal_format.function) {
+ case PAL_OSF1_retsys:
+ case PAL_OSF1_rti:
+ case PAL_OSF1_callsys:
+ return (TRUE);
+ }
+ }
+
+ return (FALSE);
+}
+
+#if 0
+boolean_t
+db_inst_spill(ins, regn)
+ int ins, regn;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+ return ((insn.mem_format.opcode == op_stq) &&
+ (insn.mem_format.rd == regn));
+}
+#endif
+
+boolean_t
+db_inst_load(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+
+ /* Loads. */
+ if (insn.mem_format.opcode == op_ldbu ||
+ insn.mem_format.opcode == op_ldq_u ||
+ insn.mem_format.opcode == op_ldwu)
+ return (TRUE);
+ if ((insn.mem_format.opcode >= op_ldf) &&
+ (insn.mem_format.opcode <= op_ldt))
+ return (TRUE);
+ if ((insn.mem_format.opcode >= op_ldl) &&
+ (insn.mem_format.opcode <= op_ldq_l))
+ return (TRUE);
+
+ /* Prefetches. */
+ if (insn.mem_format.opcode == op_special) {
+ /* Note: MB is treated as a store. */
+ if ((insn.mem_format.displacement == (short)op_fetch) ||
+ (insn.mem_format.displacement == (short)op_fetch_m))
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+boolean_t
+db_inst_store(ins)
+ int ins;
+{
+ alpha_instruction insn;
+
+ insn.bits = ins;
+
+ /* Stores. */
+ if (insn.mem_format.opcode == op_stw ||
+ insn.mem_format.opcode == op_stb ||
+ insn.mem_format.opcode == op_stq_u)
+ return (TRUE);
+ if ((insn.mem_format.opcode >= op_stf) &&
+ (insn.mem_format.opcode <= op_stt))
+ return (TRUE);
+ if ((insn.mem_format.opcode >= op_stl) &&
+ (insn.mem_format.opcode <= op_stq_c))
+ return (TRUE);
+
+ /* Barriers. */
+ if (insn.mem_format.opcode == op_special) {
+ if (insn.mem_format.displacement == op_mb)
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+db_addr_t
+db_branch_taken(ins, pc, regs)
+ int ins;
+ db_addr_t pc;
+ db_regs_t *regs;
+{
+ alpha_instruction insn;
+ db_addr_t newpc;
+
+ insn.bits = ins;
+ switch (insn.branch_format.opcode) {
+ /*
+ * Jump format: target PC is (contents of instruction's "RB") & ~3.
+ */
+ case op_j:
+ newpc = db_register_value(regs, insn.jump_format.rs) & ~3;
+ break;
+
+ /*
+ * Branch format: target PC is
+ * (new PC) + (4 * sign-ext(displacement)).
+ */
+ case op_br:
+ case op_fbeq:
+ case op_fblt:
+ case op_fble:
+ case op_bsr:
+ case op_fbne:
+ case op_fbge:
+ case op_fbgt:
+ case op_blbc:
+ case op_beq:
+ case op_blt:
+ case op_ble:
+ case op_blbs:
+ case op_bne:
+ case op_bge:
+ case op_bgt:
+ newpc = (insn.branch_format.displacement << 2) + (pc + 4);
+ break;
+
+ default:
+ printf("DDB: db_inst_branch_taken on non-branch!\n");
+ newpc = pc; /* XXX */
+ }
+
+ return (newpc);
+}
diff --git a/sys/alpha/alpha/db_trace.c b/sys/alpha/alpha/db_trace.c
new file mode 100644
index 000000000000..944e17195b0c
--- /dev/null
+++ b/sys/alpha/alpha/db_trace.c
@@ -0,0 +1,25 @@
+/* $NetBSD: db_trace.c,v 1.1 1997/09/06 02:00:50 thorpej Exp $ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+/* __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.1 1997/09/06 02:00:50 thorpej Exp $"); */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <machine/db_machdep.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_access.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_output.h>
+
+void
+db_stack_trace_cmd(addr, have_addr, count, modif)
+ db_expr_t addr;
+ boolean_t have_addr;
+ db_expr_t count;
+ char *modif;
+{
+ /* nothing, yet. */
+}
diff --git a/sys/alpha/alpha/dec_kn8ae.c b/sys/alpha/alpha/dec_kn8ae.c
new file mode 100644
index 000000000000..aad572b7a560
--- /dev/null
+++ b/sys/alpha/alpha/dec_kn8ae.c
@@ -0,0 +1,89 @@
+/* $Id$ */
+/* $NetBSD: dec_kn8ae.c,v 1.15 1998/02/13 00:12:50 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_simos.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/termios.h>
+
+#include <machine/rpb.h>
+#include <machine/conf.h>
+#include <machine/cpuconf.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/gbusreg.h>
+
+void dec_kn8ae_init(int);
+static void dec_kn8ae_cons_init(void);
+
+static const struct alpha_variation_table dec_kn8ae_variations[] = {
+ { 0, "AlphaServer 8400" },
+ { 0, NULL },
+};
+
+void
+dec_kn8ae_init(int cputype)
+{
+ u_int64_t variation;
+
+ platform.family = "AlphaServer 8400";
+
+ if ((platform.model = alpha_dsr_sysname()) == NULL) {
+ variation = hwrpb->rpb_variation & SV_ST_MASK;
+ if ((platform.model = alpha_variation_name(variation,
+ dec_kn8ae_variations)) == NULL)
+ platform.model = alpha_unknown_sysname();
+ }
+
+ platform.iobus = "tlsb";
+ platform.cons_init = dec_kn8ae_cons_init;
+}
+
+/*
+ * dec_kn8ae_cons_init- not needed right now. XXX hack in SimOS console
+ *
+ * Info to retain:
+ *
+ * The AXP 8X00 seems to encode the
+ * type of console in the ctb_type field,
+ * not the ctb_term_type field.
+ */
+static void
+dec_kn8ae_cons_init(void)
+{
+#ifdef SIMOS
+ zs_cnattach(TLSB_GBUS_BASE, GBUS_DUART0_OFFSET);
+#endif
+}
diff --git a/sys/alpha/alpha/diskslice_machdep.c b/sys/alpha/alpha/diskslice_machdep.c
new file mode 100644
index 000000000000..ada18dcd0830
--- /dev/null
+++ b/sys/alpha/alpha/diskslice_machdep.c
@@ -0,0 +1,461 @@
+/*-
+ * Copyright (c) 1994 Bruce D. Evans.
+ * All rights reserved.
+ *
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
+ * $Id: diskslice_machdep.c,v 1.27 1997/12/02 21:06:20 phk Exp $
+ */
+
+#include <stddef.h>
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/disklabel.h>
+#define DOSPTYP_EXTENDED 5
+#define DOSPTYP_ONTRACK 84
+#include <sys/diskslice.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+
+#define TRACE(str) do { if (dsi_debug) printf str; } while (0)
+
+static volatile u_char dsi_debug;
+
+static struct dos_partition historical_bogus_partition_table[NDOSPART] = {
+ { 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, },
+ { 0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000, },
+};
+
+static int check_part __P((char *sname, struct dos_partition *dp,
+ u_long offset, int nsectors, int ntracks,
+ u_long mbr_offset));
+static void extended __P((char *dname, dev_t dev, d_strategy_t *strat,
+ struct disklabel *lp, struct diskslices *ssp,
+ u_long ext_offset, u_long ext_size,
+ u_long base_ext_offset, int nsectors, int ntracks,
+ u_long mbr_offset));
+
+static int
+check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
+ char *sname;
+ struct dos_partition *dp;
+ u_long offset;
+ int nsectors;
+ int ntracks;
+ u_long mbr_offset;
+{
+ int chs_ecyl;
+ int chs_esect;
+ int chs_scyl;
+ int chs_ssect;
+ int error;
+ u_long esector;
+ u_long esector1;
+ u_long secpercyl;
+ u_long ssector;
+ u_long ssector1;
+
+ secpercyl = (u_long)nsectors * ntracks;
+ chs_scyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
+ chs_ssect = DPSECT(dp->dp_ssect);
+ ssector = chs_ssect - 1 + dp->dp_shd * nsectors + chs_scyl * secpercyl
+ + mbr_offset;
+ ssector1 = offset + dp->dp_start;
+
+ /*
+ * If ssector1 is on a cylinder >= 1024, then ssector can't be right.
+ * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
+ * apart from the cylinder being reduced modulo 1024. Always allow
+ * 1023/255/63.
+ */
+ if (ssector < ssector1
+ && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
+ && chs_scyl == 1023)
+ || (secpercyl != 0
+ && (ssector1 - ssector) % (1024 * secpercyl) == 0))
+ || (dp->dp_scyl == 255 && dp->dp_shd == 255
+ && dp->dp_ssect == 255)) {
+ TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
+ sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
+ ssector = ssector1;
+ }
+
+ chs_ecyl = DPCYL(dp->dp_ecyl, dp->dp_esect);
+ chs_esect = DPSECT(dp->dp_esect);
+ esector = chs_esect - 1 + dp->dp_ehd * nsectors + chs_ecyl * secpercyl
+ + mbr_offset;
+ esector1 = ssector1 + dp->dp_size - 1;
+
+ /* Allow certain bogus C/H/S values for esector, as above. */
+ if (esector < esector1
+ && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
+ && chs_ecyl == 1023)
+ || (secpercyl != 0
+ && (esector1 - esector) % (1024 * secpercyl) == 0))
+ || (dp->dp_ecyl == 255 && dp->dp_ehd == 255
+ && dp->dp_esect == 255)) {
+ TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
+ sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
+ esector = esector1;
+ }
+
+ error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
+ if (bootverbose)
+ printf("%s: type 0x%x, start %lu, end = %lu, size %lu %s\n",
+ sname, dp->dp_typ, ssector1, esector1, dp->dp_size,
+ error ? "" : ": OK");
+ if (ssector != ssector1 && bootverbose)
+ printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
+ sname, chs_scyl, dp->dp_shd, chs_ssect,
+ ssector, ssector1);
+ if (esector != esector1 && bootverbose)
+ printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
+ sname, chs_ecyl, dp->dp_ehd, chs_esect,
+ esector, esector1);
+ return (error);
+}
+
+int
+dsinit(dname, dev, strat, lp, sspp)
+ char *dname;
+ dev_t dev;
+ d_strategy_t *strat;
+ struct disklabel *lp;
+ struct diskslices **sspp;
+{
+ struct buf *bp;
+ u_char *cp;
+ int dospart;
+ struct dos_partition *dp;
+ struct dos_partition *dp0;
+ int error;
+ int max_ncyls;
+ int max_nsectors;
+ int max_ntracks;
+ u_long mbr_offset;
+ char partname[2];
+ u_long secpercyl;
+ char *sname;
+ struct diskslice *sp;
+ struct diskslices *ssp;
+
+ /*
+ * Allocate a dummy slices "struct" and initialize it to contain
+ * only an empty compatibility slice (pointing to itself) and a
+ * whole disk slice (covering the disk as described by the label).
+ * If there is an error, then the dummy struct becomes final.
+ */
+ ssp = malloc(offsetof(struct diskslices, dss_slices)
+ + BASE_SLICE * sizeof *sp, M_DEVBUF, M_WAITOK);
+ *sspp = ssp;
+ ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
+ ssp->dss_nslices = BASE_SLICE;
+ sp = &ssp->dss_slices[0];
+ bzero(sp, BASE_SLICE * sizeof *sp);
+ sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
+
+ mbr_offset = DOSBBSECTOR;
+reread_mbr:
+ /* Read master boot record. */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
+ bp->b_blkno = mbr_offset;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags |= B_BUSY | B_READ;
+ (*strat)(bp);
+ if (biowait(bp) != 0) {
+ diskerr(bp, dname, "error reading primary partition table",
+ LOG_PRINTF, 0, lp);
+ printf("\n");
+ error = EIO;
+ goto done;
+ }
+
+ /* Weakly verify it. */
+ cp = bp->b_data;
+ sname = dsname(dname, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART,
+ partname);
+ if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
+ if (bootverbose)
+ printf("%s: invalid primary partition table: no magic\n",
+ sname);
+ error = EINVAL;
+ goto done;
+ }
+ dp0 = (struct dos_partition *)(cp + DOSPARTOFF);
+
+ /* Check for "Ontrack Diskmanager". */
+ for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
+ if (dp->dp_typ == DOSPTYP_ONTRACK) {
+ if (bootverbose)
+ printf(
+ "%s: Found \"Ontrack Disk Manager\" on this disk.\n", sname);
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+ mbr_offset = 63;
+ goto reread_mbr;
+ }
+ }
+
+ if (bcmp(dp0, historical_bogus_partition_table,
+ sizeof historical_bogus_partition_table) == 0) {
+ TRACE(("%s: invalid primary partition table: historical\n",
+ sname));
+ error = EINVAL;
+ goto done;
+ }
+
+ /* Guess the geometry. */
+ /*
+ * TODO:
+ * Perhaps skip entries with 0 size.
+ * Perhaps only look at entries of type DOSPTYP_386BSD.
+ */
+ max_ncyls = 0;
+ max_nsectors = 0;
+ max_ntracks = 0;
+ for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
+ int ncyls;
+ int nsectors;
+ int ntracks;
+
+ ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
+ if (max_ncyls < ncyls)
+ max_ncyls = ncyls;
+ nsectors = DPSECT(dp->dp_esect);
+ if (max_nsectors < nsectors)
+ max_nsectors = nsectors;
+ ntracks = dp->dp_ehd + 1;
+ if (max_ntracks < ntracks)
+ max_ntracks = ntracks;
+ }
+
+ /*
+ * Check that we have guessed the geometry right by checking the
+ * partition entries.
+ */
+ /*
+ * TODO:
+ * As above.
+ * Check for overlaps.
+ * Check against d_secperunit if the latter is reliable.
+ */
+ error = 0;
+ for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
+ if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
+ && dp->dp_start == 0 && dp->dp_size == 0)
+ continue;
+ sname = dsname(dname, dkunit(dev), BASE_SLICE + dospart,
+ RAW_PART, partname);
+
+ /*
+ * Temporarily ignore errors from this check. We could
+ * simplify things by accepting the table eariler if we
+ * always ignore errors here. Perhaps we should always
+ * accept the table if the magic is right but not let
+ * bad entries affect the geometry.
+ */
+ check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
+ mbr_offset);
+ }
+ if (error != 0)
+ goto done;
+
+ /*
+ * Accept the DOS partition table.
+ * First adjust the label (we have been careful not to change it
+ * before we can guarantee success).
+ */
+ secpercyl = (u_long)max_nsectors * max_ntracks;
+ if (secpercyl != 0) {
+ u_long secperunit;
+
+ lp->d_nsectors = max_nsectors;
+ lp->d_ntracks = max_ntracks;
+ lp->d_secpercyl = secpercyl;
+ secperunit = secpercyl * max_ncyls;
+ if (lp->d_secperunit < secperunit)
+ lp->d_secperunit = secperunit;
+ lp->d_ncylinders = lp->d_secperunit / secpercyl;
+ }
+
+ /*
+ * Free the dummy slices "struct" and allocate a real new one.
+ * Initialize special slices as above.
+ */
+ free(ssp, M_DEVBUF);
+ ssp = malloc(offsetof(struct diskslices, dss_slices)
+#define MAX_SLICES_SUPPORTED MAX_SLICES /* was (BASE_SLICE + NDOSPART) */
+ + MAX_SLICES_SUPPORTED * sizeof *sp, M_DEVBUF, M_WAITOK);
+ *sspp = ssp;
+ ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
+ sp = &ssp->dss_slices[0];
+ bzero(sp, MAX_SLICES_SUPPORTED * sizeof *sp);
+ sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
+
+ /* Initialize normal slices. */
+ sp += BASE_SLICE;
+ for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
+ sp->ds_offset = mbr_offset + dp->dp_start;
+ sp->ds_size = dp->dp_size;
+ sp->ds_type = dp->dp_typ;
+#if 0
+ lp->d_subtype |= (lp->d_subtype & 3) | dospart
+ | DSTYPE_INDOSPART;
+#endif
+ }
+ ssp->dss_nslices = BASE_SLICE + NDOSPART;
+
+ /* Handle extended partitions. */
+ sp -= NDOSPART;
+ for (dospart = 0; dospart < NDOSPART; dospart++, sp++)
+ if (sp->ds_type == DOSPTYP_EXTENDED)
+ extended(dname, bp->b_dev, strat, lp, ssp,
+ sp->ds_offset, sp->ds_size, sp->ds_offset,
+ max_nsectors, max_ntracks, mbr_offset);
+
+done:
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+ if (error == EINVAL)
+ error = 0;
+ return (error);
+}
+
+void
+extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset,
+ nsectors, ntracks, mbr_offset)
+ char *dname;
+ dev_t dev;
+ struct disklabel *lp;
+ d_strategy_t *strat;
+ struct diskslices *ssp;
+ u_long ext_offset;
+ u_long ext_size;
+ u_long base_ext_offset;
+ int nsectors;
+ int ntracks;
+ u_long mbr_offset;
+{
+ struct buf *bp;
+ u_char *cp;
+ int dospart;
+ struct dos_partition *dp;
+ u_long ext_offsets[NDOSPART];
+ u_long ext_sizes[NDOSPART];
+ char partname[2];
+ int slice;
+ char *sname;
+ struct diskslice *sp;
+
+ /* Read extended boot record. */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+ bp->b_blkno = ext_offset;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags |= B_BUSY | B_READ;
+ (*strat)(bp);
+ if (biowait(bp) != 0) {
+ diskerr(bp, dname, "error reading extended partition table",
+ LOG_PRINTF, 0, lp);
+ printf("\n");
+ goto done;
+ }
+
+ /* Weakly verify it. */
+ cp = bp->b_data;
+ if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
+ sname = dsname(dname, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART,
+ partname);
+ if (bootverbose)
+ printf("%s: invalid extended partition table: no magic\n",
+ sname);
+ goto done;
+ }
+
+ for (dospart = 0,
+ dp = (struct dos_partition *)(bp->b_data + DOSPARTOFF),
+ slice = ssp->dss_nslices, sp = &ssp->dss_slices[slice];
+ dospart < NDOSPART; dospart++, dp++) {
+ ext_sizes[dospart] = 0;
+ if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
+ && dp->dp_start == 0 && dp->dp_size == 0)
+ continue;
+ if (dp->dp_typ == DOSPTYP_EXTENDED) {
+ char buf[32];
+
+ sname = dsname(dname, dkunit(dev), WHOLE_DISK_SLICE,
+ RAW_PART, partname);
+ strcpy(buf, sname);
+ if (strlen(buf) < sizeof buf - 11)
+ strcat(buf, "<extended>");
+ check_part(buf, dp, base_ext_offset, nsectors,
+ ntracks, mbr_offset);
+ ext_offsets[dospart] = base_ext_offset + dp->dp_start;
+ ext_sizes[dospart] = dp->dp_size;
+ } else {
+ sname = dsname(dname, dkunit(dev), slice, RAW_PART,
+ partname);
+ check_part(sname, dp, ext_offset, nsectors, ntracks,
+ mbr_offset);
+ if (slice >= MAX_SLICES) {
+ printf("%s: too many slices\n", sname);
+ slice++;
+ continue;
+ }
+ sp->ds_offset = ext_offset + dp->dp_start;
+ sp->ds_size = dp->dp_size;
+ sp->ds_type = dp->dp_typ;
+ ssp->dss_nslices++;
+ slice++;
+ sp++;
+ }
+ }
+
+ /* If we found any more slices, recursively find all the subslices. */
+ for (dospart = 0; dospart < NDOSPART; dospart++)
+ if (ext_sizes[dospart] != 0)
+ extended(dname, dev, strat, lp, ssp,
+ ext_offsets[dospart], ext_sizes[dospart],
+ base_ext_offset, nsectors, ntracks,
+ mbr_offset);
+
+done:
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+}
diff --git a/sys/alpha/alpha/divrem.m4 b/sys/alpha/alpha/divrem.m4
new file mode 100644
index 000000000000..c24689f3d2b2
--- /dev/null
+++ b/sys/alpha/alpha/divrem.m4
@@ -0,0 +1,197 @@
+/* $NetBSD: divrem.m4,v 1.5 1996/10/17 04:26:25 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Division and remainder.
+ *
+ * The use of m4 is modeled after the sparc code, but the algorithm is
+ * simple binary long division.
+ *
+ * Note that the loops could probably benefit from unrolling.
+ */
+
+/*
+ * M4 Parameters
+ * NAME name of function to generate
+ * OP OP=div: t10 / t11 -> t12; OP=rem: t10 % t11 -> t12
+ * S S=true: signed; S=false: unsigned
+ * WORDSIZE total number of bits
+ */
+
+define(A, `t10')
+define(B, `t11')
+define(RESULT, `t12')
+
+define(BIT, `t0')
+define(I, `t1')
+define(CC, `t2')
+define(T_0, `t3')
+ifelse(S, `true', `define(NEG, `t4')')
+
+#include <machine/asm.h>
+
+LEAF(NAME, 0) /* XXX */
+ lda sp, -64(sp)
+ stq BIT, 0(sp)
+ stq I, 8(sp)
+ stq CC, 16(sp)
+ stq T_0, 24(sp)
+ifelse(S, `true',
+` stq NEG, 32(sp)')
+ stq A, 40(sp)
+ stq B, 48(sp)
+ mov zero, RESULT /* Initialize result to zero */
+
+ifelse(S, `true',
+`
+ /* Compute sign of result. If either is negative, this is easy. */
+ or A, B, NEG /* not the sign, but... */
+ srl NEG, WORDSIZE - 1, NEG /* rather, or of high bits */
+ blbc NEG, Ldoit /* neither negative? do it! */
+
+ifelse(OP, `div',
+` xor A, B, NEG /* THIS is the sign! */
+', ` mov A, NEG /* sign follows A. */
+')
+ srl NEG, WORDSIZE - 1, NEG /* make negation the low bit. */
+
+ srl A, WORDSIZE - 1, I /* is A negative? */
+ blbc I, LnegB /* no. */
+ /* A is negative; flip it. */
+ifelse(WORDSIZE, `32', `
+ /* top 32 bits may be random junk */
+ zap A, 0xf0, A
+')
+ subq zero, A, A
+ srl B, WORDSIZE - 1, I /* is B negative? */
+ blbc I, Ldoit /* no. */
+LnegB:
+ /* B is definitely negative, no matter how we got here. */
+ifelse(WORDSIZE, `32', `
+ /* top 32 bits may be random junk */
+ zap B, 0xf0, B
+')
+ subq zero, B, B
+Ldoit:
+')
+ifelse(WORDSIZE, `32', `
+ /*
+ * Clear the top 32 bits of each operand, as they may
+ * sign extension (if negated above), or random junk.
+ */
+ zap A, 0xf0, A
+ zap B, 0xf0, B
+')
+
+ /* kill the special cases. */
+ beq B, Ldotrap /* division by zero! */
+
+ cmpult A, B, CC /* A < B? */
+ /* RESULT is already zero, from above. A is untouched. */
+ bne CC, Lret_result
+
+ cmpeq A, B, CC /* A == B? */
+ cmovne CC, 1, RESULT
+ cmovne CC, zero, A
+ bne CC, Lret_result
+
+ /*
+ * Find out how many bits of zeros are at the beginning of the divisor.
+ */
+LBbits:
+ ldiq T_0, 1 /* I = 0; BIT = 1<<WORDSIZE-1 */
+ mov zero, I
+ sll T_0, WORDSIZE-1, BIT
+LBloop:
+ and B, BIT, CC /* if bit in B is set, done. */
+ bne CC, LAbits
+ addq I, 1, I /* increment I, shift bit */
+ srl BIT, 1, BIT
+ cmplt I, WORDSIZE-1, CC /* if I leaves one bit, done. */
+ bne CC, LBloop
+
+LAbits:
+ beq I, Ldodiv /* If I = 0, divide now. */
+ ldiq T_0, 1 /* BIT = 1<<WORDSIZE-1 */
+ sll T_0, WORDSIZE-1, BIT
+
+LAloop:
+ and A, BIT, CC /* if bit in A is set, done. */
+ bne CC, Ldodiv
+ subq I, 1, I /* decrement I, shift bit */
+ srl BIT, 1, BIT
+ bne I, LAloop /* If I != 0, loop again */
+
+Ldodiv:
+ sll B, I, B /* B <<= i */
+ ldiq T_0, 1
+ sll T_0, I, BIT
+
+Ldivloop:
+ cmpult A, B, CC
+ or RESULT, BIT, T_0
+ cmoveq CC, T_0, RESULT
+ subq A, B, T_0
+ cmoveq CC, T_0, A
+ srl BIT, 1, BIT
+ srl B, 1, B
+ beq A, Lret_result
+ bne BIT, Ldivloop
+
+Lret_result:
+ifelse(OP, `div',
+`', ` mov A, RESULT
+')
+ifelse(S, `true',
+`
+ /* Check to see if we should negate it. */
+ subqv zero, RESULT, T_0
+ cmovlbs NEG, T_0, RESULT
+')
+
+ ldq BIT, 0(sp)
+ ldq I, 8(sp)
+ ldq CC, 16(sp)
+ ldq T_0, 24(sp)
+ifelse(S, `true',
+` ldq NEG, 32(sp)')
+ ldq A, 40(sp)
+ ldq B, 48(sp)
+ lda sp, 64(sp)
+ ret zero, (t9), 1
+
+Ldotrap:
+ ldiq a0, -2 /* This is the signal to SIGFPE! */
+ call_pal PAL_gentrap
+ifelse(OP, `div',
+`', ` mov zero, A /* so that zero will be returned */
+')
+ br zero, Lret_result
+
+END(NAME)
diff --git a/sys/alpha/alpha/exception.s b/sys/alpha/alpha/exception.s
new file mode 100644
index 000000000000..8bfc571d2934
--- /dev/null
+++ b/sys/alpha/alpha/exception.s
@@ -0,0 +1,200 @@
+/* $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+#include <assym.s>
+
+/**************************************************************************/
+
+/*
+ * XentArith:
+ * System arithmetic trap entry point.
+ */
+
+ PALVECT(XentArith) /* setup frame, save registers */
+
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_ARITH
+ mov sp, a4 ; .loc 1 __LINE__
+ CALL(trap)
+
+ jmp zero, exception_return
+ END(XentArith)
+
+/**************************************************************************/
+
+/*
+ * XentIF:
+ * System instruction fault trap entry point.
+ */
+
+ PALVECT(XentIF) /* setup frame, save registers */
+
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_IF
+ mov sp, a4 ; .loc 1 __LINE__
+ CALL(trap)
+ jmp zero, exception_return
+ END(XentIF)
+
+/**************************************************************************/
+
+/*
+ * XentInt:
+ * System interrupt entry point.
+ */
+
+ PALVECT(XentInt) /* setup frame, save registers */
+
+ /* a0, a1, & a2 already set up */
+ mov sp, a3 ; .loc 1 __LINE__
+ CALL(interrupt)
+ jmp zero, exception_return
+ END(XentInt)
+
+/**************************************************************************/
+
+/*
+ * XentMM:
+ * System memory management fault entry point.
+ */
+
+ PALVECT(XentMM) /* setup frame, save registers */
+
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_MM
+ mov sp, a4 ; .loc 1 __LINE__
+ CALL(trap)
+
+ jmp zero, exception_return
+ END(XentMM)
+
+/**************************************************************************/
+
+/*
+ * XentSys:
+ * System call entry point.
+ */
+
+ ESETUP(XentSys) ; .loc 1 __LINE__
+
+ stq v0,(FRAME_V0*8)(sp) /* in case we need to restart */
+ stq s0,(FRAME_S0*8)(sp)
+ stq s1,(FRAME_S1*8)(sp)
+ stq s2,(FRAME_S2*8)(sp)
+ stq s3,(FRAME_S3*8)(sp)
+ stq s4,(FRAME_S4*8)(sp)
+ stq s5,(FRAME_S5*8)(sp)
+ stq s6,(FRAME_S6*8)(sp)
+ stq a0,(FRAME_A0*8)(sp)
+ stq a1,(FRAME_A1*8)(sp)
+ stq a2,(FRAME_A2*8)(sp)
+ stq a3,(FRAME_A3*8)(sp)
+ stq a4,(FRAME_A4*8)(sp)
+ stq a5,(FRAME_A5*8)(sp)
+ stq ra,(FRAME_RA*8)(sp)
+
+ /* syscall number, passed in v0, is first arg, frame pointer second */
+ mov v0,a0
+ mov sp,a1 ; .loc 1 __LINE__
+ CALL(syscall)
+
+ jmp zero, exception_return
+ END(XentSys)
+
+/**************************************************************************/
+
+/*
+ * XentUna:
+ * System unaligned access entry point.
+ */
+
+LEAF(XentUna, 3) /* XXX should be NESTED */
+ .set noat
+ lda sp,-(FRAME_SW_SIZE*8)(sp)
+ stq at_reg,(FRAME_AT*8)(sp)
+ .set at
+ stq ra,(FRAME_RA*8)(sp)
+ bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */
+
+ /* a0, a1, & a2 already set up */
+ ldiq a3, ALPHA_KENTRY_UNA
+ mov sp, a4 ; .loc 1 __LINE__
+ CALL(trap)
+
+ jmp zero, exception_return
+ END(XentUna)
+
+
+/**************************************************************************/
+
+/*
+ * console 'restart' routine to be placed in HWRPB.
+ */
+LEAF(XentRestart, 1) /* XXX should be NESTED */
+ .set noat
+ lda sp,-(FRAME_SIZE*8)(sp)
+ stq at_reg,(FRAME_AT*8)(sp)
+ .set at
+ stq v0,(FRAME_V0*8)(sp)
+ stq a3,(FRAME_A3*8)(sp)
+ stq a4,(FRAME_A4*8)(sp)
+ stq a5,(FRAME_A5*8)(sp)
+ stq s0,(FRAME_S0*8)(sp)
+ stq s1,(FRAME_S1*8)(sp)
+ stq s2,(FRAME_S2*8)(sp)
+ stq s3,(FRAME_S3*8)(sp)
+ stq s4,(FRAME_S4*8)(sp)
+ stq s5,(FRAME_S5*8)(sp)
+ stq s6,(FRAME_S6*8)(sp)
+ stq t0,(FRAME_T0*8)(sp)
+ stq t1,(FRAME_T1*8)(sp)
+ stq t2,(FRAME_T2*8)(sp)
+ stq t3,(FRAME_T3*8)(sp)
+ stq t4,(FRAME_T4*8)(sp)
+ stq t5,(FRAME_T5*8)(sp)
+ stq t6,(FRAME_T6*8)(sp)
+ stq t7,(FRAME_T7*8)(sp)
+ stq t8,(FRAME_T8*8)(sp)
+ stq t9,(FRAME_T9*8)(sp)
+ stq t10,(FRAME_T10*8)(sp)
+ stq t11,(FRAME_T11*8)(sp)
+ stq t12,(FRAME_T12*8)(sp)
+ stq ra,(FRAME_RA*8)(sp)
+
+ br pv,LXconsole_restart1
+LXconsole_restart1: LDGP(pv)
+
+ ldq a0,(FRAME_RA*8)(sp) /* a0 = ra */
+ ldq a1,(FRAME_T11*8)(sp) /* a1 = ai */
+ ldq a2,(FRAME_T12*8)(sp) /* a2 = pv */
+ CALL(console_restart)
+
+ call_pal PAL_halt
+ END(XentRestart)
diff --git a/sys/alpha/alpha/genassym.c b/sys/alpha/alpha/genassym.c
new file mode 100644
index 000000000000..520bd41384ee
--- /dev/null
+++ b/sys/alpha/alpha/genassym.c
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
+ * $Id: genassym.c,v 1.54 1998/04/06 18:59:14 peter Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/errno.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <machine/frame.h>
+#include <sys/vmmeter.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#define KERNEL /* XXX avoid user headers */
+#include <sys/user.h>
+#undef KERNEL
+#include <net/if.h>
+#include <netinet/in.h>
+#include <nfs/nfsv2.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfs.h>
+#include <nfs/nfsdiskless.h>
+
+int main __P((void));
+int printf __P((const char *, ...));
+
+#define P(name, val) \
+ printf(val > 999 ? "#define\t%s 0x%lx\n" : "#define\t%s %ld\n", name, val)
+
+/* XXX Danger Will Robinson */
+struct prochd {
+ struct proc *ph_link; /* Linked list of running processes. */
+ struct proc *ph_rlink;
+};
+
+#define OFF(name, type, elem) P(#name, (long)&((type*)0)->elem)
+#define CONST2(name, val) P(#name, val)
+#define CONST1(name) P(#name, name)
+
+int
+main()
+{
+ OFF(P_FORW, struct proc, p_procq.tqe_next);
+ OFF(P_BACK, struct proc, p_procq.tqe_prev);
+ OFF(P_VMSPACE, struct proc, p_vmspace);
+ OFF(P_ADDR, struct proc, p_addr);
+ OFF(P_PRI, struct proc, p_priority);
+ OFF(P_RTPRIO_TYPE, struct proc, p_rtprio.type);
+ OFF(P_RTPRIO_PRIO, struct proc, p_rtprio.prio);
+ OFF(P_STAT, struct proc, p_stat);
+ OFF(P_WCHAN, struct proc, p_wchan);
+ OFF(P_FLAG, struct proc, p_flag);
+ OFF(P_PID, struct proc, p_pid);
+ OFF(P_RUNTIME, struct proc, p_runtime);
+ OFF(P_MD_PCBPADDR, struct proc, p_md.md_pcbpaddr);
+
+ OFF(PH_LINK, struct prochd, ph_link);
+ OFF(PH_RLINK, struct prochd, ph_rlink);
+
+ CONST1(SSLEEP);
+ CONST1(SRUN);
+
+ OFF(VM_PMAP, struct vmspace, vm_pmap);
+ OFF(V_TRAP, struct vmmeter, v_trap);
+ OFF(V_SYSCALL, struct vmmeter, v_trap);
+ OFF(V_INTR, struct vmmeter, v_trap);
+
+ CONST1(UPAGES);
+ CONST1(PAGE_SIZE);
+ CONST1(PAGE_SHIFT);
+ CONST1(PAGE_MASK);
+ CONST1(USRSTACK);
+ CONST1(VM_MAXUSER_ADDRESS);
+ CONST1(KERNBASE);
+ CONST1(PTLEV1I);
+ CONST1(PTESIZE);
+
+ OFF(U_PCB_ONFAULT, struct user, u_pcb.pcb_onfault);
+ OFF(U_PCB_HWPCB_KSP, struct user, u_pcb.pcb_hw.apcb_ksp);
+ OFF(U_PCB_CONTEXT, struct user, u_pcb.pcb_context);
+ OFF(U_PROFSCALE, struct user, u_stats.p_prof.pr_scale);
+
+ OFF(PR_BASE, struct uprof, pr_base);
+ OFF(PR_SIZE, struct uprof, pr_size);
+ OFF(PR_OFF, struct uprof, pr_off);
+ OFF(PR_SCALE, struct uprof, pr_scale);
+
+ OFF(RU_MINFLT, struct rusage, ru_minflt);
+
+ OFF(PCB_HW, struct pcb, pcb_hw);
+ OFF(PCB_CONTEXT, struct pcb, pcb_context);
+ OFF(PCB_FP, struct pcb, pcb_fp);
+ OFF(PCB_ONFAULT, struct pcb, pcb_onfault);
+ OFF(PCB_ACCESSADDR, struct pcb, pcb_accessaddr);
+
+ OFF(FPREG_FPR_REGS, struct fpreg, fpr_regs);
+ OFF(FPREG_FPR_CR, struct fpreg, fpr_cr);
+
+ CONST1(B_READ);
+ CONST1(ENOENT);
+ CONST1(EFAULT);
+ CONST1(ENAMETOOLONG);
+ CONST1(MAXPATHLEN);
+
+ /* Register offsets, for stack frames. */
+ CONST1(FRAME_V0),
+ CONST1(FRAME_T0),
+ CONST1(FRAME_T1),
+ CONST1(FRAME_T2),
+ CONST1(FRAME_T3),
+ CONST1(FRAME_T4),
+ CONST1(FRAME_T5),
+ CONST1(FRAME_T6),
+ CONST1(FRAME_T7),
+ CONST1(FRAME_S0),
+ CONST1(FRAME_S1),
+ CONST1(FRAME_S2),
+ CONST1(FRAME_S3),
+ CONST1(FRAME_S4),
+ CONST1(FRAME_S5),
+ CONST1(FRAME_S6),
+ CONST1(FRAME_A3),
+ CONST1(FRAME_A4),
+ CONST1(FRAME_A5),
+ CONST1(FRAME_T8),
+ CONST1(FRAME_T9),
+ CONST1(FRAME_T10),
+ CONST1(FRAME_T11),
+ CONST1(FRAME_RA),
+ CONST1(FRAME_T12),
+ CONST1(FRAME_AT),
+ CONST1(FRAME_SP),
+
+ CONST1(FRAME_SW_SIZE),
+
+ CONST1(FRAME_PS),
+ CONST1(FRAME_PC),
+ CONST1(FRAME_GP),
+ CONST1(FRAME_A0),
+ CONST1(FRAME_A1),
+ CONST1(FRAME_A2),
+
+ CONST1(FRAME_SIZE),
+
+ /* bits of the PS register */
+ CONST1(ALPHA_PSL_USERMODE);
+ CONST1(ALPHA_PSL_IPL_MASK);
+ CONST1(ALPHA_PSL_IPL_0);
+ CONST1(ALPHA_PSL_IPL_SOFT);
+ CONST1(ALPHA_PSL_IPL_HIGH);
+
+ /* pte bits */
+ CONST1(ALPHA_L1SHIFT);
+ CONST1(ALPHA_L2SHIFT);
+ CONST1(ALPHA_L3SHIFT);
+ CONST1(ALPHA_K1SEG_BASE);
+ CONST1(ALPHA_PTE_VALID);
+ CONST1(ALPHA_PTE_ASM);
+ CONST1(ALPHA_PTE_KR);
+ CONST1(ALPHA_PTE_KW);
+
+ /* Kernel entries */
+ CONST1(ALPHA_KENTRY_ARITH);
+ CONST1(ALPHA_KENTRY_MM);
+
+ CONST1(ALPHA_KENTRY_IF);
+ CONST1(ALPHA_KENTRY_UNA);
+
+ CONST1(VPTBASE);
+
+ return (0);
+}
diff --git a/sys/alpha/alpha/gensetdefs.c b/sys/alpha/alpha/gensetdefs.c
new file mode 100644
index 000000000000..0e446345f6f4
--- /dev/null
+++ b/sys/alpha/alpha/gensetdefs.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1997 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: gensetdefs.c,v 1.1 1997/05/21 23:21:25 jdp Exp $
+ */
+
+#include <sys/types.h>
+#include <machine/elf.h>
+
+#include <err.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define HASHSIZE 1009u /* Number of hash chains. */
+#define PREFIX ".set." /* Section name prefix for linker sets. */
+
+/* One entry in the hash table. */
+typedef struct hashent {
+ struct hashent *next; /* Next entry with the same hash. */
+ char *name; /* Name of the linker set. */
+ size_t size; /* Size in bytes. */
+} hashent;
+
+/* Allocate storage for "count" objects of type "type". */
+#define NEW(type, count) ((type *) xmalloc((count) * sizeof(type)))
+
+static hashent *hashtab[HASHSIZE]; /* Hash chain heads. */
+
+static void enter(const char *, size_t);
+static int enter_sets(const char *);
+static unsigned int hash(const char *);
+static hashent *merge(void);
+static int my_byte_order(void);
+static void *xmalloc(size_t);
+static char *xstrdup(const char *);
+
+/*
+ * This is a special-purpose program to generate the linker set definitions
+ * needed when building an ELF kernel. Its arguments are the names of
+ * ELF object files. It scans the section names of the object files,
+ * building a table of those that begin with ".set.", which represent
+ * linker sets. Finally, for each set "foo" with "count" elements, it
+ * writes a line "DEFINE_SET(foo, count);" to the standard output.
+ */
+int
+main(int argc, char **argv)
+{
+ int i;
+ int status = EXIT_SUCCESS;
+ hashent *list;
+
+ for (i = 1; i < argc; i++)
+ if (enter_sets(argv[i]) == -1)
+ status = EXIT_FAILURE;
+
+ list = merge();
+ while (list != NULL) {
+ hashent *next;
+
+ printf("DEFINE_SET(%s, %lu);\n", list->name,
+ (unsigned long) (list->size / sizeof (void *)));
+ next = list->next;
+ free(list->name);
+ free(list);
+ list = next;
+ }
+
+ return (status);
+}
+
+/*
+ * Enter the given string into the hash table, if it is not already there.
+ * Each hash chain is kept sorted, so that it will be easy to merge the
+ * chains to get a single sorted list.
+ */
+static void
+enter(const char *name, size_t size)
+{
+ int c = 0;
+ hashent *entp;
+ hashent **linkp;
+ hashent *newp;
+
+ linkp = &hashtab[hash(name) % HASHSIZE];
+ while ((entp = *linkp) != NULL && (c = strcmp(name, entp->name)) > 0)
+ linkp = &entp->next;
+
+ if (entp == NULL || c != 0) { /* Not found; create a new entry. */
+ newp = NEW(hashent, 1);
+ newp->name = xstrdup(name);
+ newp->size = 0;
+ newp->next = entp;
+ *linkp = newp;
+ entp = newp;
+ }
+
+ entp->size += size;
+}
+
+/*
+ * Return a hash value for the given string.
+ */
+static unsigned int
+hash(const char *s)
+{
+ unsigned char ch;
+ unsigned int h = 0;
+
+ while((ch = *s) != '\0') {
+ h = 9*h + ch;
+ s++;
+ }
+ return (h);
+}
+
+/*
+ * Enter the linker sets from the given ELF object file. Returns 0 on
+ * success, or -1 if an error occurred.
+ */
+static int
+enter_sets(const char *filename)
+{
+ int i;
+ FILE *iop;
+ Elf64_Shdr *shdr;
+ char *shstr;
+ Elf64_Ehdr ehdr;
+
+ if ((iop = fopen(filename, "rb")) == NULL) {
+ warn("%s", filename);
+ return (-1);
+ }
+ if (fread(&ehdr, sizeof ehdr, 1, iop) != 1 ||
+ ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
+ ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
+ ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
+ ehdr.e_ident[EI_MAG3] != ELFMAG3) {
+ warnx("%s: not an ELF file", filename);
+ fclose(iop);
+ return (-1);
+ }
+ if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
+ warnx("%s: unsupported ELF version", filename);
+ fclose(iop);
+ return (-1);
+ }
+ if (ehdr.e_ident[EI_DATA] != my_byte_order()) {
+ warnx("%s: unsupported byte order", filename);
+ fclose(iop);
+ return (-1);
+ }
+ if (ehdr.e_shoff == 0) {
+ warnx("%s: no section table", filename);
+ fclose(iop);
+ return (-1);
+ }
+ if (ehdr.e_shstrndx == SHN_UNDEF) {
+ warnx("%s: no section name string table", filename);
+ fclose(iop);
+ return (-1);
+ }
+
+ shdr = NEW(Elf64_Shdr, ehdr.e_shnum);
+ if (fseek(iop, ehdr.e_shoff, SEEK_SET) == -1) {
+ warn("%s", filename);
+ free(shdr);
+ fclose(iop);
+ return (-1);
+ }
+ if (fread(shdr, sizeof *shdr, ehdr.e_shnum, iop) != ehdr.e_shnum) {
+ warnx("%s: truncated section table", filename);
+ free(shdr);
+ fclose(iop);
+ return (-1);
+ }
+
+ shstr = NEW(char, shdr[ehdr.e_shstrndx].sh_size);
+ if (fseek(iop, shdr[ehdr.e_shstrndx].sh_offset, SEEK_SET) == -1) {
+ warn("%s", filename);
+ free(shstr);
+ free(shdr);
+ fclose(iop);
+ return (-1);
+ }
+ if (fread(shstr, sizeof *shstr, shdr[ehdr.e_shstrndx].sh_size, iop) !=
+ shdr[ehdr.e_shstrndx].sh_size) {
+ warnx("%s: truncated section name string table", filename);
+ free(shstr);
+ free(shdr);
+ fclose(iop);
+ return (-1);
+ }
+
+ for (i = 1; i < ehdr.e_shnum; i++) {
+ const char *name = shstr + shdr[i].sh_name;
+
+ if (strncmp(name, PREFIX, sizeof (PREFIX) - 1) == 0)
+ enter(name + sizeof (PREFIX) - 1, shdr[i].sh_size);
+ }
+
+ free(shstr);
+ free(shdr);
+ fclose(iop);
+ return (0);
+}
+
+/*
+ * Destructively merge all the sorted hash chains into a single sorted
+ * list, and return a pointer to its first element.
+ */
+static hashent *
+merge(void)
+{
+ unsigned int numchains = HASHSIZE;
+
+ while (numchains > 1) { /* More merging to do. */
+ unsigned int lo = 0;
+ /*
+ * Merge chains pairwise from the outside in, halving the
+ * number of chains.
+ */
+ while (numchains - lo >= 2) {
+ hashent **linkp = &hashtab[lo];
+ hashent *l1 = hashtab[lo++];
+ hashent *l2 = hashtab[--numchains];
+
+ while (l1 != NULL && l2 != NULL) {
+ if (strcmp(l1->name, l2->name) < 0) {
+ *linkp = l1;
+ linkp = &l1->next;
+ l1 = l1->next;
+ } else {
+ *linkp = l2;
+ linkp = &l2->next;
+ l2 = l2->next;
+ }
+ }
+ *linkp = l1==NULL ? l2 : l1;
+ }
+ }
+
+ return (hashtab[0]);
+}
+
+/*
+ * Determine the host byte order.
+ */
+static int
+my_byte_order(void)
+{
+ static unsigned short s = 0xbbaa;
+ int byte0;
+
+ byte0 = *(unsigned char *)&s;
+ if (byte0 == 0xaa)
+ return (ELFDATA2LSB);
+ else if (byte0 == 0xbb)
+ return (ELFDATA2MSB);
+ else
+ return (ELFDATANONE);
+}
+
+/*
+ * Allocate a chunk of memory and return a pointer to it. Die if the
+ * malloc fails.
+ */
+static void *
+xmalloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+ if (p == NULL)
+ err(EXIT_FAILURE, "malloc");
+ return (p);
+}
+
+/*
+ * Duplicate a string and return a pointer to the copy. Die if there is
+ * not enough memory.
+ */
+static char *
+xstrdup(const char *s)
+{
+ int size;
+
+ size = strlen(s) + 1;
+ return (memcpy(xmalloc(size), s, size));
+}
diff --git a/sys/alpha/alpha/in_cksum.c b/sys/alpha/alpha/in_cksum.c
new file mode 100644
index 000000000000..cbebc65853a0
--- /dev/null
+++ b/sys/alpha/alpha/in_cksum.c
@@ -0,0 +1,216 @@
+/* $Id$ */
+/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1988, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1996
+ * Matt Thomas <matt@3am-software.com>
+ *
+ * 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.
+ *
+ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <machine/in_cksum.h>
+
+/*
+ * Checksum routine for Internet Protocol family headers
+ * (Portable Alpha version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
+#define REDUCE32 \
+ { \
+ q_util.q = sum; \
+ sum = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
+ }
+#define REDUCE16 \
+ { \
+ q_util.q = sum; \
+ l_util.l = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
+ sum = l_util.s[0] + l_util.s[1]; \
+ ADDCARRY(sum); \
+ }
+
+static const u_int32_t in_masks[] = {
+ /*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/
+ 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF, /* offset 0 */
+ 0x00000000, 0x0000FF00, 0x00FFFF00, 0xFFFFFF00, /* offset 1 */
+ 0x00000000, 0x00FF0000, 0xFFFF0000, 0xFFFF0000, /* offset 2 */
+ 0x00000000, 0xFF000000, 0xFF000000, 0xFF000000, /* offset 3 */
+};
+
+union l_util {
+ u_int16_t s[2];
+ u_int32_t l;
+};
+union q_util {
+ u_int16_t s[4];
+ u_int32_t l[2];
+ u_int64_t q;
+};
+
+u_int64_t in_cksumdata __P((caddr_t buf, int len));
+
+u_int64_t
+in_cksumdata(buf, len)
+ register caddr_t buf;
+ register int len;
+{
+ const u_int32_t *lw = (u_int32_t *) buf;
+ u_int64_t sum = 0;
+ u_int64_t prefilled;
+ int offset;
+ union q_util q_util;
+
+ if ((3 & (long) lw) == 0 && len == 20) {
+ sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
+ REDUCE32;
+ return sum;
+ }
+
+ if ((offset = 3 & (long) lw) != 0) {
+ const u_int32_t *masks = in_masks + (offset << 2);
+ lw = (u_int32_t *) (((long) lw) - offset);
+ sum = *lw++ & masks[len >= 3 ? 3 : len];
+ len -= 4 - offset;
+ if (len <= 0) {
+ REDUCE32;
+ return sum;
+ }
+ }
+#if 0
+ /*
+ * Force to cache line boundary.
+ */
+ offset = 32 - (0x1f & (long) lw);
+ if (offset < 32 && len > offset) {
+ len -= offset;
+ if (4 & offset) {
+ sum += (u_int64_t) lw[0];
+ lw += 1;
+ }
+ if (8 & offset) {
+ sum += (u_int64_t) lw[0] + lw[1];
+ lw += 2;
+ }
+ if (16 & offset) {
+ sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3];
+ lw += 4;
+ }
+ }
+#endif
+ /*
+ * access prefilling to start load of next cache line.
+ * then add current cache line
+ * save result of prefilling for loop iteration.
+ */
+ prefilled = lw[0];
+ while ((len -= 32) >= 4) {
+ u_int64_t prefilling = lw[8];
+ sum += prefilled + lw[1] + lw[2] + lw[3]
+ + lw[4] + lw[5] + lw[6] + lw[7];
+ lw += 8;
+ prefilled = prefilling;
+ }
+ if (len >= 0) {
+ sum += prefilled + lw[1] + lw[2] + lw[3]
+ + lw[4] + lw[5] + lw[6] + lw[7];
+ lw += 8;
+ } else {
+ len += 32;
+ }
+ while ((len -= 16) >= 0) {
+ sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3];
+ lw += 4;
+ }
+ len += 16;
+ while ((len -= 4) >= 0) {
+ sum += (u_int64_t) *lw++;
+ }
+ len += 4;
+ if (len > 0)
+ sum += (u_int64_t) (in_masks[len] & *lw);
+ REDUCE32;
+ return sum;
+}
+
+int
+in_cksum(m, len)
+ register struct mbuf *m;
+ register int len;
+{
+ register u_int64_t sum = 0;
+ register int mlen = 0;
+ register int clen = 0;
+ register caddr_t addr;
+ union q_util q_util;
+ union l_util l_util;
+
+ for (; m && len; m = m->m_next) {
+ if (m->m_len == 0)
+ continue;
+ mlen = m->m_len;
+ if (len < mlen)
+ mlen = len;
+ addr = mtod(m, caddr_t);
+ if ((clen ^ (long) addr) & 1)
+ sum += in_cksumdata(addr, mlen) << 8;
+ else
+ sum += in_cksumdata(addr, mlen);
+
+ clen += mlen;
+ len -= mlen;
+ }
+ REDUCE16;
+ return (~sum & 0xffff);
+}
+
+u_int in_cksum_hdr(ip)
+ const struct ip *ip;
+{
+ u_int64_t sum = in_cksumdata((caddr_t) ip, sizeof(struct ip));
+ union q_util q_util;
+ union l_util l_util;
+ REDUCE16;
+ return (~sum & 0xffff);
+}
+
diff --git a/sys/alpha/alpha/interrupt.c b/sys/alpha/alpha/interrupt.c
new file mode 100644
index 000000000000..c4945a10124d
--- /dev/null
+++ b/sys/alpha/alpha/interrupt.c
@@ -0,0 +1,264 @@
+/* $Id */
+/* $NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Authors: Keith Bostic, Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+/*
+ * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center.
+ * Redistribute and modify at will, leaving only this additional copyright
+ * notice.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+/* __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $");*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/vmmeter.h>
+
+#include <machine/reg.h>
+#include <machine/frame.h>
+#include <machine/cpuconf.h>
+
+#if 0
+#ifdef EVCNT_COUNTERS
+#include <sys/device.h>
+struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
+#else
+#include <machine/intrcnt.h>
+#endif
+#endif
+
+volatile int mc_expected, mc_received;
+
+void
+interrupt(a0, a1, a2, framep)
+ unsigned long a0, a1, a2;
+ struct trapframe *framep;
+{
+
+ {
+ struct proc* p = curproc;
+ if (!p) p = &proc0;
+ if ((caddr_t) framep < (caddr_t) p->p_addr + 1024)
+ printf("possible stack overflow\n");
+ }
+
+ switch (a0) {
+ case ALPHA_INTR_XPROC: /* interprocessor interrupt */
+ printf("interprocessor interrupt!\n");
+ break;
+
+ case ALPHA_INTR_CLOCK: /* clock interrupt */
+ cnt.v_intr++;
+#if 0
+#ifdef EVCNT_COUNTERS
+ clock_intr_evcnt.ev_count++;
+#else
+ intrcnt[INTRCNT_CLOCK]++;
+#endif
+#endif
+ if (platform.clockintr)
+ (*platform.clockintr)(framep);
+ break;
+
+ case ALPHA_INTR_ERROR: /* Machine Check or Correctable Error */
+ a0 = alpha_pal_rdmces();
+ if (platform.mcheck_handler)
+ (*platform.mcheck_handler)(a0, framep, a1, a2);
+ else
+ machine_check(a0, framep, a1, a2);
+ break;
+
+ case ALPHA_INTR_DEVICE: /* I/O device interrupt */
+ cnt.v_intr++;
+ if (platform.iointr)
+ (*platform.iointr)(framep, a1);
+ break;
+
+ case ALPHA_INTR_PERF: /* interprocessor interrupt */
+ printf("performance interrupt!\n");
+ break;
+
+ case ALPHA_INTR_PASSIVE:
+#if 0
+ printf("passive release interrupt vec 0x%lx (ignoring)\n", a1);
+#endif
+ break;
+
+ default:
+ panic("unexpected interrupt: type 0x%lx vec 0x%lx a2 0x%lx\n",
+ a0, a1, a2);
+ /* NOTREACHED */
+ }
+}
+
+void
+set_iointr(niointr)
+ void (*niointr) __P((void *, unsigned long));
+{
+ if (platform.iointr)
+ panic("set iointr twice");
+ platform.iointr = niointr;
+}
+
+
+void
+machine_check(mces, framep, vector, param)
+ unsigned long mces;
+ struct trapframe *framep;
+ unsigned long vector, param;
+{
+ const char *type;
+
+ /* Make sure it's an error we know about. */
+ if ((mces & (ALPHA_MCES_MIP|ALPHA_MCES_SCE|ALPHA_MCES_PCE)) == 0) {
+ type = "fatal machine check or error (unknown type)";
+ goto fatal;
+ }
+
+ /* Machine checks. */
+ if (mces & ALPHA_MCES_MIP) {
+ /* If we weren't expecting it, then we punt. */
+ if (!mc_expected) {
+ type = "unexpected machine check";
+ goto fatal;
+ }
+
+ mc_expected = 0;
+ mc_received = 1;
+ }
+
+ /* System correctable errors. */
+ if (mces & ALPHA_MCES_SCE)
+ printf("Warning: received system correctable error.\n");
+
+ /* Processor correctable errors. */
+ if (mces & ALPHA_MCES_PCE)
+ printf("Warning: received processor correctable error.\n");
+
+ /* Clear pending machine checks and correctable errors */
+ alpha_pal_wrmces(mces);
+ return;
+
+fatal:
+ /* Clear pending machine checks and correctable errors */
+ alpha_pal_wrmces(mces);
+
+ printf("\n");
+ printf("%s:\n", type);
+ printf("\n");
+ printf(" mces = 0x%lx\n", mces);
+ printf(" vector = 0x%lx\n", vector);
+ printf(" param = 0x%lx\n", param);
+ printf(" pc = 0x%lx\n", framep->tf_regs[FRAME_PC]);
+ printf(" ra = 0x%lx\n", framep->tf_regs[FRAME_RA]);
+ printf(" curproc = %p\n", curproc);
+ if (curproc != NULL)
+ printf(" pid = %d, comm = %s\n", curproc->p_pid,
+ curproc->p_comm);
+ printf("\n");
+ panic("machine check");
+}
+
+int
+badaddr(addr, size)
+ void *addr;
+ size_t size;
+{
+ return(badaddr_read(addr, size, NULL));
+}
+
+int
+badaddr_read(addr, size, rptr)
+ void *addr;
+ size_t size;
+ void *rptr;
+{
+ long rcpt;
+
+ /* Get rid of any stale machine checks that have been waiting. */
+ alpha_pal_draina();
+
+ /* Tell the trap code to expect a machine check. */
+ mc_received = 0;
+ mc_expected = 1;
+
+ /* Read from the test address, and make sure the read happens. */
+ alpha_mb();
+ switch (size) {
+ case sizeof (u_int8_t):
+ rcpt = *(volatile u_int8_t *)addr;
+ break;
+
+ case sizeof (u_int16_t):
+ rcpt = *(volatile u_int16_t *)addr;
+ break;
+
+ case sizeof (u_int32_t):
+ rcpt = *(volatile u_int32_t *)addr;
+ break;
+
+ case sizeof (u_int64_t):
+ rcpt = *(volatile u_int64_t *)addr;
+ break;
+
+ default:
+ panic("badaddr: invalid size (%ld)\n", size);
+ }
+ alpha_mb();
+
+ /* Make sure we took the machine check, if we caused one. */
+ alpha_pal_draina();
+
+ /* disallow further machine checks */
+ mc_expected = 0;
+
+ if (rptr) {
+ switch (size) {
+ case sizeof (u_int8_t):
+ *(volatile u_int8_t *)rptr = rcpt;
+ break;
+
+ case sizeof (u_int16_t):
+ *(volatile u_int16_t *)rptr = rcpt;
+ break;
+
+ case sizeof (u_int32_t):
+ *(volatile u_int32_t *)rptr = rcpt;
+ break;
+
+ case sizeof (u_int64_t):
+ *(volatile u_int64_t *)rptr = rcpt;
+ break;
+ }
+ }
+ /* Return non-zero (i.e. true) if it's a bad address. */
+ return (mc_received);
+}
diff --git a/sys/alpha/alpha/ipl_funcs.c b/sys/alpha/alpha/ipl_funcs.c
new file mode 100644
index 000000000000..61ebc4b7755e
--- /dev/null
+++ b/sys/alpha/alpha/ipl_funcs.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <machine/ipl.h>
+#include <machine/cpu.h>
+#include <net/netisr.h>
+
+unsigned int netisr;
+
+void
+do_sir()
+{
+}
+
+void (*netisrs[32]) __P((void));
+
+u_int64_t ssir;
+
+void
+spl0()
+{
+ /* XXX soft interrupts here */
+
+ alpha_pal_swpipl(ALPHA_PSL_IPL_0);
+}
diff --git a/sys/alpha/alpha/mem.c b/sys/alpha/alpha/mem.c
new file mode 100644
index 000000000000..baf0ae5867fd
--- /dev/null
+++ b/sys/alpha/alpha/mem.c
@@ -0,0 +1,443 @@
+/*-
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 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, and code derived from software contributed to
+ * Berkeley by William Jolitz.
+ *
+ * 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.
+ *
+ * from: Utah $Hdr: mem.c 1.13 89/10/08$
+ * from: @(#)mem.c 7.2 (Berkeley) 5/9/91
+ * $Id: mem.c,v 1.50 1998/03/12 09:14:18 bde Exp $
+ */
+
+/*
+ * Memory special file
+ */
+
+#include "opt_devfs.h"
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#endif /* DEVFS */
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/msgbuf.h>
+
+#include <machine/frame.h>
+/* #include <machine/random.h>*/
+#include <machine/psl.h>
+#ifdef PERFMON
+#include <machine/perfmon.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_prot.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+static caddr_t zeropage;
+
+static d_open_t mmopen;
+static d_close_t mmclose;
+static d_read_t mmrw;
+static d_ioctl_t mmioctl;
+static d_mmap_t memmmap;
+static d_poll_t mmpoll;
+
+#define CDEV_MAJOR 2
+static struct cdevsw mem_cdevsw =
+ { mmopen, mmclose, mmrw, mmrw, /*2*/
+ mmioctl, nullstop, nullreset, nodevtotty,/* memory */
+ mmpoll, memmmap, NULL, "mem", NULL, -1 };
+
+static caddr_t zbuf;
+
+#ifdef DEVFS
+static void *mem_devfs_token;
+static void *kmem_devfs_token;
+static void *null_devfs_token;
+static void *random_devfs_token;
+static void *urandom_devfs_token;
+static void *zero_devfs_token;
+static void *io_devfs_token;
+#ifdef PERFMON
+static void *perfmon_devfs_token;
+#endif
+
+static void memdevfs_init __P((void));
+
+static void
+memdevfs_init()
+{
+ mem_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 0, DV_CHR,
+ UID_ROOT, GID_KMEM, 0640, "mem");
+ kmem_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 1, DV_CHR,
+ UID_ROOT, GID_KMEM, 0640, "kmem");
+ null_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 2, DV_CHR,
+ UID_ROOT, GID_WHEEL, 0666, "null");
+ random_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 3, DV_CHR,
+ UID_ROOT, GID_WHEEL, 0644, "random");
+ urandom_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 4, DV_CHR,
+ UID_ROOT, GID_WHEEL, 0644, "urandom");
+ zero_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 12, DV_CHR,
+ UID_ROOT, GID_WHEEL, 0666, "zero");
+#ifdef PERFMON
+ perfmon_devfs_token =
+ devfs_add_devswf(&mem_cdevsw, 32, DV_CHR,
+ UID_ROOT, GID_KMEM, 0640, "perfmon");
+#endif /* PERFMON */
+}
+#endif /* DEVFS */
+
+static int
+mmclose(dev, flags, fmt, p)
+ dev_t dev;
+ int flags;
+ int fmt;
+ struct proc *p;
+{
+ switch (minor(dev)) {
+#ifdef PERFMON
+ case 32:
+ return perfmon_close(dev, flags, fmt, p);
+#endif
+ default:
+ break;
+ }
+ return(0);
+}
+
+static int
+mmopen(dev, flags, fmt, p)
+ dev_t dev;
+ int flags;
+ int fmt;
+ struct proc *p;
+{
+ int error;
+
+ switch (minor(dev)) {
+ case 32:
+#ifdef PERFMON
+ return perfmon_open(dev, flags, fmt, p);
+#else
+ return ENODEV;
+#endif
+ default:
+ break;
+ }
+ return(0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ register vm_offset_t o, v;
+ register int c;
+ register struct iovec *iov;
+ int error = 0, rw;
+
+ while (uio->uio_resid > 0 && !error) {
+ 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:
+ v = uio->uio_offset;
+kmemphys:
+ if (v >= ALPHA_K0SEG_TO_PHYS((vm_offset_t)msgbufp)) {
+ if (msgbufmapped == 0) {
+ printf("Message Buf not Mapped\n");
+ error = EFAULT;
+ break;
+ }
+ }
+
+ /* Allow reads only in RAM. */
+ rw = (uio->uio_rw == UIO_READ) ? VM_PROT_READ : VM_PROT_WRITE;
+ if ((alpha_pa_access(v) & rw) != rw) {
+ error = EFAULT;
+ break;
+ }
+
+ o = uio->uio_offset & PAGE_MASK;
+ c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
+ error =
+ uiomove((caddr_t)ALPHA_PHYS_TO_K0SEG(v), c, uio);
+ break;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+
+ if (v >= ALPHA_K0SEG_BASE && v <= ALPHA_K0SEG_END) {
+ v = ALPHA_K0SEG_TO_PHYS(v);
+ goto kmemphys;
+ }
+
+ c = min(iov->iov_len, MAXPHYS);
+#if defined(UVM)
+ if (!uvm_kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+#else
+ if (!kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+#endif
+ error = uiomove((caddr_t)v, c, uio);
+ break;
+
+/* minor device 2 is EOF/rathole */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+/* 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);
+ }
+ /*
+ * On the first call, allocate and zero a page
+ * of memory for use with /dev/zero.
+ */
+ if (zeropage == NULL) {
+ zeropage = (caddr_t)
+ malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
+ bzero(zeropage, PAGE_SIZE);
+ }
+ c = min(iov->iov_len, PAGE_SIZE);
+ error = uiomove(zeropage, c, uio);
+ break;
+
+ default:
+ return (ENXIO);
+ }
+ }
+ return (error);
+}
+
+/*******************************************************\
+* allow user processes to MMAP some memory sections *
+* instead of going through read/write *
+\*******************************************************/
+static int
+memmmap(dev_t dev, int offset, int prot)
+{
+ /*
+ * /dev/mem is the only one that makes sense through this
+ * interface. For /dev/kmem any physaddr we return here
+ * could be transient and hence incorrect or invalid at
+ * a later time. /dev/null just doesn't make any sense
+ * and /dev/zero is a hack that is handled via the default
+ * pager in mmap().
+ */
+ if (minor(dev) != 0)
+ return (-1);
+
+ /*
+ * Allow access only in RAM.
+ */
+ if ((prot & alpha_pa_access(atop((vm_offset_t)offset))) != prot)
+ return (-1);
+ return (alpha_btop(offset));
+}
+
+/*
+ * Allow userland to select which interrupts will be used in the muck
+ * gathering business.
+ */
+static int
+mmioctl(dev, cmd, cmdarg, flags, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t cmdarg;
+ int flags;
+ struct proc *p;
+{
+ static u_int16_t interrupt_allowed = 0;
+ u_int16_t interrupt_mask;
+ int error;
+
+ switch(minor(dev)) {
+ case 3:
+ case 4:
+ break;
+
+#ifdef PERFMON
+ case 32:
+ return perfmon_ioctl(dev, cmd, cmdarg, flags, p);
+#endif
+ default:
+ return ENODEV;
+ }
+
+ if (*(u_int16_t *)cmdarg >= 16)
+ return (EINVAL);
+
+#if 0
+ /* Only root can do this */
+ error = suser(p->p_ucred, &p->p_acflag);
+ if (error) {
+ return (error);
+ }
+ interrupt_mask = 1 << *(u_int16_t *)cmdarg;
+
+ switch (cmd) {
+
+ case MEM_SETIRQ:
+ if (!(interrupt_allowed & interrupt_mask)) {
+ disable_intr();
+ interrupt_allowed |= interrupt_mask;
+ sec_intr_handler[*(u_int16_t *)cmdarg] =
+ intr_handler[*(u_int16_t *)cmdarg];
+ intr_handler[*(u_int16_t *)cmdarg] =
+ add_interrupt_randomness;
+ sec_intr_unit[*(u_int16_t *)cmdarg] =
+ intr_unit[*(u_int16_t *)cmdarg];
+ intr_unit[*(u_int16_t *)cmdarg] =
+ *(u_int16_t *)cmdarg;
+ enable_intr();
+ }
+ else return (EPERM);
+ break;
+
+ case MEM_CLEARIRQ:
+ if (interrupt_allowed & interrupt_mask) {
+ disable_intr();
+ interrupt_allowed &= ~(interrupt_mask);
+ intr_handler[*(u_int16_t *)cmdarg] =
+ sec_intr_handler[*(u_int16_t *)cmdarg];
+ intr_unit[*(u_int16_t *)cmdarg] =
+ sec_intr_unit[*(u_int16_t *)cmdarg];
+ enable_intr();
+ }
+ else return (EPERM);
+ break;
+
+ case MEM_RETURNIRQ:
+ *(u_int16_t *)cmdarg = interrupt_allowed;
+ break;
+
+ default:
+ return (ENOTTY);
+ }
+#endif
+ return (0);
+}
+
+int
+mmpoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
+{
+ switch (minor(dev)) {
+ case 3: /* /dev/random */
+ /* return random_poll(dev, events, p);*/
+ case 4: /* /dev/urandom */
+ default:
+ return seltrue(dev, events, p);
+ }
+}
+
+/*
+ * Routine that identifies /dev/mem and /dev/kmem.
+ *
+ * A minimal stub routine can always return 0.
+ */
+int
+iskmemdev(dev)
+ dev_t dev;
+{
+
+ return ((major(dev) == mem_cdevsw.d_maj)
+ && (minor(dev) == 0 || minor(dev) == 1));
+}
+
+int
+iszerodev(dev)
+ dev_t dev;
+{
+ return ((major(dev) == mem_cdevsw.d_maj)
+ && minor(dev) == 12);
+}
+
+
+
+static int mem_devsw_installed;
+
+static void
+mem_drvinit(void *unused)
+{
+ dev_t dev;
+
+ if( ! mem_devsw_installed ) {
+ dev = makedev(CDEV_MAJOR, 0);
+ cdevsw_add(&dev,&mem_cdevsw, NULL);
+ mem_devsw_installed = 1;
+#ifdef DEVFS
+ memdevfs_init();
+#endif
+ }
+}
+
+SYSINIT(memdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,mem_drvinit,NULL)
+
diff --git a/sys/alpha/alpha/pal.s b/sys/alpha/alpha/pal.s
new file mode 100644
index 000000000000..36ecdfb22e1c
--- /dev/null
+++ b/sys/alpha/alpha/pal.s
@@ -0,0 +1,350 @@
+/* $NetBSD: pal.s,v 1.12 1998/02/27 03:44:53 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * The various OSF PALcode routines.
+ *
+ * The following code is originally derived from pages: (I) 6-5 - (I) 6-7
+ * and (III) 2-1 - (III) 2-25 of "Alpha Architecture Reference Manual" by
+ * Richard L. Sites.
+ *
+ * Updates taken from pages: (II-B) 2-1 - (II-B) 2-33 of "Alpha AXP
+ * Architecture Reference Manual, Second Edition" by Richard L. Sites
+ * and Richard T. Witek.
+ */
+
+#include <machine/asm.h>
+
+__KERNEL_RCSID(1, "$NetBSD: pal.s,v 1.12 1998/02/27 03:44:53 thorpej Exp $");
+
+inc2: .stabs __FILE__,132,0,0,inc2; .loc 1 __LINE__
+/*
+ * alpha_rpcc: read process cycle counter (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_rpcc,1)
+ rpcc v0
+ RET
+ END(alpha_rpcc)
+
+/*
+ * alpha_mb: memory barrier (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_mb,0)
+ mb
+ RET
+ END(alpha_mb)
+
+/*
+ * alpha_wmb: write memory barrier (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_wmb,0)
+ /* wmb XXX */
+ mb /* XXX */
+ RET
+ END(alpha_wmb)
+
+/*
+ * alpha_amask: read architecture features (XXX INSTRUCTION, NOT PALcode OP)
+ *
+ * Arguments:
+ * a0 bitmask of features to test
+ *
+ * Returns:
+ * v0 bitmask - bit is _cleared_ if feature is supported
+ */
+ .text
+LEAF(alpha_amask,1)
+ amask a0, v0
+ RET
+ END(alpha_amask)
+
+/*
+ * alpha_implver: read implementation version (XXX INSTRUCTION, NOT PALcode OP)
+ *
+ * Returns:
+ * v0 implementation version - see <machine/alpha_cpu.h>
+ */
+ .text
+LEAF(alpha_implver,0)
+#if 0
+ implver 0x1, v0
+#else
+ .long 0x47e03d80 /* XXX gas(1) does the Wrong Thing */
+#endif
+ RET
+ END(alpha_implver)
+
+/*
+ * alpha_pal_imb: I-Stream memory barrier. [UNPRIVILEGED]
+ * (Makes instruction stream coherent with data stream.)
+ */
+ .text
+LEAF(alpha_pal_imb,0)
+ call_pal PAL_imb
+ RET
+ END(alpha_pal_imb)
+
+/*
+ * alpha_pal_cflush: Cache flush [PRIVILEGED]
+ *
+ * Flush the entire physical page specified by the PFN specified in
+ * a0 from any data caches associated with the current processor.
+ *
+ * Arguments:
+ * a0 page frame number of page to flush
+ */
+ .text
+LEAF(alpha_pal_cflush,1)
+ call_pal PAL_cflush
+ RET
+ END(alpha_pal_cflush)
+
+/*
+ * alpha_pal_draina: Drain aborts. [PRIVILEGED]
+ */
+ .text
+LEAF(alpha_pal_draina,0)
+ call_pal PAL_draina
+ RET
+ END(alpha_pal_draina)
+
+/*
+ * alpha_pal_halt: Halt the processor. [PRIVILEGED]
+ */
+ .text
+LEAF(alpha_pal_halt,0)
+ call_pal PAL_halt
+ br zero,alpha_pal_halt /* Just in case */
+ RET
+ END(alpha_pal_halt)
+
+/*
+ * alpha_pal_rdmces: Read MCES processor register. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current MCES value
+ */
+ .text
+LEAF(alpha_pal_rdmces,1)
+ call_pal PAL_OSF1_rdmces
+ RET
+ END(alpha_pal_rdmces)
+
+/*
+ * alpha_pal_rdps: Read processor status. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current PS value
+ */
+ .text
+LEAF(alpha_pal_rdps,0)
+ call_pal PAL_OSF1_rdps
+ RET
+ END(alpha_pal_rdps)
+
+/*
+ * alpha_pal_rdusp: Read user stack pointer. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current user stack pointer
+ */
+ .text
+LEAF(alpha_pal_rdusp,0)
+ call_pal PAL_OSF1_rdusp
+ RET
+ END(alpha_pal_rdusp)
+
+/*
+ * alpha_pal_rdval: Read system value. [PRIVILEGED]
+ *
+ * Returns the sysvalue in v0, allowing access to a 64-bit
+ * per-processor value for use by the operating system.
+ *
+ * Return:
+ * v0 sysvalue
+ */
+ .text
+LEAF(alpha_pal_rdval,0)
+ call_pal PAL_OSF1_rdval
+ RET
+ END(alpha_pal_rdval)
+
+/*
+ * alpha_pal_swpipl: Swap Interrupt priority level. [PRIVILEGED]
+ * _alpha_pal_swpipl: Same, from profiling code. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new IPL
+ *
+ * Return:
+ * v0 old IPL
+ */
+ .text
+LEAF(alpha_pal_swpipl,1)
+ call_pal PAL_OSF1_swpipl
+ RET
+ END(alpha_pal_swpipl)
+
+LEAF_NOPROFILE(_alpha_pal_swpipl,1)
+ call_pal PAL_OSF1_swpipl
+ RET
+ END(_alpha_pal_swpipl)
+
+/*
+ * alpha_pal_tbi: Translation buffer invalidate. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 operation selector
+ * a1 address to operate on (if necessary)
+ */
+ .text
+LEAF(alpha_pal_tbi,2)
+ call_pal PAL_OSF1_tbi
+ RET
+ END(alpha_pal_tbi)
+
+/*
+ * alpha_pal_whami: Who am I? [PRIVILEGED]
+ *
+ * Return:
+ * v0 processor number
+ */
+ .text
+LEAF(alpha_pal_whami,0)
+ call_pal PAL_OSF1_whami
+ RET
+ END(alpha_pal_whami)
+
+/*
+ * alpha_pal_wrent: Write system entry address. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new vector
+ * a1 vector selector
+ */
+ .text
+LEAF(alpha_pal_wrent,2)
+ call_pal PAL_OSF1_wrent
+ RET
+ END(alpha_pal_wrent)
+
+/*
+ * alpha_pal_wrfen: Write floating-point enable. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new enable value (val & 0x1 -> enable).
+ */
+ .text
+LEAF(alpha_pal_wrfen,1)
+ call_pal PAL_OSF1_wrfen
+ RET
+ END(alpha_pal_wrfen)
+
+/*
+ * alpha_pal_wripir: Write interprocessor interrupt request. [PRIVILEGED]
+ *
+ * Generate an interprocessor interrupt on the processor specified by
+ * processor number in a0.
+ *
+ * Arguments:
+ * a0 processor to interrupt
+ */
+ .text
+LEAF(alpha_pal_wripir,1)
+ call_pal PAL_ipir
+ RET
+ END(alpha_pal_wripir)
+
+/*
+ * alpha_pal_wrusp: Write user stack pointer. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new user stack pointer
+ */
+ .text
+LEAF(alpha_pal_wrusp,1)
+ call_pal PAL_OSF1_wrusp
+ RET
+ END(alpha_pal_wrusp)
+
+/*
+ * alpha_pal_wrvptptr: Write virtual page table pointer. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new virtual page table pointer
+ */
+ .text
+LEAF(alpha_pal_wrvptptr,1)
+ call_pal PAL_OSF1_wrvptptr
+ RET
+ END(alpha_pal_wrvptptr)
+
+/*
+ * alpha_pal_wrmces: Write MCES processor register. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 value to write to MCES
+ */
+ .text
+LEAF(alpha_pal_wrmces,1)
+ call_pal PAL_OSF1_wrmces
+ RET
+ END(alpha_pal_wrmces)
+
+/*
+ * alpha_pal_wrval: Write system value. [PRIVILEGED]
+ *
+ * Write the value passed in a0 to this processor's sysvalue.
+ *
+ * Arguments:
+ * a0 value to write to sysvalue
+ */
+LEAF(alpha_pal_wrval,1)
+ call_pal PAL_OSF1_wrval
+ RET
+ END(alpha_pal_wrval)
+
+/*
+ * alpha_pal_swpctx: Swap context. [PRIVILEGED]
+ *
+ * Switch to a new process context.
+ *
+ * Arguments:
+ * a0 physical address of hardware PCB describing context
+ *
+ * Returns:
+ * v0 physical address of hardware PCB describing previous context
+ */
+LEAF(alpha_pal_swpctx,1)
+ call_pal PAL_OSF1_swpctx
+ RET
+ END(alpha_pal_swpctx)
diff --git a/sys/alpha/alpha/pmap.c b/sys/alpha/alpha/pmap.c
new file mode 100644
index 000000000000..54f86331f5e4
--- /dev/null
+++ b/sys/alpha/alpha/pmap.c
@@ -0,0 +1,3081 @@
+/*
+ * Copyright (c) 1991 Regents of the University of California.
+ * All rights reserved.
+ * Copyright (c) 1994 John S. Dyson
+ * All rights reserved.
+ * Copyright (c) 1994 David Greenman
+ * All rights reserved.
+ * Copyright (c) 1998 Doug Rabson
+ * 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 and William Jolitz of UUNET Technologies Inc.
+ *
+ * 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.
+ *
+ * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
+ * from: i386 Id: pmap.c,v 1.193 1998/04/19 15:22:48 bde Exp
+ * with some ideas from NetBSD's alpha pmap
+ * $Id$
+ */
+
+/*
+ * Manages physical address maps.
+ *
+ * In addition to hardware address maps, this
+ * module is called upon to provide software-use-only
+ * maps which may or may not be stored in the same
+ * form as hardware maps. These pseudo-maps are
+ * used to store intermediate results from copy
+ * operations to and from address spaces.
+ *
+ * Since the information managed by this module is
+ * also stored by the logical address mapping module,
+ * this module may throw away valid virtual-to-physical
+ * mappings at almost any time. However, invalidations
+ * of virtual-to-physical mappings must be done as
+ * requested.
+ *
+ * In order to cope with hardware architectures which
+ * make virtual-to-physical map invalidates expensive,
+ * this module may delay invalidate or reduced protection
+ * operations until such time as they are actually
+ * necessary. This module is given full information as
+ * to which processors are currently using which maps,
+ * and to when physical maps must be made correct.
+ */
+
+/*
+ * Notes for alpha pmap.
+ *
+ * On alpha, pm_pdeobj will hold lev1, lev2 and lev3 page tables.
+ * Indices from 0 to NUSERLEV3MAPS-1 will map user lev3 page tables,
+ * indices from NUSERLEV3MAPS to NUSERLEV3MAPS+NUSERLEV2MAPS-1 will
+ * map user lev2 page tables and index NUSERLEV3MAPS+NUSERLEV2MAPS
+ * will map the lev1 page table. The lev1 table will self map at
+ * address VADDR(PTLEV1I,0,0).
+ *
+ * The vm_object kptobj holds the kernel page tables on i386 (62 or 63
+ * of them, depending on whether the system is SMP). On alpha, kptobj
+ * will hold the lev3 and lev2 page tables for K1SEG. Indices 0 to
+ * NKLEV3MAPS-1 will map kernel lev3 page tables and indices
+ * NKLEV3MAPS to NKLEV3MAPS+NKLEV2MAPS will map lev2 page tables. (XXX
+ * should the kernel Lev1map be inserted into this object?).
+ *
+ * pvtmmap is not needed for alpha since K0SEG maps all of physical
+ * memory. CADDR1 and CADDR2 are not needed for the same reason. The
+ * only places outside pmap and machdep which use CADDR1 are xxdump
+ * routines which use them for dumping physical pages.
+ *
+ *
+ * alpha virtual memory map:
+ *
+ *
+ * Address Lev1 index
+ *
+ * ---------------------------------
+ * 0000000000000000 | | 0
+ * | |
+ * | |
+ * | |
+ * | |
+ * --- ---
+ * User space (USEG)
+ * --- ---
+ * | |
+ * | |
+ * | |
+ * | |
+ * 000003ffffffffff | | 511=UMAXLEV1I
+ * ---------------------------------
+ * fffffc0000000000 | | 512=K0SEGLEV1I
+ * | Kernel code/data/bss |
+ * | |
+ * | |
+ * | |
+ * --- ---
+ * K0SEG
+ * --- ---
+ * | |
+ * | 1-1 physical/virtual |
+ * | |
+ * | |
+ * fffffdffffffffff | |
+ * ---------------------------------
+ * fffffe0000000000 | | 768=K1SEGLEV1I
+ * | Kernel dynamic data |
+ * | |
+ * | |
+ * | |
+ * --- ---
+ * K1SEG
+ * --- ---
+ * | |
+ * | mapped by ptes |
+ * | |
+ * | |
+ * fffffff7ffffffff | |
+ * ---------------------------------
+ * fffffffe00000000 | | 1023=PTLEV1I
+ * | PTmap (pte self map) |
+ * ffffffffffffffff | |
+ * ---------------------------------
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/msgbuf.h>
+#include <sys/vmmeter.h>
+#include <sys/mman.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_prot.h>
+#include <sys/lock.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_zone.h>
+
+#include <sys/user.h>
+
+#include <machine/md_var.h>
+
+#ifndef PMAP_SHPGPERPROC
+#define PMAP_SHPGPERPROC 200
+#endif
+
+#if defined(DIAGNOSTIC)
+#define PMAP_DIAGNOSTIC
+#endif
+
+#define MINPV 2048
+
+#define PMAP_DIAGNOSTIC
+
+#if !defined(PMAP_DIAGNOSTIC)
+#define PMAP_INLINE __inline
+#else
+#define PMAP_INLINE
+#endif
+
+/*
+ * Some macros for manipulating virtual addresses
+ */
+#define ALPHA_L1SIZE (1L << ALPHA_L1SHIFT)
+#define ALPHA_L2SIZE (1L << ALPHA_L2SHIFT)
+
+#define alpha_l1trunc(va) ((va) & (ALPHA_L1SIZE-1))
+#define alpha_l2trunc(va) ((va) & (ALPHA_L2SIZE-1))
+
+/*
+ * Get PDEs and PTEs for user/kernel address space
+ */
+#define pmap_pte_w(pte) ((*(pte) & PG_W) != 0)
+#define pmap_pte_managed(pte) ((*(pte) & PG_MANAGED) != 0)
+#define pmap_pte_v(pte) ((*(pte) & PG_V) != 0)
+#define pmap_pte_pa(pte) alpha_ptob(ALPHA_PTE_TO_PFN(*(pte)))
+#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
+
+#define pmap_pte_set_w(pte, v) ((v)?(*pte |= PG_W):(*pte &= ~PG_W))
+#define pmap_pte_set_prot(pte, v) ((*pte &= ~PG_PROT), (*pte |= (v)))
+
+/*
+ * Given a map and a machine independent protection code,
+ * convert to an alpha protection code.
+ */
+#define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p])
+int protection_codes[2][8];
+
+#define pa_index(pa) atop((pa) - vm_first_phys)
+#define pa_to_pvh(pa) (&pv_table[pa_index(pa)])
+
+/*
+ * Return non-zero if this pmap is currently active
+ */
+#define pmap_isactive(pmap) (pmap == kernel_pmap || \
+ ALPHA_PTE_TO_PFN(pmap->pm_lev1[PTLEV1I]) == ALPHA_PTE_TO_PFN(PTlev1pte))
+
+/*
+ * Extract level 1, 2 and 3 page table indices from a va
+ */
+#define PTMASK ((1 << ALPHA_PTSHIFT) - 1)
+
+#define pmap_lev1_index(va) (((va) >> ALPHA_L1SHIFT) & PTMASK)
+#define pmap_lev2_index(va) (((va) >> ALPHA_L2SHIFT) & PTMASK)
+#define pmap_lev3_index(va) (((va) >> ALPHA_L3SHIFT) & PTMASK)
+
+/*
+ * Given a physical address, construct a pte
+ */
+#define pmap_phys_to_pte(pa) ALPHA_PTE_FROM_PFN(alpha_btop(pa))
+
+/*
+ * Given a page frame number, construct a k0seg va
+ */
+#define pmap_k0seg_to_pfn(va) alpha_btop(ALPHA_K0SEG_TO_PHYS(va))
+
+/*
+ * Given a pte, construct a k0seg va
+ */
+#define pmap_k0seg_to_pte(va) ALPHA_PTE_FROM_PFN(pmap_k0seg_to_pfn(va))
+
+/*
+ * Lev1map:
+ *
+ * Kernel level 1 page table. This maps all kernel level 2
+ * page table pages, and is used as a template for all user
+ * pmap level 1 page tables. When a new user level 1 page
+ * table is allocated, all Lev1map PTEs for kernel addresses
+ * are copied to the new map.
+ *
+ * Lev2map:
+ *
+ * Initial set of kernel level 2 page table pages. These
+ * map the kernel level 3 page table pages. As kernel
+ * level 3 page table pages are added, more level 2 page
+ * table pages may be added to map them. These pages are
+ * never freed.
+ *
+ * Lev3map:
+ *
+ * Initial set of kernel level 3 page table pages. These
+ * map pages in K1SEG. More level 3 page table pages may
+ * be added at run-time if additional K1SEG address space
+ * is required. These pages are never freed.
+ *
+ * Lev2mapsize:
+ *
+ * Number of entries in the initial Lev2map.
+ *
+ * Lev3mapsize:
+ *
+ * Number of entries in the initial Lev3map.
+ *
+ * NOTE: When mappings are inserted into the kernel pmap, all
+ * level 2 and level 3 page table pages must already be allocated
+ * and mapped into the parent page table.
+ */
+pt_entry_t *Lev1map, *Lev2map, *Lev3map;
+vm_size_t Lev2mapsize, Lev3mapsize;
+
+/*
+ * Statically allocated kernel pmap
+ */
+static struct pmap kernel_pmap_store;
+pmap_t kernel_pmap;
+
+vm_offset_t avail_start; /* PA of first available physical page */
+vm_offset_t avail_end; /* PA of last available physical page */
+vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */
+vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
+static boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
+static vm_offset_t vm_first_phys;
+static int pv_npg;
+
+static vm_object_t kptobj;
+
+static int nklev3, nklev2;
+vm_offset_t kernel_vm_end;
+
+/*
+ * Data for the pv entry allocation mechanism
+ */
+static vm_zone_t pvzone;
+static struct vm_zone pvzone_store;
+static struct vm_object pvzone_obj;
+static int pv_entry_count=0, pv_entry_max=0, pv_entry_high_water=0;
+static int pmap_pagedaemon_waken = 0;
+static struct pv_entry *pvinit;
+
+/*
+ * All those kernel PT submaps that BSD is so fond of
+ */
+pt_entry_t *CMAP1 = 0;
+static pt_entry_t *CMAP2, *ptmmap;
+static pv_table_t *pv_table;
+caddr_t CADDR1;
+static caddr_t CADDR2;
+
+static PMAP_INLINE void free_pv_entry __P((pv_entry_t pv));
+static pv_entry_t get_pv_entry __P((void));
+static void alpha_protection_init __P((void));
+static void pmap_changebit __P((vm_offset_t pa, int bit, boolean_t setem));
+
+static PMAP_INLINE int pmap_is_managed __P((vm_offset_t pa));
+static void pmap_remove_all __P((vm_offset_t pa));
+static vm_page_t pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
+ vm_offset_t pa, vm_page_t mpte));
+static int pmap_remove_pte __P((pmap_t pmap, pt_entry_t* ptq, vm_offset_t sva));
+static void pmap_remove_page __P((struct pmap *pmap, vm_offset_t va));
+static int pmap_remove_entry __P((struct pmap *pmap, pv_table_t *pv,
+ vm_offset_t va));
+static boolean_t pmap_testbit __P((vm_offset_t pa, int bit));
+static void pmap_insert_entry __P((pmap_t pmap, vm_offset_t va,
+ vm_page_t mpte, vm_offset_t pa));
+
+static vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
+
+static int pmap_release_free_page __P((pmap_t pmap, vm_page_t p));
+static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
+static vm_page_t pmap_page_lookup __P((vm_object_t object, vm_pindex_t pindex));
+static int pmap_unuse_pt __P((pmap_t, vm_offset_t, vm_page_t));
+static vm_offset_t pmap_kmem_choose(vm_offset_t addr) ;
+void pmap_collect(void);
+
+
+/*
+ * Routine: pmap_lev1pte
+ * Function:
+ * Extract the level 1 page table entry associated
+ * with the given map/virtual_address pair.
+ */
+static PMAP_INLINE pt_entry_t*
+pmap_lev1pte(pmap_t pmap, vm_offset_t va)
+{
+ if (!pmap)
+ return 0;
+ return &pmap->pm_lev1[pmap_lev1_index(va)];
+}
+
+/*
+ * Routine: pmap_lev2pte
+ * Function:
+ * Extract the level 2 page table entry associated
+ * with the given map/virtual_address pair.
+ */
+static PMAP_INLINE pt_entry_t*
+pmap_lev2pte(pmap_t pmap, vm_offset_t va)
+{
+ pt_entry_t* l1pte;
+ pt_entry_t* l2map;
+
+ l1pte = pmap_lev1pte(pmap, va);
+ if (!pmap_pte_v(l1pte))
+ return 0;
+
+ l2map = (pt_entry_t*) ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
+ return &l2map[pmap_lev2_index(va)];
+}
+
+/*
+ * Routine: pmap_lev3pte
+ * Function:
+ * Extract the level 3 page table entry associated
+ * with the given map/virtual_address pair.
+ */
+static PMAP_INLINE pt_entry_t*
+pmap_lev3pte(pmap_t pmap, vm_offset_t va)
+{
+ pt_entry_t* l2pte;
+ pt_entry_t* l3map;
+
+ l2pte = pmap_lev2pte(pmap, va);
+ if (!l2pte || !pmap_pte_v(l2pte))
+ return 0;
+
+ l3map = (pt_entry_t*) ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l2pte));
+ return &l3map[pmap_lev3_index(va)];
+}
+
+vm_offset_t
+pmap_steal_memory(vm_size_t size)
+{
+ vm_size_t bank_size;
+ vm_offset_t pa, va;
+
+ size = round_page(size);
+
+ bank_size = phys_avail[1] - phys_avail[0];
+ while (size > bank_size) {
+ int i;
+ for (i = 0; phys_avail[i+2]; i+= 2) {
+ phys_avail[i] = phys_avail[i+2];
+ phys_avail[i+1] = phys_avail[i+3];
+ }
+ phys_avail[i] = 0;
+ phys_avail[i+1] = 0;
+ if (!phys_avail[0])
+ panic("pmap_steal_memory: out of memory");
+ bank_size = phys_avail[1] - phys_avail[0];
+ }
+
+ pa = phys_avail[0];
+ phys_avail[0] += size;
+
+ va = ALPHA_PHYS_TO_K0SEG(pa);
+ bzero((caddr_t) va, size);
+ return va;
+}
+
+extern pt_entry_t rom_pte; /* XXX */
+extern int prom_mapped; /* XXX */
+
+/*
+ * Bootstrap the system enough to run with virtual memory.
+ */
+void
+pmap_bootstrap(vm_offset_t ptaddr, u_int maxasn)
+{
+ pt_entry_t newpte;
+ pt_entry_t* pte;
+ vm_offset_t va;
+ int i;
+
+ /*
+ * Allocate a level 1 map for the kernel.
+ */
+ Lev1map = (pt_entry_t*) pmap_steal_memory(PAGE_SIZE);
+
+ /*
+ * Allocate a level 2 map for the kernel
+ */
+ Lev2map = (pt_entry_t*) pmap_steal_memory(PAGE_SIZE);
+ Lev2mapsize = PAGE_SIZE;
+
+ /*
+ * Allocate some level 3 maps for the kernel
+ */
+ Lev3map = (pt_entry_t*) pmap_steal_memory(PAGE_SIZE*NKPT);
+ Lev3mapsize = NKPT * PAGE_SIZE;
+
+ /* Map all of the level 2 maps */
+ for (i = 0; i < howmany(Lev2mapsize, PAGE_SIZE); i++) {
+ unsigned long pfn =
+ pmap_k0seg_to_pfn((vm_offset_t) Lev2map) + i;
+ newpte = ALPHA_PTE_FROM_PFN(pfn);
+ newpte |= PG_V | PG_KRE | PG_KWE | PG_W;
+ Lev1map[K1SEGLEV1I + i] = newpte;
+ }
+
+
+ /* Setup the mapping for the prom console */
+ {
+
+ if (pmap_uses_prom_console()) {
+ /* XXX save old pte so that we can remap prom if necessary */
+ rom_pte = *(pt_entry_t *)ptaddr & ~PG_ASM; /* XXX */
+ }
+ prom_mapped = 0;
+
+ /*
+ * Actually, this code lies. The prom is still mapped, and will
+ * remain so until the context switch after alpha_init() returns.
+ * Printfs using the firmware before then will end up frobbing
+ * Lev1map unnecessarily, but that's OK.
+ */
+ }
+
+ /* Level 1 self mapping */
+ newpte = pmap_k0seg_to_pte((vm_offset_t) Lev1map);
+ newpte |= PG_V | PG_KRE | PG_KWE;
+ Lev1map[PTLEV1I] = newpte;
+
+ /* Map all of the level 3 maps */
+ for (i = 0; i < howmany(Lev3mapsize, PAGE_SIZE); i++) {
+ unsigned long pfn =
+ pmap_k0seg_to_pfn((vm_offset_t) Lev3map) + i;
+ newpte = ALPHA_PTE_FROM_PFN(pfn);
+ newpte |= PG_V | PG_KRE | PG_KWE | PG_W;
+ Lev2map[i] = newpte;
+ }
+
+ avail_start = phys_avail[0];
+ for (i = 0; phys_avail[i+2]; i+= 2) ;
+ avail_end = phys_avail[i+1];
+
+ virtual_avail = VM_MIN_KERNEL_ADDRESS;
+ virtual_end = VPTBASE;
+
+ /*
+ * Initialize protection array.
+ */
+ alpha_protection_init();
+
+ /*
+ * The kernel's pmap is statically allocated so we don't have to use
+ * pmap_create, which is unlikely to work correctly at this part of
+ * the boot sequence (XXX and which no longer exists).
+ */
+ kernel_pmap = &kernel_pmap_store;
+ kernel_pmap->pm_lev1 = Lev1map;
+ kernel_pmap->pm_count = 1;
+ TAILQ_INIT(&kernel_pmap->pm_pvlist);
+ nklev3 = NKPT;
+ nklev2 = 1;
+
+ /*
+ * Reserve some special page table entries/VA space for temporary
+ * mapping of pages.
+ */
+#define SYSMAP(c, p, v, n) \
+ v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
+
+ va = virtual_avail;
+ pte = pmap_lev3pte(kernel_pmap, va);
+
+ /*
+ * CMAP1/CMAP2 are used for zeroing and copying pages.
+ */
+ SYSMAP(caddr_t, CMAP1, CADDR1, 1)
+ SYSMAP(caddr_t, CMAP2, CADDR2, 1)
+
+ virtual_avail = va;
+
+ *CMAP1 = *CMAP2 = 0;
+
+ /*
+ * Set up proc0's PCB such that the ptbr points to the right place
+ * and has the kernel pmap's (really unused) ASN.
+ */
+ proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr =
+ ALPHA_K0SEG_TO_PHYS((vm_offset_t)Lev1map) >> PAGE_SHIFT;
+ proc0.p_addr->u_pcb.pcb_hw.apcb_asn = 0;
+}
+
+int
+pmap_uses_prom_console()
+{
+#if 0
+ extern int cputype;
+
+#if defined(NEW_SCC_DRIVER)
+ return (cputype == ST_DEC_21000);
+#else
+ return (cputype == ST_DEC_21000
+ || cputype == ST_DEC_3000_300
+ || cputype == ST_DEC_3000_500);
+#endif /* NEW_SCC_DRIVER */
+#endif
+
+ return 1;
+}
+
+void
+pmap_setdevram(unsigned long long basea, vm_offset_t sizea)
+{
+}
+
+/*
+ * Initialize the pmap module.
+ * Called by vm_init, to initialize any structures that the pmap
+ * system needs to map virtual memory.
+ * pmap_init has been enhanced to support in a fairly consistant
+ * way, discontiguous physical memory.
+ */
+void
+pmap_init(phys_start, phys_end)
+ vm_offset_t phys_start, phys_end;
+{
+ vm_offset_t addr;
+ vm_size_t s;
+ int i;
+ int initial_pvs;
+
+ /*
+ * calculate the number of pv_entries needed
+ */
+ vm_first_phys = phys_avail[0];
+ for (i = 0; phys_avail[i + 1]; i += 2);
+ pv_npg = (phys_avail[(i - 2) + 1] - vm_first_phys) / PAGE_SIZE;
+
+ /*
+ * Allocate memory for random pmap data structures. Includes the
+ * pv_head_table.
+ */
+ s = (vm_size_t) (sizeof(pv_table_t) * pv_npg);
+ s = round_page(s);
+
+ addr = (vm_offset_t) kmem_alloc(kernel_map, s);
+ pv_table = (pv_table_t *) addr;
+ for(i = 0; i < pv_npg; i++) {
+ vm_offset_t pa;
+ TAILQ_INIT(&pv_table[i].pv_list);
+ pv_table[i].pv_list_count = 0;
+ pa = vm_first_phys + i * PAGE_SIZE;
+ pv_table[i].pv_vm_page = PHYS_TO_VM_PAGE(pa);
+ }
+
+ /*
+ * init the pv free list
+ */
+ initial_pvs = pv_npg;
+ if (initial_pvs < MINPV)
+ initial_pvs = MINPV;
+ pvzone = &pvzone_store;
+ pvinit = (struct pv_entry *) kmem_alloc(kernel_map,
+ initial_pvs * sizeof (struct pv_entry));
+ zbootinit(pvzone, "PV ENTRY", sizeof (struct pv_entry), pvinit, pv_npg);
+ /*
+ * object for kernel page table pages
+ */
+ kptobj = vm_object_allocate(OBJT_DEFAULT, NKLEV3MAPS + NKLEV2MAPS);
+
+ /*
+ * Now it is safe to enable pv_table recording.
+ */
+ pmap_initialized = TRUE;
+}
+
+/*
+ * Initialize the address space (zone) for the pv_entries. Set a
+ * high water mark so that the system can recover from excessive
+ * numbers of pv entries.
+ */
+void
+pmap_init2()
+{
+ pv_entry_max = PMAP_SHPGPERPROC * maxproc + pv_npg;
+ pv_entry_high_water = 9 * (pv_entry_max / 10);
+ zinitna(pvzone, &pvzone_obj, NULL, 0, pv_entry_max, ZONE_INTERRUPT, 1);
+}
+
+/*
+ * Used to map a range of physical addresses into kernel
+ * virtual address space.
+ *
+ * For now, VM is already on, we only need to map the
+ * specified memory.
+ */
+vm_offset_t
+pmap_map(virt, start, end, prot)
+ vm_offset_t virt;
+ vm_offset_t start;
+ vm_offset_t end;
+ int prot;
+{
+ while (start < end) {
+ pmap_enter(kernel_pmap, virt, start, prot, FALSE);
+ virt += PAGE_SIZE;
+ start += PAGE_SIZE;
+ }
+ return (virt);
+}
+
+
+/***************************************************
+ * Low level helper routines.....
+ ***************************************************/
+
+/*
+ * this routine defines the region(s) of memory that should
+ * not be tested for the modified bit.
+ */
+static PMAP_INLINE int
+pmap_track_modified( vm_offset_t va) {
+ if ((va < clean_sva) || (va >= clean_eva))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * Routine: pmap_extract
+ * Function:
+ * Extract the physical page address associated
+ * with the given map/virtual_address pair.
+ */
+vm_offset_t
+pmap_extract(pmap, va)
+ register pmap_t pmap;
+ vm_offset_t va;
+{
+ pt_entry_t* pte = pmap_lev3pte(pmap, va);
+ if (pte)
+ return alpha_ptob(ALPHA_PTE_TO_PFN(*pte));
+ else
+ return 0;
+}
+
+/*
+ * determine if a page is managed (memory vs. device)
+ */
+static PMAP_INLINE int
+pmap_is_managed(pa)
+ vm_offset_t pa;
+{
+ int i;
+
+ if (!pmap_initialized)
+ return 0;
+
+ for (i = 0; phys_avail[i + 1]; i += 2) {
+ if (pa < phys_avail[i + 1] && pa >= phys_avail[i])
+ return 1;
+ }
+ return 0;
+}
+
+
+/***************************************************
+ * Low level mapping routines.....
+ ***************************************************/
+
+/*
+ * Add a list of wired pages to the kva
+ * this routine is only used for temporary
+ * kernel mappings that do not need to have
+ * page modification or references recorded.
+ * Note that old mappings are simply written
+ * over. The page *must* be wired.
+ */
+void
+pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
+{
+ int i;
+ pt_entry_t *pte;
+
+ for (i = 0; i < count; i++) {
+ vm_offset_t tva = va + i * PAGE_SIZE;
+ pt_entry_t npte = pmap_phys_to_pte(VM_PAGE_TO_PHYS(m[i]))
+ | PG_KRE | PG_KWE | PG_V;
+ pt_entry_t opte;
+ pte = vtopte(tva);
+ opte = *pte;
+ *pte = npte;
+ if (opte)
+ ALPHA_TBIS(tva);
+ }
+}
+
+/*
+ * this routine jerks page mappings from the
+ * kernel -- it is meant only for temporary mappings.
+ */
+void
+pmap_qremove(va, count)
+ vm_offset_t va;
+ int count;
+{
+ int i;
+ register pt_entry_t *pte;
+
+ for (i = 0; i < count; i++) {
+ pte = vtopte(va);
+ *pte = 0;
+ ALPHA_TBIS(va);
+ va += PAGE_SIZE;
+ }
+}
+
+/*
+ * add a wired page to the kva
+ * note that in order for the mapping to take effect -- you
+ * should do a invltlb after doing the pmap_kenter...
+ */
+PMAP_INLINE void
+pmap_kenter(vm_offset_t va, vm_offset_t pa)
+{
+ pt_entry_t *pte;
+ pt_entry_t npte, opte;
+
+ npte = pmap_phys_to_pte(pa) | PG_KRE | PG_KWE | PG_V;
+ pte = vtopte(va);
+ opte = *pte;
+ *pte = npte;
+ if (opte)
+ ALPHA_TBIS(va);
+}
+
+/*
+ * remove a page from the kernel pagetables
+ */
+PMAP_INLINE void
+pmap_kremove(vm_offset_t va)
+{
+ register pt_entry_t *pte;
+
+ pte = vtopte(va);
+ *pte = 0;
+ ALPHA_TBIS(va);
+}
+
+static vm_page_t
+pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
+{
+ vm_page_t m;
+retry:
+ m = vm_page_lookup(object, pindex);
+ if (m && vm_page_sleep(m, "pplookp", NULL))
+ goto retry;
+ return m;
+}
+
+/*
+ * Create the UPAGES for a new process.
+ * This routine directly affects the fork perf for a process.
+ */
+void
+pmap_new_proc(struct proc *p)
+{
+ int i;
+ vm_object_t upobj;
+ vm_page_t m;
+ struct user *up;
+ pt_entry_t *ptek, oldpte;
+
+ /*
+ * allocate object for the upages
+ */
+ if ((upobj = p->p_upages_obj) == NULL) {
+ upobj = vm_object_allocate( OBJT_DEFAULT, UPAGES);
+ p->p_upages_obj = upobj;
+ }
+
+ /* get a kernel virtual address for the UPAGES for this proc */
+ if ((up = p->p_addr) == NULL) {
+ up = (struct user *) kmem_alloc_pageable(kernel_map,
+ UPAGES * PAGE_SIZE);
+#if !defined(MAX_PERF)
+ if (up == NULL)
+ panic("pmap_new_proc: u_map allocation failed");
+#endif
+ p->p_addr = up;
+ }
+
+ ptek = vtopte((vm_offset_t) up);
+
+ for(i=0;i<UPAGES;i++) {
+ /*
+ * Get a kernel stack page
+ */
+ m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+
+ /*
+ * Wire the page
+ */
+ m->wire_count++;
+ cnt.v_wire_count++;
+
+ oldpte = *(ptek + i);
+ /*
+ * Enter the page into the kernel address space.
+ */
+ *(ptek + i) = pmap_phys_to_pte(VM_PAGE_TO_PHYS(m)) | PG_KRE | PG_KWE | PG_V;
+ if (oldpte)
+ ALPHA_TBIS((vm_offset_t)up + i * PAGE_SIZE);
+
+ PAGE_WAKEUP(m);
+ m->flags &= ~PG_ZERO;
+ m->flags |= PG_MAPPED | PG_WRITEABLE;
+ m->valid = VM_PAGE_BITS_ALL;
+ }
+}
+
+/*
+ * Dispose the UPAGES for a process that has exited.
+ * This routine directly impacts the exit perf of a process.
+ */
+void
+pmap_dispose_proc(p)
+ struct proc *p;
+{
+ int i;
+ vm_object_t upobj;
+ vm_page_t m;
+ pt_entry_t *ptek, oldpte;
+
+ upobj = p->p_upages_obj;
+
+ ptek = vtopte((vm_offset_t) p->p_addr);
+ for(i=0;i<UPAGES;i++) {
+
+ if ((m = vm_page_lookup(upobj, i)) == NULL)
+ panic("pmap_dispose_proc: upage already missing???");
+
+ m->flags |= PG_BUSY;
+
+ oldpte = *(ptek + i);
+ *(ptek + i) = 0;
+ ALPHA_TBIS((vm_offset_t)p->p_addr + i * PAGE_SIZE);
+ vm_page_unwire(m);
+ vm_page_free(m);
+ }
+}
+
+/*
+ * Allow the UPAGES for a process to be prejudicially paged out.
+ */
+void
+pmap_swapout_proc(p)
+ struct proc *p;
+{
+ int i;
+ vm_object_t upobj;
+ vm_page_t m;
+
+ upobj = p->p_upages_obj;
+ /*
+ * let the upages be paged
+ */
+ for(i=0;i<UPAGES;i++) {
+ if ((m = vm_page_lookup(upobj, i)) == NULL)
+ panic("pmap_swapout_proc: upage already missing???");
+ m->dirty = VM_PAGE_BITS_ALL;
+ vm_page_unwire(m);
+ vm_page_deactivate(m);
+ pmap_kremove( (vm_offset_t) p->p_addr + PAGE_SIZE * i);
+ }
+}
+
+/*
+ * Bring the UPAGES for a specified process back in.
+ */
+void
+pmap_swapin_proc(p)
+ struct proc *p;
+{
+ int i,rv;
+ vm_object_t upobj;
+ vm_page_t m;
+
+ upobj = p->p_upages_obj;
+ for(i=0;i<UPAGES;i++) {
+
+ m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+
+ pmap_kenter(((vm_offset_t) p->p_addr) + i * PAGE_SIZE,
+ VM_PAGE_TO_PHYS(m));
+
+ if (m->valid != VM_PAGE_BITS_ALL) {
+ rv = vm_pager_get_pages(upobj, &m, 1, 0);
+#if !defined(MAX_PERF)
+ if (rv != VM_PAGER_OK)
+ panic("pmap_swapin_proc: cannot get upages for proc: %d\n", p->p_pid);
+#endif
+ m = vm_page_lookup(upobj, i);
+ m->valid = VM_PAGE_BITS_ALL;
+ }
+
+ vm_page_wire(m);
+ PAGE_WAKEUP(m);
+ m->flags |= PG_MAPPED | PG_WRITEABLE;
+ }
+}
+
+/***************************************************
+ * Page table page management routines.....
+ ***************************************************/
+
+/*
+ * This routine unholds page table pages, and if the hold count
+ * drops to zero, then it decrements the wire count.
+ */
+static int
+_pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m)
+{
+ int s;
+
+ while (vm_page_sleep(m, "pmuwpt", NULL));
+
+ if (m->hold_count == 0) {
+ vm_offset_t pteva;
+ pt_entry_t* pte;
+ int level;
+
+ /*
+ * unmap the page table page
+ */
+ if (m->pindex >= NUSERLEV3MAPS) {
+ /* Level 2 page table */
+ pte = pmap_lev1pte(pmap, va);
+ pteva = (vm_offset_t) PTlev2 + alpha_ptob(m->pindex - NUSERLEV3MAPS);
+ } else {
+ /* Level 3 page table */
+ pte = pmap_lev2pte(pmap, va);
+ pteva = (vm_offset_t) PTmap + alpha_ptob(m->pindex);
+ }
+
+ *pte = 0;
+
+ if (m->pindex < NUSERLEV3MAPS) {
+ /* unhold the level 2 page table */
+ vm_page_t lev2pg;
+ lev2pg = pmap_page_lookup(pmap->pm_pteobj,
+ NUSERLEV3MAPS + pmap_lev1_index(va));
+ vm_page_unhold(lev2pg);
+ if (m->hold_count == 0)
+ _pmap_unwire_pte_hold(pmap, va, lev2pg);
+ }
+
+ --pmap->pm_stats.resident_count;
+ if (ALPHA_PTE_TO_PFN(pmap->pm_lev1[PTLEV1I]) == ALPHA_PTE_TO_PFN(PTlev1pte)) {
+ /*
+ * Do a invltlb to make the invalidated mapping
+ * take effect immediately.
+ */
+ ALPHA_TBIS(pteva);
+ }
+
+ if (pmap->pm_ptphint == m)
+ pmap->pm_ptphint = NULL;
+
+ /*
+ * If the page is finally unwired, simply free it.
+ */
+ --m->wire_count;
+ if (m->wire_count == 0) {
+
+ if (m->flags & PG_WANTED) {
+ m->flags &= ~PG_WANTED;
+ wakeup(m);
+ }
+
+ m->flags |= PG_BUSY;
+ vm_page_free_zero(m);
+ --cnt.v_wire_count;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static PMAP_INLINE int
+pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m)
+{
+ vm_page_unhold(m);
+ if (m->hold_count == 0)
+ return _pmap_unwire_pte_hold(pmap, va, m);
+ else
+ return 0;
+}
+
+/*
+ * After removing a page table entry, this routine is used to
+ * conditionally free the page, and manage the hold/wire counts.
+ */
+static int
+pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte)
+{
+ unsigned ptepindex;
+ if (va >= VM_MAXUSER_ADDRESS)
+ return 0;
+
+ if (mpte == NULL) {
+ ptepindex = (va >> ALPHA_L2SHIFT);
+ if (pmap->pm_ptphint &&
+ (pmap->pm_ptphint->pindex == ptepindex)) {
+ mpte = pmap->pm_ptphint;
+ } else {
+ mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+ pmap->pm_ptphint = mpte;
+ }
+ }
+
+ return pmap_unwire_pte_hold(pmap, va, mpte);
+}
+
+void
+pmap_pinit0(pmap)
+ struct pmap *pmap;
+{
+ pmap->pm_lev1 = Lev1map;
+ pmap->pm_flags = 0;
+ pmap->pm_count = 1;
+ pmap->pm_ptphint = NULL;
+ TAILQ_INIT(&pmap->pm_pvlist);
+ bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure,
+ * such as one in a vmspace structure.
+ */
+void
+pmap_pinit(pmap)
+ register struct pmap *pmap;
+{
+ vm_page_t lev1pg;
+
+ /*
+ * allocate object for the ptes
+ */
+ if (pmap->pm_pteobj == NULL)
+ pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, NUSERLEV3MAPS + NUSERLEV2MAPS + 1);
+
+ /*
+ * allocate the page directory page
+ */
+retry:
+ lev1pg = vm_page_grab(pmap->pm_pteobj, NUSERLEV3MAPS + NUSERLEV2MAPS,
+ VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
+
+ lev1pg->wire_count = 1;
+ ++cnt.v_wire_count;
+
+ lev1pg->flags &= ~(PG_MAPPED | PG_BUSY); /* not mapped normally */
+ lev1pg->valid = VM_PAGE_BITS_ALL;
+
+ pmap->pm_lev1 = (pt_entry_t*) ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(lev1pg));
+ if ((lev1pg->flags & PG_ZERO) == 0)
+ bzero(pmap->pm_lev1, PAGE_SIZE);
+
+ /* wire in kernel global address entries */
+ /* XXX copies current process, does not fill in MPPTDI */
+ bcopy(PTlev1 + K1SEGLEV1I, pmap->pm_lev1 + K1SEGLEV1I, nklev2 * PTESIZE);
+
+ /* install self-referential address mapping entry */
+ pmap->pm_lev1[PTLEV1I] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(lev1pg))
+ | PG_V | PG_KRE | PG_KWE;
+
+ pmap->pm_flags = 0;
+ pmap->pm_count = 1;
+ pmap->pm_ptphint = NULL;
+ TAILQ_INIT(&pmap->pm_pvlist);
+ bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+}
+
+static int
+pmap_release_free_page(pmap_t pmap, vm_page_t p)
+{
+ int s;
+ pt_entry_t* pte;
+ pt_entry_t* l2map;
+
+ if (p->pindex >= NUSERLEV3MAPS + NUSERLEV2MAPS)
+ /* level 1 page table */
+ pte = &pmap->pm_lev1[PTLEV1I];
+ else if (p->pindex >= NUSERLEV3MAPS)
+ /* level 2 page table */
+ pte = &pmap->pm_lev1[p->pindex - NUSERLEV3MAPS];
+ else {
+ /* level 3 page table */
+ pte = &pmap->pm_lev1[p->pindex >> ALPHA_PTSHIFT];
+ l2map = (pt_entry_t*) ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(pte));
+ pte = &l2map[p->pindex & ((1 << ALPHA_PTSHIFT) - 1)];
+ }
+
+ /*
+ * This code optimizes the case of freeing non-busy
+ * page-table pages. Those pages are zero now, and
+ * might as well be placed directly into the zero queue.
+ */
+ if (vm_page_sleep(p, "pmaprl", NULL))
+ return 0;
+
+ p->flags |= PG_BUSY;
+
+ /*
+ * Remove the page table page from the processes address space.
+ */
+ *pte = 0;
+ pmap->pm_stats.resident_count--;
+
+#if !defined(MAX_PERF)
+ if (p->hold_count) {
+ panic("pmap_release: freeing held page table page");
+ }
+#endif
+ /*
+ * Level1 pages need to have the kernel
+ * stuff cleared, so they can go into the zero queue also.
+ */
+ if (p->pindex == NUSERLEV3MAPS + NUSERLEV2MAPS)
+ bzero(pmap->pm_lev1 + K1SEGLEV1I, nklev2 * PTESIZE);
+
+ if (pmap->pm_ptphint && (pmap->pm_ptphint->pindex == p->pindex))
+ pmap->pm_ptphint = NULL;
+
+ vm_page_free_zero(p);
+ return 1;
+}
+
+/*
+ * this routine is called if the page table page is not
+ * mapped correctly.
+ */
+static vm_page_t
+_pmap_allocpte(pmap, ptepindex)
+ pmap_t pmap;
+ unsigned ptepindex;
+{
+ pt_entry_t* pte;
+ vm_offset_t pteva, ptepa;
+ vm_page_t m;
+
+ /*
+ * Find or fabricate a new pagetable page
+ */
+ m = vm_page_grab(pmap->pm_pteobj, ptepindex,
+ VM_ALLOC_ZERO | VM_ALLOC_RETRY);
+
+ if (m->queue != PQ_NONE) {
+ int s = splvm();
+ vm_page_unqueue(m);
+ splx(s);
+ }
+
+ if (m->wire_count == 0)
+ cnt.v_wire_count++;
+ m->wire_count++;
+
+ /*
+ * Increment the hold count for the page table page
+ * (denoting a new mapping.)
+ */
+ m->hold_count++;
+
+ /*
+ * Map the pagetable page into the process address space, if
+ * it isn't already there.
+ */
+
+ pmap->pm_stats.resident_count++;
+
+ ptepa = VM_PAGE_TO_PHYS(m);
+
+ if (ptepindex >= NUSERLEV3MAPS) {
+ pte = &pmap->pm_lev1[ptepindex - NUSERLEV3MAPS];
+ } else {
+ int l1index = ptepindex >> ALPHA_PTSHIFT;
+ pt_entry_t* l1pte = &pmap->pm_lev1[l1index];
+ pt_entry_t* l2map;
+ if (!pmap_pte_v(l1pte))
+ _pmap_allocpte(pmap, NUSERLEV3MAPS + l1index);
+ l2map = (pt_entry_t*) ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
+ pte = &l2map[ptepindex & ((1 << ALPHA_PTSHIFT) - 1)];
+ }
+
+ *pte = pmap_phys_to_pte(ptepa) | PG_KRE | PG_KWE | PG_V;
+
+ /*
+ * Set the page table hint
+ */
+ pmap->pm_ptphint = m;
+
+ if ((m->flags & PG_ZERO) == 0)
+ bzero((caddr_t) ALPHA_PHYS_TO_K0SEG(ptepa), PAGE_SIZE);
+
+ m->valid = VM_PAGE_BITS_ALL;
+ m->flags &= ~(PG_ZERO | PG_BUSY);
+ m->flags |= PG_MAPPED;
+
+ return m;
+}
+
+static vm_page_t
+pmap_allocpte(pmap_t pmap, vm_offset_t va)
+{
+ unsigned ptepindex;
+ pt_entry_t* lev2pte;
+ vm_offset_t ptepa;
+ vm_page_t m;
+
+ /*
+ * Calculate pagetable page index
+ */
+ ptepindex = va >> (PAGE_SHIFT + ALPHA_PTSHIFT);
+
+ /*
+ * Get the level2 entry
+ */
+ lev2pte = pmap_lev2pte(pmap, va);
+
+ /*
+ * If the page table page is mapped, we just increment the
+ * hold count, and activate it.
+ */
+ if (lev2pte && pmap_pte_v(lev2pte)) {
+ /*
+ * In order to get the page table page, try the
+ * hint first.
+ */
+ if (pmap->pm_ptphint &&
+ (pmap->pm_ptphint->pindex == ptepindex)) {
+ m = pmap->pm_ptphint;
+ } else {
+ m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+ pmap->pm_ptphint = m;
+ }
+ m->hold_count++;
+ return m;
+ }
+ /*
+ * Here if the pte page isn't mapped, or if it has been deallocated.
+ */
+ return _pmap_allocpte(pmap, ptepindex);
+}
+
+
+/***************************************************
+* Pmap allocation/deallocation routines.
+ ***************************************************/
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_release(pmap_t pmap)
+{
+ vm_page_t p,n,lev1pg;
+ vm_object_t object = pmap->pm_pteobj;
+ int curgeneration;
+
+#if defined(DIAGNOSTIC)
+ if (object->ref_count != 1)
+ panic("pmap_release: pteobj reference count != 1");
+#endif
+
+ lev1pg = NULL;
+retry:
+ curgeneration = object->generation;
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
+ n = TAILQ_NEXT(p, listq);
+ if (p->pindex >= NUSERLEV3MAPS) {
+ continue;
+ }
+ while (1) {
+ if (!pmap_release_free_page(pmap, p) &&
+ (object->generation != curgeneration))
+ goto retry;
+ }
+ }
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
+ n = TAILQ_NEXT(p, listq);
+ if (p->pindex < NUSERLEV3MAPS) {
+ /* can this happen? maybe panic */
+ goto retry;
+ }
+ if (p->pindex >= NUSERLEV3MAPS + NUSERLEV2MAPS) {
+ lev1pg = p;
+ continue;
+ }
+ while (1) {
+ if (!pmap_release_free_page(pmap, p) &&
+ (object->generation != curgeneration))
+ goto retry;
+ }
+ }
+
+ if (lev1pg && !pmap_release_free_page(pmap, lev1pg))
+ goto retry;
+}
+
+/*
+ * grow the number of kernel page table entries, if needed
+ */
+void
+pmap_growkernel(vm_offset_t addr)
+{
+ /* XXX come back to this */
+ struct proc *p;
+ struct pmap *pmap;
+ int s;
+ pt_entry_t* pte;
+ pt_entry_t newlev1, newlev2;
+ vm_offset_t pa;
+ vm_page_t nkpg;
+
+ s = splhigh();
+
+ if (kernel_vm_end == 0) {
+ kernel_vm_end = VM_MIN_KERNEL_ADDRESS;;
+
+ /* Count the level 2 page tables */
+ nklev2 = 0;
+ nklev3 = 0;
+ while (pmap_pte_v(pmap_lev1pte(kernel_pmap, kernel_vm_end))) {
+ nklev2++;
+ nklev3 += (1L << ALPHA_PTSHIFT);
+ kernel_vm_end += ALPHA_L1SIZE;
+ }
+
+ /* Count the level 3 page tables in the last level 2 page table */
+ kernel_vm_end -= ALPHA_L1SIZE;
+ nklev3 -= (1 << ALPHA_PTSHIFT);
+ while (pmap_pte_v(pmap_lev2pte(kernel_pmap, kernel_vm_end))) {
+ nklev3++;
+ kernel_vm_end += ALPHA_L2SIZE;
+ }
+ }
+
+ addr = (addr + ALPHA_L2SIZE) & ~(ALPHA_L2SIZE - 1);
+ while (kernel_vm_end < addr) {
+ /*
+ * If the level 1 pte is invalid, allocate a new level 2 page table
+ */
+ pte = pmap_lev1pte(kernel_pmap, kernel_vm_end);
+ if (!pmap_pte_v(pte)) {
+ int pindex = NKLEV3MAPS + pmap_lev1_index(kernel_vm_end) - K1SEGLEV1I;
+
+ nkpg = vm_page_alloc(kptobj, pindex, VM_ALLOC_SYSTEM);
+#if !defined(MAX_PERF)
+ if (!nkpg)
+ panic("pmap_growkernel: no memory to grow kernel");
+#endif
+ nklev2++;
+ vm_page_wire(nkpg);
+ pa = VM_PAGE_TO_PHYS(nkpg);
+ pmap_zero_page(pa);
+
+ newlev1 = pmap_phys_to_pte(pa) | PG_V | PG_KRE | PG_KWE;
+
+ for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+ if (p->p_vmspace) {
+ pmap = &p->p_vmspace->vm_pmap;
+ *pmap_lev1pte(pmap, kernel_vm_end) = newlev1;
+ }
+ }
+ *pte = newlev1;
+ ALPHA_TBIA();
+ }
+
+ /*
+ * If the level 2 pte is invalid, allocate a new level 3 page table
+ */
+ pte = pmap_lev2pte(kernel_pmap, kernel_vm_end);
+ if (pmap_pte_v(pte)) {
+ kernel_vm_end = (kernel_vm_end + ALPHA_L2SIZE) & ~(ALPHA_L2SIZE - 1);
+ continue;
+ }
+
+ /*
+ * This index is bogus, but out of the way
+ */
+ nkpg = vm_page_alloc(kptobj, nklev3, VM_ALLOC_SYSTEM);
+#if !defined(MAX_PERF)
+ if (!nkpg)
+ panic("pmap_growkernel: no memory to grow kernel");
+#endif
+
+ nklev3++;
+
+ vm_page_wire(nkpg);
+ pa = VM_PAGE_TO_PHYS(nkpg);
+ pmap_zero_page(pa);
+ newlev2 = pmap_phys_to_pte(pa) | PG_V | PG_KRE | PG_KWE;
+ *pte = newlev2;
+
+ kernel_vm_end = (kernel_vm_end + ALPHA_L2SIZE) & ~(ALPHA_L2SIZE - 1);
+ }
+ splx(s);
+}
+
+/*
+ * Retire the given physical map from service.
+ * Should only be called if the map contains
+ * no valid mappings.
+ */
+void
+pmap_destroy(pmap_t pmap)
+{
+ int count;
+
+ if (pmap == NULL)
+ return;
+
+ count = --pmap->pm_count;
+ if (count == 0) {
+ pmap_release(pmap);
+#if !defined(MAX_PERF)
+ panic("destroying a pmap is not yet implemented");
+#endif
+ }
+}
+
+/*
+ * Add a reference to the specified pmap.
+ */
+void
+pmap_reference(pmap_t pmap)
+{
+ if (pmap != NULL) {
+ pmap->pm_count++;
+ }
+}
+
+/***************************************************
+* page management routines.
+ ***************************************************/
+
+/*
+ * free the pv_entry back to the free list
+ */
+static PMAP_INLINE void
+free_pv_entry(pv_entry_t pv)
+{
+ pv_entry_count--;
+ zfreei(pvzone, pv);
+}
+
+/*
+ * get a new pv_entry, allocating a block from the system
+ * when needed.
+ * the memory allocation is performed bypassing the malloc code
+ * because of the possibility of allocations at interrupt time.
+ */
+static pv_entry_t
+get_pv_entry(void)
+{
+ pv_entry_count++;
+ if (pv_entry_high_water &&
+ (pv_entry_count > pv_entry_high_water) &&
+ (pmap_pagedaemon_waken == 0)) {
+ pmap_pagedaemon_waken = 1;
+ wakeup (&vm_pages_needed);
+ }
+ return zalloci(pvzone);
+}
+
+/*
+ * This routine is very drastic, but can save the system
+ * in a pinch.
+ */
+void
+pmap_collect()
+{
+ pv_table_t *ppv;
+ int i;
+ vm_offset_t pa;
+ vm_page_t m;
+ static int warningdone=0;
+
+ if (pmap_pagedaemon_waken == 0)
+ return;
+
+ if (warningdone < 5) {
+ printf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
+ warningdone++;
+ }
+
+ for(i = 0; i < pv_npg; i++) {
+ if ((ppv = &pv_table[i]) == 0)
+ continue;
+ m = ppv->pv_vm_page;
+ if ((pa = VM_PAGE_TO_PHYS(m)) == 0)
+ continue;
+ if (m->wire_count || m->hold_count || m->busy ||
+ (m->flags & PG_BUSY))
+ continue;
+ pmap_remove_all(pa);
+ }
+ pmap_pagedaemon_waken = 0;
+}
+
+
+/*
+ * If it is the first entry on the list, it is actually
+ * in the header and we must copy the following entry up
+ * to the header. Otherwise we must search the list for
+ * the entry. In either case we free the now unused entry.
+ */
+
+static int
+pmap_remove_entry(pmap_t pmap, pv_table_t* ppv, vm_offset_t va)
+{
+ pv_entry_t pv;
+ int rtval;
+ int s;
+
+ s = splvm();
+ if (ppv->pv_list_count < pmap->pm_stats.resident_count) {
+ for (pv = TAILQ_FIRST(&ppv->pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ if (pmap == pv->pv_pmap && va == pv->pv_va)
+ break;
+ }
+ } else {
+ for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_plist)) {
+ if (va == pv->pv_va)
+ break;
+ }
+ }
+
+ rtval = 0;
+ if (pv) {
+ rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
+ TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+ ppv->pv_list_count--;
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL)
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED | PG_WRITEABLE);
+
+ TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
+ free_pv_entry(pv);
+ }
+
+ splx(s);
+ return rtval;
+}
+
+/*
+ * Create a pv entry for page at pa for
+ * (pmap, va).
+ */
+static void
+pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t mpte, vm_offset_t pa)
+{
+
+ int s;
+ pv_entry_t pv;
+ pv_table_t *ppv;
+
+ s = splvm();
+ pv = get_pv_entry();
+ pv->pv_va = va;
+ pv->pv_pmap = pmap;
+ pv->pv_ptem = mpte;
+
+ TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+
+ ppv = pa_to_pvh(pa);
+ TAILQ_INSERT_TAIL(&ppv->pv_list, pv, pv_list);
+ ppv->pv_list_count++;
+
+ splx(s);
+}
+
+/*
+ * pmap_remove_pte: do the things to unmap a page in a process
+ */
+static int
+pmap_remove_pte(pmap_t pmap, pt_entry_t* ptq, vm_offset_t va)
+{
+ pt_entry_t oldpte;
+ pv_table_t *ppv;
+
+ oldpte = *ptq;
+ *ptq = 0;
+ if (oldpte & PG_W)
+ pmap->pm_stats.wired_count -= 1;
+
+ pmap->pm_stats.resident_count -= 1;
+ if (oldpte & PG_MANAGED) {
+ ppv = pa_to_pvh(pmap_pte_pa(&oldpte));
+ return pmap_remove_entry(pmap, ppv, va);
+ } else {
+ return pmap_unuse_pt(pmap, va, NULL);
+ }
+
+ return 0;
+}
+
+/*
+ * Remove a single page from a process address space
+ */
+static void
+pmap_remove_page(pmap_t pmap, vm_offset_t va)
+{
+ register pt_entry_t *ptq;
+
+ ptq = pmap_lev3pte(pmap, va);
+
+ /*
+ * if there is no pte for this address, just skip it!!!
+ */
+ if (!ptq || !pmap_pte_v(ptq))
+ return;
+
+ /*
+ * get a local va for mappings for this pmap.
+ */
+ (void) pmap_remove_pte(pmap, ptq, va);
+ ALPHA_TBIS(va);
+
+ return;
+}
+
+/*
+ * Remove the given range of addresses from the specified map.
+ *
+ * It is assumed that the start and end are properly
+ * rounded to the page size.
+ */
+void
+pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+ vm_offset_t va;
+
+ if (pmap == NULL)
+ return;
+
+ if (pmap->pm_stats.resident_count == 0)
+ return;
+
+ for (va = sva; va < eva; va += PAGE_SIZE)
+ pmap_remove_page(pmap, va);
+}
+
+/*
+ * Routine: pmap_remove_all
+ * Function:
+ * Removes this physical page from
+ * all physical maps in which it resides.
+ * Reflects back modify bits to the pager.
+ *
+ * Notes:
+ * Original versions of this routine were very
+ * inefficient because they iteratively called
+ * pmap_remove (slow...)
+ */
+
+static void
+pmap_remove_all(vm_offset_t pa)
+{
+ register pv_entry_t pv;
+ pv_table_t *ppv;
+ pt_entry_t *pte, tpte;
+ int nmodify;
+ int update_needed;
+ int s;
+
+ nmodify = 0;
+ update_needed = 0;
+#if defined(PMAP_DIAGNOSTIC)
+ /*
+ * XXX this makes pmap_page_protect(NONE) illegal for non-managed
+ * pages!
+ */
+ if (!pmap_is_managed(pa)) {
+ panic("pmap_page_protect: illegal for unmanaged page, va: 0x%lx", pa);
+ }
+#endif
+
+ s = splvm();
+ ppv = pa_to_pvh(pa);
+ while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) {
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+
+ pv->pv_pmap->pm_stats.resident_count--;
+
+ if (pmap_pte_pa(pte) != pa)
+ panic("pmap_remove_all: pv_table for %x is inconsistent", pa);
+
+ tpte = *pte;
+
+ *pte = 0;
+ if (tpte & PG_W)
+ pv->pv_pmap->pm_stats.wired_count--;
+
+ if (!update_needed &&
+ ((!curproc || (&curproc->p_vmspace->vm_pmap == pv->pv_pmap)) ||
+ (pv->pv_pmap == kernel_pmap))) {
+ update_needed = 1;
+ }
+
+ TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+ TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+ ppv->pv_list_count--;
+ pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
+ free_pv_entry(pv);
+ }
+
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED | PG_WRITEABLE);
+
+ if (update_needed)
+ ALPHA_TBIA();
+
+ splx(s);
+ return;
+}
+
+/*
+ * Set the physical protection on the
+ * specified range of this map as requested.
+ */
+void
+pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
+{
+ pt_entry_t* pte;
+ vm_offset_t pdnxt, ptpaddr;
+ int isactive;
+ int newprot;
+
+ if (pmap == NULL)
+ return;
+
+ if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
+ pmap_remove(pmap, sva, eva);
+ return;
+ }
+
+ if (prot & VM_PROT_WRITE)
+ return;
+
+ newprot = pte_prot(pmap, prot);
+ isactive = pmap_isactive(pmap);
+
+ if ((sva & PAGE_MASK) || (eva & PAGE_MASK))
+ panic("pmap_protect: unaligned addresses");
+
+ while (sva < eva) {
+ pt_entry_t pbits;
+
+ /*
+ * If level 1 pte is invalid, skip this segment
+ */
+ pte = pmap_lev1pte(pmap, sva);
+ if (!pmap_pte_v(pte)) {
+ sva = alpha_l1trunc(sva) + ALPHA_L1SIZE;
+ continue;
+ }
+
+ /*
+ * If level 2 pte is invalid, skip this segment
+ */
+ pte = pmap_lev2pte(pmap, sva);
+ if (!pmap_pte_v(pte)) {
+ sva = alpha_l2trunc(sva) + ALPHA_L2SIZE;
+ continue;
+ }
+
+ /*
+ * If level 3 pte is invalid, skip this page
+ */
+ pte = pmap_lev3pte(pmap, sva);
+ if (!pmap_pte_v(pte)) {
+ sva += PAGE_SIZE;
+ continue;
+ }
+
+ if (pmap_pte_prot(pte) != newprot) {
+ pmap_pte_set_prot(pte, newprot);
+ if (isactive)
+ ALPHA_TBIS(sva);
+ }
+
+ sva += PAGE_SIZE;
+ }
+}
+
+/*
+ * Insert the given physical page (p) at
+ * the specified virtual address (v) in the
+ * target physical map with the protection requested.
+ *
+ * If specified, the page will be wired down, meaning
+ * that the related pte can not be reclaimed.
+ *
+ * NB: This is the only routine which MAY NOT lazy-evaluate
+ * or lose information. That is, this routine must actually
+ * insert this page into the given map NOW.
+ */
+void
+pmap_enter(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_prot_t prot,
+ boolean_t wired)
+{
+ pt_entry_t *pte;
+ vm_offset_t opa;
+ pt_entry_t origpte, newpte;
+ vm_page_t mpte;
+ int managed;
+
+ if (pmap == NULL)
+ return;
+
+ va &= ~PAGE_MASK;
+#ifdef PMAP_DIAGNOSTIC
+ if (va > VM_MAX_KERNEL_ADDRESS)
+ panic("pmap_enter: toobig");
+#endif
+
+ mpte = NULL;
+ /*
+ * In the case that a page table page is not
+ * resident, we are creating it here.
+ */
+ if (va < VM_MAXUSER_ADDRESS) {
+ mpte = pmap_allocpte(pmap, va);
+ }
+
+ pte = pmap_lev3pte(pmap, va);
+
+#if !defined(MAX_PERF)
+ /*
+ * Page Directory table entry not valid, we need a new PT page
+ */
+ if (pte == NULL) {
+ panic("pmap_enter: invalid kernel page tables pmap=%p, va=0x%lx\n", pmap, va);
+ }
+#endif
+
+ origpte = *pte;
+ pa &= ~PAGE_MASK;
+ managed = 0;
+ opa = pmap_pte_pa(pte);
+
+ /*
+ * Mapping has not changed, must be protection or wiring change.
+ */
+ if (origpte && (opa == pa)) {
+ /*
+ * Wiring change, just update stats. We don't worry about
+ * wiring PT pages as they remain resident as long as there
+ * are valid mappings in them. Hence, if a user page is wired,
+ * the PT page will be also.
+ */
+ if (wired && ((origpte & PG_W) == 0))
+ pmap->pm_stats.wired_count++;
+ else if (!wired && (origpte & PG_W))
+ pmap->pm_stats.wired_count--;
+
+ /*
+ * Remove extra pte reference
+ */
+ if (mpte)
+ mpte->hold_count--;
+
+ managed = origpte & PG_MANAGED;
+ goto validate;
+ }
+ /*
+ * Mapping has changed, invalidate old range and fall through to
+ * handle validating new mapping.
+ */
+ if (opa) {
+ int err;
+ err = pmap_remove_pte(pmap, pte, va);
+#if !defined(MAX_PERF)
+ if (err)
+ panic("pmap_enter: pte vanished, va: 0x%x", va);
+#endif
+ }
+
+ /*
+ * Enter on the PV list if part of our managed memory Note that we
+ * raise IPL while manipulating pv_table since pmap_enter can be
+ * called at interrupt time.
+ */
+ if (pmap_is_managed(pa)) {
+ pmap_insert_entry(pmap, va, mpte, pa);
+ managed |= PG_MANAGED;
+ }
+
+ /*
+ * Increment counters
+ */
+ pmap->pm_stats.resident_count++;
+ if (wired)
+ pmap->pm_stats.wired_count++;
+
+validate:
+ /*
+ * Now validate mapping with desired protection/wiring.
+ */
+ newpte = pmap_phys_to_pte(pa) | pte_prot(pmap, prot) | PG_V | managed;
+
+ if (managed) {
+ pv_table_t* ppv;
+
+ /*
+ * Set up referenced/modified emulation for the new mapping
+ */
+ ppv = pa_to_pvh(pa);
+ if ((ppv->pv_flags & PV_TABLE_REF) == 0)
+ newpte |= PG_FOR | PG_FOW | PG_FOE;
+ else if ((ppv->pv_flags & PV_TABLE_MOD) == 0)
+ newpte |= PG_FOW;
+ }
+
+ if (wired)
+ newpte |= PG_W;
+
+ /*
+ * if the mapping or permission bits are different, we need
+ * to update the pte.
+ */
+ if (origpte != newpte) {
+ *pte = newpte;
+ if (origpte)
+ ALPHA_TBIS(va);
+ }
+}
+
+/*
+ * this code makes some *MAJOR* assumptions:
+ * 1. Current pmap & pmap exists.
+ * 2. Not wired.
+ * 3. Read access.
+ * 4. No page table pages.
+ * 5. Tlbflush is deferred to calling procedure.
+ * 6. Page IS managed.
+ * but is *MUCH* faster than pmap_enter...
+ */
+
+static vm_page_t
+pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_page_t mpte)
+{
+ register pt_entry_t *pte;
+
+
+ /*
+ * In the case that a page table page is not
+ * resident, we are creating it here.
+ */
+ if (va < VM_MAXUSER_ADDRESS) {
+ unsigned ptepindex;
+ pt_entry_t* l2pte;
+
+ /*
+ * Calculate lev2 page index
+ */
+ ptepindex = va >> ALPHA_L2SHIFT;
+ if (mpte && (mpte->pindex == ptepindex)) {
+ mpte->hold_count++;
+ } else {
+retry:
+ /*
+ * Get the level 2 entry
+ */
+ l2pte = pmap_lev2pte(pmap, va);
+
+ /*
+ * If the level 2 page table is mapped, we just increment
+ * the hold count, and activate it.
+ */
+ if (l2pte) {
+ if (pmap->pm_ptphint &&
+ (pmap->pm_ptphint->pindex == ptepindex)) {
+ mpte = pmap->pm_ptphint;
+ } else {
+ mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+ pmap->pm_ptphint = mpte;
+ }
+ if (mpte == NULL)
+ goto retry;
+ mpte->hold_count++;
+ } else {
+ mpte = _pmap_allocpte(pmap, ptepindex);
+ }
+ }
+ } else {
+ mpte = NULL;
+ }
+
+ /*
+ * This call to vtopte makes the assumption that we are
+ * entering the page into the current pmap. In order to support
+ * quick entry into any pmap, one would likely use pmap_pte_quick.
+ * But that isn't as quick as vtopte.
+ */
+ pte = vtopte(va);
+ if (*pte) {
+ if (mpte)
+ pmap_unwire_pte_hold(pmap, va, mpte);
+ return 0;
+ }
+
+ /*
+ * Enter on the PV list if part of our managed memory Note that we
+ * raise IPL while manipulating pv_table since pmap_enter can be
+ * called at interrupt time.
+ */
+ pmap_insert_entry(pmap, va, mpte, pa);
+
+ /*
+ * Increment counters
+ */
+ pmap->pm_stats.resident_count++;
+
+ /*
+ * Now validate mapping with RO protection
+ */
+ *pte = pmap_phys_to_pte(pa) | PG_V | PG_KRE | PG_URE | PG_MANAGED;
+
+ return mpte;
+}
+
+#define MAX_INIT_PT (96)
+/*
+ * pmap_object_init_pt preloads the ptes for a given object
+ * into the specified pmap. This eliminates the blast of soft
+ * faults on process startup and immediately after an mmap.
+ */
+void
+pmap_object_init_pt(pmap_t pmap, vm_offset_t addr,
+ vm_object_t object, vm_pindex_t pindex,
+ vm_size_t size, int limit)
+{
+ vm_offset_t tmpidx;
+ int psize;
+ vm_page_t p, mpte;
+ int objpgs;
+
+ if (!pmap)
+ return;
+
+ psize = alpha_btop(size);
+
+ if ((object->type != OBJT_VNODE) ||
+ (limit && (psize > MAX_INIT_PT) &&
+ (object->resident_page_count > MAX_INIT_PT))) {
+ return;
+ }
+
+ if (psize + pindex > object->size)
+ psize = object->size - pindex;
+
+ mpte = NULL;
+ /*
+ * if we are processing a major portion of the object, then scan the
+ * entire thing.
+ */
+ if (psize > (object->size >> 2)) {
+ objpgs = psize;
+
+ for (p = TAILQ_FIRST(&object->memq);
+ ((objpgs > 0) && (p != NULL));
+ p = TAILQ_NEXT(p, listq)) {
+
+ tmpidx = p->pindex;
+ if (tmpidx < pindex) {
+ continue;
+ }
+ tmpidx -= pindex;
+ if (tmpidx >= psize) {
+ continue;
+ }
+ if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
+ (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
+ if ((p->queue - p->pc) == PQ_CACHE)
+ vm_page_deactivate(p);
+ p->flags |= PG_BUSY;
+ mpte = pmap_enter_quick(pmap,
+ addr + alpha_ptob(tmpidx),
+ VM_PAGE_TO_PHYS(p), mpte);
+ p->flags |= PG_MAPPED;
+ PAGE_WAKEUP(p);
+ }
+ objpgs -= 1;
+ }
+ } else {
+ /*
+ * else lookup the pages one-by-one.
+ */
+ for (tmpidx = 0; tmpidx < psize; tmpidx += 1) {
+ p = vm_page_lookup(object, tmpidx + pindex);
+ if (p &&
+ ((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
+ (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
+ if ((p->queue - p->pc) == PQ_CACHE)
+ vm_page_deactivate(p);
+ p->flags |= PG_BUSY;
+ mpte = pmap_enter_quick(pmap,
+ addr + alpha_ptob(tmpidx),
+ VM_PAGE_TO_PHYS(p), mpte);
+ p->flags |= PG_MAPPED;
+ PAGE_WAKEUP(p);
+ }
+ }
+ }
+ return;
+}
+
+/*
+ * pmap_prefault provides a quick way of clustering
+ * pagefaults into a processes address space. It is a "cousin"
+ * of pmap_object_init_pt, except it runs at page fault time instead
+ * of mmap time.
+ */
+#define PFBAK 4
+#define PFFOR 4
+#define PAGEORDER_SIZE (PFBAK+PFFOR)
+
+static int pmap_prefault_pageorder[] = {
+ -PAGE_SIZE, PAGE_SIZE,
+ -2 * PAGE_SIZE, 2 * PAGE_SIZE,
+ -3 * PAGE_SIZE, 3 * PAGE_SIZE
+ -4 * PAGE_SIZE, 4 * PAGE_SIZE
+};
+
+void
+pmap_prefault(pmap, addra, entry)
+ pmap_t pmap;
+ vm_offset_t addra;
+ vm_map_entry_t entry;
+{
+ int i;
+ vm_offset_t starta;
+ vm_offset_t addr;
+ vm_pindex_t pindex;
+ vm_page_t m, mpte;
+ vm_object_t object;
+
+ if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap))
+ return;
+
+ object = entry->object.vm_object;
+
+ starta = addra - PFBAK * PAGE_SIZE;
+ if (starta < entry->start) {
+ starta = entry->start;
+ } else if (starta > addra) {
+ starta = 0;
+ }
+
+ mpte = NULL;
+ for (i = 0; i < PAGEORDER_SIZE; i++) {
+ vm_object_t lobject;
+ pt_entry_t *pte;
+
+ addr = addra + pmap_prefault_pageorder[i];
+ if (addr > addra + (PFFOR * PAGE_SIZE))
+ addr = 0;
+
+ if (addr < starta || addr >= entry->end)
+ continue;
+
+ if (!pmap_pte_v(pmap_lev1pte(pmap, addr))
+ || !pmap_pte_v(pmap_lev2pte(pmap, addr)))
+ continue;
+
+ pte = vtopte(addr);
+ if (*pte)
+ continue;
+
+ pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
+ lobject = object;
+ for (m = vm_page_lookup(lobject, pindex);
+ (!m && (lobject->type == OBJT_DEFAULT) && (lobject->backing_object));
+ lobject = lobject->backing_object) {
+ if (lobject->backing_object_offset & PAGE_MASK)
+ break;
+ pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
+ m = vm_page_lookup(lobject->backing_object, pindex);
+ }
+
+ /*
+ * give-up when a page is not in memory
+ */
+ if (m == NULL)
+ break;
+
+ if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
+ (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
+
+ if ((m->queue - m->pc) == PQ_CACHE) {
+ vm_page_deactivate(m);
+ }
+ m->flags |= PG_BUSY;
+ mpte = pmap_enter_quick(pmap, addr,
+ VM_PAGE_TO_PHYS(m), mpte);
+ m->flags |= PG_MAPPED;
+ PAGE_WAKEUP(m);
+ }
+ }
+}
+
+/*
+ * Routine: pmap_change_wiring
+ * Function: Change the wiring attribute for a map/virtual-address
+ * pair.
+ * In/out conditions:
+ * The mapping must already exist in the pmap.
+ */
+void
+pmap_change_wiring(pmap, va, wired)
+ register pmap_t pmap;
+ vm_offset_t va;
+ boolean_t wired;
+{
+ pt_entry_t *pte;
+
+ if (pmap == NULL)
+ return;
+
+ pte = pmap_lev3pte(pmap, va);
+
+ if (wired && !pmap_pte_w(pte))
+ pmap->pm_stats.wired_count++;
+ else if (!wired && pmap_pte_w(pte))
+ pmap->pm_stats.wired_count--;
+
+ /*
+ * Wiring is not a hardware characteristic so there is no need to
+ * invalidate TLB.
+ */
+ pmap_pte_set_w(pte, wired);
+}
+
+
+
+/*
+ * Copy the range specified by src_addr/len
+ * from the source map to the range dst_addr/len
+ * in the destination map.
+ *
+ * This routine is only advisory and need not do anything.
+ */
+
+void
+pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
+ vm_offset_t src_addr)
+{
+}
+
+/*
+ * Routine: pmap_kernel
+ * Function:
+ * Returns the physical map handle for the kernel.
+ */
+pmap_t
+pmap_kernel()
+{
+ return (kernel_pmap);
+}
+
+/*
+ * pmap_zero_page zeros the specified (machine independent)
+ * page by mapping the page into virtual memory and using
+ * bzero to clear its contents, one machine dependent page
+ * at a time.
+ */
+void
+pmap_zero_page(vm_offset_t pa)
+{
+ vm_offset_t va = ALPHA_PHYS_TO_K0SEG(pa);
+ bzero((caddr_t) va, PAGE_SIZE);
+}
+
+/*
+ * pmap_copy_page copies the specified (machine independent)
+ * page by mapping the page into virtual memory and using
+ * bcopy to copy the page, one machine dependent page at a
+ * time.
+ */
+void
+pmap_copy_page(vm_offset_t src, vm_offset_t dst)
+{
+ src = ALPHA_PHYS_TO_K0SEG(src);
+ dst = ALPHA_PHYS_TO_K0SEG(dst);
+ bcopy((caddr_t) src, (caddr_t) dst, PAGE_SIZE);
+}
+
+
+/*
+ * Routine: pmap_pageable
+ * Function:
+ * Make the specified pages (by pmap, offset)
+ * pageable (or not) as requested.
+ *
+ * A page which is not pageable may not take
+ * a fault; therefore, its page table entry
+ * must remain valid for the duration.
+ *
+ * This routine is merely advisory; pmap_enter
+ * will specify that these pages are to be wired
+ * down (or not) as appropriate.
+ */
+void
+pmap_pageable(pmap, sva, eva, pageable)
+ pmap_t pmap;
+ vm_offset_t sva, eva;
+ boolean_t pageable;
+{
+}
+
+/*
+ * this routine returns true if a physical page resides
+ * in the given pmap.
+ */
+boolean_t
+pmap_page_exists(pmap, pa)
+ pmap_t pmap;
+ vm_offset_t pa;
+{
+ register pv_entry_t pv;
+ pv_table_t *ppv;
+ int s;
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ s = splvm();
+
+ ppv = pa_to_pvh(pa);
+ /*
+ * Not found, check current mappings returning immediately if found.
+ */
+ for (pv = TAILQ_FIRST(&ppv->pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+ if (pv->pv_pmap == pmap) {
+ splx(s);
+ return TRUE;
+ }
+ }
+ splx(s);
+ return (FALSE);
+}
+
+#define PMAP_REMOVE_PAGES_CURPROC_ONLY
+/*
+ * Remove all pages from specified address space
+ * this aids process exit speeds. Also, this code
+ * is special cased for current process only, but
+ * can have the more generic (and slightly slower)
+ * mode enabled. This is much faster than pmap_remove
+ * in the case of running down an entire address space.
+ */
+void
+pmap_remove_pages(pmap, sva, eva)
+ pmap_t pmap;
+ vm_offset_t sva, eva;
+{
+ pt_entry_t *pte, tpte;
+ pv_table_t *ppv;
+ pv_entry_t pv, npv;
+ int s;
+
+#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
+ if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap)) {
+ printf("warning: pmap_remove_pages called with non-current pmap\n");
+ return;
+ }
+#endif
+
+ s = splvm();
+ for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
+ pv;
+ pv = npv) {
+
+ if (pv->pv_va >= eva || pv->pv_va < sva) {
+ npv = TAILQ_NEXT(pv, pv_plist);
+ continue;
+ }
+
+#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
+ pte = vtopte(pv->pv_va);
+#else
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+#endif
+ if (!pmap_pte_v(pte))
+ panic("pmap_remove_pages: page on pm_pvlist has no pte\n");
+ tpte = *pte;
+
+
+/*
+ * We cannot remove wired pages from a process' mapping at this time
+ */
+ if (tpte & PG_W) {
+ npv = TAILQ_NEXT(pv, pv_plist);
+ continue;
+ }
+ *pte = 0;
+
+ ppv = pa_to_pvh(pmap_pte_pa(&tpte));
+
+ pv->pv_pmap->pm_stats.resident_count--;
+
+ npv = TAILQ_NEXT(pv, pv_plist);
+ TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+
+ ppv->pv_list_count--;
+ TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
+ ppv->pv_vm_page->flags &= ~(PG_MAPPED | PG_WRITEABLE);
+ }
+
+ pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
+ free_pv_entry(pv);
+ }
+ splx(s);
+ ALPHA_TBIA();
+}
+
+/*
+ * pmap_testbit tests bits in pte's
+ * note that the testbit/changebit routines are inline,
+ * and a lot of things compile-time evaluate.
+ */
+static boolean_t
+pmap_testbit(vm_offset_t pa, int bit)
+{
+ register pv_entry_t pv;
+ pv_table_t *ppv;
+ pt_entry_t *pte;
+ int s;
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ ppv = pa_to_pvh(pa);
+ if (TAILQ_FIRST(&ppv->pv_list) == NULL)
+ return FALSE;
+
+ s = splvm();
+
+ for (pv = TAILQ_FIRST(&ppv->pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+
+#if defined(PMAP_DIAGNOSTIC)
+ if (!pv->pv_pmap) {
+ printf("Null pmap (tb) at va: 0x%lx\n", pv->pv_va);
+ continue;
+ }
+#endif
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+ if (*pte & bit) {
+ splx(s);
+ return TRUE;
+ }
+ }
+ splx(s);
+ return (FALSE);
+}
+
+/*
+ * this routine is used to modify bits in ptes
+ */
+static void
+pmap_changebit(vm_offset_t pa, int bit, boolean_t setem)
+{
+ pv_entry_t pv;
+ pv_table_t *ppv;
+ pt_entry_t *pte;
+ int changed;
+ int s;
+
+ if (!pmap_is_managed(pa))
+ return;
+
+ s = splvm();
+ changed = 0;
+ ppv = pa_to_pvh(pa);
+
+ /*
+ * Loop over all current mappings setting/clearing as appropos If
+ * setting RO do we need to clear the VAC?
+ */
+ for (pv = TAILQ_FIRST(&ppv->pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+
+ /*
+ * don't write protect pager mappings
+ */
+ if (!setem && bit == (PG_UWE|PG_KWE)) {
+ if (!pmap_track_modified(pv->pv_va))
+ continue;
+ }
+
+#if defined(PMAP_DIAGNOSTIC)
+ if (!pv->pv_pmap) {
+ printf("Null pmap (cb) at va: 0x%lx\n", pv->pv_va);
+ continue;
+ }
+#endif
+
+ pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va);
+
+ if (setem) {
+ *pte |= bit;
+ changed = 1;
+ } else {
+ pt_entry_t pbits = *pte;
+ if (pbits & bit) {
+ changed = 1;
+ *pte = pbits & ~bit;
+ }
+ }
+ }
+ splx(s);
+ if (changed)
+ ALPHA_TBIA();
+}
+
+/*
+ * pmap_page_protect:
+ *
+ * Lower the permission for all mappings to a given page.
+ */
+void
+pmap_page_protect(vm_offset_t phys, vm_prot_t prot)
+{
+ if ((prot & VM_PROT_WRITE) == 0) {
+ if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
+ pmap_changebit(phys, PG_KWE|PG_UWE, FALSE);
+ } else {
+ pmap_remove_all(phys);
+ }
+ }
+}
+
+vm_offset_t
+pmap_phys_address(ppn)
+ int ppn;
+{
+ return (alpha_ptob(ppn));
+}
+
+/*
+ * pmap_ts_referenced:
+ *
+ * Return the count of reference bits for a page, clearing all of them.
+ *
+ */
+int
+pmap_ts_referenced(vm_offset_t pa)
+{
+ pv_table_t *ppv;
+ int ret;
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ ppv = pa_to_pvh(pa);
+
+ ret = (ppv->pv_flags & PV_TABLE_REF) != 0;
+ ppv->pv_flags &= ~PV_TABLE_REF;
+
+ return ret;
+}
+
+/*
+ * pmap_is_modified:
+ *
+ * Return whether or not the specified physical page was modified
+ * in any physical maps.
+ */
+boolean_t
+pmap_is_modified(vm_offset_t pa)
+{
+ pv_table_t *ppv;
+
+ if (!pmap_is_managed(pa))
+ return FALSE;
+
+ ppv = pa_to_pvh(pa);
+
+ return (ppv->pv_flags & PV_TABLE_MOD) != 0;
+}
+
+/*
+ * Clear the modify bits on the specified physical page.
+ */
+void
+pmap_clear_modify(vm_offset_t pa)
+{
+ pv_table_t *ppv;
+
+ if (!pmap_is_managed(pa))
+ return;
+
+ ppv = pa_to_pvh(pa);
+
+ if (ppv->pv_flags & PV_TABLE_MOD) {
+ pmap_changebit(pa, PG_FOW, TRUE);
+ ppv->pv_flags &= ~PV_TABLE_MOD;
+ }
+}
+
+/*
+ * pmap_clear_reference:
+ *
+ * Clear the reference bit on the specified physical page.
+ */
+void
+pmap_clear_reference(vm_offset_t pa)
+{
+ pv_table_t *ppv;
+
+ if (!pmap_is_managed(pa))
+ return;
+
+ ppv = pa_to_pvh(pa);
+
+ if (ppv->pv_flags & PV_TABLE_REF) {
+ pmap_changebit(pa, PG_FOR|PG_FOE|PG_FOW, TRUE);
+ ppv->pv_flags &= ~PV_TABLE_REF;
+ }
+}
+
+/*
+ * pmap_emulate_reference:
+ *
+ * Emulate reference and/or modified bit hits.
+ * From NetBSD
+ */
+void
+pmap_emulate_reference(struct proc *p, vm_offset_t v, int user, int write)
+{
+ pt_entry_t faultoff, *pte;
+ vm_offset_t pa;
+ pv_table_t *ppv;
+
+ /*
+ * Convert process and virtual address to physical address.
+ */
+ if (v >= VM_MIN_KERNEL_ADDRESS) {
+ if (user)
+ panic("pmap_emulate_reference: user ref to kernel");
+ pte = vtopte(v);
+ } else {
+#ifdef DIAGNOSTIC
+ if (p == NULL)
+ panic("pmap_emulate_reference: bad proc");
+ if (p->p_vmspace == NULL)
+ panic("pmap_emulate_reference: bad p_vmspace");
+#endif
+ pte = pmap_lev3pte(p->p_vmspace->vm_map.pmap, v);
+ }
+#ifdef DEBUG /* These checks are more expensive */
+ if (!pmap_pte_v(pte))
+ panic("pmap_emulate_reference: invalid pte");
+#if 0
+ /*
+ * Can't do these, because cpu_fork and cpu_swapin call
+ * pmap_emulate_reference(), and the bits aren't guaranteed,
+ * for them...
+ */
+ if (write) {
+ if (!(*pte & (user ? PG_UWE : PG_UWE | PG_KWE)))
+ panic("pmap_emulate_reference: write but unwritable");
+ if (!(*pte & PG_FOW))
+ panic("pmap_emulate_reference: write but not FOW");
+ } else {
+ if (!(*pte & (user ? PG_URE : PG_URE | PG_KRE)))
+ panic("pmap_emulate_reference: !write but unreadable");
+ if (!(*pte & (PG_FOR | PG_FOE)))
+ panic("pmap_emulate_reference: !write but not FOR|FOE");
+ }
+#endif
+ /* Other diagnostics? */
+#endif
+ pa = pmap_pte_pa(pte);
+
+#ifdef DIAGNOSTIC
+ if ((*pte & PG_MANAGED) == 0)
+ panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): pa 0x%lx not managed", p, v, user, write, pa);
+#endif
+
+ /*
+ * Twiddle the appropriate bits to reflect the reference
+ * and/or modification..
+ *
+ * The rules:
+ * (1) always mark page as used, and
+ * (2) if it was a write fault, mark page as modified.
+ */
+ ppv = pa_to_pvh(pa);
+ ppv->pv_flags = PV_TABLE_REF;
+ faultoff = PG_FOR | PG_FOE;
+ ppv->pv_vm_page->flags |= PG_REFERENCED;
+ if (write) {
+ ppv->pv_flags |= PV_TABLE_MOD;
+ ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
+ faultoff |= PG_FOW;
+ }
+ pmap_changebit(pa, faultoff, FALSE);
+ if ((*pte & faultoff) != 0) {
+#if 0
+ /*
+ * This is apparently normal. Why? -- cgd
+ * XXX because was being called on unmanaged pages?
+ */
+ printf("warning: pmap_changebit didn't.");
+#endif
+ *pte &= ~faultoff;
+ ALPHA_TBIS(v);
+ }
+}
+
+/*
+ * Miscellaneous support routines follow
+ */
+
+static void
+alpha_protection_init()
+{
+ int prot, *kp, *up;
+
+ kp = protection_codes[0];
+ up = protection_codes[1];
+
+ for (prot = 0; prot < 8; prot++) {
+ switch (prot) {
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
+ *kp++ = PG_ASM;
+ *up++ = 0;
+ break;
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
+ *kp++ = PG_ASM | PG_KRE;
+ *up++ = PG_URE | PG_KRE;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
+ *kp++ = PG_ASM | PG_KWE;
+ *up++ = PG_UWE | PG_KWE;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ *kp++ = PG_ASM | PG_KWE | PG_KRE;
+ *up++ = PG_UWE | PG_URE | PG_KWE | PG_KRE;
+ break;
+ }
+ }
+}
+
+/*
+ * Map a set of physical memory pages into the kernel virtual
+ * address space. Return a pointer to where it is mapped. This
+ * routine is intended to be used for mapping device memory,
+ * NOT real memory.
+ */
+void *
+pmap_mapdev(pa, size)
+ vm_offset_t pa;
+ vm_size_t size;
+{
+ vm_offset_t va, tmpva;
+ pt_entry_t *pte;
+
+ size = roundup(size, PAGE_SIZE);
+
+ va = kmem_alloc_pageable(kernel_map, size);
+#if !defined(MAX_PERF)
+ if (!va)
+ panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
+#endif
+
+ pa = pa & ~PAGE_MASK;
+ for (tmpva = va; size > 0;) {
+ pte = vtopte(tmpva);
+ *pte = pmap_phys_to_pte(pa) | PG_KRE | PG_KWE | PG_V;
+ size -= PAGE_SIZE;
+ tmpva += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ }
+ ALPHA_TBIA();
+
+ return ((void *) va);
+}
+
+/*
+ * perform the pmap work for mincore
+ */
+int
+pmap_mincore(pmap, addr)
+ pmap_t pmap;
+ vm_offset_t addr;
+{
+
+ pt_entry_t *pte;
+ vm_page_t m;
+ int val = 0;
+
+ pte = pmap_lev3pte(pmap, addr);
+ if (pte == 0) {
+ return 0;
+ }
+
+ if (pmap_pte_v(pte)) {
+ pv_table_t *ppv;
+ vm_offset_t pa;
+
+ val = MINCORE_INCORE;
+ if ((*pte & PG_MANAGED) == 0)
+ return val;
+
+ pa = pmap_pte_pa(pte);
+
+ ppv = pa_to_pvh(pa);
+ m = ppv->pv_vm_page;
+
+ /*
+ * Modified by us
+ */
+ if (ppv->pv_flags & PV_TABLE_MOD)
+ val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
+ /*
+ * Modified by someone
+ */
+ else if (m->dirty || pmap_is_modified(pa))
+ val |= MINCORE_MODIFIED_OTHER;
+ /*
+ * Referenced by us
+ */
+ if (ppv->pv_flags & PV_TABLE_REF)
+ val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
+
+ /*
+ * Referenced by someone
+ */
+ else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(pa)) {
+ val |= MINCORE_REFERENCED_OTHER;
+ m->flags |= PG_REFERENCED;
+ }
+ }
+ return val;
+}
+
+void
+pmap_activate(struct proc *p)
+{
+ pmap_t pmap;
+
+ pmap = &p->p_vmspace->vm_pmap;
+ p->p_addr->u_pcb.pcb_hw.apcb_ptbr =
+ ALPHA_K0SEG_TO_PHYS((vm_offset_t) pmap->pm_lev1) >> PAGE_SHIFT;
+
+ if (p == curproc) {
+ alpha_pal_swpctx((u_long)p->p_md.md_pcbpaddr);
+ } else
+ /* XXX remove after implementing ASNs */
+ ALPHA_TBIA();
+
+}
+
+void
+pmap_deactivate(struct proc *p)
+{
+}
+
+vm_offset_t
+pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) {
+
+ return addr;
+}
+
+#if 0
+#if defined(PMAP_DEBUG)
+pmap_pid_dump(int pid) {
+ pmap_t pmap;
+ struct proc *p;
+ int npte = 0;
+ int index;
+ for (p = allproc.lh_first; p != NULL; p = p->p_list.le_next) {
+ if (p->p_pid != pid)
+ continue;
+
+ if (p->p_vmspace) {
+ int i,j;
+ index = 0;
+ pmap = &p->p_vmspace->vm_pmap;
+ for(i=0;i<1024;i++) {
+ pd_entry_t *pde;
+ pt_entry_t *pte;
+ unsigned base = i << PDRSHIFT;
+
+ pde = &pmap->pm_pdir[i];
+ if (pde && pmap_pde_v(pde)) {
+ for(j=0;j<1024;j++) {
+ unsigned va = base + (j << PAGE_SHIFT);
+ if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
+ if (index) {
+ index = 0;
+ printf("\n");
+ }
+ return npte;
+ }
+ pte = pmap_pte_quick( pmap, va);
+ if (pte && pmap_pte_v(pte)) {
+ vm_offset_t pa;
+ vm_page_t m;
+ pa = *(int *)pte;
+ m = PHYS_TO_VM_PAGE((pa & PG_FRAME));
+ printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
+ va, pa, m->hold_count, m->wire_count, m->flags);
+ npte++;
+ index++;
+ if (index >= 2) {
+ index = 0;
+ printf("\n");
+ } else {
+ printf(" ");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return npte;
+}
+#endif
+
+#if defined(DEBUG)
+
+static void pads __P((pmap_t pm));
+static void pmap_pvdump __P((vm_offset_t pa));
+
+/* print address space of pmap*/
+static void
+pads(pm)
+ pmap_t pm;
+{
+ int i, j;
+ vm_offset_t va;
+ pt_entry_t *ptep;
+
+ if (pm == kernel_pmap)
+ return;
+ for (i = 0; i < 1024; i++)
+ if (pm->pm_pdir[i])
+ for (j = 0; j < 1024; j++) {
+ va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
+ if (pm == kernel_pmap && va < KERNBASE)
+ continue;
+ if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
+ continue;
+ ptep = pmap_pte_quick(pm, va);
+ if (pmap_pte_v(ptep))
+ printf("%x:%x ", va, *(int *) ptep);
+ };
+
+}
+
+static void
+pmap_pvdump(pa)
+ vm_offset_t pa;
+{
+ pv_table_t *ppv;
+ register pv_entry_t pv;
+
+ printf("pa %x", pa);
+ ppv = pa_to_pvh(pa);
+ for (pv = TAILQ_FIRST(&ppv->pv_list);
+ pv;
+ pv = TAILQ_NEXT(pv, pv_list)) {
+#ifdef used_to_be
+ printf(" -> pmap %x, va %x, flags %x",
+ pv->pv_pmap, pv->pv_va, pv->pv_flags);
+#endif
+ printf(" -> pmap %x, va %x",
+ pv->pv_pmap, pv->pv_va);
+ pads(pv->pv_pmap);
+ }
+ printf(" ");
+}
+#endif
+#endif
diff --git a/sys/alpha/alpha/procfs_machdep.c b/sys/alpha/alpha/procfs_machdep.c
new file mode 100644
index 000000000000..11898d0cf3cb
--- /dev/null
+++ b/sys/alpha/alpha/procfs_machdep.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993 Jan-Simon Pendry
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * 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.
+ *
+ * @(#)procfs_machdep.c 8.3 (Berkeley) 1/27/94
+ *
+ * From:
+ * $Id: procfs_machdep.c,v 1.10 1997/07/20 08:37:22 bde Exp $
+ */
+
+/*
+ * Functions to be implemented here are:
+ *
+ * procfs_read_regs(proc, regs)
+ * Get the current user-visible register set from the process
+ * and copy it into the regs structure (<machine/reg.h>).
+ * The process is stopped at the time read_regs is called.
+ *
+ * procfs_write_regs(proc, regs)
+ * Update the current register set from the passed in regs
+ * structure. Take care to avoid clobbering special CPU
+ * registers or privileged bits in the PSL.
+ * Depending on the architecture this may have fix-up work to do,
+ * especially if the IAR or PCW are modified.
+ * The process is stopped at the time write_regs is called.
+ *
+ * procfs_read_fpregs, procfs_write_fpregs
+ * deal with the floating point register set, otherwise as above.
+ *
+ * procfs_sstep(proc)
+ * Arrange for the process to trap after executing a single instruction.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/vnode.h>
+#include <machine/reg.h>
+#include <machine/md_var.h>
+#include <miscfs/procfs/procfs.h>
+
+#include <vm/vm.h>
+#include <sys/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+#include <sys/user.h>
+
+int
+procfs_read_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+ return (fill_regs(p, regs));
+}
+
+int
+procfs_write_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+ return (set_regs(p, regs));
+}
+
+/*
+ * Ptrace doesn't support fpregs at all, and there are no security holes
+ * or translations for fpregs, so we can just copy them.
+ */
+
+int
+procfs_read_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ if (p == fpcurproc) {
+ alpha_pal_wrfen(1);
+ savefpstate(&p->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+ }
+
+ bcopy(&p->p_addr->u_pcb.pcb_fp, fpregs, sizeof *fpregs);
+ return (0);
+}
+
+int
+procfs_write_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ if (p == fpcurproc)
+ fpcurproc = NULL;
+
+ bcopy(fpregs, &p->p_addr->u_pcb.pcb_fp, sizeof *fpregs);
+ return (0);
+}
+
+int
+procfs_sstep(p)
+ struct proc *p;
+{
+ return (EINVAL);
+}
diff --git a/sys/alpha/alpha/prom.c b/sys/alpha/alpha/prom.c
new file mode 100644
index 000000000000..1069ac784b6b
--- /dev/null
+++ b/sys/alpha/alpha/prom.c
@@ -0,0 +1,361 @@
+/* $NetBSD: prom.c,v 1.22 1998/02/27 04:03:00 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1992, 1994, 1995, 1996 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include "opt_simos.h"
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+/* __KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.22 1998/02/27 04:03:00 thorpej Exp $"); */
+
+#include <stddef.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_prot.h>
+#include <vm/vm_map.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <machine/rpb.h>
+#include <machine/prom.h>
+#include <machine/vmparam.h>
+
+#include <machine/cons.h>
+
+/* XXX this is to fake out the console routines, while booting. */
+struct consdev promcons = { NULL, NULL, promcngetc, NULL, promcnputc,
+ NULL, NODEV, CN_NORMAL };
+
+struct rpb *hwrpb;
+int alpha_console;
+
+extern struct prom_vec prom_dispatch_v;
+
+int prom_mapped = 1; /* Is PROM still mapped? */
+pt_entry_t rom_pte, saved_pte[1]; /* XXX */
+
+static pt_entry_t *rom_lev1map __P((void));
+extern struct pcb* curpcb;
+extern pt_entry_t* Lev1map;
+
+static void prom_cache_sync __P((void));
+
+static pt_entry_t *
+rom_lev1map()
+{
+ struct alpha_pcb *apcb;
+
+ /*
+ * We may be called before the first context switch
+ * after alpha_init(), in which case we just need
+ * to use the kernel Lev1map.
+ */
+ if (curpcb == 0)
+ return (Lev1map);
+
+ /*
+ * Find the level 1 map that we're currently running on.
+ */
+ apcb = (struct alpha_pcb *)ALPHA_PHYS_TO_K0SEG((vm_offset_t) curpcb);
+
+ return ((pt_entry_t *)ALPHA_PHYS_TO_K0SEG(alpha_ptob(apcb->apcb_ptbr)));
+}
+
+void
+init_prom_interface(rpb)
+ struct rpb *rpb;
+{
+ struct crb *c;
+
+ c = (struct crb *)((char *)rpb + rpb->rpb_crb_off);
+
+ prom_dispatch_v.routine_arg = c->crb_v_dispatch;
+ prom_dispatch_v.routine = c->crb_v_dispatch->entry_va;
+}
+
+extern struct consdev* cn_tab;
+
+void
+init_bootstrap_console()
+{
+ char buf[4];
+
+ init_prom_interface(hwrpb);
+
+#ifdef SIMOS
+ alpha_console = 0;
+#else
+ prom_getenv(PROM_E_TTY_DEV, buf, 4);
+ alpha_console = buf[0] - '0';
+#endif
+
+ /* XXX fake out the console routines, for now */
+ cn_tab = &promcons;
+}
+
+static int enter_prom __P((void));
+static void leave_prom __P((int));
+#ifdef _PMAP_MAY_USE_PROM_CONSOLE
+static void prom_cache_sync __P((void));
+#endif
+
+static int
+enter_prom()
+{
+ int s = splhigh();
+
+ pt_entry_t *lev1map;
+
+ if (!prom_mapped) {
+#ifdef SIMOS
+ /*
+ * SimOS console uses floating point.
+ */
+ if (curproc != fpcurproc) {
+ alpha_pal_wrfen(1);
+ if (fpcurproc)
+ savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ fpcurproc = curproc;
+ restorefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ }
+#endif
+ if (!pmap_uses_prom_console())
+ panic("enter_prom");
+ lev1map = rom_lev1map(); /* XXX */
+ saved_pte[0] = lev1map[0]; /* XXX */
+ lev1map[0] = rom_pte; /* XXX */
+ prom_cache_sync(); /* XXX */
+ }
+ return s;
+}
+
+static void
+leave_prom __P((s))
+ int s;
+{
+
+ pt_entry_t *lev1map;
+
+ if (!prom_mapped) {
+ if (!pmap_uses_prom_console())
+ panic("leave_prom");
+ lev1map = rom_lev1map(); /* XXX */
+ lev1map[0] = saved_pte[0]; /* XXX */
+ prom_cache_sync(); /* XXX */
+ }
+ splx(s);
+}
+
+static void
+prom_cache_sync __P((void))
+{
+ ALPHA_TBIA();
+ alpha_pal_imb();
+}
+
+/*
+ * promcnputc:
+ *
+ * Remap char before passing off to prom.
+ *
+ * Prom only takes 32 bit addresses. Copy char somewhere prom can
+ * find it. This routine will stop working after pmap_rid_of_console
+ * is called in alpha_init. This is due to the hard coded address
+ * of the console area.
+ */
+void
+promcnputc(dev, c)
+ dev_t dev;
+ int c;
+{
+ prom_return_t ret;
+ unsigned char *to = (unsigned char *)0x20000000;
+ int s;
+
+ s = enter_prom(); /* splhigh() and map prom */
+ *to = c;
+
+ do {
+ ret.bits = prom_putstr(alpha_console, to, 1);
+ } while ((ret.u.retval & 1) == 0);
+
+ leave_prom(s); /* unmap prom and splx(s) */
+}
+
+/*
+ * promcngetc:
+ *
+ * Wait for the prom to get a real char and pass it back.
+ */
+int
+promcngetc(dev)
+ dev_t dev;
+{
+ prom_return_t ret;
+ int s;
+
+ for (;;) {
+ s = enter_prom();
+ ret.bits = prom_getc(alpha_console);
+ leave_prom(s);
+ if (ret.u.status == 0 || ret.u.status == 1)
+ return (ret.u.retval);
+ }
+}
+
+/*
+ * promcnlookc:
+ *
+ * See if prom has a real char and pass it back.
+ */
+int
+promcnlookc(dev, cp)
+ dev_t dev;
+ char *cp;
+{
+ prom_return_t ret;
+ int s;
+
+ s = enter_prom();
+ ret.bits = prom_getc(alpha_console);
+ leave_prom(s);
+ if (ret.u.status == 0 || ret.u.status == 1) {
+ *cp = ret.u.retval;
+ return 1;
+ } else
+ return 0;
+}
+
+int
+prom_getenv(id, buf, len)
+ int id, len;
+ char *buf;
+{
+ unsigned char *to = (unsigned char *)0x20000000;
+ prom_return_t ret;
+ int s;
+
+ s = enter_prom();
+ ret.bits = prom_getenv_disp(id, to, len);
+ bcopy(to, buf, len);
+ leave_prom(s);
+
+ if (ret.u.status & 0x4)
+ ret.u.retval = 0;
+ buf[ret.u.retval] = '\0';
+
+ return (ret.bits);
+}
+
+void
+prom_halt(halt)
+ int halt;
+{
+ struct pcs *p;
+
+ /*
+ * Turn off interrupts, for sanity.
+ */
+ (void) splhigh();
+
+ /*
+ * Set "boot request" part of the CPU state depending on what
+ * we want to happen when we halt.
+ */
+ p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off +
+ (hwrpb->rpb_primary_cpu_id * hwrpb->rpb_pcs_size));
+ p->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ);
+ if (halt)
+ p->pcs_flags |= PCS_HALT_STAY_HALTED;
+ else
+ p->pcs_flags |= PCS_HALT_WARM_BOOT;
+
+ /*
+ * Halt the machine.
+ */
+ alpha_pal_halt();
+}
+
+u_int64_t
+hwrpb_checksum()
+{
+ u_int64_t *p, sum;
+ int i;
+
+ for (i = 0, p = (u_int64_t *)hwrpb, sum = 0;
+ i < (offsetof(struct rpb, rpb_checksum) / sizeof (u_int64_t));
+ i++, p++)
+ sum += *p;
+
+ return (sum);
+}
+
+void
+hwrpb_restart_setup()
+{
+ struct pcs *p;
+
+ /* Clear bootstrap-in-progress flag since we're done bootstrapping */
+ p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
+ p->pcs_flags &= ~PCS_BIP;
+
+ bcopy(&proc0.p_addr->u_pcb.pcb_hw, p->pcs_hwpcb,
+ sizeof proc0.p_addr->u_pcb.pcb_hw);
+ hwrpb->rpb_vptb = VPTBASE;
+
+ /* when 'c'ontinuing from console halt, do a dump */
+ hwrpb->rpb_rest_term = (u_int64_t)&XentRestart;
+ hwrpb->rpb_rest_term_val = 0x1;
+
+#if 0
+ /* don't know what this is really used by, so don't mess with it. */
+ hwrpb->rpb_restart = (u_int64_t)&XentRestart;
+ hwrpb->rpb_restart_val = 0x2;
+#endif
+
+ hwrpb->rpb_checksum = hwrpb_checksum();
+
+ p->pcs_flags |= (PCS_RC | PCS_CV);
+}
+
+u_int64_t
+console_restart(ra, ai, pv)
+ u_int64_t ra, ai, pv;
+{
+ struct pcs *p;
+
+ /* Clear restart-capable flag, since we can no longer restart. */
+ p = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off);
+ p->pcs_flags &= ~PCS_RC;
+
+ panic("user requested console halt");
+
+ return (1);
+}
diff --git a/sys/alpha/alpha/prom_disp.s b/sys/alpha/alpha/prom_disp.s
new file mode 100644
index 000000000000..23bdbef9315c
--- /dev/null
+++ b/sys/alpha/alpha/prom_disp.s
@@ -0,0 +1,116 @@
+/* $NetBSD: prom_disp.s,v 1.8 1997/11/03 04:22:03 ross Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _LOCORE
+#include <machine/asm.h>
+#else
+__KERNEL_RCSID(2, "$NetBSD: prom_disp.s,v 1.8 1997/11/03 04:22:03 ross Exp $");
+#endif
+
+ .globl prom_dispatch_v
+ .comm prom_dispatch_v,16
+
+ .text
+ .align 4
+
+inc3: .stabs __FILE__,132,0,0,inc3; .loc 1 __LINE__
+/*
+ * Dispatcher routine. Implements prom's calling machinery, saves our
+ * callee-saved registers as required by C.
+ */
+#define D_RA (7*8)
+#define D_S0 (8*8)
+#define D_S1 (9*8)
+#define D_S2 (10*8)
+#define D_S3 (11*8)
+#define D_S4 (12*8)
+#define D_S5 (13*8)
+#define D_S6 (14*8)
+#define DISPATCH_FRAME_SIZE (15*8)
+#define DISPATCH_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5|IM_S6
+
+NESTED(prom_dispatch, 5, DISPATCH_FRAME_SIZE, ra, DISPATCH_REGS, 0)
+
+ ldgp gp, 0(pv)
+
+ lda sp, -DISPATCH_FRAME_SIZE(sp)
+ stq ra, D_RA(sp)
+ stq s0, D_S0(sp)
+ stq s1, D_S1(sp)
+ stq s2, D_S2(sp)
+ stq s3, D_S3(sp)
+ stq s4, D_S4(sp)
+ stq s5, D_S5(sp)
+ stq s6, D_S6(sp)
+
+ /* Lord have mercy because.. I would not. */
+#define STUPID_PROM_IS_32_BITS
+#ifdef STUPID_PROM_IS_32_BITS
+ ldah s0, 0x2000(zero) /* hack for hack */
+ lda s0, (0x2000-8)(s0)
+
+ stq sp, 0(s0)
+ or s0, zero, sp
+#endif /* STUPID_PROM_IS_32_BITS */
+
+ lda pv, prom_dispatch_v
+ ldq v0, 0(pv) /* routine */
+ ldq pv, 8(pv) /* routine_arg */
+
+ jsr ra, (v0)
+
+#ifdef STUPID_PROM_IS_32_BITS
+ ldah s0, 0x2000(zero) /* hack for hack */
+ lda s0, (0x2000-8)(s0)
+
+ ldq sp, 0(s0)
+#endif /* STUPID_PROM_IS_32_BITS */
+
+ ldq ra, D_RA(sp)
+ ldq s0, D_S0(sp)
+ ldq s1, D_S1(sp)
+ ldq s2, D_S2(sp)
+ ldq s3, D_S3(sp)
+ ldq s4, D_S4(sp)
+ ldq s5, D_S5(sp)
+ ldq s6, D_S6(sp)
+ lda sp, DISPATCH_FRAME_SIZE(sp)
+ RET
+END(prom_dispatch)
+
+#undef D_RA
+#undef D_S0
+#undef D_S1
+#undef D_S2
+#undef D_S3
+#undef D_S4
+#undef D_S5
+#undef D_S6
+#undef DISPATCH_FRAME_SIZE
+#undef DISPATCH_REGS
diff --git a/sys/alpha/alpha/promcons.c b/sys/alpha/alpha/promcons.c
new file mode 100644
index 000000000000..8be259a69ce1
--- /dev/null
+++ b/sys/alpha/alpha/promcons.c
@@ -0,0 +1,249 @@
+/* $NetBSD: promcons.c,v 1.13 1998/03/21 22:52:59 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: promcons.c,v 1.13 1998/03/21 22:52:59 mycroft Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <vm/vm.h> /* XXX for _PMAP_MAY_USE_PROM_CONSOLE */
+
+#include <machine/conf.h>
+#include <machine/prom.h>
+
+#ifdef _PMAP_MAY_USE_PROM_CONSOLE
+
+#define PROM_POLL_HZ 50
+
+static struct tty *prom_tty[1];
+static int polltime;
+
+void promstart __P((struct tty *));
+void promtimeout __P((void *));
+int promparam __P((struct tty *, struct termios *));
+
+int
+promopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct tty *tp;
+ int s;
+ int error = 0, setuptimeout = 0;
+
+ if (!pmap_uses_prom_console() || unit >= 1)
+ return ENXIO;
+
+ s = spltty();
+
+ if (!prom_tty[unit]) {
+ tp = prom_tty[unit] = ttymalloc();
+ tty_attach(tp);
+ } else
+ tp = prom_tty[unit];
+
+ tp->t_oproc = promstart;
+ tp->t_param = promparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_CARR_ON;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = 9600;
+ ttsetwater(tp);
+
+ setuptimeout = 1;
+ } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return EBUSY;
+ }
+
+ splx(s);
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error == 0 && setuptimeout) {
+ polltime = hz / PROM_POLL_HZ;
+ if (polltime < 1)
+ polltime = 1;
+ timeout(promtimeout, tp, polltime);
+ }
+ return error;
+}
+
+int
+promclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct tty *tp = prom_tty[unit];
+
+ untimeout(promtimeout, tp);
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return 0;
+}
+
+int
+promread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct tty *tp = prom_tty[minor(dev)];
+
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+promwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct tty *tp = prom_tty[minor(dev)];
+
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+int
+promioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct tty *tp = prom_tty[unit];
+ int error;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+
+ return ENOTTY;
+}
+
+int
+promparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+
+ return 0;
+}
+
+void
+promstart(tp)
+ struct tty *tp;
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & (TS_TTSTOP | TS_BUSY))
+ goto out;
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0)
+ promcnputc(tp->t_dev, getc(&tp->t_outq));
+ tp->t_state &= ~TS_BUSY;
+out:
+ splx(s);
+}
+
+/*
+ * Stop output on a line.
+ */
+void
+promstop(tp, flag)
+ struct tty *tp;
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY)
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ splx(s);
+}
+
+void
+promtimeout(v)
+ void *v;
+{
+ struct tty *tp = v;
+ u_char c;
+
+ while (promcnlookc(tp->t_dev, &c)) {
+ if (tp->t_state & TS_ISOPEN)
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ }
+ timeout(promtimeout, tp, polltime);
+}
+
+struct tty *
+promtty(dev)
+ dev_t dev;
+{
+
+ if (minor(dev) != 0)
+ panic("promtty: bogus");
+
+ return prom_tty[0];
+}
+
+#endif /* _PMAP_MAY_USE_PROM_CONSOLE */
diff --git a/sys/alpha/alpha/setdef0.c b/sys/alpha/alpha/setdef0.c
new file mode 100644
index 000000000000..e91857f9f815
--- /dev/null
+++ b/sys/alpha/alpha/setdef0.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1997 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: setdef0.c,v 1.2 1997/05/21 23:21:30 jdp Exp $
+ */
+
+#ifdef __ELF__
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+
+/*
+ * DEFINE_SET creates the section and label for a set, and emits the
+ * count word at the front of it.
+ */
+#define DEFINE_SET(set, count) \
+ __asm__(".section .set." #set ",\"aw\""); \
+ __asm__(".globl " #set); \
+ __asm__(".type " #set ",@object"); \
+ __asm__(".p2align 3"); \
+ __asm__(#set ":"); \
+ __asm__(".quad " #count); \
+ __asm__(".previous")
+
+#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
+
+#endif /* __ELF__ */
diff --git a/sys/alpha/alpha/setdef1.c b/sys/alpha/alpha/setdef1.c
new file mode 100644
index 000000000000..0b2bbaa7bb57
--- /dev/null
+++ b/sys/alpha/alpha/setdef1.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1997 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: setdef1.c,v 1.2 1997/05/21 23:21:30 jdp Exp $
+ */
+
+#ifdef __ELF__
+
+/*
+ * DEFINE_SET emits the NULL terminator for a set.
+ */
+#define DEFINE_SET(set, count) \
+ __asm__(".section .set." #set ",\"aw\""); \
+ __asm__(".quad 0"); \
+ __asm__(".previous")
+
+#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
+
+#endif /* __ELF__ */
diff --git a/sys/alpha/alpha/support.s b/sys/alpha/alpha/support.s
new file mode 100644
index 000000000000..1bf8b45156ad
--- /dev/null
+++ b/sys/alpha/alpha/support.s
@@ -0,0 +1,626 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+#include <assym.s>
+
+ .text
+
+/**************************************************************************/
+
+/*
+ * fu{byte,word} : fetch a byte (word) from user memory
+ */
+
+ LEAF(suword, 1)
+
+ ldiq t0, VM_MAXUSER_ADDRESS /* verify address validity */
+ cmpult a0, t0, t1
+ beq t1, fusufault
+
+ lda t0, fusufault /* trap faults */
+ ldq t2, curproc
+ ldq t2, P_ADDR(t2)
+ stq t0, U_PCB_ONFAULT(t2)
+
+ stq a1, 0(a0) /* try the store */
+
+ stq zero, U_PCB_ONFAULT(t2) /* clean up */
+
+ mov zero, v0
+ RET
+ END(suword)
+
+ LEAF(subyte, 1)
+
+ ldiq t0, VM_MAXUSER_ADDRESS /* verify address validity */
+ cmpult a0, t0, t1
+ beq t1, fusufault
+
+ lda t0, fusufault /* trap faults */
+ ldq t2, curproc
+ ldq t2, P_ADDR(t2)
+ stq t0, U_PCB_ONFAULT(t2)
+
+ zap a1, 0xfe, a1 /* mask off the byte to store */
+ insbl a1, a0, a1 /* shift it to the right place */
+ ldq_u t0, 0(a0) /* read the qword to store it in */
+ mskbl t0, a0, t0 /* make a place for our byte */
+ or a1, t0, a1 /* move it in */
+ stq_u a1, 0(a0) /* and put the byte back */
+
+ stq zero, U_PCB_ONFAULT(t2) /* clean up */
+
+ mov zero, v0
+ RET
+ END(subyte)
+
+ LEAF(fuword, 1)
+
+ ldiq t0, VM_MAXUSER_ADDRESS /* verify address validity */
+ cmpult a0, t0, t1
+ beq t1, fusufault
+
+ lda t0, fusufault /* trap faults */
+ ldq t2, curproc
+ ldq t2, P_ADDR(t2)
+ stq t0, U_PCB_ONFAULT(t2)
+
+ ldq v0, 0(a0) /* try the fetch */
+
+ stq zero, U_PCB_ONFAULT(t2) /* clean up */
+
+ RET
+ END(fuword)
+
+ LEAF(fubyte, 1)
+
+ ldiq t0, VM_MAXUSER_ADDRESS /* verify address validity */
+ cmpult a0, t0, t1
+ beq t1, fusufault
+
+ lda t0, fusufault /* trap faults */
+ ldq t2, curproc
+ ldq t2, P_ADDR(t2)
+ stq t0, U_PCB_ONFAULT(t2)
+
+ ldq_u v0, 0(a0) /* get the word containing our byte */
+ extbl v0, a0, v0 /* extract the byte */
+
+ stq zero, U_PCB_ONFAULT(t2) /* clean up */
+
+ mov zero, v0
+ RET
+ END(fubyte)
+
+ LEAF(suibyte, 2)
+ ldiq v0, -1
+ RET
+ END(suibyte)
+
+ LEAF(fusufault, 0)
+ ldq t0, curproc
+ ldq t0, P_ADDR(t0)
+ stq zero, U_PCB_ONFAULT(t0)
+ ldiq v0, -1
+ RET
+ END(fusufault)
+
+LEAF(fswintrberr, 0)
+XLEAF(fuswintr, 2) /* XXX what is a 'word'? */
+XLEAF(suswintr, 2) /* XXX what is a 'word'? */
+ LDGP(pv)
+ ldiq v0, -1
+ RET
+ END(fswintrberr)
+
+/**************************************************************************/
+
+/*
+ * Copy a null-terminated string within the kernel's address space.
+ * If lenp is not NULL, store the number of chars copied in *lenp
+ *
+ * int copystr(char *from, char *to, size_t len, size_t *lenp);
+ */
+LEAF(copystr, 4)
+ LDGP(pv)
+
+ mov a2, t0 /* t0 = i = len */
+ beq a2, Lcopystr2 /* if (len == 0), bail out */
+
+Lcopystr1:
+ ldq_u t1, 0(a0) /* t1 = *from */
+ extbl t1, a0, t1
+ ldq_u t3, 0(a1) /* set up t2 with quad around *to */
+ insbl t1, a1, t2
+ mskbl t3, a1, t3
+ or t3, t2, t3 /* add *from to quad around *to */
+ stq_u t3, 0(a1) /* write out that quad */
+
+ subl a2, 1, a2 /* len-- */
+ beq t1, Lcopystr2 /* if (*from == 0), bail out */
+ addq a1, 1, a1 /* to++ */
+ addq a0, 1, a0 /* from++ */
+ bne a2, Lcopystr1 /* if (len != 0) copy more */
+
+Lcopystr2:
+ beq a3, Lcopystr3 /* if (lenp != NULL) */
+ subl t0, a2, t0 /* *lenp = (i - len) */
+ stq t0, 0(a3)
+Lcopystr3:
+ beq t1, Lcopystr4 /* *from == '\0'; leave quietly */
+
+ ldiq v0, ENAMETOOLONG /* *from != '\0'; error. */
+ RET
+
+Lcopystr4:
+ mov zero, v0 /* return 0. */
+ RET
+ END(copystr)
+
+NESTED(copyinstr, 4, 16, ra, 0, 0)
+ LDGP(pv)
+ lda sp, -16(sp) /* set up stack frame */
+ stq ra, (16-8)(sp) /* save ra */
+ ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */
+ cmpult a0, t0, t1 /* is in user space. */
+ beq t1, copyerr /* if it's not, error out. */
+ lda v0, copyerr /* set up fault handler. */
+ .set noat
+ ldq at_reg, curproc
+ ldq at_reg, P_ADDR(at_reg)
+ stq v0, U_PCB_ONFAULT(at_reg)
+ .set at
+ CALL(copystr) /* do the copy. */
+ .set noat
+ ldq at_reg, curproc /* kill the fault handler. */
+ ldq at_reg, P_ADDR(at_reg)
+ stq zero, U_PCB_ONFAULT(at_reg)
+ .set at
+ ldq ra, (16-8)(sp) /* restore ra. */
+ lda sp, 16(sp) /* kill stack frame. */
+ RET /* v0 left over from copystr */
+ END(copyinstr)
+
+NESTED(copyoutstr, 4, 16, ra, 0, 0)
+ LDGP(pv)
+ lda sp, -16(sp) /* set up stack frame */
+ stq ra, (16-8)(sp) /* save ra */
+ ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */
+ cmpult a1, t0, t1 /* is in user space. */
+ beq t1, copyerr /* if it's not, error out. */
+ lda v0, copyerr /* set up fault handler. */
+ .set noat
+ ldq at_reg, curproc
+ ldq at_reg, P_ADDR(at_reg)
+ stq v0, U_PCB_ONFAULT(at_reg)
+ .set at
+ CALL(copystr) /* do the copy. */
+ .set noat
+ ldq at_reg, curproc /* kill the fault handler. */
+ ldq at_reg, P_ADDR(at_reg)
+ stq zero, U_PCB_ONFAULT(at_reg)
+ .set at
+ ldq ra, (16-8)(sp) /* restore ra. */
+ lda sp, 16(sp) /* kill stack frame. */
+ RET /* v0 left over from copystr */
+ END(copyoutstr)
+
+/*
+ * Alternative memory mover
+ */
+ LEAF(memcpy,3)
+ mov a0,t0
+ mov a1,a0
+ mov t0,a1
+ br bcopy
+ END(memcpy)
+
+/*
+ * Copy a bytes within the kernel's address space.
+ *
+ * In the kernel, bcopy() doesn't have to handle the overlapping
+ * case; that's that ovbcopy() is for. However, it doesn't hurt
+ * to do both in bcopy, and it does provide a measure of safety.
+ *
+ * void bcopy(char *from, char *to, size_t len);
+ * void ovbcopy(char *from, char *to, size_t len);
+ */
+LEAF(bcopy,3)
+XLEAF(ovbcopy,3)
+
+ /* Check for negative length */
+ ble a2,bcopy_done
+
+ /* Check for overlap */
+ subq a1,a0,t5
+ cmpult t5,a2,t5
+ bne t5,bcopy_overlap
+
+ /* a3 = end address */
+ addq a0,a2,a3
+
+ /* Get the first word */
+ ldq_u t2,0(a0)
+
+ /* Do they have the same alignment? */
+ xor a0,a1,t0
+ and t0,7,t0
+ and a1,7,t1
+ bne t0,bcopy_different_alignment
+
+ /* src & dst have same alignment */
+ beq t1,bcopy_all_aligned
+
+ ldq_u t3,0(a1)
+ addq a2,t1,a2
+ mskqh t2,a0,t2
+ mskql t3,a0,t3
+ or t2,t3,t2
+
+ /* Dst is 8-byte aligned */
+
+bcopy_all_aligned:
+ /* If less than 8 bytes,skip loop */
+ subq a2,1,t0
+ and a2,7,a2
+ bic t0,7,t0
+ beq t0,bcopy_samealign_lp_end
+
+bcopy_samealign_lp:
+ stq_u t2,0(a1)
+ addq a1,8,a1
+ ldq_u t2,8(a0)
+ subq t0,8,t0
+ addq a0,8,a0
+ bne t0,bcopy_samealign_lp
+
+bcopy_samealign_lp_end:
+ /* If we're done, exit */
+ bne a2,bcopy_small_left
+ stq_u t2,0(a1)
+ RET
+
+bcopy_small_left:
+ mskql t2,a2,t4
+ ldq_u t3,0(a1)
+ mskqh t3,a2,t3
+ or t4,t3,t4
+ stq_u t4,0(a1)
+ RET
+
+bcopy_different_alignment:
+ /*
+ * this is the fun part
+ */
+ addq a0,a2,a3
+ cmpule a2,8,t0
+ bne t0,bcopy_da_finish
+
+ beq t1,bcopy_da_noentry
+
+ /* Do the initial partial word */
+ subq zero,a1,t0
+ and t0,7,t0
+ ldq_u t3,7(a0)
+ extql t2,a0,t2
+ extqh t3,a0,t3
+ or t2,t3,t5
+ insql t5,a1,t5
+ ldq_u t6,0(a1)
+ mskql t6,a1,t6
+ or t5,t6,t5
+ stq_u t5,0(a1)
+ addq a0,t0,a0
+ addq a1,t0,a1
+ subq a2,t0,a2
+ ldq_u t2,0(a0)
+
+bcopy_da_noentry:
+ subq a2,1,t0
+ bic t0,7,t0
+ and a2,7,a2
+ beq t0,bcopy_da_finish2
+
+bcopy_da_lp:
+ ldq_u t3,7(a0)
+ addq a0,8,a0
+ extql t2,a0,t4
+ extqh t3,a0,t5
+ subq t0,8,t0
+ or t4,t5,t5
+ stq t5,0(a1)
+ addq a1,8,a1
+ beq t0,bcopy_da_finish1
+ ldq_u t2,7(a0)
+ addq a0,8,a0
+ extql t3,a0,t4
+ extqh t2,a0,t5
+ subq t0,8,t0
+ or t4,t5,t5
+ stq t5,0(a1)
+ addq a1,8,a1
+ bne t0,bcopy_da_lp
+
+bcopy_da_finish2:
+ /* Do the last new word */
+ mov t2,t3
+
+bcopy_da_finish1:
+ /* Do the last partial word */
+ ldq_u t2,-1(a3)
+ extql t3,a0,t3
+ extqh t2,a0,t2
+ or t2,t3,t2
+ br zero,bcopy_samealign_lp_end
+
+bcopy_da_finish:
+ /* Do the last word in the next source word */
+ ldq_u t3,-1(a3)
+ extql t2,a0,t2
+ extqh t3,a0,t3
+ or t2,t3,t2
+ insqh t2,a1,t3
+ insql t2,a1,t2
+ lda t4,-1(zero)
+ mskql t4,a2,t5
+ cmovne t5,t5,t4
+ insqh t4,a1,t5
+ insql t4,a1,t4
+ addq a1,a2,a4
+ ldq_u t6,0(a1)
+ ldq_u t7,-1(a4)
+ bic t6,t4,t6
+ bic t7,t5,t7
+ and t2,t4,t2
+ and t3,t5,t3
+ or t2,t6,t2
+ or t3,t7,t3
+ stq_u t3,-1(a4)
+ stq_u t2,0(a1)
+ RET
+
+bcopy_overlap:
+ /*
+ * Basically equivalent to previous case, only backwards.
+ * Not quite as highly optimized
+ */
+ addq a0,a2,a3
+ addq a1,a2,a4
+
+ /* less than 8 bytes - don't worry about overlap */
+ cmpule a2,8,t0
+ bne t0,bcopy_ov_short
+
+ /* Possibly do a partial first word */
+ and a4,7,t4
+ beq t4,bcopy_ov_nostart2
+ subq a3,t4,a3
+ subq a4,t4,a4
+ ldq_u t1,0(a3)
+ subq a2,t4,a2
+ ldq_u t2,7(a3)
+ ldq t3,0(a4)
+ extql t1,a3,t1
+ extqh t2,a3,t2
+ or t1,t2,t1
+ mskqh t3,t4,t3
+ mskql t1,t4,t1
+ or t1,t3,t1
+ stq t1,0(a4)
+
+bcopy_ov_nostart2:
+ bic a2,7,t4
+ and a2,7,a2
+ beq t4,bcopy_ov_lp_end
+
+bcopy_ov_lp:
+ /* This could be more pipelined, but it doesn't seem worth it */
+ ldq_u t0,-8(a3)
+ subq a4,8,a4
+ ldq_u t1,-1(a3)
+ subq a3,8,a3
+ extql t0,a3,t0
+ extqh t1,a3,t1
+ subq t4,8,t4
+ or t0,t1,t0
+ stq t0,0(a4)
+ bne t4,bcopy_ov_lp
+
+bcopy_ov_lp_end:
+ beq a2,bcopy_done
+
+ ldq_u t0,0(a0)
+ ldq_u t1,7(a0)
+ ldq_u t2,0(a1)
+ extql t0,a0,t0
+ extqh t1,a0,t1
+ or t0,t1,t0
+ insql t0,a1,t0
+ mskql t2,a1,t2
+ or t2,t0,t2
+ stq_u t2,0(a1)
+
+bcopy_done:
+ RET
+
+bcopy_ov_short:
+ ldq_u t2,0(a0)
+ br zero,bcopy_da_finish
+
+ END(bcopy)
+
+NESTED(copyin, 3, 16, ra, 0, 0)
+ LDGP(pv)
+ lda sp, -16(sp) /* set up stack frame */
+ stq ra, (16-8)(sp) /* save ra */
+ ldiq t0, VM_MAXUSER_ADDRESS /* make sure that src addr */
+ cmpult a0, t0, t1 /* is in user space. */
+ beq t1, copyerr /* if it's not, error out. */
+ lda v0, copyerr /* set up fault handler. */
+ .set noat
+ ldq at_reg, curproc
+ ldq at_reg, P_ADDR(at_reg)
+ stq v0, U_PCB_ONFAULT(at_reg)
+ .set at
+ CALL(bcopy) /* do the copy. */
+ .set noat
+ ldq at_reg, curproc /* kill the fault handler. */
+ ldq at_reg, P_ADDR(at_reg)
+ stq zero, U_PCB_ONFAULT(at_reg)
+ .set at
+ ldq ra, (16-8)(sp) /* restore ra. */
+ lda sp, 16(sp) /* kill stack frame. */
+ mov zero, v0 /* return 0. */
+ RET
+ END(copyin)
+
+NESTED(copyout, 3, 16, ra, 0, 0)
+ LDGP(pv)
+ lda sp, -16(sp) /* set up stack frame */
+ stq ra, (16-8)(sp) /* save ra */
+ ldiq t0, VM_MAXUSER_ADDRESS /* make sure that dest addr */
+ cmpult a1, t0, t1 /* is in user space. */
+ beq t1, copyerr /* if it's not, error out. */
+ lda v0, copyerr /* set up fault handler. */
+ .set noat
+ ldq at_reg, curproc
+ ldq at_reg, P_ADDR(at_reg)
+ stq v0, U_PCB_ONFAULT(at_reg)
+ .set at
+ CALL(bcopy) /* do the copy. */
+ .set noat
+ ldq at_reg, curproc /* kill the fault handler. */
+ ldq at_reg, P_ADDR(at_reg)
+ stq zero, U_PCB_ONFAULT(at_reg)
+ .set at
+ ldq ra, (16-8)(sp) /* restore ra. */
+ lda sp, 16(sp) /* kill stack frame. */
+ mov zero, v0 /* return 0. */
+ RET
+ END(copyout)
+
+LEAF(copyerr, 0)
+ LDGP(pv)
+ ldq ra, (16-8)(sp) /* restore ra. */
+ lda sp, 16(sp) /* kill stack frame. */
+ ldiq v0, EFAULT /* return EFAULT. */
+ RET
+END(copyerr)
+
+/**************************************************************************/
+
+/*
+ * Kernel setjmp and longjmp. Rather minimalist.
+ *
+ * longjmp(label_t *a)
+ * will generate a "return (1)" from the last call to
+ * setjmp(label_t *a)
+ * by restoring registers from the stack,
+ */
+
+ .set noreorder
+
+LEAF(setjmp, 1)
+ LDGP(pv)
+
+ stq ra, (0 * 8)(a0) /* return address */
+ stq s0, (1 * 8)(a0) /* callee-saved registers */
+ stq s1, (2 * 8)(a0)
+ stq s2, (3 * 8)(a0)
+ stq s3, (4 * 8)(a0)
+ stq s4, (5 * 8)(a0)
+ stq s5, (6 * 8)(a0)
+ stq s6, (7 * 8)(a0)
+ stq sp, (8 * 8)(a0)
+
+ ldiq t0, 0xbeeffedadeadbabe /* set magic number */
+ stq t0, (9 * 8)(a0)
+
+ mov zero, v0 /* return zero */
+ RET
+END(setjmp)
+
+LEAF(longjmp, 1)
+ LDGP(pv)
+
+ ldiq t0, 0xbeeffedadeadbabe /* check magic number */
+ ldq t1, (9 * 8)(a0)
+ cmpeq t0, t1, t0
+ beq t0, longjmp_botch /* if bad, punt */
+
+ ldq ra, (0 * 8)(a0) /* return address */
+ ldq s0, (1 * 8)(a0) /* callee-saved registers */
+ ldq s1, (2 * 8)(a0)
+ ldq s2, (3 * 8)(a0)
+ ldq s3, (4 * 8)(a0)
+ ldq s4, (5 * 8)(a0)
+ ldq s5, (6 * 8)(a0)
+ ldq s6, (7 * 8)(a0)
+ ldq sp, (8 * 8)(a0)
+
+ ldiq v0, 1
+ RET
+
+longjmp_botch:
+ lda a0, longjmp_botchmsg
+ mov ra, a1
+ CALL(panic)
+ call_pal PAL_bugchk
+
+ .data
+longjmp_botchmsg:
+ .asciz "longjmp botch from %p"
+ .text
+END(longjmp)
diff --git a/sys/alpha/alpha/swtch.s b/sys/alpha/alpha/swtch.s
new file mode 100644
index 000000000000..2953f1d06e81
--- /dev/null
+++ b/sys/alpha/alpha/swtch.s
@@ -0,0 +1,388 @@
+/* $Id$ */
+/* $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+#include "assym.s"
+
+/**************************************************************************/
+
+/*
+ * Perform actions necessary to switch to a new context. The
+ * hwpcb should be in a0.
+ */
+#define SWITCH_CONTEXT \
+ /* Make a note of the context we're running on. */ \
+ stq a0, curpcb; \
+ \
+ /* Swap in the new context. */ \
+ call_pal PAL_OSF1_swpctx
+
+/*
+ * savectx: save process context, i.e. callee-saved registers
+ *
+ * Note that savectx() only works for processes other than curproc,
+ * since cpu_switch will copy over the info saved here. (It _can_
+ * sanely be used for curproc iff cpu_switch won't be called again, e.g.
+ * from if called from boot().)
+ *
+ * Arguments:
+ * a0 'struct user *' of the process that needs its context saved
+ *
+ * Return:
+ * v0 0. (note that for child processes, it seems
+ * like savectx() returns 1, because the return address
+ * in the PCB is set to the return address from savectx().)
+ */
+
+LEAF(savectx, 1)
+ br pv, Lsavectx1
+Lsavectx1: LDGP(pv)
+ stq sp, U_PCB_HWPCB_KSP(a0) /* store sp */
+ stq s0, U_PCB_CONTEXT+(0 * 8)(a0) /* store s0 - s6 */
+ stq s1, U_PCB_CONTEXT+(1 * 8)(a0)
+ stq s2, U_PCB_CONTEXT+(2 * 8)(a0)
+ stq s3, U_PCB_CONTEXT+(3 * 8)(a0)
+ stq s4, U_PCB_CONTEXT+(4 * 8)(a0)
+ stq s5, U_PCB_CONTEXT+(5 * 8)(a0)
+ stq s6, U_PCB_CONTEXT+(6 * 8)(a0)
+ stq ra, U_PCB_CONTEXT+(7 * 8)(a0) /* store ra */
+ call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
+ stq v0, U_PCB_CONTEXT+(8 * 8)(a0) /* store ps, for ipl */
+
+ mov zero, v0
+ RET
+ END(savectx)
+
+/**************************************************************************/
+
+IMPORT(whichqs, 4)
+IMPORT(want_resched, 8)
+IMPORT(Lev1map, 8)
+
+/*
+ * When no processes are on the runq, cpu_switch branches to idle
+ * to wait for something to come ready.
+ * Note: this is really a part of cpu_switch() but defined here for kernel
+ * profiling.
+ */
+LEAF(idle, 0)
+ br pv, Lidle1
+Lidle1: LDGP(pv)
+ stq zero, curproc /* curproc <- NULL for stats */
+ mov zero, a0 /* enable all interrupts */
+ call_pal PAL_OSF1_swpipl
+Lidle2:
+ ldl t0, whichqs /* look for non-empty queue */
+ beq t0, Lidle2
+ ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
+ call_pal PAL_OSF1_swpipl
+ jmp zero, sw1 /* jump back into the fray */
+ END(idle)
+
+/*
+ * cpu_switch()
+ * Find the highest priority process and resume it.
+ */
+LEAF(cpu_switch, 1)
+ LDGP(pv)
+ /* do an inline savectx(), to save old context */
+ ldq a1, P_ADDR(a0)
+ /* NOTE: ksp is stored by the swpctx */
+ stq s0, U_PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
+ stq s1, U_PCB_CONTEXT+(1 * 8)(a1)
+ stq s2, U_PCB_CONTEXT+(2 * 8)(a1)
+ stq s3, U_PCB_CONTEXT+(3 * 8)(a1)
+ stq s4, U_PCB_CONTEXT+(4 * 8)(a1)
+ stq s5, U_PCB_CONTEXT+(5 * 8)(a1)
+ stq s6, U_PCB_CONTEXT+(6 * 8)(a1)
+ stq ra, U_PCB_CONTEXT+(7 * 8)(a1) /* store ra */
+ call_pal PAL_OSF1_rdps /* NOTE: doesn't kill a0 */
+ stq v0, U_PCB_CONTEXT+(8 * 8)(a1) /* store ps, for ipl */
+
+ mov a0, s0 /* save old curproc */
+ mov a1, s1 /* save old U-area */
+
+ ldl t0, whichqs /* look for non-empty queue */
+ beq t0, idle /* and if none, go idle */
+
+ ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */
+ call_pal PAL_OSF1_swpipl
+sw1:
+ br pv, Lcs1
+Lcs1: LDGP(pv)
+ ldl t0, whichqs /* look for non-empty queue */
+ beq t0, idle /* and if none, go idle */
+ mov t0, t3 /* t3 = saved whichqs */
+ mov zero, t2 /* t2 = lowest bit set */
+ blbs t0, Lcs3 /* if low bit set, done! */
+
+Lcs2: srl t0, 1, t0 /* try next bit */
+ addq t2, 1, t2
+ blbc t0, Lcs2 /* if clear, try again */
+
+Lcs3:
+ /*
+ * Remove process from queue
+ */
+ lda t1, qs /* get queues */
+ sll t2, 4, t0 /* queue head is 16 bytes */
+ addq t1, t0, t0 /* t0 = qp = &qs[firstbit] */
+
+ ldq t4, PH_LINK(t0) /* t4 = p = highest pri proc */
+ ldq t5, P_FORW(t4) /* t5 = p->p_forw */
+ bne t4, Lcs4 /* make sure p != NULL */
+ PANIC("cpu_switch",Lcpu_switch_pmsg) /* nothing in queue! */
+
+Lcs4:
+ stq t5, PH_LINK(t0) /* qp->ph_link = p->p_forw */
+ stq t0, P_BACK(t5) /* p->p_forw->p_back = qp */
+ stq zero, P_BACK(t4) /* firewall: p->p_back = NULL */
+ cmpeq t0, t5, t0 /* see if queue is empty */
+ beq t0, Lcs5 /* nope, it's not! */
+
+ ldiq t0, 1 /* compute bit in whichqs */
+ sll t0, t2, t0
+ xor t3, t0, t3 /* clear bit in whichqs */
+ stl t3, whichqs
+
+Lcs5:
+ mov t4, s2 /* save new proc */
+ ldq s3, P_MD_PCBPADDR(s2) /* save new pcbpaddr */
+
+ /*
+ * Check to see if we're switching to ourself. If we are,
+ * don't bother loading the new context.
+ *
+ * Note that even if we re-enter cpu_switch() from idle(),
+ * s0 will still contain the old curproc value because any
+ * users of that register between then and now must have
+ * saved it. Also note that switch_exit() ensures that
+ * s0 is clear before jumping here to find a new process.
+ */
+ cmpeq s0, t4, t0 /* oldproc == newproc? */
+ bne t0, Lcs7 /* Yes! Skip! */
+
+ /*
+ * Deactivate the old address space before activating the
+ * new one. We need to do this before activating the
+ * new process's address space in the event that new
+ * process is using the same vmspace as the old. If we
+ * do this after we activate, then we might end up
+ * incorrectly marking the pmap inactive!
+ *
+ * We don't deactivate if we came here from switch_exit
+ * (old pmap no longer exists; vmspace has been freed).
+ * oldproc will be NULL in this case. We have actually
+ * taken care of calling pmap_deactivate() in cpu_exit(),
+ * before the vmspace went away.
+ */
+ beq s0, Lcs6
+
+ mov s0, a0 /* pmap_deactivate(oldproc) */
+ CALL(pmap_deactivate)
+
+Lcs6:
+ /*
+ * Activate the new process's address space and perform
+ * the actual context swap.
+ */
+
+ mov s2, a0 /* pmap_activate(p) */
+ CALL(pmap_activate)
+
+ mov s3, a0 /* swap the context */
+ SWITCH_CONTEXT
+
+Lcs7:
+
+ /*
+ * Now that the switch is done, update curproc and other
+ * globals. We must do this even if switching to ourselves
+ * because we might have re-entered cpu_switch() from idle(),
+ * in which case curproc would be NULL.
+ */
+ stq s2, curproc /* curproc = p */
+ stq zero, want_resched /* we've rescheduled */
+
+ /*
+ * Now running on the new u struct.
+ * Restore registers and return.
+ */
+ ldq t0, P_ADDR(s2)
+
+ /* NOTE: ksp is restored by the swpctx */
+ ldq s0, U_PCB_CONTEXT+(0 * 8)(t0) /* restore s0 - s6 */
+ ldq s1, U_PCB_CONTEXT+(1 * 8)(t0)
+ ldq s2, U_PCB_CONTEXT+(2 * 8)(t0)
+ ldq s3, U_PCB_CONTEXT+(3 * 8)(t0)
+ ldq s4, U_PCB_CONTEXT+(4 * 8)(t0)
+ ldq s5, U_PCB_CONTEXT+(5 * 8)(t0)
+ ldq s6, U_PCB_CONTEXT+(6 * 8)(t0)
+ ldq ra, U_PCB_CONTEXT+(7 * 8)(t0) /* restore ra */
+ ldq a0, U_PCB_CONTEXT+(8 * 8)(t0) /* restore ipl */
+ and a0, ALPHA_PSL_IPL_MASK, a0
+ call_pal PAL_OSF1_swpipl
+
+ ldiq v0, 1 /* possible ret to savectx() */
+ RET
+ END(cpu_switch)
+
+
+/*
+ * switch_trampoline()
+ *
+ * Arrange for a function to be invoked neatly, after a cpu_switch().
+ *
+ * Invokes the function specified by the s0 register with the return
+ * address specified by the s1 register and with one argument, a
+ * pointer to the executing process's proc structure.
+ */
+LEAF(switch_trampoline, 0)
+ mov s0, pv
+ mov s1, ra
+ mov s2, a0
+ jmp zero, (pv)
+ END(switch_trampoline)
+
+
+/**************************************************************************/
+
+/*
+ * exception_return: return from trap, exception, or syscall
+ */
+
+BSS(ssir, 8)
+IMPORT(astpending, 8)
+
+LEAF(exception_return, 1) /* XXX should be NESTED */
+ br pv, Ler1
+Ler1: LDGP(pv)
+
+ ldq s1, (FRAME_PS * 8)(sp) /* get the saved PS */
+ and s1, ALPHA_PSL_IPL_MASK, t0 /* look at the saved IPL */
+ bne t0, Lrestoreregs /* != 0: can't do AST or SIR */
+
+ /* see if we can do an SIR */
+ ldq t1, ssir /* SIR pending? */
+ beq t1, Lchkast /* no, try an AST*/
+
+ /* We've got a SIR. */
+ CALL(do_sir) /* do the SIR; lowers IPL */
+
+Lchkast:
+ ldiq a0, ALPHA_PSL_IPL_0 /* drop IPL to zero*/
+ call_pal PAL_OSF1_swpipl
+
+ and s1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */
+ beq t0, Lrestoreregs /* no: just return */
+
+ ldq t2, astpending /* AST pending? */
+ beq t2, Lsetfpenable /* no: return & deal with FP */
+
+ /* We've got an AST. Handle it. */
+ mov sp, a0 /* only arg is frame */
+ CALL(ast)
+
+Lsetfpenable:
+ /* enable FPU based on whether the current proc is fpcurproc */
+ ldq t0, curproc
+ ldq t1, fpcurproc
+ cmpeq t0, t1, t0
+ mov zero, a0
+ cmovne t0, 1, a0
+ call_pal PAL_OSF1_wrfen
+
+Lrestoreregs:
+ /* restore the registers, and return */
+ bsr ra, exception_restore_regs /* jmp/CALL trashes pv/t12 */
+ ldq ra,(FRAME_RA*8)(sp)
+ .set noat
+ ldq at_reg,(FRAME_AT*8)(sp)
+
+ lda sp,(FRAME_SW_SIZE*8)(sp)
+ call_pal PAL_OSF1_rti
+ .set at
+ END(exception_return)
+
+LEAF(exception_save_regs, 0)
+ stq v0,(FRAME_V0*8)(sp)
+ stq a3,(FRAME_A3*8)(sp)
+ stq a4,(FRAME_A4*8)(sp)
+ stq a5,(FRAME_A5*8)(sp)
+ stq s0,(FRAME_S0*8)(sp)
+ stq s1,(FRAME_S1*8)(sp)
+ stq s2,(FRAME_S2*8)(sp)
+ stq s3,(FRAME_S3*8)(sp)
+ stq s4,(FRAME_S4*8)(sp)
+ stq s5,(FRAME_S5*8)(sp)
+ stq s6,(FRAME_S6*8)(sp)
+ stq t0,(FRAME_T0*8)(sp)
+ stq t1,(FRAME_T1*8)(sp)
+ stq t2,(FRAME_T2*8)(sp)
+ stq t3,(FRAME_T3*8)(sp)
+ stq t4,(FRAME_T4*8)(sp)
+ stq t5,(FRAME_T5*8)(sp)
+ stq t6,(FRAME_T6*8)(sp)
+ stq t7,(FRAME_T7*8)(sp)
+ stq t8,(FRAME_T8*8)(sp)
+ stq t9,(FRAME_T9*8)(sp)
+ stq t10,(FRAME_T10*8)(sp)
+ stq t11,(FRAME_T11*8)(sp)
+ stq t12,(FRAME_T12*8)(sp)
+ RET
+ END(exception_save_regs)
+
+LEAF(exception_restore_regs, 0)
+ ldq v0,(FRAME_V0*8)(sp)
+ ldq a3,(FRAME_A3*8)(sp)
+ ldq a4,(FRAME_A4*8)(sp)
+ ldq a5,(FRAME_A5*8)(sp)
+ ldq s0,(FRAME_S0*8)(sp)
+ ldq s1,(FRAME_S1*8)(sp)
+ ldq s2,(FRAME_S2*8)(sp)
+ ldq s3,(FRAME_S3*8)(sp)
+ ldq s4,(FRAME_S4*8)(sp)
+ ldq s5,(FRAME_S5*8)(sp)
+ ldq s6,(FRAME_S6*8)(sp)
+ ldq t0,(FRAME_T0*8)(sp)
+ ldq t1,(FRAME_T1*8)(sp)
+ ldq t2,(FRAME_T2*8)(sp)
+ ldq t3,(FRAME_T3*8)(sp)
+ ldq t4,(FRAME_T4*8)(sp)
+ ldq t5,(FRAME_T5*8)(sp)
+ ldq t6,(FRAME_T6*8)(sp)
+ ldq t7,(FRAME_T7*8)(sp)
+ ldq t8,(FRAME_T8*8)(sp)
+ ldq t9,(FRAME_T9*8)(sp)
+ ldq t10,(FRAME_T10*8)(sp)
+ ldq t11,(FRAME_T11*8)(sp)
+ ldq t12,(FRAME_T12*8)(sp)
+ RET
+ END(exception_restore_regs)
diff --git a/sys/alpha/alpha/symbols.raw b/sys/alpha/alpha/symbols.raw
new file mode 100644
index 000000000000..bf8881a0ac66
--- /dev/null
+++ b/sys/alpha/alpha/symbols.raw
@@ -0,0 +1,81 @@
+# @(#)symbols.raw 7.6 (Berkeley) 5/8/91
+#
+# $Id: symbols.raw,v 1.12 1998/03/30 09:48:20 phk Exp $
+#
+
+
+#gdb
+ _IdlePTD
+ _PTD
+ _panicstr
+ _atdevbase
+# _version
+#dmesg
+ _msgbufp
+# _msgbuf
+#iostat
+ _dk_busy
+ _dk_time
+ _dk_xfer
+ _dk_wds
+ _tk_nin
+ _tk_nout
+ _dk_seek
+ _cp_time
+ _dk_wpms
+# _io_info
+#ps
+ _nswap
+ _maxslp
+ _ccpu
+ _fscale
+ _avail_start
+ _avail_end
+#pstat
+# _cons
+ _nswap
+ _swaplist
+#vmstat
+ _cp_time
+# _rate
+# _total
+# _sum
+# _rectime
+# _pgintime
+ _dk_xfer
+ _boottime
+#w
+ _swapdev
+ _nswap
+ _averunnable
+ _boottime
+#netstat
+ _mbstat
+ _ipstat
+ _tcb
+ _tcpstat
+ _udb
+ _udpstat
+# _rawcb
+ _ifnet
+# _rthost
+# _rtnet
+ _icmpstat
+ _filehead
+ _nfiles
+# _rthashsize
+# _radix_node_head
+#routed
+ _ifnet
+#rwho
+ _boottime
+#savecore
+ _dumpdev
+ _dumplo
+ _time_second
+ _version
+ _dumpsize
+ _panicstr
+ _dumpmag
+#deprecated
+# _avenrun
diff --git a/sys/alpha/alpha/sys_machdep.c b/sys/alpha/alpha/sys_machdep.c
new file mode 100644
index 000000000000..e0c55dd9df72
--- /dev/null
+++ b/sys/alpha/alpha/sys_machdep.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
+ * $Id: sys_machdep.c,v 1.34 1998/03/23 19:52:34 jlemon Exp $
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/sysent.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <sys/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <sys/user.h>
+
+#include <machine/cpu.h>
+
+#include <vm/vm_kern.h> /* for kernel_map */
+
+#ifndef _SYS_SYSPROTO_H_
+struct sysarch_args {
+ int op;
+ char *parms;
+};
+#endif
+
+int
+sysarch(p, uap)
+ struct proc *p;
+ register struct sysarch_args *uap;
+{
+ int error = 0;
+
+ switch(SCARG(uap,op)) {
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c
new file mode 100644
index 000000000000..e68aef1d3ae4
--- /dev/null
+++ b/sys/alpha/alpha/trap.c
@@ -0,0 +1,1010 @@
+/* $Id */
+/* $NetBSD: trap.c,v 1.31 1998/03/26 02:21:46 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/* #include "opt_fix_unaligned_vax_fp.h" */
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/vmmeter.h>
+#include <sys/buf.h>
+#include <sys/sysent.h>
+#include <sys/syscall.h>
+#include <sys/pioctl.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_prot.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_param.h>
+#include <sys/user.h>
+#include <sys/ptrace.h>
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#include <machine/reg.h>
+#include <machine/pal.h>
+
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
+struct proc *fpcurproc; /* current user of the FPU */
+
+void userret __P((struct proc *, u_int64_t, u_quad_t));
+
+unsigned long Sfloat_to_reg __P((unsigned int));
+unsigned int reg_to_Sfloat __P((unsigned long));
+unsigned long Tfloat_reg_cvt __P((unsigned long));
+#ifdef FIX_UNALIGNED_VAX_FP
+unsigned long Ffloat_to_reg __P((unsigned int));
+unsigned int reg_to_Ffloat __P((unsigned long));
+unsigned long Gfloat_reg_cvt __P((unsigned long));
+#endif
+
+int unaligned_fixup __P((unsigned long, unsigned long,
+ unsigned long, struct proc *));
+
+static void printtrap __P((const unsigned long, const unsigned long,
+ const unsigned long, const unsigned long, struct trapframe *, int, int));
+/*
+ * Define the code needed before returning to user mode, for
+ * trap and syscall.
+ */
+void
+userret(p, pc, oticks)
+ register struct proc *p;
+ u_int64_t pc;
+ u_quad_t oticks;
+{
+ int sig, s;
+
+ /* take pending signals */
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, a clock interrupt could
+ * change our priority without changing run queues
+ * (the running process is not kept on a run queue).
+ * If this happened after we setrunqueue ourselves but
+ * before we switch()'ed, we might not be on the queue
+ * indicated by our priority.
+ */
+ s = splstatclock();
+ setrunqueue(p);
+ p->p_stats->p_ru.ru_nivcsw++;
+ mi_switch();
+ splx(s);
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+
+ /*
+ * If profiling, charge recent system time to the trapped pc.
+ */
+ if (p->p_flag & P_PROFIL) {
+ addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio);
+ }
+
+ curpriority = p->p_priority;
+}
+
+static void
+printtrap(a0, a1, a2, entry, framep, isfatal, user)
+ const unsigned long a0, a1, a2, entry;
+ struct trapframe *framep;
+ int isfatal, user;
+{
+ char ubuf[64];
+ const char *entryname;
+
+ switch (entry) {
+ case ALPHA_KENTRY_INT:
+ entryname = "interrupt";
+ break;
+ case ALPHA_KENTRY_ARITH:
+ entryname = "arithmetic trap";
+ break;
+ case ALPHA_KENTRY_MM:
+ entryname = "memory management fault";
+ break;
+ case ALPHA_KENTRY_IF:
+ entryname = "instruction fault";
+ break;
+ case ALPHA_KENTRY_UNA:
+ entryname = "unaligned access fault";
+ break;
+ case ALPHA_KENTRY_SYS:
+ entryname = "system call";
+ break;
+ default:
+ sprintf(ubuf, "type %lx", entry);
+ entryname = (const char *) ubuf;
+ break;
+ }
+
+ printf("\n");
+ printf("%s %s trap:\n", isfatal? "fatal" : "handled",
+ user ? "user" : "kernel");
+ printf("\n");
+ printf(" trap entry = 0x%lx (%s)\n", entry, entryname);
+ printf(" a0 = 0x%lx\n", a0);
+ printf(" a1 = 0x%lx\n", a1);
+ printf(" a2 = 0x%lx\n", a2);
+ printf(" pc = 0x%lx\n", framep->tf_regs[FRAME_PC]);
+ printf(" ra = 0x%lx\n", framep->tf_regs[FRAME_RA]);
+ printf(" curproc = %p\n", curproc);
+ if (curproc != NULL)
+ printf(" pid = %d, comm = %s\n", curproc->p_pid,
+ curproc->p_comm);
+ printf("\n");
+}
+
+/*
+ * Trap is called from locore to handle most types of processor traps.
+ * System calls are broken out for efficiency and ASTs are broken out
+ * to make the code a bit cleaner and more representative of the
+ * Alpha architecture.
+ */
+/*ARGSUSED*/
+void
+trap(a0, a1, a2, entry, framep)
+ const unsigned long a0, a1, a2, entry;
+ struct trapframe *framep;
+{
+ register struct proc *p;
+ register int i;
+ u_int64_t ucode;
+ u_quad_t sticks;
+ int user;
+
+ cnt.v_trap++;
+ p = curproc;
+ ucode = 0;
+ user = (framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0;
+ if (user) {
+ sticks = p->p_sticks;
+ p->p_md.md_tf = framep;
+#if 0
+/* This is to catch some wierd stuff on the UDB (mj) */
+ if (framep->tf_regs[FRAME_PC] > 0 &&
+ framep->tf_regs[FRAME_PC] < 0x120000000) {
+ printf("PC Out of Whack\n");
+ printtrap(a0, a1, a2, entry, framep, 1, user);
+ }
+#endif
+ } else {
+ sticks = 0; /* XXX bogus -Wuninitialized warning */
+ }
+
+ switch (entry) {
+ case ALPHA_KENTRY_UNA:
+ /*
+ * If user-land, do whatever fixups, printing, and
+ * signalling is appropriate (based on system-wide
+ * and per-process unaligned-access-handling flags).
+ */
+ if (user) {
+ if ((i = unaligned_fixup(a0, a1, a2, p)) == 0)
+ goto out;
+
+ ucode = a0; /* VA */
+ break;
+ }
+
+ /*
+ * Unaligned access from kernel mode is always an error,
+ * EVEN IF A COPY FAULT HANDLER IS SET!
+ *
+ * It's an error if a copy fault handler is set because
+ * the various routines which do user-initiated copies
+ * do so in a bcopy-like manner. In other words, the
+ * kernel never assumes that pointers provided by the
+ * user are properly aligned, and so if the kernel
+ * does cause an unaligned access it's a kernel bug.
+ */
+ goto dopanic;
+
+ case ALPHA_KENTRY_ARITH:
+ /*
+ * If user-land, just give a SIGFPE. Should do
+ * software completion and IEEE handling, if the
+ * user has requested that.
+ */
+ if (user) {
+ i = SIGFPE;
+ ucode = a0; /* exception summary */
+ break;
+ }
+
+ /* Always fatal in kernel. Should never happen. */
+ goto dopanic;
+
+ case ALPHA_KENTRY_IF:
+ /*
+ * These are always fatal in kernel, and should never
+ * happen.
+ */
+ if (!user) {
+#ifdef DDB
+ /*
+ * ...unless, of course, DDB is configured; BUGCHK
+ * is used to invoke the kernel debugger, and we
+ * might have set a breakpoint.
+ */
+ if (a0 == ALPHA_IF_CODE_BUGCHK ||
+ a0 == ALPHA_IF_CODE_BPT) {
+ if (ddb_trap(a0, a1, a2, entry, framep))
+ goto out;
+ }
+
+ /*
+ * If we get here, DDB did _not_ handle the
+ * trap, and we need to PANIC!
+ */
+#endif
+ goto dopanic;
+ }
+ i = 0;
+ switch (a0) {
+ case ALPHA_IF_CODE_GENTRAP:
+ if (framep->tf_regs[FRAME_A0] == -2) { /* weird! */
+ i = SIGFPE;
+ ucode = a0; /* exception summary */
+ break;
+ }
+ /* FALLTHROUTH */
+ case ALPHA_IF_CODE_BPT:
+ case ALPHA_IF_CODE_BUGCHK:
+ ucode = a0; /* trap type */
+ i = SIGTRAP;
+ break;
+
+ case ALPHA_IF_CODE_OPDEC:
+ ucode = a0; /* trap type */
+ i = SIGILL;
+ break;
+
+ case ALPHA_IF_CODE_FEN:
+ /*
+ * on exit from the kernel, if proc == fpcurproc,
+ * FP is enabled.
+ */
+ if (fpcurproc == p) {
+ printf("trap: fp disabled for fpcurproc == %p",
+ p);
+ goto dopanic;
+ }
+
+ alpha_pal_wrfen(1);
+ if (fpcurproc)
+ savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ fpcurproc = p;
+ restorefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+
+ p->p_md.md_flags |= MDP_FPUSED;
+ goto out;
+
+ default:
+ printf("trap: unknown IF type 0x%lx\n", a0);
+ goto dopanic;
+ }
+ break;
+
+ case ALPHA_KENTRY_MM:
+ switch (a1) {
+ case ALPHA_MMCSR_FOR:
+ case ALPHA_MMCSR_FOE:
+ pmap_emulate_reference(p, a0, user, 0);
+ goto out;
+
+ case ALPHA_MMCSR_FOW:
+ pmap_emulate_reference(p, a0, user, 1);
+ goto out;
+
+ case ALPHA_MMCSR_INVALTRANS:
+ case ALPHA_MMCSR_ACCESS:
+ {
+ register vm_offset_t va;
+ register struct vmspace *vm = NULL;
+ register vm_map_t map;
+ vm_prot_t ftype = 0;
+ int rv;
+
+ /*
+ * If it was caused by fuswintr or suswintr,
+ * just punt. Note that we check the faulting
+ * address against the address accessed by
+ * [fs]uswintr, in case another fault happens
+ * when they are running.
+ */
+ if (!user &&
+ p != NULL &&
+ p->p_addr->u_pcb.pcb_onfault ==
+ (unsigned long)fswintrberr &&
+ p->p_addr->u_pcb.pcb_accessaddr == a0) {
+ framep->tf_regs[FRAME_PC] =
+ p->p_addr->u_pcb.pcb_onfault;
+ p->p_addr->u_pcb.pcb_onfault = 0;
+ goto out;
+ }
+
+ /*
+ * It is only a kernel address space fault iff:
+ * 1. !user and
+ * 2. pcb_onfault not set or
+ * 3. pcb_onfault set but kernel space data fault
+ * The last can occur during an exec() copyin where the
+ * argument space is lazy-allocated.
+ */
+ if (!user && (a0 >= VM_MIN_KERNEL_ADDRESS ||
+ p == NULL || p->p_addr->u_pcb.pcb_onfault == 0))
+ map = kernel_map;
+ else {
+ vm = p->p_vmspace;
+ map = &vm->vm_map;
+ }
+
+ switch (a2) {
+ case -1: /* instruction fetch fault */
+ case 0: /* load instruction */
+ ftype = VM_PROT_READ;
+ break;
+ case 1: /* store instruction */
+ ftype = VM_PROT_WRITE;
+ break;
+#ifdef DIAGNOSTIC
+ default: /* XXX gcc -Wuninitialized */
+ goto dopanic;
+#endif
+ }
+
+ va = trunc_page((vm_offset_t)a0);
+ rv = vm_fault(map, va, ftype, FALSE);
+ /*
+ * If this was a stack access we keep track of the
+ * maximum accessed stack size. Also, if vm_fault
+ * gets a protection failure it is due to accessing
+ * the stack region outside the current limit and
+ * we need to reflect that as an access error.
+ */
+ if (map != kernel_map &&
+ (caddr_t)va >= vm->vm_maxsaddr) {
+ if (rv == KERN_SUCCESS) {
+ unsigned nss;
+
+ nss = alpha_btop(round_page(USRSTACK - va));
+ if (nss > vm->vm_ssize)
+ vm->vm_ssize = nss;
+ } else if (rv == KERN_PROTECTION_FAILURE)
+ rv = KERN_INVALID_ADDRESS;
+ }
+ if (rv == KERN_SUCCESS) {
+ goto out;
+ }
+
+ if (!user) {
+ /* Check for copyin/copyout fault */
+ if (p != NULL &&
+ p->p_addr->u_pcb.pcb_onfault != 0) {
+ framep->tf_regs[FRAME_PC] =
+ p->p_addr->u_pcb.pcb_onfault;
+ p->p_addr->u_pcb.pcb_onfault = 0;
+ goto out;
+ }
+ goto dopanic;
+ }
+ ucode = a0;
+ i = SIGSEGV;
+#ifdef DEBUG
+ printtrap(a0, a1, a2, entry, framep, 1, user);
+#endif
+ break;
+ }
+
+ default:
+ printf("trap: unknown MMCSR value 0x%lx\n", a1);
+ goto dopanic;
+ }
+ break;
+
+ default:
+ goto dopanic;
+ }
+
+#ifdef DEBUG
+ printtrap(a0, a1, a2, entry, framep, 1, user);
+#endif
+ trapsignal(p, i, ucode);
+out:
+ if (user)
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
+ return;
+
+dopanic:
+ printtrap(a0, a1, a2, entry, framep, 1, user);
+
+ /* XXX dump registers */
+
+#ifdef DDB
+ /* XXX
+ * Really would like to be able to indicate that the
+ * kernel should _not_ panic, here. However, two problems
+ * exist:
+ *
+ * (a) There is not currently a way for DDB to distinguish
+ * between "continue and panic" and "continue, and
+ * don't panic".
+ *
+ * (b) panic() will again invoke the debugger, so calling
+ * it here is silly.
+ *
+ * For now, we just do nothing.
+ */
+#endif
+
+ panic("trap");
+}
+
+/*
+ * Process a system call.
+ *
+ * System calls are strange beasts. They are passed the syscall number
+ * in v0, and the arguments in the registers (as normal). They return
+ * an error flag in a3 (if a3 != 0 on return, the syscall had an error),
+ * and the return value (if any) in v0.
+ *
+ * The assembly stub takes care of moving the call number into a register
+ * we can get to, and moves all of the argument registers into their places
+ * in the trap frame. On return, it restores the callee-saved registers,
+ * a3, and v0 from the frame before returning to the user process.
+ */
+void
+syscall(code, framep)
+ u_int64_t code;
+ struct trapframe *framep;
+{
+ struct sysent *callp;
+ struct proc *p;
+ int error = 0, numsys;
+ u_int64_t opc;
+ u_quad_t sticks;
+ u_int64_t args[10]; /* XXX */
+ u_int hidden = 0, nargs;
+
+#if notdef /* can't happen, ever. */
+ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0) {
+ panic("syscall");
+#endif
+ cnt.v_syscall++;
+ p = curproc;
+ p->p_md.md_tf = framep;
+ opc = framep->tf_regs[FRAME_PC] - 4;
+ sticks = p->p_sticks;
+
+ if (p->p_sysent->sv_prepsyscall) {
+ /* (*p->p_sysent->sv_prepsyscall)(framep, args, &code, &params); */
+ panic("prepsyscall");
+ } else {
+ /*
+ * syscall() and __syscall() are handled the same on
+ * the alpha, as everything is 64-bit aligned, anyway.
+ */
+ if (code == SYS_syscall || code == SYS___syscall) {
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = framep->tf_regs[FRAME_A0];
+ hidden = 1;
+ }
+ }
+
+ if (p->p_sysent->sv_mask)
+ code &= p->p_sysent->sv_mask;
+
+ if (code >= p->p_sysent->sv_size)
+ callp = &p->p_sysent->sv_table[0];
+ else
+ callp = &p->p_sysent->sv_table[code];
+
+ nargs = callp->sy_narg + hidden;
+ switch (nargs) {
+ default:
+ if (nargs > 10) /* XXX */
+ panic("syscall: too many args (%d)", nargs);
+ error = copyin((caddr_t)(alpha_pal_rdusp()), &args[6],
+ (nargs - 6) * sizeof(u_int64_t));
+ case 6:
+ args[5] = framep->tf_regs[FRAME_A5];
+ case 5:
+ args[4] = framep->tf_regs[FRAME_A4];
+ case 4:
+ args[3] = framep->tf_regs[FRAME_A3];
+ case 3:
+ args[2] = framep->tf_regs[FRAME_A2];
+ case 2:
+ args[1] = framep->tf_regs[FRAME_A1];
+ case 1:
+ args[0] = framep->tf_regs[FRAME_A0];
+ case 0:
+ break;
+ }
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p->p_tracep, code, callp->sy_narg, args + hidden);
+#endif
+ if (error == 0) {
+ p->p_retval[0] = 0;
+ p->p_retval[1] = 0;
+
+ STOPEVENT(p, S_SCE, callp->sy_narg);
+
+ error = (*callp->sy_call)(p, args + hidden);
+ }
+
+
+ switch (error) {
+ case 0:
+ framep->tf_regs[FRAME_V0] = p->p_retval[0];
+ framep->tf_regs[FRAME_A4] = p->p_retval[1];
+ framep->tf_regs[FRAME_A3] = 0;
+ break;
+ case ERESTART:
+ framep->tf_regs[FRAME_PC] = opc;
+ break;
+ case EJUSTRETURN:
+ break;
+ default:
+ if (p->p_sysent->sv_errsize)
+ if (error >= p->p_sysent->sv_errsize)
+ error = -1; /* XXX */
+ else
+ error = p->p_sysent->sv_errtbl[error];
+ framep->tf_regs[FRAME_V0] = error;
+ framep->tf_regs[FRAME_A3] = 1;
+ break;
+ }
+
+ /*
+ * Reinitialize proc pointer `p' as it may be different
+ * if this is a child returning from fork syscall.
+ */
+ p = curproc;
+
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, code, error, rval[0]);
+#endif
+
+ /*
+ * This works because errno is findable through the
+ * register set. If we ever support an emulation where this
+ * is not the case, this code will need to be revisited.
+ */
+ STOPEVENT(p, S_SCX, code);
+}
+
+/*
+ * Process the tail end of a fork() for the child.
+ */
+void
+child_return(p)
+ struct proc *p;
+{
+
+ /*
+ * Return values in the frame set by cpu_fork().
+ */
+
+ userret(p, p->p_md.md_tf->tf_regs[FRAME_PC], 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, SYS_fork, 0, 0);
+#endif
+}
+
+/*
+ * Process an asynchronous software trap.
+ * This is relatively easy.
+ */
+void
+ast(framep)
+ struct trapframe *framep;
+{
+ register struct proc *p;
+ u_quad_t sticks;
+
+ p = curproc;
+ sticks = p->p_sticks;
+ p->p_md.md_tf = framep;
+
+ if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0)
+ panic("ast and not user");
+
+ cnt.v_soft++;
+
+ astpending = 0;
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ addupc_task(p, p->p_stats->p_prof.pr_addr,
+ p->p_stats->p_prof.pr_ticks);
+ }
+
+ userret(p, framep->tf_regs[FRAME_PC], sticks);
+}
+
+/*
+ * Unaligned access handler. It's not clear that this can get much slower...
+ *
+ */
+const static int reg_to_framereg[32] = {
+ FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2,
+ FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6,
+ FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2,
+ FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6,
+ FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3,
+ FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9,
+ FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12,
+ FRAME_AT, FRAME_GP, FRAME_SP, -1,
+};
+
+#define irp(p, reg) \
+ ((reg_to_framereg[(reg)] == -1) ? NULL : \
+ &(p)->p_md.md_tf->tf_regs[reg_to_framereg[(reg)]])
+
+#define frp(p, reg) \
+ (&(p)->p_addr->u_pcb.pcb_fp.fpr_regs[(reg)])
+
+#define dump_fp_regs() \
+ if (p == fpcurproc) { \
+ alpha_pal_wrfen(1); \
+ savefpstate(&fpcurproc->p_addr->u_pcb.pcb_fp); \
+ alpha_pal_wrfen(0); \
+ fpcurproc = NULL; \
+ }
+
+#define unaligned_load(storage, ptrf, mod) \
+ if (copyin((caddr_t)va, &(storage), sizeof (storage)) == 0 && \
+ (regptr = ptrf(p, reg)) != NULL) \
+ signal = 0; \
+ else \
+ break; \
+ *regptr = mod (storage);
+
+#define unaligned_store(storage, ptrf, mod) \
+ if ((regptr = ptrf(p, reg)) == NULL) \
+ break; \
+ (storage) = mod (*regptr); \
+ if (copyout(&(storage), (caddr_t)va, sizeof (storage)) == 0) \
+ signal = 0; \
+ else \
+ break;
+
+#define unaligned_load_integer(storage) \
+ unaligned_load(storage, irp, )
+
+#define unaligned_store_integer(storage) \
+ unaligned_store(storage, irp, )
+
+#define unaligned_load_floating(storage, mod) \
+ dump_fp_regs(); \
+ unaligned_load(storage, frp, mod)
+
+#define unaligned_store_floating(storage, mod) \
+ dump_fp_regs(); \
+ unaligned_store(storage, frp, mod)
+
+unsigned long
+Sfloat_to_reg(s)
+ unsigned int s;
+{
+ unsigned long sign, expn, frac;
+ unsigned long result;
+
+ sign = (s & 0x80000000) >> 31;
+ expn = (s & 0x7f800000) >> 23;
+ frac = (s & 0x007fffff) >> 0;
+
+ /* map exponent part, as appropriate. */
+ if (expn == 0xff)
+ expn = 0x7ff;
+ else if ((expn & 0x80) != 0)
+ expn = (0x400 | (expn & ~0x80));
+ else if ((expn & 0x80) == 0 && expn != 0)
+ expn = (0x380 | (expn & ~0x80));
+
+ result = (sign << 63) | (expn << 52) | (frac << 29);
+ return (result);
+}
+
+unsigned int
+reg_to_Sfloat(r)
+ unsigned long r;
+{
+ unsigned long sign, expn, frac;
+ unsigned int result;
+
+ sign = (r & 0x8000000000000000) >> 63;
+ expn = (r & 0x7ff0000000000000) >> 52;
+ frac = (r & 0x000fffffe0000000) >> 29;
+
+ /* map exponent part, as appropriate. */
+ expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
+
+ result = (sign << 31) | (expn << 23) | (frac << 0);
+ return (result);
+}
+
+/*
+ * Conversion of T floating datums to and from register format
+ * requires no bit reordering whatsoever.
+ */
+unsigned long
+Tfloat_reg_cvt(input)
+ unsigned long input;
+{
+
+ return (input);
+}
+
+#ifdef FIX_UNALIGNED_VAX_FP
+unsigned long
+Ffloat_to_reg(f)
+ unsigned int f;
+{
+ unsigned long sign, expn, frlo, frhi;
+ unsigned long result;
+
+ sign = (f & 0x00008000) >> 15;
+ expn = (f & 0x00007f80) >> 7;
+ frhi = (f & 0x0000007f) >> 0;
+ frlo = (f & 0xffff0000) >> 16;
+
+ /* map exponent part, as appropriate. */
+ if ((expn & 0x80) != 0)
+ expn = (0x400 | (expn & ~0x80));
+ else if ((expn & 0x80) == 0 && expn != 0)
+ expn = (0x380 | (expn & ~0x80));
+
+ result = (sign << 63) | (expn << 52) | (frhi << 45) | (frlo << 29);
+ return (result);
+}
+
+unsigned int
+reg_to_Ffloat(r)
+ unsigned long r;
+{
+ unsigned long sign, expn, frhi, frlo;
+ unsigned int result;
+
+ sign = (r & 0x8000000000000000) >> 63;
+ expn = (r & 0x7ff0000000000000) >> 52;
+ frhi = (r & 0x000fe00000000000) >> 45;
+ frlo = (r & 0x00001fffe0000000) >> 29;
+
+ /* map exponent part, as appropriate. */
+ expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00);
+
+ result = (sign << 15) | (expn << 7) | (frhi << 0) | (frlo << 16);
+ return (result);
+}
+
+/*
+ * Conversion of G floating datums to and from register format is
+ * symmetrical. Just swap shorts in the quad...
+ */
+unsigned long
+Gfloat_reg_cvt(input)
+ unsigned long input;
+{
+ unsigned long a, b, c, d;
+ unsigned long result;
+
+ a = (input & 0x000000000000ffff) >> 0;
+ b = (input & 0x00000000ffff0000) >> 16;
+ c = (input & 0x0000ffff00000000) >> 32;
+ d = (input & 0xffff000000000000) >> 48;
+
+ result = (a << 48) | (b << 32) | (c << 16) | (d << 0);
+ return (result);
+}
+#endif /* FIX_UNALIGNED_VAX_FP */
+
+extern int alpha_unaligned_print, alpha_unaligned_fix;
+extern int alpha_unaligned_sigbus;
+
+int
+unaligned_fixup(va, opcode, reg, p)
+ unsigned long va, opcode, reg;
+ struct proc *p;
+{
+ int doprint, dofix, dosigbus;
+ int signal, size;
+ const char *type;
+ unsigned long *regptr, longdata;
+ int intdata; /* signed to get extension when storing */
+ struct {
+ const char *type; /* opcode name */
+ int size; /* size, 0 if fixup not supported */
+ } tab[0x10] = {
+#ifdef FIX_UNALIGNED_VAX_FP
+ { "ldf", 4 }, { "ldg", 8 },
+#else
+ { "ldf", 0 }, { "ldg", 0 },
+#endif
+ { "lds", 4 }, { "ldt", 8 },
+#ifdef FIX_UNALIGNED_VAX_FP
+ { "stf", 4 }, { "stg", 8 },
+#else
+ { "stf", 0 }, { "stg", 0 },
+#endif
+ { "sts", 4 }, { "stt", 8 },
+ { "ldl", 4 }, { "ldq", 8 },
+ { "ldl_l", 0 }, { "ldq_l", 0 }, /* can't fix */
+ { "stl", 4 }, { "stq", 8 },
+ { "stl_c", 0 }, { "stq_c", 0 }, /* can't fix */
+ };
+
+ /*
+ * Figure out what actions to take.
+ *
+ * XXX In the future, this should have a per-process component
+ * as well.
+ */
+ doprint = alpha_unaligned_print;
+ dofix = alpha_unaligned_fix;
+ dosigbus = alpha_unaligned_sigbus;
+
+ /*
+ * Find out which opcode it is. Arrange to have the opcode
+ * printed if it's an unknown opcode.
+ */
+ if (opcode >= 0x20 && opcode <= 0x2f) {
+ type = tab[opcode - 0x20].type;
+ size = tab[opcode - 0x20].size;
+ } else {
+ type = "0x%lx";
+ size = 0;
+ }
+
+ /*
+ * See if the user can access the memory in question.
+ * Even if it's an unknown opcode, SEGV if the access
+ * should have failed.
+ */
+ if (!useracc((caddr_t)va, size ? size : 1, B_WRITE)) {
+ signal = SIGSEGV;
+ goto out;
+ }
+
+ /*
+ * If we're supposed to be noisy, squawk now.
+ */
+ if (doprint) {
+ uprintf(
+ "pid %d (%s): unaligned access: va=0x%lx pc=0x%lx ra=0x%lx op=",
+ p->p_pid, p->p_comm, va, p->p_md.md_tf->tf_regs[FRAME_PC],
+ p->p_md.md_tf->tf_regs[FRAME_RA]);
+ uprintf(type,opcode);
+ uprintf("\n");
+ }
+
+ /*
+ * If we should try to fix it and know how, give it a shot.
+ *
+ * We never allow bad data to be unknowingly used by the
+ * user process. That is, if we decide not to fix up an
+ * access we cause a SIGBUS rather than letting the user
+ * process go on without warning.
+ *
+ * If we're trying to do a fixup, we assume that things
+ * will be botched. If everything works out OK,
+ * unaligned_{load,store}_* clears the signal flag.
+ */
+ signal = SIGBUS;
+ if (dofix && size != 0) {
+ switch (opcode) {
+#ifdef FIX_UNALIGNED_VAX_FP
+ case 0x20: /* ldf */
+ unaligned_load_floating(intdata, Ffloat_to_reg);
+ break;
+
+ case 0x21: /* ldg */
+ unaligned_load_floating(longdata, Gfloat_reg_cvt);
+ break;
+#endif
+
+ case 0x22: /* lds */
+ unaligned_load_floating(intdata, Sfloat_to_reg);
+ break;
+
+ case 0x23: /* ldt */
+ unaligned_load_floating(longdata, Tfloat_reg_cvt);
+ break;
+
+#ifdef FIX_UNALIGNED_VAX_FP
+ case 0x24: /* stf */
+ unaligned_store_floating(intdata, reg_to_Ffloat);
+ break;
+
+ case 0x25: /* stg */
+ unaligned_store_floating(longdata, Gfloat_reg_cvt);
+ break;
+#endif
+
+ case 0x26: /* sts */
+ unaligned_store_floating(intdata, reg_to_Sfloat);
+ break;
+
+ case 0x27: /* stt */
+ unaligned_store_floating(longdata, Tfloat_reg_cvt);
+ break;
+
+ case 0x28: /* ldl */
+ unaligned_load_integer(intdata);
+ break;
+
+ case 0x29: /* ldq */
+ unaligned_load_integer(longdata);
+ break;
+
+ case 0x2c: /* stl */
+ unaligned_store_integer(intdata);
+ break;
+
+ case 0x2d: /* stq */
+ unaligned_store_integer(longdata);
+ break;
+
+#ifdef DIAGNOSTIC
+ default:
+ panic("unaligned_fixup: can't get here");
+#endif
+ }
+ }
+
+ /*
+ * Force SIGBUS if requested.
+ */
+ if (dosigbus)
+ signal = SIGBUS;
+
+out:
+ return (signal);
+}
diff --git a/sys/alpha/conf/GENERIC b/sys/alpha/conf/GENERIC
new file mode 100644
index 000000000000..55d674a5df8d
--- /dev/null
+++ b/sys/alpha/conf/GENERIC
@@ -0,0 +1,74 @@
+#
+# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
+#
+# For more information read the handbook part System Administration ->
+# Configuring the FreeBSD Kernel -> The Configuration File.
+# The handbook is available in /usr/share/doc/handbook or online as
+# latest version from the FreeBSD World Wide Web server
+# <URL:http://www.FreeBSD.ORG/>
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is present in the ./LINT configuration file. If you are
+# in doubt as to the purpose or necessity of a line, check first in LINT.
+#
+# $Id: GENERIC,v 1.107 1998/02/16 23:57:03 msmith Exp $
+
+machine "alpha"
+cpu "EV5"
+ident GENERIC
+maxusers 10
+
+options __FreeBSD__=3 #XXX hack city
+
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+options FFS #Berkeley Fast Filesystem
+options NFS #Network Filesystem
+options MSDOSFS #MSDOS Filesystem
+options "CD9660" #ISO 9660 Filesystem
+options "CD9660_ROOT" #CD-ROM usable as root device
+options FFS_ROOT #FFS usable as root device [keep this!]
+options NFS_ROOT #NFS usable as root device
+options PROCFS #Process filesystem
+options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device
+options UCONSOLE #Allow users to grab the console
+options FAILSAFE #Be conservative
+
+config kernel root on sd0
+
+controller scbus0
+
+device sd0
+
+device od0 #See LINT for possible `od' options.
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+# Order is important here due to intrusive probes, do *not* alphabetize
+# this list of network interfaces until the probes have been fixed.
+# Right now it appears that the ie0 must be probed before ep0. See
+# revision 1.20 of this file.
+#device de0
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device tun 1
+pseudo-device pty 16
+pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
+# This provides support for System V shared memory.
+#
+options SYSVSHM
+
+options DDB
+
diff --git a/sys/alpha/conf/Makefile.alpha b/sys/alpha/conf/Makefile.alpha
new file mode 100644
index 000000000000..ecc9daa7235d
--- /dev/null
+++ b/sys/alpha/conf/Makefile.alpha
@@ -0,0 +1,272 @@
+# Makefile.alpha -- with config changes.
+# Copyright 1990 W. Jolitz
+# from: @(#)Makefile.alpha 7.1 5/10/91
+# $Id: Makefile.alpha,v 1.109 1998/04/17 07:51:36 dima Exp $
+#
+# Makefile for FreeBSD
+#
+# This makefile is constructed from a machine description:
+# config machineid
+# Most changes should be made in the machine description
+# /sys/alpha/conf/``machineid''
+# after which you should do
+# config machineid
+# Generic makefile changes should be made in
+# /sys/alpha/conf/Makefile.alpha
+# after which config should be rerun for all machines.
+#
+
+# Which version of config(8) is required.
+%VERSREQ= 300003
+
+BINFORMAT?= elf
+
+STD8X16FONT?= iso
+
+.if exists(./@/.)
+S= ./@
+.else
+S= ../..
+.endif
+ALPHA= ${S}/alpha
+
+COPTFLAGS?=-O
+INCLUDES= -nostdinc -I- -I. -I$S
+# This hack is to allow kernel compiles to succeed on machines w/out srcdist
+.if exists($S/../include)
+INCLUDES+= -I$S/../include
+.else
+INCLUDES+= -I/usr/include
+.endif
+COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
+CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS} -mno-fp-regs
+LOAD_ADDRESS?= 0xfffffc0000230000
+DEFINED_PROF= ${PROF}
+.if defined(PROF)
+CFLAGS+= -malign-functions=4
+.if ${PROFLEVEL} >= 2
+IDENT+= -DGPROF4 -DGUPROF
+PROF+= -mprofiler-epilogue
+.endif
+.endif
+
+NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} $<
+NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+# XXX LOCORE means "don't declare C stuff" not "for locore.s".
+NORMAL_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
+DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
+DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+DRIVER_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
+PROFILE_C= ${CC} -c ${CFLAGS} ${PARAM} $<
+
+# ${ALPHA}/alpha/setdef0.c and ${ALPHA}/alpha/setdef1.c are intentionally
+# omitted from SYSTEM_CFILES. They depend on setdefs.h, a header which
+# is generated from all of ${OBJS}. We don't want to have to compile
+# everything just to do a make depend.
+SYSTEM_CFILES= ioconf.c param.c vnode_if.c config.c
+SYSTEM_SFILES= ${ALPHA}/alpha/locore.s
+SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
+.if ${CFLAGS:M-g} == ""
+SYMORDER_EXCLUDE=-x symbols.exclude
+.endif
+SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
+.if ${BINFORMAT} == elf
+SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} ioconf.o param.o config.o \
+ setdef1.o
+SYSTEM_LD= @${LD} -Bstatic -N -Ttext ${LOAD_ADDRESS} -e locorestart -defsym _DYNAMIC=0 \
+ -o $@ -X ${SYSTEM_OBJS} vers.o
+SYSTEM_LD_TAIL= @size $@; chmod 755 $@
+.endif
+
+%BEFORE_DEPEND
+
+%OBJS
+
+%CFILES
+
+%SFILES
+
+%LOAD
+
+%CLEAN
+
+clean:
+ rm -f *.o *.s eddep errs genassym gensetdefs kernel linterrs \
+ makelinks param.c setdefs.h symbols.exclude symbols.sort tags \
+ vers.c vnode_if.c vnode_if.h ${CLEAN}
+
+#lint: /tmp param.c
+# @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} \
+# ${ALPHA}/alpha/Locore.c ${CFILES} ioconf.c param.c | \
+# grep -v 'struct/union .* never defined' | \
+# grep -v 'possible pointer alignment problem'
+
+symbols.exclude: Makefile
+ echo "gcc2_compiled." >symbols.exclude
+ echo "___gnu_compiled_c" >>symbols.exclude
+
+symbols.sort: ${ALPHA}/alpha/symbols.raw
+ grep -v '^#' ${ALPHA}/alpha/symbols.raw \
+ | sed 's/^ //' | sort -u > symbols.sort
+
+locore.o: ${ALPHA}/alpha/locore.s assym.s
+ ${NORMAL_S}
+
+setdef0.o: ${ALPHA}/alpha/setdef0.c setdefs.h
+ ${NORMAL_C}
+
+setdef1.o: ${ALPHA}/alpha/setdef1.c setdefs.h
+ ${NORMAL_C}
+
+setdefs.h: gensetdefs ${OBJS}
+ @echo Generating kernel linker sets
+ @./gensetdefs ${OBJS} >setdefs.h
+
+gensetdefs: gensetdefs.o
+ ${CC} ${CFLAGS} gensetdefs.o -o $@
+
+gensetdefs.o: ${ALPHA}/alpha/gensetdefs.c
+ ${CC} -c ${CFLAGS} ${ALPHA}/alpha/gensetdefs.c
+
+# everything potentially depends on the Makefile since everything potentially
+# depends on the options. Some things are more dependent on the Makefile for
+# historical reasons.
+machdep.o: Makefile
+
+# the following is necessary because autoconf.o depends on #if GENERIC
+autoconf.o: Makefile
+
+# XXX - may no longer be needed
+locore.o: Makefile
+
+# depends on KDB (cons.o also depends on GENERIC)
+trap.o cons.o: Makefile
+
+# this rule stops ./assym.s in .depend from causing problems
+./assym.s: assym.s
+
+assym.s: genassym
+ ./genassym >assym.s
+
+# Some of the defines that genassym outputs may well depend on the
+# value of kernel options.
+genassym.o: ${ALPHA}/alpha/genassym.c Makefile opt_global.h
+ ${CC} -c ${CFLAGS} ${PARAM} -UKERNEL ${ALPHA}/alpha/genassym.c
+
+genassym: genassym.o
+ ${CC} ${CFLAGS} ${PARAM} genassym.o -o $@
+
+SYSTEM_OBJS+= __divqu.o __divq.o __divlu.o __divl.o
+SYSTEM_OBJS+= __remqu.o __remq.o __remlu.o __reml.o
+CLEAN+= __divqu.S __divq.S __divlu.S __divl.S
+CLEAN+= __remqu.S __remq.S __remlu.S __reml.S
+
+__divqu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divqu')define(OP,\`div')define(S,\`false')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divq.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divq')define(OP,\`div')define(S,\`true')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divlu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divlu')define(OP,\`div')define(S,\`false')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divl.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divl')define(OP,\`div')define(S,\`true')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remqu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remqu')define(OP,\`rem')define(S,\`false')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remq.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remq')define(OP,\`rem')define(S,\`true')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remlu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remlu')define(OP,\`rem')define(S,\`false')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__reml.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__reml')define(OP,\`rem')define(S,\`true')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+
+${OBJS}: opt_global.h
+
+# XXX this assumes that the options for NORMAL_C* and DRIVER_C* are identical.
+depend: assym.s param.c vnode_if.h ${BEFORE_DEPEND}
+ rm -f .newdep
+ mkdep -a -f .newdep ${COPTS} ${CFILES} ${SYSTEM_CFILES}
+ mkdep -a -f .newdep ${COPTS} ${PARAM} -UKERNEL ${ALPHA}/alpha/genassym.c
+ MKDEP_CPP="${CC} -E -x assembler-with-cpp" ; export MKDEP_CPP ; \
+ mkdep -a -f .newdep -DLOCORE ${COPTS} ${SFILES} ${SYSTEM_SFILES}
+ rm -f .depend
+ mv -f .newdep .depend
+
+cleandepend:
+ rm -f .depend
+
+links:
+ egrep '#if' ${CFILES:Nswapkernel.c} | sed -f $S/conf/defines | \
+ sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
+ echo ${CFILES:Nswapkernel.c} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
+ sort -u | comm -23 - dontlink | \
+ sed 's,../.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks
+ sh makelinks && rm -f dontlink
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+install:
+ @if [ ! -f kernel ] ; then \
+ echo "You must first build your kernel before trying to install." ; \
+ exit 1 ; \
+ fi
+.if exists(${DESTDIR}/kernel)
+ chflags noschg ${DESTDIR}/kernel
+ mv ${DESTDIR}/kernel ${DESTDIR}/kernel.old
+.endif
+ PATH=$${PATH}:/sbin:/usr/sbin; \
+ if [ `sysctl -n kern.bootfile` = ${DESTDIR}/kernel ] ; then \
+ sysctl -w kern.bootfile=${DESTDIR}/kernel.old ; \
+ if [ -f /var/db/kvm_kernel.db ] ; then \
+ mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
+ fi \
+ fi
+ install -c -m 555 -o root -g wheel -fschg kernel ${DESTDIR}/
+
+ioconf.o: ioconf.c $S/sys/param.h $S/sys/buf.h
+ ${CC} -c ${CFLAGS} ioconf.c
+
+param.c: $S/conf/param.c
+ -rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${CC} -c ${CFLAGS} ${PARAM} param.c
+
+vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh ${KERN_IDENT} ${IDENT}
+ ${CC} ${CFLAGS} -c vers.c
+
+vnode_if.c: $S/kern/vnode_if.sh $S/kern/vnode_if.src
+ sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src
+ sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+
+.include <bsd.kern.mk>
+
+%RULES
+
+# DO NOT DELETE THIS LINE -- make depend uses it
diff --git a/sys/alpha/conf/NOTES b/sys/alpha/conf/NOTES
new file mode 100644
index 000000000000..55d674a5df8d
--- /dev/null
+++ b/sys/alpha/conf/NOTES
@@ -0,0 +1,74 @@
+#
+# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
+#
+# For more information read the handbook part System Administration ->
+# Configuring the FreeBSD Kernel -> The Configuration File.
+# The handbook is available in /usr/share/doc/handbook or online as
+# latest version from the FreeBSD World Wide Web server
+# <URL:http://www.FreeBSD.ORG/>
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is present in the ./LINT configuration file. If you are
+# in doubt as to the purpose or necessity of a line, check first in LINT.
+#
+# $Id: GENERIC,v 1.107 1998/02/16 23:57:03 msmith Exp $
+
+machine "alpha"
+cpu "EV5"
+ident GENERIC
+maxusers 10
+
+options __FreeBSD__=3 #XXX hack city
+
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+options FFS #Berkeley Fast Filesystem
+options NFS #Network Filesystem
+options MSDOSFS #MSDOS Filesystem
+options "CD9660" #ISO 9660 Filesystem
+options "CD9660_ROOT" #CD-ROM usable as root device
+options FFS_ROOT #FFS usable as root device [keep this!]
+options NFS_ROOT #NFS usable as root device
+options PROCFS #Process filesystem
+options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device
+options UCONSOLE #Allow users to grab the console
+options FAILSAFE #Be conservative
+
+config kernel root on sd0
+
+controller scbus0
+
+device sd0
+
+device od0 #See LINT for possible `od' options.
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+# Order is important here due to intrusive probes, do *not* alphabetize
+# this list of network interfaces until the probes have been fixed.
+# Right now it appears that the ie0 must be probed before ep0. See
+# revision 1.20 of this file.
+#device de0
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device tun 1
+pseudo-device pty 16
+pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
+# This provides support for System V shared memory.
+#
+options SYSVSHM
+
+options DDB
+
diff --git a/sys/alpha/conf/SIMOS b/sys/alpha/conf/SIMOS
new file mode 100644
index 000000000000..052dfadb171a
--- /dev/null
+++ b/sys/alpha/conf/SIMOS
@@ -0,0 +1,84 @@
+#
+# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
+#
+# For more information read the handbook part System Administration ->
+# Configuring the FreeBSD Kernel -> The Configuration File.
+# The handbook is available in /usr/share/doc/handbook or online as
+# latest version from the FreeBSD World Wide Web server
+# <URL:http://www.FreeBSD.ORG/>
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is present in the ./LINT configuration file. If you are
+# in doubt as to the purpose or necessity of a line, check first in LINT.
+#
+# $Id: GENERIC,v 1.107 1998/02/16 23:57:03 msmith Exp $
+
+machine "alpha"
+cpu "EV5"
+ident GENERIC
+maxusers 10
+
+options __FreeBSD__=3 #XXX hack city
+
+options "DEC_KN8AE"
+options SIMOS
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+options FFS #Berkeley Fast Filesystem
+options NFS #Network Filesystem
+options MSDOSFS #MSDOS Filesystem
+options "CD9660" #ISO 9660 Filesystem
+options "CD9660_ROOT" #CD-ROM usable as root device
+options FFS_ROOT #FFS usable as root device [keep this!]
+options NFS_ROOT #NFS usable as root device
+options PROCFS #Process filesystem
+options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device
+options UCONSOLE #Allow users to grab the console
+options FAILSAFE #Be conservative
+
+config kernel root on sd0
+
+controller pci0
+controller tlsb0
+controller gbus0
+controller kft0
+controller dwlpx0
+
+controller simos0
+
+controller scbus0
+
+device sd0
+
+device od0 #See LINT for possible `od' options.
+
+device st0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+# Order is important here due to intrusive probes, do *not* alphabetize
+# this list of network interfaces until the probes have been fixed.
+# Right now it appears that the ie0 must be probed before ep0. See
+# revision 1.20 of this file.
+#device de0
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device tun 1
+pseudo-device pty 16
+pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
+# This provides support for System V shared memory.
+#
+options SYSVSHM
+
+options DDB
+
diff --git a/sys/alpha/conf/devices.alpha b/sys/alpha/conf/devices.alpha
new file mode 100644
index 000000000000..27278625b167
--- /dev/null
+++ b/sys/alpha/conf/devices.alpha
@@ -0,0 +1,18 @@
+# This file tells what major numbers the various possible swap devices have.
+#
+# $Id: devices.i386,v 1.13 1998/02/17 11:33:31 sos Exp $
+#
+wd 0
+wfd 1
+fd 2
+wt 3
+sd 4
+st 5
+cd 6
+mcd 7
+vn 15
+scd 16
+pcd 17
+wcd 19
+od 20
+wst 24
diff --git a/sys/alpha/conf/files.alpha b/sys/alpha/conf/files.alpha
new file mode 100644
index 000000000000..04e5410ad8b4
--- /dev/null
+++ b/sys/alpha/conf/files.alpha
@@ -0,0 +1,80 @@
+# This file tells config what files go into building a kernel,
+# files marked standard are always included.
+#
+# $Id$
+#
+# The long compile-with and dependency lines are required because of
+# limitations in config: backslash-newline doesn't work in strings, and
+# dependency lines other than the first are silently ignored.
+#
+#
+font8x16.o optional std8x16font \
+ compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
+ no-implicit-rule before-depend \
+ clean "${STD8X16FONT}-8x16 font8x16.c"
+
+#
+alpha/alpha/autoconf.c standard device-driver
+alpha/alpha/cpuconf.c standard
+alpha/alpha/dec_kn8ae.c optional dec_kn8ae
+alpha/alpha/mountroot.c optional slice
+alpha/alpha/ipl_funcs.c standard
+alpha/alpha/pal.s standard
+alpha/alpha/cons.c standard
+alpha/alpha/prom.c standard
+alpha/alpha/prom_disp.s standard
+alpha/alpha/db_disasm.c optional ddb
+alpha/alpha/db_interface.c optional ddb
+alpha/alpha/db_trace.c optional ddb
+alpha/alpha/exception.s standard
+alpha/alpha/in_cksum.c optional inet
+# locore.s needs to be handled in Makefile to put it first. Otherwise it's
+# now normal.
+# alpha/alpha/locore.s standard
+alpha/alpha/machdep.c standard
+alpha/alpha/math_emulate.c optional math_emulate
+alpha/alpha/mem.c standard
+alpha/alpha/mp_machdep.c optional smp
+alpha/alpha/perfmon.c optional perfmon profiling-routine
+alpha/alpha/perfmon.c optional perfmon
+alpha/alpha/pmap.c standard
+alpha/alpha/procfs_machdep.c standard
+alpha/alpha/simplelock.s optional smp
+alpha/alpha/support.s standard
+alpha/alpha/swtch.s standard
+alpha/alpha/sys_machdep.c standard
+alpha/alpha/trap.c standard
+alpha/alpha/interrupt.c standard
+alpha/alpha/userconfig.c optional userconfig
+alpha/alpha/vm_machdep.c standard
+alpha/alpha/clock.c standard
+alpha/alpha/diskslice_machdep.c standard
+alpha/tlsb/tlsb.c optional tlsb
+alpha/tlsb/gbus.c optional gbus
+alpha/tlsb/kftxx.c optional kft
+alpha/tlsb/mcclock_tlsb.c optional gbus
+alpha/tlsb/zs_tlsb.c optional gbus
+alpha/tlsb/dwlpx.c optional dwlpx
+dev/dec/mcclock.c optional gbus
+alpha/pci/pcibus.c optional pci
+kern/subr_bus.c standard
+libkern/bcd.c standard
+libkern/bcmp.c standard
+libkern/ffs.c standard
+libkern/inet_ntoa.c standard
+libkern/index.c standard
+libkern/mcount.c optional profiling-routine
+libkern/qsort.c standard
+libkern/random.c standard
+libkern/scanc.c standard
+libkern/skpc.c standard
+libkern/strcat.c standard
+libkern/strcmp.c standard
+libkern/strcpy.c standard
+libkern/strlen.c standard
+libkern/strncmp.c standard
+libkern/strncpy.c standard
+libkern/alpha/htonl.S standard
+libkern/alpha/htons.S standard
+libkern/alpha/ntohl.S standard
+libkern/alpha/ntohs.S standard
diff --git a/sys/alpha/conf/majors.alpha b/sys/alpha/conf/majors.alpha
new file mode 100644
index 000000000000..a171d68c9293
--- /dev/null
+++ b/sys/alpha/conf/majors.alpha
@@ -0,0 +1,141 @@
+$Id: majors.i386,v 1.37 1998/04/17 20:26:43 julian Exp $
+
+Hopefully, this list will one day be obsoleted by DEVFS, but for now
+this is the current allocation of device major numbers.
+
+For local use, you are encouraged to use the reserved numbers.
+
+If you intend the driver to be available, send email to the
+hackers@freebsd.org mailing list to see about having a number
+reserved for you.
+
+The most "complete" version of this will be the one in FreeBSD-current.
+(see http://www.freebsd.org/ or from ftp://ftp.cdrom.com/pub/FreeBSD/)
+
+blkdev name comments
+0 wd ST506 disk controller (with IDE extensions)
+1 wfd ATAPI Floppy client of "ata"
+2 fd floppy disk
+3 wt QIC-02/36 tape
+4 sd SCSI "disk" type
+5 st SCSI "tape" type
+6 cd SCSI "cdrom" type
+7 mcd Mitsumi CDROM interface
+8 lkm assigned to Loadable Kernel modules
+9 lkm assigned to Loadable Kernel modules
+10 lkm assigned to Loadable Kernel modules
+11 lkm assigned to Loadable Kernel modules
+12 lkm assigned to Loadable Kernel modules
+13 lkm assigned to Loadable Kernel modules
+14 ?? reserved for local use
+15 vn vnode disk device
+16 scd Sony CDROM interface
+17 matcd Matsushita/Panasonic/Creative(SB) CDROM interface
+18 ata "device independent" ATA/IDE driver
+19 wcdb ATAPI CDROM client of "ata"
+20 od SCSI "magneto-optical" disk
+21 ccd concatenated disk
+22 gd Geometry disk.
+23 worm SCSI "worm type"
+24 wstb ATAPI tape client of "ata"
+25 vinum RAID fs
+26 sw VM internal swap device
+chrdev name comments
+0 cn console
+1 ctty /dev/tty
+2 mm /dev/mem,kmem,etc
+3 wd ST506 disk controller (with IDE extensions)
+4 swap /dev/drum
+5 pts pseudo tty "tty" half
+6 ptc pseudo tty "master" half
+7 log system log
+8 bqu B004 transputer board
+9 fd floppy disk
+10 wt QIC-02/36 tape
+11 spigot Video capture?
+12 sc syscons/pcvt virtual consoles
+13 sd SCSI "disk type"
+14 st SCSI "tape type"
+15 cd SCSI "CDROM type"
+16 lpt PC parallel printer port
+17 ch SCSI changer
+18 su SCSI universal type
+19 tw X-10 power interface
+20 ?? reserved for local use
+21 psm PS/2 Mouse
+22 fd (/dev/stdin etc)
+23 bpf Berkeley Packet Filter
+24 pca PC speaker (/dev/pcaudio)
+25 ?? was vat
+26 spkr PC speaker (/dev/spkr)
+27 mse Microsoft bus-mouse
+28 sio 16450/16550 serial
+29 mcd Mitsumi CDROM interface
+30 snd sound driver system
+31 uk SCSI "unknown device type"
+32 lkmc Loadable Kernel Module Controller
+33 lkm assigned to Loadable Kernel Modules
+34 lkm assigned to Loadable Kernel Modules
+35 lkm assigned to Loadable Kernel Modules
+36 lkm assigned to Loadable Kernel Modules
+37 lkm assigned to Loadable Kernel Modules
+38 lkm assigned to Loadable Kernel Modules
+39 apm Advanced Power Management
+40 ctx Cortex
+41 ?? was socksys
+42 cx Cronyx
+43 vn vnode "disk" device
+44 gp GPIB
+45 scd Sony CDROM interface
+46 matcd Matsushita/Panasonic/Creative(SB) CDROM interface
+47 gsc Genius Scanner
+48 cy Cyclades
+49 ssc SCSI super device
+50 card pcmcia cards
+51 joy joystick
+52 tun IP tunnel device
+53 snp tty snoop
+54 OLDnic ISDN system
+55 OLDisdn ISDN system
+56 OLDity ISDN system
+57 OLDitel ISDN system
+58 dgb Digiboard
+59 OLDispy ISDN system
+60 OLDnnic ISDN system
+61 pt SCSI "processor type"
+62 worm SCSI "worm type"
+63 rc Riscom/8 driver
+64 ?? Talisman
+65 sctarg SCSI target
+66 labpc National Instruments LabPC
+67 meteor Matrox Meteor video capture
+68 si Specialix SI/XIO (peter@freebsd.org)
+69 wcd ATAPI CDROM client of "ata"
+70 od SCSI "magneto-optical disk type"
+71 asc AmiScan driver
+72 stl Stallion (cd1400 based) (gerg@stallion.oz.au)
+73 ?? was qcam
+74 ccd concatenated disk
+75 stli Stallion (intelligent cdk based) (gerg@stallion.oz.au)
+76 scc IBM Smart Capture Card (ohashi@mickey.ai.kyutech.ac.jp)
+77 cyy Cyclades Ye/PCI serial card
+78 pci PCI bus
+79 ipl IP Filter
+80 xdcp Assigned to Chris Ficklin <chris@serengeti.com>
+81 rp RocketPort/Steve Gericke <steveg@comtrol.com>
+82 ppi Generic Parallel I/O <Nicolas.Souchu@prism.uvsq.fr>
+83 can CAN16-2 CAN-PC Interface
+84 ttxt Unitext teletext decoder (arg@arg1.demon.co.uk)
+85 vesa VESA support device (j_mini@efn.org)
+86 alog Industrial Computer Source AIO8-P driver
+87 wfd ATAPI floppy client of "ata"
+88 dpt DPT RAID Controller <shimon@i-connect.net>
+89 pps Pulse-Per-Second timing interface
+90 wst ATAPI tape client of "ata"
+91 vinum RAID fs
+92 bktr Bt848 video capture driver (hasty@star-gate.com)
+93 coda CODA filesystem.
+94 loran Loran-C Receiver
+95 gd Geometry disk
+96 altq alternate queueing (including cbq, red, wfq)
+97 zsc TurboLaser console uart
diff --git a/sys/alpha/conf/options.alpha b/sys/alpha/conf/options.alpha
new file mode 100644
index 000000000000..666e7f77eff6
--- /dev/null
+++ b/sys/alpha/conf/options.alpha
@@ -0,0 +1,18 @@
+# $Id$
+
+EV5 opt_global.h
+DEC_KN8AE opt_cpu.h
+
+ATAPI opt_atapi.h
+ATAPI_STATIC opt_atapi.h
+
+CMD640 opt_wd.h
+
+SHOW_BUSYBUFS
+PANIC_REBOOT_WAIT_TIME opt_panic.h
+
+AHC_TAGENABLE opt_aic7xxx.h
+AHC_SCBPAGING_ENABLE opt_aic7xxx.h
+AHC_ALLOW_MEMIO opt_aic7xxx.h
+AHC_SHARE_SCBS opt_aic7xxx.h
+
diff --git a/sys/alpha/include/alpha_cpu.h b/sys/alpha/include/alpha_cpu.h
index 267b12029532..9bd97f49a938 100644
--- a/sys/alpha/include/alpha_cpu.h
+++ b/sys/alpha/include/alpha_cpu.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: alpha_cpu.h,v 1.1 1998/01/10 10:13:13 jb Exp $ */
/* From: NetBSD: alpha_cpu.h,v 1.15 1997/09/20 19:02:34 mjacob Exp */
/*
@@ -183,8 +183,12 @@ struct alpha_logout_area {
* NOTE THAT THESE DEFINITIONS MAY CHANGE IN FUTURE ALPHA CPUS!
*/
-#define ALPHA_PGSHIFT 13
+#define ALPHA_PGSHIFT 13 /* bits that index within page */
+#define ALPHA_PTSHIFT 10 /* bits that index within page tables */
#define ALPHA_PGBYTES (1 << ALPHA_PGSHIFT)
+#define ALPHA_L3SHIFT ALPHA_PGSHIFT
+#define ALPHA_L2SHIFT (ALPHA_L3SHIFT+ALPHA_PTSHIFT)
+#define ALPHA_L1SHIFT (ALPHA_L2SHIFT+ALPHA_PTSHIFT)
#define ALPHA_USEG_BASE 0 /* virtual */
#define ALPHA_USEG_END 0x000003ffffffffff
@@ -218,8 +222,8 @@ struct alpha_logout_area {
#define ALPHA_PTE_PFN 0xffffffff00000000
-#define ALPHA_PTE_TO_PFN(pte) ((pte) >> 32)
-#define ALPHA_PTE_FROM_PFN(pfn) ((pfn) << 32)
+#define ALPHA_PTE_TO_PFN(pte) ((u_long)(pte) >> 32)
+#define ALPHA_PTE_FROM_PFN(pfn) ((u_long)(pfn) << 32)
typedef unsigned long alpha_pt_entry_t;
@@ -280,6 +284,7 @@ typedef unsigned long alpha_pt_entry_t;
#define ALPHA_IMPLVER_EV5 1 /* EV5/EV56/PCA56 */
#define ALPHA_IMPLVER_EV6 2 /* EV6 */
+
/*
* Stubs for Alpha instructions normally inaccessible from C.
*/
@@ -307,6 +312,7 @@ unsigned long alpha_pal_rdmces __P((void));
unsigned long alpha_pal_rdps __P((void));
unsigned long alpha_pal_rdusp __P((void));
unsigned long alpha_pal_rdval __P((void));
+unsigned long alpha_pal_swpctx __P((unsigned long));
unsigned long alpha_pal_swpipl __P((unsigned long));
unsigned long _alpha_pal_swpipl __P((unsigned long)); /* for profiling */
void alpha_pal_tbi __P((unsigned long, vm_offset_t));
diff --git a/sys/alpha/include/asm.h b/sys/alpha/include/asm.h
index e68927fb4a2d..f5044df62778 100644
--- a/sys/alpha/include/asm.h
+++ b/sys/alpha/include/asm.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: asm.h,v 1.1 1998/01/10 22:09:52 jb Exp $ */
/* From: NetBSD: asm.h,v 1.18 1997/11/03 04:22:06 ross Exp */
/*
@@ -474,7 +474,7 @@ _name_ = _value_
_name_:; \
.mask _i_mask_|IM_EXC,0; \
.frame sp,MSS_SIZE,ra;
-/* .livereg _i_mask_|IM_EXC,0
+/* .livereg _i_mask_|IM_EXC,0 */
/* should have been
.proc _name_,1; \
.frame MSS_SIZE,$31,_i_mask_,0; \
@@ -617,7 +617,7 @@ label: ASCIZ msg; \
* Kernel RCS ID tag and copyright macros
*/
-#ifdef _KERNEL
+#ifdef KERNEL
#ifdef __ELF__
#define __KERNEL_SECTIONSTRING(_sec, _str) \
diff --git a/sys/alpha/include/bootinfo.h b/sys/alpha/include/bootinfo.h
new file mode 100644
index 000000000000..36b394323d29
--- /dev/null
+++ b/sys/alpha/include/bootinfo.h
@@ -0,0 +1,21 @@
+/*
+ * Kernel-internal structure used to hold important bits of boot
+ * information. NOT to be used by boot blocks.
+ *
+ * Note that not all of the fields from the bootinfo struct(s)
+ * passed by the boot blocks aren't here (because they're not currently
+ * used by the kernel!). Fields here which aren't supplied by the
+ * bootinfo structure passed by the boot blocks are supposed to be
+ * filled in at startup with sane contents.
+ */
+struct bootinfo_kernel {
+ u_long ssym; /* start of syms */
+ u_long esym; /* end of syms */
+ u_long hwrpb_phys; /* hwrpb physical address */
+ u_long hwrpb_size; /* size of hwrpb data */
+ char boot_flags[64]; /* boot flags */
+ char booted_kernel[64]; /* name of booted kernel */
+ char booted_dev[64]; /* name of booted device */
+};
+
+extern struct bootinfo_kernel bootinfo;
diff --git a/sys/alpha/include/bus.h b/sys/alpha/include/bus.h
new file mode 100644
index 000000000000..dfb7cde2c2a5
--- /dev/null
+++ b/sys/alpha/include/bus.h
@@ -0,0 +1,620 @@
+/* $NetBSD: bus.h,v 1.22 1998/05/13 21:21:16 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 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.
+ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _ALPHA_BUS_H_
+#define _ALPHA_BUS_H_
+
+#ifndef __BUS_SPACE_COMPAT_OLDDEFS
+#define __BUS_SPACE_COMPAT_OLDDEFS
+#endif
+
+/*
+ * Addresses (in bus space).
+ */
+typedef u_long bus_addr_t;
+typedef u_long bus_size_t;
+
+/*
+ * Access methods for bus space.
+ */
+typedef struct alpha_bus_space *bus_space_tag_t;
+typedef u_long bus_space_handle_t;
+
+struct alpha_bus_space {
+ /* cookie */
+ void *abs_cookie;
+
+ /* mapping/unmapping */
+ int (*abs_map) __P((void *, bus_addr_t, bus_size_t,
+ int, bus_space_handle_t *));
+ void (*abs_unmap) __P((void *, bus_space_handle_t,
+ bus_size_t));
+ int (*abs_subregion) __P((void *, bus_space_handle_t,
+ bus_size_t, bus_size_t, bus_space_handle_t *));
+
+ /* allocation/deallocation */
+ int (*abs_alloc) __P((void *, bus_addr_t, bus_addr_t,
+ bus_size_t, bus_size_t, bus_size_t, int,
+ bus_addr_t *, bus_space_handle_t *));
+ void (*abs_free) __P((void *, bus_space_handle_t,
+ bus_size_t));
+
+ /* barrier */
+ void (*abs_barrier) __P((void *, bus_space_handle_t,
+ bus_size_t, bus_size_t, int));
+
+ /* read (single) */
+ u_int8_t (*abs_r_1) __P((void *, bus_space_handle_t,
+ bus_size_t));
+ u_int16_t (*abs_r_2) __P((void *, bus_space_handle_t,
+ bus_size_t));
+ u_int32_t (*abs_r_4) __P((void *, bus_space_handle_t,
+ bus_size_t));
+ u_int64_t (*abs_r_8) __P((void *, bus_space_handle_t,
+ bus_size_t));
+
+ /* read multiple */
+ void (*abs_rm_1) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int8_t *, bus_size_t));
+ void (*abs_rm_2) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int16_t *, bus_size_t));
+ void (*abs_rm_4) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int32_t *, bus_size_t));
+ void (*abs_rm_8) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int64_t *, bus_size_t));
+
+ /* read region */
+ void (*abs_rr_1) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int8_t *, bus_size_t));
+ void (*abs_rr_2) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int16_t *, bus_size_t));
+ void (*abs_rr_4) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int32_t *, bus_size_t));
+ void (*abs_rr_8) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int64_t *, bus_size_t));
+
+ /* write (single) */
+ void (*abs_w_1) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int8_t));
+ void (*abs_w_2) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int16_t));
+ void (*abs_w_4) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int32_t));
+ void (*abs_w_8) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int64_t));
+
+ /* write multiple */
+ void (*abs_wm_1) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int8_t *, bus_size_t));
+ void (*abs_wm_2) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int16_t *, bus_size_t));
+ void (*abs_wm_4) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int32_t *, bus_size_t));
+ void (*abs_wm_8) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int64_t *, bus_size_t));
+
+ /* write region */
+ void (*abs_wr_1) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int8_t *, bus_size_t));
+ void (*abs_wr_2) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int16_t *, bus_size_t));
+ void (*abs_wr_4) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int32_t *, bus_size_t));
+ void (*abs_wr_8) __P((void *, bus_space_handle_t,
+ bus_size_t, const u_int64_t *, bus_size_t));
+
+ /* set multiple */
+ void (*abs_sm_1) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int8_t, bus_size_t));
+ void (*abs_sm_2) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int16_t, bus_size_t));
+ void (*abs_sm_4) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int32_t, bus_size_t));
+ void (*abs_sm_8) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int64_t, bus_size_t));
+
+ /* set region */
+ void (*abs_sr_1) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int8_t, bus_size_t));
+ void (*abs_sr_2) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int16_t, bus_size_t));
+ void (*abs_sr_4) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int32_t, bus_size_t));
+ void (*abs_sr_8) __P((void *, bus_space_handle_t,
+ bus_size_t, u_int64_t, bus_size_t));
+
+ /* copy */
+ void (*abs_c_1) __P((void *, bus_space_handle_t, bus_size_t,
+ bus_space_handle_t, bus_size_t, bus_size_t));
+ void (*abs_c_2) __P((void *, bus_space_handle_t, bus_size_t,
+ bus_space_handle_t, bus_size_t, bus_size_t));
+ void (*abs_c_4) __P((void *, bus_space_handle_t, bus_size_t,
+ bus_space_handle_t, bus_size_t, bus_size_t));
+ void (*abs_c_8) __P((void *, bus_space_handle_t, bus_size_t,
+ bus_space_handle_t, bus_size_t, bus_size_t));
+};
+
+
+/*
+ * Utility macros; INTERNAL USE ONLY.
+ */
+#define __abs_c(a,b) __CONCAT(a,b)
+#define __abs_opname(op,size) __abs_c(__abs_c(__abs_c(abs_,op),_),size)
+
+#define __abs_rs(sz, t, h, o) \
+ (*(t)->__abs_opname(r,sz))((t)->abs_cookie, h, o)
+#define __abs_ws(sz, t, h, o, v) \
+ (*(t)->__abs_opname(w,sz))((t)->abs_cookie, h, o, v)
+#ifndef DEBUG
+#define __abs_nonsingle(type, sz, t, h, o, a, c) \
+ (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c)
+#else
+#define __abs_nonsingle(type, sz, t, h, o, a, c) \
+ do { \
+ if (((unsigned long)a & (sz - 1)) != 0) \
+ panic("bus non-single %d-byte unaligned (to %p) at %s:%d", \
+ sz, a, __FILE__, __LINE__); \
+ (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c); \
+ } while (0)
+#endif
+#define __abs_set(type, sz, t, h, o, v, c) \
+ (*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, v, c)
+#define __abs_copy(sz, t, h1, o1, h2, o2, cnt) \
+ (*(t)->__abs_opname(c,sz))((t)->abs_cookie, h1, o1, h2, o2, cnt)
+
+
+/*
+ * Mapping and unmapping operations.
+ */
+#define bus_space_map(t, a, s, f, hp) \
+ (*(t)->abs_map)((t)->abs_cookie, (a), (s), (f), (hp))
+#define bus_space_unmap(t, h, s) \
+ (*(t)->abs_unmap)((t)->abs_cookie, (h), (s))
+#define bus_space_subregion(t, h, o, s, hp) \
+ (*(t)->abs_subregion)((t)->abs_cookie, (h), (o), (s), (hp))
+
+#define BUS_SPACE_MAP_CACHEABLE 0x01
+#define BUS_SPACE_MAP_LINEAR 0x02
+
+/*
+ * Allocation and deallocation operations.
+ */
+#define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
+ (*(t)->abs_alloc)((t)->abs_cookie, (rs), (re), (s), (a), (b), \
+ (f), (ap), (hp))
+#define bus_space_free(t, h, s) \
+ (*(t)->abs_free)((t)->abs_cookie, (h), (s))
+
+
+/*
+ * Bus barrier operations.
+ */
+#define bus_space_barrier(t, h, o, l, f) \
+ (*(t)->abs_barrier)((t)->abs_cookie, (h), (o), (l), (f))
+
+#define BUS_SPACE_BARRIER_READ 0x01
+#define BUS_SPACE_BARRIER_WRITE 0x02
+
+#ifdef __BUS_SPACE_COMPAT_OLDDEFS
+/* compatibility definitions; deprecated */
+#define BUS_BARRIER_READ BUS_SPACE_BARRIER_READ
+#define BUS_BARRIER_WRITE BUS_SPACE_BARRIER_WRITE
+#endif
+
+
+/*
+ * Bus read (single) operations.
+ */
+#define bus_space_read_1(t, h, o) __abs_rs(1,(t),(h),(o))
+#define bus_space_read_2(t, h, o) __abs_rs(2,(t),(h),(o))
+#define bus_space_read_4(t, h, o) __abs_rs(4,(t),(h),(o))
+#define bus_space_read_8(t, h, o) __abs_rs(8,(t),(h),(o))
+
+
+/*
+ * Bus read multiple operations.
+ */
+#define bus_space_read_multi_1(t, h, o, a, c) \
+ __abs_nonsingle(rm,1,(t),(h),(o),(a),(c))
+#define bus_space_read_multi_2(t, h, o, a, c) \
+ __abs_nonsingle(rm,2,(t),(h),(o),(a),(c))
+#define bus_space_read_multi_4(t, h, o, a, c) \
+ __abs_nonsingle(rm,4,(t),(h),(o),(a),(c))
+#define bus_space_read_multi_8(t, h, o, a, c) \
+ __abs_nonsingle(rm,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus read region operations.
+ */
+#define bus_space_read_region_1(t, h, o, a, c) \
+ __abs_nonsingle(rr,1,(t),(h),(o),(a),(c))
+#define bus_space_read_region_2(t, h, o, a, c) \
+ __abs_nonsingle(rr,2,(t),(h),(o),(a),(c))
+#define bus_space_read_region_4(t, h, o, a, c) \
+ __abs_nonsingle(rr,4,(t),(h),(o),(a),(c))
+#define bus_space_read_region_8(t, h, o, a, c) \
+ __abs_nonsingle(rr,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus write (single) operations.
+ */
+#define bus_space_write_1(t, h, o, v) __abs_ws(1,(t),(h),(o),(v))
+#define bus_space_write_2(t, h, o, v) __abs_ws(2,(t),(h),(o),(v))
+#define bus_space_write_4(t, h, o, v) __abs_ws(4,(t),(h),(o),(v))
+#define bus_space_write_8(t, h, o, v) __abs_ws(8,(t),(h),(o),(v))
+
+
+/*
+ * Bus write multiple operations.
+ */
+#define bus_space_write_multi_1(t, h, o, a, c) \
+ __abs_nonsingle(wm,1,(t),(h),(o),(a),(c))
+#define bus_space_write_multi_2(t, h, o, a, c) \
+ __abs_nonsingle(wm,2,(t),(h),(o),(a),(c))
+#define bus_space_write_multi_4(t, h, o, a, c) \
+ __abs_nonsingle(wm,4,(t),(h),(o),(a),(c))
+#define bus_space_write_multi_8(t, h, o, a, c) \
+ __abs_nonsingle(wm,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus write region operations.
+ */
+#define bus_space_write_region_1(t, h, o, a, c) \
+ __abs_nonsingle(wr,1,(t),(h),(o),(a),(c))
+#define bus_space_write_region_2(t, h, o, a, c) \
+ __abs_nonsingle(wr,2,(t),(h),(o),(a),(c))
+#define bus_space_write_region_4(t, h, o, a, c) \
+ __abs_nonsingle(wr,4,(t),(h),(o),(a),(c))
+#define bus_space_write_region_8(t, h, o, a, c) \
+ __abs_nonsingle(wr,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Set multiple operations.
+ */
+#define bus_space_set_multi_1(t, h, o, v, c) \
+ __abs_set(sm,1,(t),(h),(o),(v),(c))
+#define bus_space_set_multi_2(t, h, o, v, c) \
+ __abs_set(sm,2,(t),(h),(o),(v),(c))
+#define bus_space_set_multi_4(t, h, o, v, c) \
+ __abs_set(sm,4,(t),(h),(o),(v),(c))
+#define bus_space_set_multi_8(t, h, o, v, c) \
+ __abs_set(sm,8,(t),(h),(o),(v),(c))
+
+
+/*
+ * Set region operations.
+ */
+#define bus_space_set_region_1(t, h, o, v, c) \
+ __abs_set(sr,1,(t),(h),(o),(v),(c))
+#define bus_space_set_region_2(t, h, o, v, c) \
+ __abs_set(sr,2,(t),(h),(o),(v),(c))
+#define bus_space_set_region_4(t, h, o, v, c) \
+ __abs_set(sr,4,(t),(h),(o),(v),(c))
+#define bus_space_set_region_8(t, h, o, v, c) \
+ __abs_set(sr,8,(t),(h),(o),(v),(c))
+
+
+/*
+ * Copy region operations.
+ */
+#define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
+ __abs_copy(1, (t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
+ __abs_copy(2, (t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
+ __abs_copy(4, (t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \
+ __abs_copy(8, (t), (h1), (o1), (h2), (o2), (c))
+
+#ifdef __BUS_SPACE_COMPAT_OLDDEFS
+/* compatibility definitions; deprecated */
+#define bus_space_copy_1(t, h1, o1, h2, o2, c) \
+ bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_2(t, h1, o1, h2, o2, c) \
+ bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_4(t, h1, o1, h2, o2, c) \
+ bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
+#define bus_space_copy_8(t, h1, o1, h2, o2, c) \
+ bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
+#endif
+
+
+/*
+ * Bus DMA methods.
+ */
+
+/*
+ * Flags used in various bus DMA methods.
+ */
+#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */
+#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */
+#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */
+#define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */
+#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */
+#define BUS_DMA_BUS2 0x20
+#define BUS_DMA_BUS3 0x40
+#define BUS_DMA_BUS4 0x80
+
+/*
+ * Private flags stored in the DMA map.
+ */
+#define DMAMAP_HAS_SGMAP 0x80000000 /* sgva/len are valid */
+
+/* Forwards needed by prototypes below. */
+struct mbuf;
+struct uio;
+struct alpha_sgmap;
+
+/*
+ * Operations performed by bus_dmamap_sync().
+ */
+#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
+#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
+#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
+#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
+
+/*
+ * alpha_bus_t
+ *
+ * Busses supported by NetBSD/alpha, used by internal
+ * utility functions. NOT TO BE USED BY MACHINE-INDEPENDENT
+ * CODE!
+ */
+typedef enum {
+ ALPHA_BUS_TURBOCHANNEL,
+ ALPHA_BUS_PCI,
+ ALPHA_BUS_EISA,
+ ALPHA_BUS_ISA,
+ ALPHA_BUS_TLSB,
+} alpha_bus_t;
+
+typedef struct alpha_bus_dma_tag *bus_dma_tag_t;
+typedef struct alpha_bus_dmamap *bus_dmamap_t;
+
+/*
+ * bus_dma_segment_t
+ *
+ * Describes a single contiguous DMA transaction. Values
+ * are suitable for programming into DMA registers.
+ */
+struct alpha_bus_dma_segment {
+ bus_addr_t ds_addr; /* DMA address */
+ bus_size_t ds_len; /* length of transfer */
+};
+typedef struct alpha_bus_dma_segment bus_dma_segment_t;
+
+/*
+ * bus_dma_tag_t
+ *
+ * A machine-dependent opaque type describing the implementation of
+ * DMA for a given bus.
+ */
+struct alpha_bus_dma_tag {
+ void *_cookie; /* cookie used in the guts */
+ bus_addr_t _wbase; /* DMA window base */
+
+ /*
+ * The following two members are used to chain DMA windows
+ * together. If, during the course of a map load, the
+ * resulting physical memory address is too large to
+ * be addressed by the window, the next window will be
+ * attempted. These would be chained together like so:
+ *
+ * direct -> sgmap -> NULL
+ * or
+ * sgmap -> NULL
+ * or
+ * direct -> NULL
+ *
+ * If the window size is 0, it will not be checked (e.g.
+ * TurboChannel DMA).
+ */
+ bus_size_t _wsize;
+ struct alpha_bus_dma_tag *_next_window;
+
+ /*
+ * A chipset may have more than one SGMAP window, so SGMAP
+ * windows also get a pointer to their SGMAP state.
+ */
+ struct alpha_sgmap *_sgmap;
+
+ /*
+ * Internal-use only utility methods. NOT TO BE USED BY
+ * MACHINE-INDEPENDENT CODE!
+ */
+ bus_dma_tag_t (*_get_tag) __P((bus_dma_tag_t, alpha_bus_t));
+
+ /*
+ * DMA mapping methods.
+ */
+ int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *));
+ void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
+ int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int));
+ int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
+ struct mbuf *, int));
+ int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
+ struct uio *, int));
+ int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
+ bus_dma_segment_t *, int, bus_size_t, int));
+ void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
+ void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
+ bus_addr_t, bus_size_t, int));
+
+ /*
+ * DMA memory utility functions.
+ */
+ int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int));
+ void (*_dmamem_free) __P((bus_dma_tag_t,
+ bus_dma_segment_t *, int));
+ int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
+ int, size_t, caddr_t *, int));
+ void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
+ int (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
+ int, int, int, int));
+};
+
+#define alphabus_dma_get_tag(t, b) \
+ (*(t)->_get_tag)(t, b)
+
+#define bus_dmamap_create(t, s, n, m, b, f, p) \
+ (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
+#define bus_dmamap_destroy(t, p) \
+ (*(t)->_dmamap_destroy)((t), (p))
+#define bus_dmamap_load(t, m, b, s, p, f) \
+ (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
+#define bus_dmamap_load_mbuf(t, m, b, f) \
+ (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
+#define bus_dmamap_load_uio(t, m, u, f) \
+ (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
+#define bus_dmamap_load_raw(t, m, sg, n, s, f) \
+ (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
+#define bus_dmamap_unload(t, p) \
+ (*(t)->_dmamap_unload)((t), (p))
+#define bus_dmamap_sync(t, p, o, l, ops) \
+ (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
+#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
+ (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
+#define bus_dmamem_free(t, sg, n) \
+ (*(t)->_dmamem_free)((t), (sg), (n))
+#define bus_dmamem_map(t, sg, n, s, k, f) \
+ (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
+#define bus_dmamem_unmap(t, k, s) \
+ (*(t)->_dmamem_unmap)((t), (k), (s))
+#define bus_dmamem_mmap(t, sg, n, o, p, f) \
+ (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
+
+/*
+ * bus_dmamap_t
+ *
+ * Describes a DMA mapping.
+ */
+struct alpha_bus_dmamap {
+ /*
+ * PRIVATE MEMBERS: not for use my machine-independent code.
+ */
+ vm_object_t _dm_obj; /* for allocating pages */
+ bus_size_t _dm_size; /* largest DMA transfer mappable */
+ int _dm_segcnt; /* number of segs this map can map */
+ bus_size_t _dm_maxsegsz; /* largest possible segment */
+ bus_size_t _dm_boundary; /* don't cross this */
+ int _dm_flags; /* misc. flags */
+
+ /*
+ * This is used only for SGMAP-mapped DMA, but we keep it
+ * here to avoid pointless indirection.
+ */
+ int _dm_pteidx; /* PTE index */
+ int _dm_ptecnt; /* PTE count */
+ u_long _dm_sgva; /* allocated sgva */
+ bus_size_t _dm_sgvalen; /* svga length */
+
+ /*
+ * PUBLIC MEMBERS: these are used by machine-independent code.
+ */
+ bus_size_t dm_mapsize; /* size of the mapping */
+ int dm_nsegs; /* # valid segments in mapping */
+ bus_dma_segment_t dm_segs[1]; /* segments; variable length */
+};
+
+#ifdef _ALPHA_BUS_DMA_PRIVATE
+int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
+ bus_size_t, int, bus_dmamap_t *));
+void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
+
+int _bus_dmamap_load_direct __P((bus_dma_tag_t, bus_dmamap_t,
+ void *, bus_size_t, struct proc *, int));
+int _bus_dmamap_load_mbuf_direct __P((bus_dma_tag_t,
+ bus_dmamap_t, struct mbuf *, int));
+int _bus_dmamap_load_uio_direct __P((bus_dma_tag_t,
+ bus_dmamap_t, struct uio *, int));
+int _bus_dmamap_load_raw_direct __P((bus_dma_tag_t,
+ bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int));
+
+void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
+void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
+ bus_size_t, int));
+
+int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_dmamap_t, bus_size_t size,
+ bus_size_t alignment, bus_size_t boundary,
+ bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
+void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs));
+int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs, size_t size, caddr_t *kvap, int flags));
+void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
+ size_t size));
+int _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
+ int nsegs, int off, int prot, int flags));
+#endif /* _ALPHA_BUS_DMA_PRIVATE */
+
+#endif /* _ALPHA_BUS_H_ */
diff --git a/sys/alpha/include/chipset.h b/sys/alpha/include/chipset.h
new file mode 100644
index 000000000000..aa6f606b5c1f
--- /dev/null
+++ b/sys/alpha/include/chipset.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_CHIPSET_H_
+#define _MACHINE_CHIPSET_H_
+
+typedef u_int8_t alpha_chipset_inb_t(u_int32_t port);
+typedef u_int16_t alpha_chipset_inw_t(u_int32_t port);
+typedef u_int32_t alpha_chipset_inl_t(u_int32_t port);
+typedef void alpha_chipset_outb_t(u_int32_t port, u_int8_t data);
+typedef void alpha_chipset_outw_t(u_int32_t port, u_int16_t data);
+typedef void alpha_chipset_outl_t(u_int32_t port, u_int32_t data);
+
+typedef int alpha_chipset_maxdevs_t(u_int bus);
+typedef u_int8_t alpha_chipset_cfgreadb_t(u_int, u_int, u_int, u_int);
+typedef u_int16_t alpha_chipset_cfgreadw_t(u_int, u_int, u_int, u_int);
+typedef u_int32_t alpha_chipset_cfgreadl_t(u_int, u_int, u_int, u_int);
+typedef void alpha_chipset_cfgwriteb_t(u_int, u_int, u_int, u_int,
+ u_int8_t);
+typedef void alpha_chipset_cfgwritew_t(u_int, u_int, u_int, u_int,
+ u_int16_t);
+typedef void alpha_chipset_cfgwritel_t(u_int, u_int, u_int, u_int,
+ u_int32_t);
+
+
+typedef struct alpha_chipset {
+ /*
+ * I/O port access
+ */
+ alpha_chipset_inb_t* inb;
+ alpha_chipset_inw_t* inw;
+ alpha_chipset_inl_t* inl;
+ alpha_chipset_outb_t* outb;
+ alpha_chipset_outw_t* outw;
+ alpha_chipset_outl_t* outl;
+
+ /*
+ * PCI configuration access
+ */
+ alpha_chipset_maxdevs_t* maxdevs;
+ alpha_chipset_cfgreadb_t* cfgreadb;
+ alpha_chipset_cfgreadw_t* cfgreadw;
+ alpha_chipset_cfgreadl_t* cfgreadl;
+ alpha_chipset_cfgwriteb_t* cfgwriteb;
+ alpha_chipset_cfgwritew_t* cfgwritew;
+ alpha_chipset_cfgwritel_t* cfgwritel;
+} alpha_chipset_t;
+
+extern alpha_chipset_t chipset;
+
+#endif /* !_MACHINE_CHIPSET_H_ */
diff --git a/sys/alpha/include/clock.h b/sys/alpha/include/clock.h
new file mode 100644
index 000000000000..95c160fed890
--- /dev/null
+++ b/sys/alpha/include/clock.h
@@ -0,0 +1,22 @@
+/*
+ * Kernel interface to machine-dependent clock driver.
+ * Garrett Wollman, September 1994.
+ * This file is in the public domain.
+ *
+ * $Id: clock.h,v 1.34 1998/03/05 21:45:42 tegge Exp $
+ */
+
+#ifndef _MACHINE_CLOCK_H_
+#define _MACHINE_CLOCK_H_
+
+#ifdef KERNEL
+
+extern int wall_cmos_clock;
+extern int adjkerntz;
+
+void DELAY __P((int usec));
+int sysbeep __P((int pitch, int period));
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/alpha/include/conf.h b/sys/alpha/include/conf.h
new file mode 100644
index 000000000000..ee6b603b81a4
--- /dev/null
+++ b/sys/alpha/include/conf.h
@@ -0,0 +1,11 @@
+#ifndef _MACHINE_CONF_H_
+#define _MACHINE_CONF_H_
+
+#ifdef KERNEL
+#ifndef ACTUALLY_LKM_NOT_KERNEL
+#include "ioconf.h"
+#endif
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_CONF_H_ */
diff --git a/sys/alpha/include/cons.h b/sys/alpha/include/cons.h
new file mode 100644
index 000000000000..df135cc1b5dd
--- /dev/null
+++ b/sys/alpha/include/cons.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)cons.h 7.2 (Berkeley) 5/9/91
+ * $Id: cons.h,v 1.17 1997/07/01 00:54:37 bde Exp $
+ */
+
+#ifndef _MACHINE_CONS_H_
+#define _MACHINE_CONS_H_
+
+struct consdev;
+typedef void cn_probe_t __P((struct consdev *));
+typedef void cn_init_t __P((struct consdev *));
+typedef int cn_getc_t __P((dev_t));
+typedef int cn_checkc_t __P((dev_t));
+typedef void cn_putc_t __P((dev_t, int));
+
+#ifdef KERNEL
+/*
+ * XXX public functions in drivers should be declared in headers produced
+ * by `config', not here.
+ */
+cn_probe_t pccnprobe;
+cn_init_t pccninit;
+cn_getc_t pccngetc;
+cn_checkc_t pccncheckc;
+cn_putc_t pccnputc;
+
+cn_probe_t sccnprobe;
+cn_init_t sccninit;
+cn_getc_t sccngetc;
+cn_checkc_t sccncheckc;
+cn_putc_t sccnputc;
+
+cn_probe_t siocnprobe;
+cn_init_t siocninit;
+cn_getc_t siocngetc;
+cn_checkc_t siocncheckc;
+cn_putc_t siocnputc;
+#endif /* KERNEL */
+
+struct consdev {
+ cn_probe_t *cn_probe;
+ /* probe hardware and fill in consdev info */
+ cn_init_t *cn_init;
+ /* turn on as console */
+ cn_getc_t *cn_getc;
+ /* kernel getchar interface */
+ cn_checkc_t *cn_checkc;
+ /* kernel "return char if available" interface */
+ cn_putc_t *cn_putc;
+ /* kernel putchar interface */
+ struct tty *cn_tp; /* tty structure for console device */
+ dev_t cn_dev; /* major/minor of device */
+ short cn_pri; /* pecking order; the higher the better */
+};
+
+/* values for cn_pri - reflect our policy for console selection */
+#define CN_DEAD 0 /* device doesn't exist */
+#define CN_NORMAL 1 /* device exists but is nothing special */
+#define CN_INTERNAL 2 /* "internal" bit-mapped display */
+#define CN_REMOTE 3 /* serial interface with remote bit set */
+
+#ifdef KERNEL
+extern int cons_unavail;
+
+/* Other kernel entry points. */
+int cncheckc __P((void));
+int cngetc __P((void));
+void cninit __P((void));
+void cninit_finish __P((void));
+void cnputc __P((int));
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_CONS_H_ */
diff --git a/sys/alpha/include/cpu.h b/sys/alpha/include/cpu.h
index adf0ebac11b8..6b0c81f558b1 100644
--- a/sys/alpha/include/cpu.h
+++ b/sys/alpha/include/cpu.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: cpu.h,v 1.1 1998/01/10 10:13:14 jb Exp $ */
/* From: NetBSD: cpu.h,v 1.18 1997/09/23 23:17:49 mjacob Exp */
/*
@@ -53,12 +53,6 @@
#include <machine/frame.h>
/*
- * definitions of cpu-dependent requirements
- * referenced in generic code
- */
-#define cpu_wait(p) /* nothing */
-
-/*
* Arguments to hardclock and gatherstats encapsulate the previous
* machine state in an opaque clockframe. One the Alpha, we use
* what we push on an interrupt (a trapframe).
@@ -98,7 +92,7 @@ struct clockframe {
#define aston() (astpending = 1)
-#ifdef _KERNEL
+#ifdef KERNEL
u_int64_t astpending; /* need to trap before returning to user mode */
u_int64_t want_resched; /* resched() was called */
#endif
@@ -125,7 +119,7 @@ u_int64_t want_resched; /* resched() was called */
{ "booted_kernel", CTLTYPE_STRING }, \
}
-#ifdef _KERNEL
+#ifdef KERNEL
struct pcb;
struct proc;
@@ -133,7 +127,6 @@ struct reg;
struct rpb;
struct trapframe;
-extern int cold;
extern struct proc *fpcurproc;
extern struct rpb *hwrpb;
extern volatile int mc_expected, mc_received;
@@ -145,19 +138,19 @@ void XentMM __P((u_int64_t, u_int64_t, u_int64_t)); /* MAGIC */
void XentRestart __P((void)); /* MAGIC */
void XentSys __P((u_int64_t, u_int64_t, u_int64_t)); /* MAGIC */
void XentUna __P((u_int64_t, u_int64_t, u_int64_t)); /* MAGIC */
-void alpha_init __P((u_long, u_long, u_long, u_long));
+void alpha_init __P((u_long, u_long, u_long, u_long, u_long));
+int alpha_pa_access __P((u_long));
void ast __P((struct trapframe *));
int badaddr __P((void *, size_t));
int badaddr_read __P((void *, size_t, void *));
void child_return __P((struct proc *p));
-void configure __P((void));
u_int64_t console_restart __P((u_int64_t, u_int64_t, u_int64_t));
void do_sir __P((void));
void dumpconf __P((void));
void exception_return __P((void)); /* MAGIC */
void frametoreg __P((struct trapframe *, struct reg *));
long fswintrberr __P((void)); /* MAGIC */
-void init_prom_interface __P((void));
+void init_prom_interface __P((struct rpb*));
void interrupt
__P((unsigned long, unsigned long, unsigned long, struct trapframe *));
void machine_check
@@ -173,6 +166,7 @@ void switch_trampoline __P((void)); /* MAGIC */
void syscall __P((u_int64_t, struct trapframe *));
void trap __P((unsigned long, unsigned long, unsigned long, unsigned long,
struct trapframe *));
+void cpu_set_fork_handler __P((struct proc *, void (*pc)(void *), void *));
#endif /* _KERNEL */
diff --git a/sys/alpha/include/cpuconf.h b/sys/alpha/include/cpuconf.h
new file mode 100644
index 000000000000..30ef4c73dd63
--- /dev/null
+++ b/sys/alpha/include/cpuconf.h
@@ -0,0 +1,118 @@
+/* $NetBSD: cpuconf.h,v 1.7 1997/11/06 00:42:03 thorpej Exp $ */
+#ifndef _ALPHA_CPUCONF_H
+#define _ALPHA_CPUCONF_H
+/*
+ * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Additional reworking by Matthew Jacob for NASA/Ames Research Center.
+ * Copyright (c) 1997
+ */
+#ifdef KERNEL
+/*
+ * Platform Specific Information and Function Hooks.
+ *
+ * The tags family and model information are strings describing the platform.
+ *
+ * The tag iobus describes the primary iobus for the platform- primarily
+ * to give a hint as to where to start configuring. The likely choices
+ * are one of tcasic, lca, apecs, cia, or tlsb.
+ *
+ */
+struct device; /* XXX */
+
+extern struct platform {
+ /*
+ * Platform Information.
+ */
+ const char *family; /* Family Name */
+ const char *model; /* Model (variant) Name */
+ const char *iobus; /* Primary iobus name */
+
+ /*
+ * Platform Specific Function Hooks
+ * cons_init - console initialization
+ * device_register - boot configuration aid
+ * iointr - I/O interrupt handler
+ * clockintr - Clock Interrupt Handler
+ * mcheck_handler - Platform Specific Machine Check Handler
+ */
+ void (*cons_init) __P((void));
+ void (*device_register) __P((struct device *, void *));
+ void (*iointr) __P((void *, unsigned long));
+ void (*clockintr) __P((void *));
+ void (*mcheck_handler) __P((unsigned long, struct trapframe *,
+ unsigned long, unsigned long));
+} platform;
+
+/*
+ * Lookup table entry for Alpha system variations.
+ */
+struct alpha_variation_table {
+ u_int64_t avt_variation; /* variation, from HWRPB */
+ const char *avt_model; /* model string */
+};
+
+/*
+ * There is an array of functions to initialize the platform structure.
+ *
+ * It's responsible for filling in the family, model_name and iobus
+ * tags. It may optionally fill in the cons_init, device_register and
+ * mcheck_handler tags.
+ *
+ * The iointr tag is filled in by set_iointr (in interrupt.c).
+ * The clockintr tag is filled in by cpu_initclocks (in clock.c).
+ *
+ * nocpu is function to call when you can't figure what platform you're on.
+ * There's no return from this function.
+ */
+
+struct cpuinit {
+ void (*init) __P((int));
+ const char *option;
+};
+
+#define cpu_notsupp(st) { platform_not_supported, st }
+#define cpu_init(fn, opt) { fn, opt }
+
+/*
+ * Misc. support routines.
+ */
+const char *alpha_dsr_sysname __P((void));
+const char *alpha_variation_name __P((u_int64_t variation,
+ const struct alpha_variation_table *avtp));
+const char *alpha_unknown_sysname __P((void));
+
+extern struct cpuinit cpuinit[];
+extern int ncpuinit;
+extern void platform_not_configured __P((int));
+extern void platform_not_supported __P((int));
+
+#endif /* KERNEL */
+#endif /* !_ALPHA_CPUCONF_H */
diff --git a/sys/alpha/include/cpufunc.h b/sys/alpha/include/cpufunc.h
new file mode 100644
index 000000000000..6125ba3e49ba
--- /dev/null
+++ b/sys/alpha/include/cpufunc.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_CPUFUNC_H_
+#define _MACHINE_CPUFUNC_H_
+
+#ifdef KERNEL
+
+#include <sys/types.h>
+#include <machine/chipset.h>
+
+#define inb(port) chipset.inb(port)
+#define inw(port) chipset.inw(port)
+#define inl(port) chipset.inl(port)
+#define outb(port, data) chipset.outb(port, data)
+#define outw(port, data) chipset.outw(port, data)
+#define outl(port, data) chipset.outl(port, data)
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_CPUFUNC_H_ */
diff --git a/sys/alpha/include/db_machdep.h b/sys/alpha/include/db_machdep.h
new file mode 100644
index 000000000000..3aa84d3bb415
--- /dev/null
+++ b/sys/alpha/include/db_machdep.h
@@ -0,0 +1,112 @@
+/* $NetBSD: db_machdep.h,v 1.6 1997/09/06 02:02:25 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _ALPHA_DB_MACHDEP_H_
+#define _ALPHA_DB_MACHDEP_H_
+
+/*
+ * Machine-dependent defines for new kernel debugger.
+ */
+
+#include <sys/param.h>
+#include <vm/vm.h>
+#include <machine/frame.h>
+
+typedef vm_offset_t db_addr_t; /* address - unsigned */
+typedef long db_expr_t; /* expression - signed */
+
+typedef struct trapframe db_regs_t;
+db_regs_t ddb_regs; /* register state */
+#define DDB_REGS (&ddb_regs)
+
+#define PC_REGS(regs) ((db_addr_t)(regs)->tf_regs[FRAME_PC])
+
+#define BKPT_INST 0x00000080 /* breakpoint instruction */
+#define BKPT_SIZE (4) /* size of breakpoint inst */
+#define BKPT_SET(inst) (BKPT_INST)
+
+#if 0
+#define FIXUP_PC_AFTER_BREAK \
+ (ddb_regs.tf_regs[FRAME_PC] -= BKPT_SIZE)
+#endif
+
+#define SOFTWARE_SSTEP 1 /* no hardware support */
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == ALPHA_KENTRY_IF && \
+ (code) == ALPHA_IF_CODE_BPT)
+#define IS_WATCHPOINT_TRAP(type, code) 0
+
+/*
+ * Functions needed for software single-stepping.
+ */
+
+boolean_t db_inst_trap_return __P((int inst));
+boolean_t db_inst_return __P((int inst));
+boolean_t db_inst_call __P((int inst));
+boolean_t db_inst_branch __P((int inst));
+boolean_t db_inst_load __P((int inst));
+boolean_t db_inst_store __P((int inst));
+boolean_t db_inst_unconditional_flow_transfer __P((int inst));
+db_addr_t db_branch_taken __P((int inst, db_addr_t pc, db_regs_t *regs));
+
+#define inst_trap_return(ins) db_inst_trap_return(ins)
+#define inst_return(ins) db_inst_return(ins)
+#define inst_call(ins) db_inst_call(ins)
+#define inst_branch(ins) db_inst_branch(ins)
+#define inst_load(ins) db_inst_load(ins)
+#define inst_store(ins) db_inst_store(ins)
+#define inst_unconditional_flow_transfer(ins) \
+ db_inst_unconditional_flow_transfer(ins)
+#define branch_taken(ins, pc, regs) \
+ db_branch_taken((ins), (pc), (regs))
+
+/* No delay slots on Alpha. */
+#define next_instr_address(v, b) ((db_addr_t) ((b) ? (v) : ((v) + 4)))
+
+u_long db_register_value __P((db_regs_t *, int));
+int ddb_trap __P((unsigned long, unsigned long, unsigned long,
+ unsigned long, struct trapframe *));
+
+/*
+ * Pretty arbitrary
+ */
+#define DB_SMALL_VALUE_MAX 0x7fffffff
+#define DB_SMALL_VALUE_MIN (-0x400001)
+
+/*
+ * We define some of our own commands.
+ */
+#define DB_MACHINE_COMMANDS
+
+/*
+ * We use Elf64 symbols in DDB.
+ */
+#define DB_ELF_SYMBOLS
+#define DB_ELFSIZE 64
+
+#endif /* _ALPHA_DB_MACHDEP_H_ */
diff --git a/sys/alpha/include/elf.h b/sys/alpha/include/elf.h
index ce2da560116c..e49a729562fa 100644
--- a/sys/alpha/include/elf.h
+++ b/sys/alpha/include/elf.h
@@ -23,17 +23,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: elf.h,v 1.2 1997/08/30 18:59:48 peter Exp $
+ * $Id: elf.h,v 1.1.1.1 1998/03/09 05:42:33 jb Exp $
*/
#ifndef _MACHINE_ELF_H_
#define _MACHINE_ELF_H_ 1
/*
- * ELF definitions for the i386 architecture.
+ * ELF definitions for the alpha architecture.
*/
-#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
+#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
/*
* Auxiliary vector entries for passing information to the interpreter.
@@ -43,13 +43,13 @@
*/
typedef struct { /* Auxiliary vector entry on initial stack */
- int a_type; /* Entry type. */
+ long a_type; /* Entry type. */
union {
long a_val; /* Integer value. */
void *a_ptr; /* Address. */
void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
-} Elf32_Auxinfo;
+} Elf64_Auxinfo;
/* Values for a_type. */
#define AT_NULL 0 /* Terminates the vector. */
@@ -89,24 +89,41 @@ typedef struct { /* Auxiliary vector entry on initial stack */
* Relocation types.
*/
-#define R_386_NONE 0 /* No relocation. */
-#define R_386_32 1 /* Add symbol value. */
-#define R_386_PC32 2 /* Add PC-relative symbol value. */
-#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
-#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
-#define R_386_COPY 5 /* Copy data from shared object. */
-#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
-#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
-#define R_386_RELATIVE 8 /* Add load address of shared object. */
-#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
-#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH 12 /* OP stack push */
+#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */
+#define R_ALPHA_GPVALUE 16
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_IMMED_GP_16 19
+#define R_ALPHA_IMMED_GP_HI32 20
+#define R_ALPHA_IMMED_SCN_HI32 21
+#define R_ALPHA_IMMED_BR_HI32 22
+#define R_ALPHA_IMMED_LO32 23
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-#define R_386_COUNT 11 /* Count of defined relocation types. */
+#define R_ALPHA_COUNT 28
/* Define "machine" characteristics */
-#define ELF_TARG_CLASS ELFCLASS32
+#define ELF_TARG_CLASS ELFCLASS64
#define ELF_TARG_DATA ELFDATA2LSB
-#define ELF_TARG_MACH EM_386
+#define ELF_TARG_MACH EM_ALPHA
#define ELF_TARG_VER 1
#endif /* !_MACHINE_ELF_H_ */
diff --git a/sys/alpha/include/in_cksum.h b/sys/alpha/include/in_cksum.h
new file mode 100644
index 000000000000..7e1c0f0dee49
--- /dev/null
+++ b/sys/alpha/include/in_cksum.h
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from tahoe: in_cksum.c 1.2 86/01/05
+ * from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91
+ * from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp
+ * $Id: in_cksum.h,v 1.5 1997/08/16 19:14:55 wollman Exp $
+ */
+
+#ifndef _MACHINE_IN_CKSUM_H_
+#define _MACHINE_IN_CKSUM_H_ 1
+
+#include <sys/cdefs.h>
+
+/*
+ * It it useful to have an Internet checksum routine which is inlineable
+ * and optimized specifically for the task of computing IP header checksums
+ * in the normal case (where there are no options and the header length is
+ * therefore always exactly five 32-bit words.
+ */
+#ifdef __GNUC__
+
+static __inline void
+in_cksum_update(struct ip *ip)
+{
+ int __tmpsum;
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256;
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16));
+}
+
+#else
+
+#define in_cksum_update(ip) \
+ do { \
+ int __tmpsum; \
+ __tmpsum = (int)ntohs(ip->ip_sum) + 256; \
+ ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16)); \
+ } while(0)
+
+#endif
+
+typedef unsigned in_psum_t;
+#ifdef KERNEL
+u_int in_cksum_hdr(const struct ip *ip);
+in_psum_t in_cksum_partial(in_psum_t psum, const u_short *w, int len);
+int in_cksum_finalize(in_psum_t psum);
+#endif /* KERNEL */
+
+#endif /* _MACHINE_IN_CKSUM_H_ */
diff --git a/sys/alpha/include/ipl.h b/sys/alpha/include/ipl.h
new file mode 100644
index 000000000000..d4ed20e09a7a
--- /dev/null
+++ b/sys/alpha/include/ipl.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_IPL_H_
+#define _MACHINE_IPL_H_
+
+#include <machine/alpha_cpu.h>
+
+/* IPL-lowering/restoring macros */
+#define splx(s) \
+ ((s) == ALPHA_PSL_IPL_0 ? spl0() : alpha_pal_swpipl(s))
+#define splsoft() alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT)
+#define splsoftclock() splsoft()
+#define splsoftnet() splsoft()
+
+/* IPL-raising functions/macros */
+static __inline int _splraise __P((int)) __attribute__ ((unused));
+static __inline int
+_splraise(s)
+ int s;
+{
+ int cur = alpha_pal_rdps() & ALPHA_PSL_IPL_MASK;
+ return (s > cur ? alpha_pal_swpipl(s) : cur);
+}
+#define splnet() _splraise(ALPHA_PSL_IPL_IO)
+#define splbio() _splraise(ALPHA_PSL_IPL_IO)
+#define splimp() _splraise(ALPHA_PSL_IPL_IO)
+#define spltty() _splraise(ALPHA_PSL_IPL_IO)
+#define splvm() _splraise(ALPHA_PSL_IPL_IO)
+#define splclock() _splraise(ALPHA_PSL_IPL_CLOCK)
+#define splstatclock() _splraise(ALPHA_PSL_IPL_CLOCK)
+#define splhigh() _splraise(ALPHA_PSL_IPL_HIGH)
+
+/*
+ * simulated software interrupt register
+ */
+extern u_int64_t ssir;
+
+#define SIR_NET 0x1
+#define SIR_CLOCK 0x2
+
+#define setsoftnet() ssir |= SIR_NET
+#define setsoftclock() ssir |= SIR_CLOCK
+
+extern void spl0(void);
+
+/* XXX bogus */
+extern unsigned cpl; /* current priority level mask */
+
+#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/alpha/include/lock.h b/sys/alpha/include/lock.h
index b5604e8e2e86..a00a1e3603ce 100644
--- a/sys/alpha/include/lock.h
+++ b/sys/alpha/include/lock.h
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: lock.h,v 1.5 1997/12/15 02:18:27 tegge Exp $
+ * $Id: lock.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $
*/
@@ -38,5 +38,9 @@ struct simplelock {
volatile int lock_data;
};
+#define simple_lock_init(alp)
+#define simple_lock(alp)
+#define simple_lock_try(alp) 1
+#define simple_unlock(alp)
#endif /* !_MACHINE_LOCK_H_ */
diff --git a/sys/alpha/include/md_var.h b/sys/alpha/include/md_var.h
new file mode 100644
index 000000000000..d70c1dabf2d7
--- /dev/null
+++ b/sys/alpha/include/md_var.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_MD_VAR_H_
+#define _MACHINE_MD_VAR_H_
+
+/*
+ * Miscellaneous machine-dependent declarations.
+ */
+
+extern char sigcode[];
+extern int szsigcode;
+extern int Maxmem;
+extern void (*netisrs[32]) __P((void));
+
+void cpu_power_down __P((void));
+void cpu_halt __P((void));
+void cpu_reset __P((void));
+int is_physical_memory __P((vm_offset_t addr));
+void swi_vm __P((void));
+int vm_page_zero_idle __P((void));
+int fill_regs __P((struct proc *, struct reg *));
+int set_regs __P((struct proc *, struct reg *));
+
+#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/alpha/include/param.h b/sys/alpha/include/param.h
index 92dbbc674a18..70101f0c0b6a 100644
--- a/sys/alpha/include/param.h
+++ b/sys/alpha/include/param.h
@@ -1,4 +1,4 @@
-/* $Id: param.h,v 1.1 1998/01/10 10:13:15 jb Exp $ */
+/* $Id: param.h,v 1.2 1998/03/09 05:53:10 jb Exp $ */
/* From: NetBSD: param.h,v 1.20 1997/09/19 13:52:53 leo Exp */
/*
@@ -70,25 +70,20 @@
#define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
#define ALIGNED_POINTER(p,t) ((((u_long)(p)) & (sizeof(t)-1)) == 0)
-#define NBPG (1 << ALPHA_PGSHIFT) /* bytes/page */
-#define PAGE_SIZE NBPG
-#define PGOFSET (NBPG-1) /* byte off. into pg */
-#define PGSHIFT ALPHA_PGSHIFT /* LOG2(NBPG) */
-#define NPTEPG (1 << (PGSHIFT-PTESHIFT)) /* pte's/page */
-
-#define SEGSHIFT (PGSHIFT + (PGSHIFT-PTESHIFT)) /* LOG2(NBSEG) */
-#define NBSEG (1 << SEGSHIFT) /* bytes/segment (8M) */
-#define SEGOFSET (NBSEG-1) /* byte off. into seg */
+#define PAGE_SIZE (1 << ALPHA_PGSHIFT) /* bytes/page */
+#define PAGE_SHIFT ALPHA_PGSHIFT
+#define PAGE_MASK (PAGE_SIZE-1)
+#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
#define KERNBASE 0xfffffc0000230000 /* start of kernel virtual */
#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
-#define DEV_BSIZE 512
#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
-#define BLKDEV_IOSIZE 2048
-#ifndef MAXPHYS
-#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
-#endif
+#define DEV_BSIZE (1<<DEV_BSHIFT)
+
+#define BLKDEV_IOSIZE 2048
+#define DFLTPHYS (64 * 1024) /* default max raw I/O transfer size */
+#define MAXPHYS (128 * 1024) /* max raw I/O transfer size */
#define CLSIZE 1
#define CLSIZELOG2 0
@@ -97,11 +92,11 @@
#define SSIZE 1 /* initial stack size/NBPG */
#define SINCR 1 /* increment of stack/NBPG */
-#define UPAGES 2 /* pages of u-area */
-#define USPACE (UPAGES * NBPG) /* total size of u-area */
+#define UPAGES 2 /* pages of u-area */
+#define USPACE (UPAGES * PAGE_SIZE) /* total size of u-area */
#ifndef MSGBUFSIZE
-#define MSGBUFSIZE NBPG /* default message buffer size */
+#define MSGBUFSIZE PAGE_SIZE /* default message buffer size */
#endif
/*
@@ -134,12 +129,12 @@
#endif
/* pages ("clicks") to disk blocks */
-#define ctod(x) ((x) << (PGSHIFT - DEV_BSHIFT))
-#define dtoc(x) ((x) >> (PGSHIFT - DEV_BSHIFT))
+#define ctod(x) ((x) << (PAGE_SHIFT - DEV_BSHIFT))
+#define dtoc(x) ((x) >> (PAGE_SHIFT - DEV_BSHIFT))
/* pages to bytes */
-#define ctob(x) ((x) << PGSHIFT)
-#define btoc(x) (((x) + PGOFSET) >> PGSHIFT)
+#define ctob(x) ((x) << PAGE_SHIFT)
+#define btoc(x) (((x) + PAGE_MASK) >> PAGE_SHIFT)
/* bytes to disk blocks */
#define btodb(x) ((x) >> DEV_BSHIFT)
@@ -156,10 +151,14 @@
/*
* Mach derived conversion macros
*/
-#define alpha_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1))
-#define alpha_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1))
-#define alpha_btop(x) ((unsigned long)(x) >> PGSHIFT)
-#define alpha_ptob(x) ((unsigned long)(x) << PGSHIFT)
+#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
+#define trunc_page(x) ((unsigned long)(x) & ~(PAGE_MASK))
+
+#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#define alpha_btop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define alpha_ptob(x) ((unsigned long)(x) << PAGE_SHIFT)
#include <machine/intr.h>
diff --git a/sys/alpha/include/pmap.h b/sys/alpha/include/pmap.h
index 9f013ac269a9..a9286787f76c 100644
--- a/sys/alpha/include/pmap.h
+++ b/sys/alpha/include/pmap.h
@@ -1,14 +1,10 @@
-/* $Id$ */
-/* From: NetBSD: pmap.old.h,v 1.16 1998/01/09 19:13:09 thorpej Exp */
-
-/*
- * Copyright (c) 1987 Carnegie-Mellon University
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
+/*
+ * Copyright (c) 1991 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.
+ * Science Department and William Jolitz of UUNET Technologies Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,103 +34,198 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)pmap.h 8.1 (Berkeley) 6/10/93
+ * Derived from hp300 version by Mike Hibler, this version by William
+ * Jolitz uses a recursive map [a pde points to the page directory] to
+ * map the page tables using the pagetables themselves. This is done to
+ * reduce the impact on kernel virtual memory for lots of sparse address
+ * space, and to reduce the cost of memory to each process.
+ *
+ * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
+ * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
+ * from: i386 pmap.h,v 1.54 1997/11/20 19:30:35 bde Exp
+ * $Id$
*/
-#ifndef _PMAP_MACHINE_
-#define _PMAP_MACHINE_
+#ifndef _MACHINE_PMAP_H_
+#define _MACHINE_PMAP_H_
-#include <machine/pte.h>
-#include <machine/lock.h>
-
-extern vm_offset_t vtophys(vm_offset_t);
-
-#define ALPHA_PAGE_SIZE NBPG
-#define ALPHA_SEG_SIZE NBSEG
+/*
+ * Define meanings for a few software bits in the pte
+ */
+#define PG_V ALPHA_PTE_VALID
+#define PG_FOR ALPHA_PTE_FAULT_ON_READ
+#define PG_FOW ALPHA_PTE_FAULT_ON_WRITE
+#define PG_FOE ALPHA_PTE_FAULT_ON_EXECUTE
+#define PG_ASM ALPHA_PTE_ASM
+#define PG_GH ALPHA_PTE_GRANULARITY
+#define PG_KRE ALPHA_PTE_KR
+#define PG_URE ALPHA_PTE_UR
+#define PG_KWE ALPHA_PTE_KW
+#define PG_UWE ALPHA_PTE_UW
+#define PG_PROT ALPHA_PTE_PROT
+#define PG_SHIFT 32
+
+#define PG_W 0x00010000 /* software wired */
+#define PG_MANAGED 0x00020000 /* software managed */
-#define alpha_trunc_seg(x) (((u_long)(x)) & ~(ALPHA_SEG_SIZE-1))
-#define alpha_round_seg(x) alpha_trunc_seg((u_long)(x) + ALPHA_SEG_SIZE-1)
+/*
+ * Pte related macros
+ */
+#define VADDR(l1, l2, l3) (((l1) << ALPHA_L1SHIFT) \
+ + ((l2) << ALPHA_L2SHIFT) \
+ + ((l3) << ALPHA_L3SHIFT)
-typedef struct simplelock simple_lock_data_t;
+#ifndef NKPT
+#define NKPT 9 /* initial number of kernel page tables */
+#endif
+#define NKLEV2MAPS 255 /* max number of lev2 page tables */
+#define NKLEV3MAPS (NKLEV2MAPS << ALPHA_PTSHIFT) /* max number of lev3 page tables */
/*
- * Pmap stuff
+ * The *PTDI values control the layout of virtual memory
+ *
+ * XXX This works for now, but I am not real happy with it, I'll fix it
+ * right after I fix locore.s and the magic 28K hole
+ *
+ * SMP_PRIVPAGES: The per-cpu address space is 0xff80000 -> 0xffbfffff
*/
-struct pmap {
- pt_entry_t *pm_ptab; /* KVA of page table */
- pt_entry_t *pm_stab; /* KVA of segment table */
- pt_entry_t pm_stpte; /* PTE mapping STE */
- short pm_sref; /* segment table ref count */
- short pm_count; /* pmap reference count */
- simple_lock_data_t pm_lock; /* lock on pmap */
- struct pmap_statistics pm_stats; /* pmap statistics */
- long pm_ptpages; /* more stats: PT pages */
-};
+#define PTLEV1I (NPTEPG-1) /* Lev0 entry that points to Lev0 */
+#define K0SEGLEV1I (NPTEPG/2)
+#define K1SEGLEV1I (K0SEGLEV1I+(NPTEPG/4))
-typedef struct pmap *pmap_t;
+#define NUSERLEV2MAPS (NPTEPG/2)
+#define NUSERLEV3MAPS (NUSERLEV2MAPS << ALPHA_PTSHIFT)
+
+#ifndef LOCORE
-extern struct pmap kernel_pmap_store;
+#include <sys/queue.h>
-#define pmap_kernel() (&kernel_pmap_store)
-#define active_pmap(pm) \
- ((pm) == pmap_kernel() \
- || curproc == NULL \
- || (pm) == curproc->p_vmspace->vm_map.pmap)
-#define active_user_pmap(pm) \
- (curproc && \
- (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap)
+typedef alpha_pt_entry_t pt_entry_t;
+
+#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
/*
- * For each vm_page_t, there is a list of all currently valid virtual
- * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
+ * Address of current address space page table maps
*/
-typedef struct pv_entry {
- struct pv_entry *pv_next; /* next pv_entry */
- struct pmap *pv_pmap; /* pmap where mapping lies */
- vm_offset_t pv_va; /* virtual address for mapping */
- pt_entry_t *pv_ptpte; /* non-zero if VA maps a PT page */
- struct pmap *pv_ptpmap; /* if pv_ptpte, pmap for PT page */
- int pv_flags; /* flags */
-} *pv_entry_t;
+#ifdef KERNEL
+extern pt_entry_t PTmap[]; /* lev3 page tables */
+extern pt_entry_t PTlev2[]; /* lev2 page tables */
+extern pt_entry_t PTlev1[]; /* lev1 page table */
+extern pt_entry_t PTlev1pte; /* pte that maps lev1 page table */
+#endif
-#define PV_PTPAGE 0x01 /* header: entry maps a page table page */
+#ifdef KERNEL
+/*
+ * virtual address to page table entry and
+ * to physical address.
+ * Note: this work recursively, thus vtopte of a pte will give
+ * the corresponding lev1 that in turn maps it.
+ */
+#define vtopte(va) (PTmap + (alpha_btop(va) \
+ & ((1 << 3*ALPHA_PTSHIFT)-1)))
-struct pv_page_info {
- TAILQ_ENTRY(pv_page) pgi_list;
- struct pv_entry *pgi_freelist;
- int pgi_nfree;
-};
+/*
+ * Routine: pmap_kextract
+ * Function:
+ * Extract the physical page address associated
+ * kernel virtual address.
+ */
+static __inline vm_offset_t
+pmap_kextract(vm_offset_t va)
+{
+ vm_offset_t pa;
+ if (va >= ALPHA_K0SEG_BASE && va <= ALPHA_K0SEG_END)
+ pa = ALPHA_K0SEG_TO_PHYS(va);
+ else
+ pa = alpha_ptob(ALPHA_PTE_TO_PFN(*vtopte(va)))
+ | (va & PAGE_MASK);
+ return pa;
+}
+
+#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
+
+#endif /* KERNEL */
+
+/*
+ * Pmap stuff
+ */
+struct pv_entry;
+typedef struct {
+ int pv_list_count;
+ struct vm_page *pv_vm_page;
+ int pv_flags;
+ TAILQ_HEAD(,pv_entry) pv_list;
+} pv_table_t;
-#define NPVPPG ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
+#define PV_TABLE_MOD 0x01 /* modified */
+#define PV_TABLE_REF 0x02 /* referenced */
-struct pv_page {
- struct pv_page_info pvp_pgi;
- struct pv_entry pvp_pv[NPVPPG];
+struct pmap {
+ pt_entry_t *pm_lev1; /* KVA of lev0map */
+ vm_object_t pm_pteobj; /* Container for pte's */
+ TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
+ int pm_count; /* reference count */
+ int pm_flags; /* pmap flags */
+ struct pmap_statistics pm_stats; /* pmap statistics */
+ struct vm_page *pm_ptphint; /* pmap ptp hint */
};
-/*
- * Physical page attributes.
- */
-typedef int pmap_attr_t;
-#define PMAP_ATTR_MOD 0x01 /* modified */
-#define PMAP_ATTR_REF 0x02 /* referenced */
+#define pmap_resident_count(pmap) (pmap)->pm_stats.resident_count
-#ifdef _KERNEL
-#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
-#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
+#define PM_FLAG_LOCKED 0x1
+#define PM_FLAG_WANTED 0x2
-extern pt_entry_t *Sysmap;
-extern char *vmmap; /* map for mem, dumps, etc. */
+typedef struct pmap *pmap_t;
-#if defined(MACHINE_NEW_NONCONTIG)
-#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */
+#ifdef KERNEL
+extern pmap_t kernel_pmap;
#endif
-/* Machine-specific functions. */
-void pmap_bootstrap __P((vm_offset_t firstaddr, vm_offset_t ptaddr));
-void pmap_emulate_reference __P((struct proc *p, vm_offset_t v,
- int user, int write));
-void pmap_unmap_prom __P((void));
-#endif /* _KERNEL */
+/*
+ * For each vm_page_t, there is a list of all currently valid virtual
+ * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
+ */
+typedef struct pv_entry {
+ pmap_t pv_pmap; /* pmap where mapping lies */
+ vm_offset_t pv_va; /* virtual address for mapping */
+ TAILQ_ENTRY(pv_entry) pv_list;
+ TAILQ_ENTRY(pv_entry) pv_plist;
+ vm_page_t pv_ptem; /* VM page for pte */
+} *pv_entry_t;
-#endif /* _PMAP_MACHINE_ */
+#define PV_ENTRY_NULL ((pv_entry_t) 0)
+
+#define PV_CI 0x01 /* all entries must be cache inhibited */
+#define PV_PTPAGE 0x02 /* entry maps a page table page */
+
+#ifdef KERNEL
+
+extern caddr_t CADDR1;
+extern pt_entry_t *CMAP1;
+extern vm_offset_t avail_end;
+extern vm_offset_t avail_start;
+extern vm_offset_t clean_eva;
+extern vm_offset_t clean_sva;
+extern vm_offset_t phys_avail[];
+extern char *ptvmmap; /* poor name! */
+extern vm_offset_t virtual_avail;
+extern vm_offset_t virtual_end;
+
+vm_offset_t pmap_steal_memory __P((vm_size_t));
+void pmap_bootstrap __P((vm_offset_t, u_int));
+void pmap_setdevram __P((unsigned long long basea, vm_offset_t sizea));
+int pmap_uses_prom_console __P((void));
+pmap_t pmap_kernel __P((void));
+void *pmap_mapdev __P((vm_offset_t, vm_size_t));
+unsigned *pmap_pte __P((pmap_t, vm_offset_t)) __pure2;
+vm_page_t pmap_use_pt __P((pmap_t, vm_offset_t));
+void pmap_set_opt __P((unsigned *));
+void pmap_set_opt_bsp __P((void));
+void pmap_deactivate __P((struct proc *p));
+void pmap_emulate_reference __P((struct proc *p, vm_offset_t v, int user, int write));
+
+#endif /* KERNEL */
+
+#endif /* !LOCORE */
+
+#endif /* !_MACHINE_PMAP_H_ */
diff --git a/sys/alpha/include/proc.h b/sys/alpha/include/proc.h
index 1f433c5081a6..6cb6d1beb457 100644
--- a/sys/alpha/include/proc.h
+++ b/sys/alpha/include/proc.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: proc.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */
/* From: NetBSD: proc.h,v 1.3 1997/04/06 08:47:36 cgd Exp */
/*
diff --git a/sys/alpha/include/prom.h b/sys/alpha/include/prom.h
new file mode 100644
index 000000000000..84f5f9c7ade6
--- /dev/null
+++ b/sys/alpha/include/prom.h
@@ -0,0 +1,104 @@
+/* $NetBSD: prom.h,v 1.7 1997/04/06 08:47:37 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Keith Bostic, Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef ASSEMBLER
+struct prom_vec {
+ u_int64_t routine;
+ void *routine_arg;
+};
+
+/* The return value from a prom call. */
+typedef union {
+ struct {
+ u_int64_t
+ retval : 32, /* return value. */
+ unit : 8,
+ mbz : 8,
+ error : 13,
+ status : 3;
+ } u;
+ u_int64_t bits;
+} prom_return_t;
+
+#ifdef STANDALONE
+int getchar __P((void));
+int prom_open __P((char *, int));
+void putchar __P((int));
+#endif
+
+void prom_halt __P((int)) __attribute__((__noreturn__));
+int prom_getenv __P((int, char *, int));
+
+#endif
+
+/* Prom operation values. */
+#define PROM_R_CLOSE 0x11
+#define PROM_R_GETC 0x01
+#define PROM_R_GETENV 0x22
+#define PROM_R_OPEN 0x10
+#define PROM_R_PUTS 0x02
+#define PROM_R_READ 0x13
+#define PROM_R_WRITE 0x14
+
+/* Environment variable values. */
+#define PROM_E_BOOTED_DEV 0x4
+#define PROM_E_BOOTED_FILE 0x6
+#define PROM_E_BOOTED_OSFLAGS 0x8
+#define PROM_E_TTY_DEV 0xf
+
+/*
+ * There have to be stub routines to do the copying that ensures that the
+ * PROM doesn't get called with an address larger than 32 bits. Calls that
+ * either don't need to copy anything, or don't need the copy because it's
+ * already being done elsewhere, are defined here.
+ */
+#define prom_close(chan) \
+ prom_dispatch(PROM_R_CLOSE, chan, 0, 0, 0)
+#define prom_read(chan, len, buf, blkno) \
+ prom_dispatch(PROM_R_READ, chan, len, (u_int64_t)buf, blkno)
+#define prom_write(chan, len, buf, blkno) \
+ prom_dispatch(PROM_R_WRITE, chan, len, (u_int64_t)buf, blkno)
+#define prom_putstr(chan, str, len) \
+ prom_dispatch(PROM_R_PUTS, chan, (u_int64_t)str, len, 0)
+#define prom_getc(chan) \
+ prom_dispatch(PROM_R_GETC, chan, 0, 0, 0)
+#define prom_getenv_disp(id, buf, len) \
+ prom_dispatch(PROM_R_GETENV, id, (u_int64_t)buf, len, 0)
+
+#ifndef ASSEMBLER
+#ifdef KERNEL
+void promcnputc __P((dev_t, int));
+int promcngetc __P((dev_t));
+int promcnlookc __P((dev_t, char *));
+
+u_int64_t prom_dispatch __P((u_int64_t, u_int64_t, u_int64_t, u_int64_t,
+ u_int64_t));
+void init_bootstrap_console __P((void));
+#endif /* _KERNEL */
+#endif /* ASSEMBLER */
diff --git a/sys/alpha/include/psl.h b/sys/alpha/include/psl.h
new file mode 100644
index 000000000000..b54c48edbc1b
--- /dev/null
+++ b/sys/alpha/include/psl.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * XXX don't need this.
+ */
+
diff --git a/sys/alpha/include/pte.h b/sys/alpha/include/pte.h
index da211ca9d8bc..4981272d48fe 100644
--- a/sys/alpha/include/pte.h
+++ b/sys/alpha/include/pte.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: pte.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */
/* From: NetBSD: pte.h,v 1.10 1997/09/02 19:07:22 thorpej Exp */
/*
@@ -91,7 +91,7 @@ typedef alpha_pt_entry_t pt_entry_t;
#define vatopa(va) \
((PG_PFNUM(*kvtopte(va)) << PGSHIFT) | ((vm_offset_t)(va) & PGOFSET))
-#define ALPHA_STSIZE ((u_long)NBPG) /* 8k */
+#define ALPHA_STSIZE ((u_long)PAGE_SIZE) /* 8k */
#define ALPHA_MAX_PTSIZE ((u_long)(NPTEPG * NBPG)) /* 8M */
#ifdef _KERNEL
diff --git a/sys/alpha/include/ptrace.h b/sys/alpha/include/ptrace.h
new file mode 100644
index 000000000000..2b4a9cb103f4
--- /dev/null
+++ b/sys/alpha/include/ptrace.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ptrace.h 8.1 (Berkeley) 6/11/93
+ * $Id: ptrace.h,v 1.6 1998/05/19 00:00:12 tegge Exp $
+ */
+
+#ifndef _MACHINE_PTRACE_H_
+#define _MACHINE_PTRACE_H_
+
+/*
+ * Machine dependent trace commands.
+ */
+#define PT_GETREGS (PT_FIRSTMACH + 1)
+#define PT_SETREGS (PT_FIRSTMACH + 2)
+#define PT_GETFPREGS (PT_FIRSTMACH + 3)
+#define PT_SETFPREGS (PT_FIRSTMACH + 4)
+
+#ifdef KERNEL
+int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len));
+#endif /* !KERNEL */
+
+#endif
+
diff --git a/sys/alpha/include/reg.h b/sys/alpha/include/reg.h
index d2d5ab9e0719..3bbc69f41eb1 100644
--- a/sys/alpha/include/reg.h
+++ b/sys/alpha/include/reg.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: reg.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */
/* From: NetBSD: reg.h,v 1.3 1997/04/06 08:47:40 cgd Exp */
/*
@@ -91,9 +91,10 @@ struct fpreg {
u_int64_t fpr_cr;
};
-#ifdef _KERNEL
+#ifdef KERNEL
void restorefpstate __P((struct fpreg *));
void savefpstate __P((struct fpreg *));
+void setregs __P((struct proc *, u_long, u_long));
#endif
#endif /* _ALPHA_REG_H_ */
diff --git a/sys/alpha/include/rpb.h b/sys/alpha/include/rpb.h
new file mode 100644
index 000000000000..164127ff9721
--- /dev/null
+++ b/sys/alpha/include/rpb.h
@@ -0,0 +1,393 @@
+/* $NetBSD: rpb.h,v 1.20 1998/04/15 00:47:33 mjacob Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Keith Bostic, Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * From DEC 3000 300/400/500/600/700/800/900 System Programmer's Manual,
+ * EK-D3SYS-PM.B01.
+ */
+
+/*
+ * HWRPB (Hardware Restart Parameter Block).
+ */
+#define HWRPB_ADDR 0x10000000 /* virtual address, at boot */
+
+#ifndef ASSEMBLER
+struct rpb {
+ u_int64_t rpb_phys; /* 0: HWRPB phys. address. */
+ char rpb_magic[8]; /* 8: "HWRPB" (in ASCII) */
+ u_int64_t rpb_version; /* 10 */
+ u_int64_t rpb_size; /* 18: HWRPB size in bytes */
+ u_int64_t rpb_primary_cpu_id; /* 20 */
+ u_int64_t rpb_page_size; /* 28: (8192) */
+ u_int64_t rpb_phys_addr_size; /* 30: (34) */
+ u_int64_t rpb_max_asn; /* 38: (16) */
+ char rpb_ssn[16]; /* 40: only first 10 valid */
+
+#define ST_ADU 1 /* Alpha Demo. Unit (?) */
+#define ST_DEC_4000 2 /* "Cobra" (?) */
+#define ST_DEC_7000 3 /* "Ruby" (?) */
+#define ST_DEC_3000_500 4 /* "Flamingo" family (TC) */
+#define ST_DEC_2000_300 6 /* "Jensen" (EISA/ISA) */
+#define ST_DEC_3000_300 7 /* "Pelican" (TC) */
+#define ST_AVALON_A12 8 /* XXX Avalon Multicomputer */
+#define ST_DEC_2100_A500 9 /* "Sable" (?) */
+#define ST_DEC_APXVME_64 10 /* "AXPvme" (VME?) */
+#define ST_DEC_AXPPCI_33 11 /* "NoName" (PCI/ISA) */
+#define ST_DEC_21000 12 /* "TurboLaser" (PCI/EISA) */
+#define ST_DEC_2100_A50 13 /* "Avanti" (PCI/ISA) */
+#define ST_DEC_MUSTANG 14 /* "Mustang" (?) */
+#define ST_DEC_KN20AA 15 /* kn20aa (PCI/EISA) */
+#define ST_DEC_1000 17 /* "Mikasa" (PCI/ISA?) */
+#define ST_EB66 19 /* EB66 (PCI/ISA?) */
+#define ST_EB64P 20 /* EB64+ (PCI/ISA?) */
+#define ST_ALPHABOOK1 21 /* Alphabook (?) */
+#define ST_DEC_4100 22 /* "Rawhide" (PCI/EISA) */
+#define ST_DEC_EV45_PBP 23 /* "Lego" (?) */
+#define ST_DEC_2100A_A500 24 /* "Lynx" (?) */
+#define ST_EB164 26 /* EB164 (PCI/ISA) */
+#define ST_DEC_1000A 27 /* "Noritake" (?) */
+#define ST_DEC_ALPHAVME_224 28 /* "Cortex" (?) */
+#define ST_DEC_EV56_PBP 32 /* "Takara" (?) */
+#define ST_DEC_ALPHAVME_320 33 /* "Yukon" (VME?) */
+
+ u_int64_t rpb_type; /* 50: */
+
+#define SV_MPCAP 0x00000001 /* multiprocessor capable */
+
+#define SV_CONSOLE 0x0000001e /* console hardware mask */
+#define SV_CONSOLE_DETACHED 0x00000002
+#define SV_CONSOLE_EMBEDDED 0x00000004
+
+#define SV_POWERFAIL 0x000000e0 /* powerfail mask */
+#define SV_PF_UNITED 0x00000020
+#define SV_PF_SEPARATE 0x00000040
+#define SV_PF_BBACKUP 0x00000060
+#define SV_PF_ACTION 0x00000100 /* powerfail restart */
+
+#define SV_GRAPHICS 0x00000200 /* graphic engine present */
+
+#define SV_ST_MASK 0x0000fc00 /* system type mask */
+#define SV_ST_RESERVED 0x00000000 /* RESERVED */
+
+/*
+ * System types for the DEC 3000/500 (Flamingo) Family
+ */
+#define SV_ST_SANDPIPER 0x00000400 /* Sandpiper; 3000/400 */
+#define SV_ST_FLAMINGO 0x00000800 /* Flamingo; 3000/500 */
+#define SV_ST_HOTPINK 0x00000c00 /* "Hot Pink"; 3000/500X */
+#define SV_ST_FLAMINGOPLUS 0x00001000 /* Flamingo+; 3000/800 */
+#define SV_ST_ULTRA 0x00001400 /* "Ultra", aka Flamingo+ */
+#define SV_ST_SANDPLUS 0x00001800 /* Sandpiper+; 3000/600 */
+#define SV_ST_SANDPIPER45 0x00001c00 /* Sandpiper45; 3000/700 */
+#define SV_ST_FLAMINGO45 0x00002000 /* Flamingo45; 3000/900 */
+
+/*
+ * System types for ???
+ */
+#define SV_ST_SABLE 0x00000400 /* Sable (???) */
+
+/*
+ * System types for the DEC 3000/300 (Pelican) Family
+ */
+#define SV_ST_PELICAN 0x00000000 /* Pelican; 3000/300 */
+#define SV_ST_PELICA 0x00000400 /* Pelica; 3000/300L */
+#define SV_ST_PELICANPLUS 0x00000800 /* Pelican+; 3000/300X */
+#define SV_ST_PELICAPLUS 0x00000c00 /* Pelica+; 3000/300LX */
+
+/*
+ * System types for the AlphaStation Family
+ */
+#define SV_ST_AVANTI 0x00000000 /* Avanti; 400 4/233 */
+#define SV_ST_MUSTANG2_4_166 0x00000800 /* Mustang II; 200 4/166 */
+#define SV_ST_MUSTANG2_4_233 0x00001000 /* Mustang II; 200 4/233 */
+#define SV_ST_AVANTI_XXX 0x00001400 /* also Avanti; 400 4/233 */
+#define SV_ST_AVANTI_4_266 0x00002000
+#define SV_ST_MUSTANG2_4_100 0x00002400 /* Mustang II; 200 4/100 */
+#define SV_ST_AVANTI_4_233 0x0000a800 /* AlphaStation 255/233 */
+
+ u_int64_t rpb_variation; /* 58 */
+
+ char rpb_revision[8]; /* 60; only first 4 valid */
+ u_int64_t rpb_intr_freq; /* 68; scaled by 4096 */
+ u_int64_t rpb_cc_freq; /* 70: cycle cntr frequency */
+ vm_offset_t rpb_vptb; /* 78: */
+ u_int64_t rpb_reserved_arch; /* 80: */
+ vm_offset_t rpb_tbhint_off; /* 88: */
+ u_int64_t rpb_pcs_cnt; /* 90: */
+ u_int64_t rpb_pcs_size; /* 98; pcs size in bytes */
+ vm_offset_t rpb_pcs_off; /* A0: offset to pcs info */
+ u_int64_t rpb_ctb_cnt; /* A8: console terminal */
+ u_int64_t rpb_ctb_size; /* B0: ctb size in bytes */
+ vm_offset_t rpb_ctb_off; /* B8: offset to ctb */
+ vm_offset_t rpb_crb_off; /* C0: offset to crb */
+ vm_offset_t rpb_memdat_off; /* C8: memory data offset */
+ vm_offset_t rpb_condat_off; /* D0: config data offset */
+ vm_offset_t rpb_fru_off; /* D8: FRU table offset */
+ u_int64_t rpb_save_term; /* E0: terminal save */
+ u_int64_t rpb_save_term_val; /* E8: */
+ u_int64_t rpb_rest_term; /* F0: terminal restore */
+ u_int64_t rpb_rest_term_val; /* F8: */
+ u_int64_t rpb_restart; /* 100: restart */
+ u_int64_t rpb_restart_val; /* 108: */
+ u_int64_t rpb_reserve_os; /* 110: */
+ u_int64_t rpb_reserve_hw; /* 118: */
+ u_int64_t rpb_checksum; /* 120: HWRPB checksum */
+ u_int64_t rpb_rxrdy; /* 128: receive ready */
+ u_int64_t rpb_txrdy; /* 130: transmit ready */
+ vm_offset_t rpb_dsrdb_off; /* 138: HWRPB + DSRDB offset */
+ u_int64_t rpb_tbhint[8]; /* 149: TB hint block */
+};
+
+/*
+ * PCS: Per-CPU information.
+ */
+struct pcs {
+ u_int8_t pcs_hwpcb[128]; /* 0: PAL dependent */
+
+#define PCS_BIP 0x000001 /* boot in progress */
+#define PCS_RC 0x000002 /* restart possible */
+#define PCS_PA 0x000004 /* processor available */
+#define PCS_PP 0x000008 /* processor present */
+#define PCS_OH 0x000010 /* user halted */
+#define PCS_CV 0x000020 /* context valid */
+#define PCS_PV 0x000040 /* PALcode valid */
+#define PCS_PMV 0x000080 /* PALcode memory valid */
+#define PCS_PL 0x000100 /* PALcode loaded */
+
+#define PCS_HALT_REQ 0xff0000 /* halt request mask */
+#define PCS_HALT_DEFAULT 0x000000
+#define PCS_HALT_SAVE_EXIT 0x010000
+#define PCS_HALT_COLD_BOOT 0x020000
+#define PCS_HALT_WARM_BOOT 0x030000
+#define PCS_HALT_STAY_HALTED 0x040000
+#define PCS_mbz 0xffffffffff000000 /* 24:63 -- must be zero */
+ u_int64_t pcs_flags; /* 80: */
+
+ u_int64_t pcs_pal_memsize; /* 88: PAL memory size */
+ u_int64_t pcs_pal_scrsize; /* 90: PAL scratch size */
+ vm_offset_t pcs_pal_memaddr; /* 98: PAL memory addr */
+ vm_offset_t pcs_pal_scraddr; /* A0: PAL scratch addr */
+ struct {
+ u_int64_t
+ minorrev : 8, /* alphabetic char 'a' - 'z' */
+ majorrev : 8, /* alphabetic char 'a' - 'z' */
+#define PAL_TYPE_STANDARD 0
+#define PAL_TYPE_VMS 1
+#define PAL_TYPE_OSF1 2
+ pal_type : 8, /* PALcode type:
+ * 0 == standard
+ * 1 == OpenVMS
+ * 2 == OSF/1
+ * 3-127 DIGITAL reserv.
+ * 128-255 non-DIGITAL reserv.
+ */
+ sbz1 : 8,
+ compatibility : 16, /* Compatibility revision */
+ proc_cnt : 16; /* Processor count */
+ } pcs_pal_rev; /* A8: */
+#define pcs_minorrev pcs_pal_rev.minorrev
+#define pcs_majorrev pcs_pal_rev.majorrev
+#define pcs_pal_type pcs_pal_rev.pal_type
+#define pcs_compatibility pcs_pal_rev.compatibility
+#define pcs_proc_cnt pcs_pal_rev.proc_cnt
+
+ u_int64_t pcs_proc_type; /* B0: processor type */
+
+#define PCS_PROC_MAJOR 0x00000000ffffffff
+#define PCS_PROC_MAJORSHIFT 0
+
+#define PCS_PROC_EV3 1 /* EV3 */
+#define PCS_PROC_EV4 2 /* EV4: 21064 */
+#define PCS_PROC_SIMULATION 3 /* Simulation */
+#define PCS_PROC_LCA4 4 /* LCA4: 2106[68] */
+#define PCS_PROC_EV5 5 /* EV5: 21164 */
+#define PCS_PROC_EV45 6 /* EV45: 21064A */
+#define PCS_PROC_EV56 7 /* EV56: 21164A */
+#define PCS_PROC_EV6 8 /* EV6: 21264 */
+#define PCS_PROC_PCA56 9 /* PCA256: 21164PC */
+
+#define PCS_PROC_MINOR 0xffffffff00000000
+#define PCS_PROC_MINORSHIFT 32
+
+ /* Minor number interpretation is processor specific. See cpu.c. */
+
+ u_int64_t pcs_proc_var; /* B8: processor variation. */
+
+#define PCS_VAR_VAXFP 0x0000000000000001 /* VAX FP support */
+#define PCS_VAR_IEEEFP 0x0000000000000002 /* IEEE FP support */
+#define PCS_VAR_PE 0x0000000000000004 /* Primary Eligible */
+#define PCS_VAR_RESERVED 0xfffffffffffffff8 /* Reserved */
+
+ char pcs_proc_revision[8]; /* C0: only first 4 valid */
+ char pcs_proc_sn[16]; /* C8: only first 10 valid */
+ vm_offset_t pcs_machcheck; /* D8: mach chk phys addr. */
+ u_int64_t pcs_machcheck_len; /* E0: length in bytes */
+ vm_offset_t pcs_halt_pcbb; /* E8: phys addr of halt PCB */
+ vm_offset_t pcs_halt_pc; /* F0: halt PC */
+ u_int64_t pcs_halt_ps; /* F8: halt PS */
+ u_int64_t pcs_halt_r25; /* 100: halt argument list */
+ u_int64_t pcs_halt_r26; /* 108: halt return addr list */
+ u_int64_t pcs_halt_r27; /* 110: halt procedure value */
+
+#define PCS_HALT_RESERVED 0
+#define PCS_HALT_POWERUP 1
+#define PCS_HALT_CONSOLE_HALT 2
+#define PCS_HALT_CONSOLE_CRASH 3
+#define PCS_HALT_KERNEL_MODE 4
+#define PCS_HALT_KERNEL_STACK_INVALID 5
+#define PCS_HALT_DOUBLE_ERROR_ABORT 6
+#define PCS_HALT_SCBB 7
+#define PCS_HALT_PTBR 8 /* 9-FF: reserved */
+ u_int64_t pcs_halt_reason; /* 118: */
+
+ u_int64_t pcs_reserved_soft; /* 120: preserved software */
+ u_int64_t pcs_buffer[21]; /* 128: console buffers */
+
+#define PALvar_reserved 0
+#define PALvar_OpenVMS 1
+#define PALvar_OSF1 2
+ u_int64_t pcs_palrevisions[16]; /* 1D0: PALcode revisions */
+
+ u_int64_t pcs_reserved_arch[6]; /* 250: reserved arch */
+};
+
+/*
+ * CTB: Console Terminal Block
+ */
+struct ctb {
+ u_int64_t ctb_type; /* 0: always 4 */
+ u_int64_t ctb_unit; /* 8: */
+ u_int64_t ctb_reserved; /* 16: */
+ u_int64_t ctb_len; /* 24: bytes of info */
+ u_int64_t ctb_ipl; /* 32: console ipl level */
+ vm_offset_t ctb_tintr_vec; /* 40: transmit vec (0x800) */
+ vm_offset_t ctb_rintr_vec; /* 48: receive vec (0x800) */
+
+#define CTB_GRAPHICS 3 /* graphics device */
+#define CTB_NETWORK 0xC0 /* network device */
+#define CTB_PRINTERPORT 2 /* printer port on the SCC */
+ u_int64_t ctb_term_type; /* 56: terminal type */
+
+ u_int64_t ctb_keybd_type; /* 64: keyboard nationality */
+ vm_offset_t ctb_keybd_trans; /* 72: trans. table addr */
+ vm_offset_t ctb_keybd_map; /* 80: map table addr */
+ u_int64_t ctb_keybd_state; /* 88: keyboard flags */
+ u_int64_t ctb_keybd_last; /* 96: last key entered */
+ vm_offset_t ctb_font_us; /* 104: US font table addr */
+ vm_offset_t ctb_font_mcs; /* 112: MCS font table addr */
+ u_int64_t ctb_font_width; /* 120: font width, height */
+ u_int64_t ctb_font_height; /* 128: in pixels */
+ u_int64_t ctb_mon_width; /* 136: monitor width, height */
+ u_int64_t ctb_mon_height; /* 144: in pixels */
+ u_int64_t ctb_dpi; /* 152: monitor dots per inch */
+ u_int64_t ctb_planes; /* 160: # of planes */
+ u_int64_t ctb_cur_width; /* 168: cursor width, height */
+ u_int64_t ctb_cur_height; /* 176: in pixels */
+ u_int64_t ctb_head_cnt; /* 184: # of heads */
+ u_int64_t ctb_opwindow; /* 192: opwindow on screen */
+ vm_offset_t ctb_head_offset; /* 200: offset to head info */
+ vm_offset_t ctb_putchar; /* 208: output char to TURBO */
+ u_int64_t ctb_io_state; /* 216: I/O flags */
+ u_int64_t ctb_listen_state; /* 224: listener flags */
+ vm_offset_t ctb_xaddr; /* 232: extended info addr */
+ u_int64_t ctb_turboslot; /* 248: TURBOchannel slot # */
+ u_int64_t ctb_server_off; /* 256: offset to server info */
+ u_int64_t ctb_line_off; /* 264: line parameter offset */
+ u_int8_t ctb_csd; /* 272: console specific data */
+};
+
+/*
+ * CRD: Console Routine Descriptor
+ */
+struct crd {
+ int64_t descriptor;
+ u_int64_t entry_va;
+};
+
+/*
+ * CRB: Console Routine Block
+ */
+struct crb {
+ struct crd *crb_v_dispatch; /* 0: virtual dispatch addr */
+ vm_offset_t crb_p_dispatch; /* 8: phys dispatch addr */
+ struct crd *crb_v_fixup; /* 10: virtual fixup addr */
+ vm_offset_t crb_p_fixup; /* 18: phys fixup addr */
+ u_int64_t crb_map_cnt; /* 20: phys/virt map entries */
+ u_int64_t crb_page_cnt; /* 28: pages to be mapped */
+};
+
+/*
+ * MDDT: Memory Data Descriptor Table
+ */
+struct mddt {
+ int64_t mddt_cksum; /* 0: 7-N checksum */
+ vm_offset_t mddt_physaddr; /* 8: bank config addr
+ * IMPLEMENTATION SPECIFIC
+ */
+ u_int64_t mddt_cluster_cnt; /* 10: memory cluster count */
+ struct mddt_cluster {
+ vm_offset_t mddt_pfn; /* 0: starting PFN */
+ u_int64_t mddt_pg_cnt; /* 8: 8KB page count */
+ u_int64_t mddt_pg_test; /* 10: tested page count */
+ vm_offset_t mddt_v_bitaddr; /* 18: bitmap virt addr */
+ vm_offset_t mddt_p_bitaddr; /* 20: bitmap phys addr */
+ int64_t mddt_bit_cksum; /* 28: bitmap checksum */
+
+#define MDDT_NONVOLATILE 0x10 /* cluster is non-volatile */
+#define MDDT_PALCODE 0x01 /* console and PAL only */
+#define MDDT_SYSTEM 0x00 /* system software only */
+#define MDDT_mbz 0xfffffffffffffffc /* 2:63 -- must be zero */
+ int64_t mddt_usage; /* 30: bitmap permissions */
+ } mddt_clusters[1]; /* variable length array */
+};
+
+/*
+ * DSR: Dynamic System Recognition. We're interested in the sysname
+ * offset. The data pointed to by sysname is:
+ *
+ * [8 bytes: length of system name][N bytes: system name string]
+ *
+ * The system name string is NUL-terminated.
+ */
+struct dsrdb {
+ int64_t dsr_smm; /* 0: SMM number */
+ u_int64_t dsr_lurt_off; /* 8: LURT table offset */
+ u_int64_t dsr_sysname_off; /* 16: offset to sysname */
+};
+
+/*
+ * The DSR appeared in version 5 of the HWRPB.
+ */
+#define HWRPB_DSRDB_MINVERS 5
+
+#ifdef _KERNEL
+int cputype;
+#endif
+
+#endif /* ASSEMBLER */
diff --git a/sys/alpha/include/vmparam.h b/sys/alpha/include/vmparam.h
index bc543fdae9d6..612fe8ee3415 100644
--- a/sys/alpha/include/vmparam.h
+++ b/sys/alpha/include/vmparam.h
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: vmparam.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */
/* From: NetBSD: vmparam.h,v 1.6 1997/09/23 23:23:23 mjacob Exp */
#ifndef _ALPHA_VMPARAM_H
#define _ALPHA_VMPARAM_H
@@ -74,6 +74,9 @@
#ifndef MAXSSIZ
#define MAXSSIZ (1<<25) /* max stack size (32M) */
#endif
+#ifndef SGROWSIZ
+#define SGROWSIZ (128UL*1024) /* amount to grow stack */
+#endif
/*
* PTEs for mapping user space into the kernel for phyio operations.
@@ -131,23 +134,30 @@
/* user/kernel map constants */
#define VM_MIN_ADDRESS ((vm_offset_t)ALPHA_USEG_BASE) /* 0 */
-#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x0000000200000000) /* 8G XXX */
+#define VM_MAXUSER_ADDRESS ((vm_offset_t)(ALPHA_USEG_END + 1L))
#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS
#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)ALPHA_K1SEG_BASE)
#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)ALPHA_K1SEG_END)
/* virtual sizes (bytes) for various kernel submaps */
-#ifndef _KERNEL
-#define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES)
-#define VM_KMEM_SIZE (NKMEMCLUSTERS*CLBYTES)
-#define VM_PHYS_SIZE (USRIOSIZE*CLBYTES)
-#else
-extern u_int32_t vm_mbuf_size, vm_kmem_size, vm_phys_size;
-#define VM_MBUF_SIZE vm_mbuf_size
-#define VM_KMEM_SIZE vm_kmem_size
-#define VM_PHYS_SIZE vm_phys_size
+#ifndef VM_KMEM_SIZE
+#define VM_KMEM_SIZE (12 * 1024 * 1024)
+#endif
+
+/*
+ * How many physical pages per KVA page allocated.
+ * min(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MAX)
+ * is the total KVA space allocated for kmem_map.
+ */
+#ifndef VM_KMEM_SIZE_SCALE
+#define VM_KMEM_SIZE_SCALE (4) /* XXX 8192 byte pages */
+#endif
+
+/* initial pagein size of beginning of executable file */
+#ifndef VM_INITIAL_PAGEIN
+#define VM_INITIAL_PAGEIN 16
#endif
/* some Alpha-specific constants */
-#define VPTBASE ((vm_offset_t)0xfffffffc00000000) /* Virt. pg table */
+#define VPTBASE ((vm_offset_t)0xfffffffe00000000) /* Virt. pg table */
#endif /* !_ALPHA_VMPARAM_H */
diff --git a/sys/alpha/pci/pcibus.c b/sys/alpha/pci/pcibus.c
new file mode 100644
index 000000000000..6e488a87656f
--- /dev/null
+++ b/sys/alpha/pci/pcibus.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
+ * 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 unmodified, 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.
+ *
+ * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus_private.h>
+
+#include <pci/pcivar.h>
+#include <machine/chipset.h>
+
+static int cfgmech;
+static int devmax;
+
+#ifdef notyet
+
+/* return max number of devices on the bus */
+int
+pci_maxdevs(pcicfgregs *cfg)
+{
+ return chipset.maxdevs(cfg->bus);
+}
+
+#endif
+
+/* read configuration space register */
+
+int
+pci_cfgread(pcicfgregs *cfg, int reg, int bytes)
+{
+ switch (bytes) {
+ case 1:
+ return chipset.cfgreadb(cfg->bus, cfg->slot, cfg->func, reg);
+ case 2:
+ return chipset.cfgreadw(cfg->bus, cfg->slot, cfg->func, reg);
+ case 4:
+ return chipset.cfgreadl(cfg->bus, cfg->slot, cfg->func, reg);
+ }
+ return ~0;
+}
+
+
+/* write configuration space register */
+
+void
+pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes)
+{
+ switch (bytes) {
+ case 1:
+ return chipset.cfgwriteb(cfg->bus, cfg->slot, cfg->func, reg, data);
+ case 2:
+ return chipset.cfgwritew(cfg->bus, cfg->slot, cfg->func, reg, data);
+ case 4:
+ return chipset.cfgwritel(cfg->bus, cfg->slot, cfg->func, reg, data);
+ }
+}
+
+int
+pci_cfgopen(void)
+{
+ return 1;
+}
diff --git a/sys/alpha/pci/pcibus.h b/sys/alpha/pci/pcibus.h
new file mode 100644
index 000000000000..eb56cec1e2d8
--- /dev/null
+++ b/sys/alpha/pci/pcibus.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+typedef int alpha_pci_maxdevs_t(pcicfgregs*);
+typedef int alpha_pci_cfgread_t(pcicfgregs*, int, int);
+typedef void alpha_pci_cfgwrite_t(pcicfgregs*, int, int, int);
+
+struct alpha_pci_ops {
+ alpha_pci_maxdevs_t* maxdevs;
+ alpha_pci_cfgread_t* cfgread;
+ alpha_pci_cfgwrite_t* cfgwrite;
+};
+
+struct alpha_pci_softc {
+ struct alpha_pci_ops* ops;
+};
diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c
new file mode 100644
index 000000000000..e9f2aa5f7037
--- /dev/null
+++ b/sys/alpha/tlsb/dwlpx.c
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "opt_simos.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <alpha/tlsb/dwlpxreg.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+#include <alpha/tlsb/kftxxvar.h>
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
+#define DWLPX_BASE(n, h) ((((u_long)(n) - 4) << 36) \
+ | ((u_long)(h) << 34) \
+ | (1L << 39))
+
+static devclass_t dwlpx_devclass;
+static device_t dwlpx0; /* XXX only one for now */
+
+struct dwlpx_softc {
+ vm_offset_t dmem_base; /* dense memory */
+ vm_offset_t smem_base; /* sparse memory */
+ vm_offset_t io_base; /* sparse i/o */
+ vm_offset_t cfg_base; /* sparse pci config */
+};
+
+#define DWLPX_SOFTC(dev) (struct dwlpx_softc*) device_get_softc(dev)
+
+#define SPARSE_READ(o) (*(u_int32_t*) (o))
+#define SPARSE_WRITE(o, d) (*(u_int32_t*) (o) = (d))
+
+#define SPARSE_BYTE_OFFSET(o) (((o) << 5) | ((o) & 3))
+#define SPARSE_WORD_OFFSET(o) (((o) << 5) | ((o) & 2) | 0x8)
+#define SPARSE_LONG_OFFSET(o) (((o) << 5) | 0x18)
+
+#define SPARSE_BYTE_EXTRACT(o, d) ((d) >> (8*((o) & 3)))
+#define SPARSE_WORD_EXTRACT(o, d) ((d) >> (8*((o) & 2)))
+
+#define SPARSE_BYTE_INSERT(o, d) ((d) << (8*((o) & 3)))
+#define SPARSE_WORD_INSERT(o, d) ((d) << (8*((o) & 2)))
+
+#define SPARSE_READ_BYTE(base, o) \
+ SPARSE_BYTE_EXTRACT(o, SPARSE_READ(base + SPARSE_BYTE_OFFSET(o)))
+
+#define SPARSE_READ_WORD(base, o) \
+ SPARSE_WORD_EXTRACT(o, SPARSE_READ(base + SPARSE_WORD_OFFSET(o)))
+
+#define SPARSE_READ_LONG(base, o) \
+ SPARSE_READ(base + SPARSE_LONG_OFFSET(o))
+
+#define SPARSE_WRITE_BYTE(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_BYTE_OFFSET(o), SPARSE_BYTE_INSERT(o, d))
+
+#define SPARSE_WRITE_WORD(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_WORD_OFFSET(o), SPARSE_WORD_INSERT(o, d))
+
+#define SPARSE_WRITE_LONG(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_LONG_OFFSET(o), d)
+
+static alpha_chipset_inb_t dwlpx_inb;
+static alpha_chipset_inw_t dwlpx_inw;
+static alpha_chipset_inl_t dwlpx_inl;
+static alpha_chipset_outb_t dwlpx_outb;
+static alpha_chipset_outw_t dwlpx_outw;
+static alpha_chipset_outl_t dwlpx_outl;
+static alpha_chipset_maxdevs_t dwlpx_maxdevs;
+static alpha_chipset_cfgreadb_t dwlpx_cfgreadb;
+static alpha_chipset_cfgreadw_t dwlpx_cfgreadw;
+static alpha_chipset_cfgreadl_t dwlpx_cfgreadl;
+static alpha_chipset_cfgwriteb_t dwlpx_cfgwriteb;
+static alpha_chipset_cfgwritew_t dwlpx_cfgwritew;
+static alpha_chipset_cfgwritel_t dwlpx_cfgwritel;
+
+static alpha_chipset_t dwlpx_chipset = {
+ dwlpx_inb,
+ dwlpx_inw,
+ dwlpx_inl,
+ dwlpx_outb,
+ dwlpx_outw,
+ dwlpx_outl,
+ dwlpx_maxdevs,
+ dwlpx_cfgreadb,
+ dwlpx_cfgreadw,
+ dwlpx_cfgreadl,
+ dwlpx_cfgwriteb,
+ dwlpx_cfgwritew,
+ dwlpx_cfgwritel,
+};
+
+/*
+ * For supporting multiple busses, we will encode the dwlpx unit number into
+ * the port address as Linux does.
+ */
+
+static u_int8_t
+dwlpx_inb(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_BYTE(sc->io_base, port);
+}
+
+static u_int16_t
+dwlpx_inw(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_WORD(sc->io_base, port);
+}
+
+static u_int32_t
+dwlpx_inl(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_LONG(sc->io_base, port);
+}
+
+static void
+dwlpx_outb(u_int32_t port, u_int8_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_BYTE(sc->io_base, port, data);
+}
+
+static void
+dwlpx_outw(u_int32_t port, u_int16_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_WORD(sc->io_base, port, data);
+}
+
+static void
+dwlpx_outl(u_int32_t port, u_int32_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_LONG(sc->io_base, port, data);
+}
+
+static int
+dwlpx_maxdevs(u_int b)
+{
+ return 12; /* XXX */
+}
+
+/* XXX only support bus 0 */
+
+#define DWLPX_CFGOFF(b, s, f, r) \
+ (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+static u_int8_t
+dwlpx_cfgreadb(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 1)) return ~0;
+ return SPARSE_READ_BYTE(sc->cfg_base, off);
+}
+
+static u_int16_t
+dwlpx_cfgreadw(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 2)) return ~0;
+ return SPARSE_READ_WORD(sc->cfg_base, off);
+}
+
+static u_int32_t
+dwlpx_cfgreadl(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 4)) return ~0;
+ return SPARSE_READ_LONG(sc->cfg_base, off);
+}
+
+static void
+dwlpx_cfgwriteb(u_int b, u_int s, u_int f, u_int r, u_int8_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 1)) return;
+ SPARSE_WRITE_BYTE(sc->cfg_base, off, data);
+}
+
+static void
+dwlpx_cfgwritew(u_int b, u_int s, u_int f, u_int r, u_int16_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 2)) return;
+ SPARSE_WRITE_WORD(sc->cfg_base, off, data);
+}
+
+static void
+dwlpx_cfgwritel(u_int b, u_int s, u_int f, u_int r, u_int32_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 4)) return;
+ SPARSE_WRITE_LONG(sc->cfg_base, off, data);
+}
+
+static driver_probe_t dwlpx_probe;
+static driver_attach_t dwlpx_attach;
+static driver_intr_t dwlpx_intr;
+
+static driver_t dwlpx_driver = {
+ "dwlpx",
+ dwlpx_probe,
+ dwlpx_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct dwlpx_softc),
+ NULL,
+};
+
+
+static int
+dwlpx_probe(bus_t bus, device_t dev)
+{
+ if (dwlpx0)
+ return ENXIO;
+ device_set_desc(dev, "DWLPA or DWLPB PCI adapter");
+ return 0;
+}
+
+static int
+dwlpx_attach(bus_t bus, device_t dev)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dev);
+ vm_offset_t regs;
+ dwlpx0 = dev;
+
+ chipset = dwlpx_chipset;
+
+ regs = KV(DWLPX_BASE(kft_get_node(dev), kft_get_hosenum(dev)));
+ sc->dmem_base = regs + (0L << 32);
+ sc->smem_base = regs + (1L << 32);
+ sc->io_base = regs + (2L << 32);
+ sc->cfg_base = regs + (3L << 32);
+
+ *(u_int32_t*) (regs + PCIA_CTL(0)) = 1; /* Type1 config cycles */
+
+ bus_map_intr(bus, dev, dwlpx_intr, 0);
+
+ return 0;
+}
+
+static void
+dwlpx_intr(void* arg)
+{
+#ifdef SIMOS
+ extern void simos_intr(int);
+ simos_intr(0);
+#endif
+}
+
+DRIVER_MODULE(dwlpx, kft, dwlpx_driver, dwlpx_devclass, 0, 0);
+
diff --git a/sys/alpha/tlsb/dwlpxreg.h b/sys/alpha/tlsb/dwlpxreg.h
new file mode 100644
index 000000000000..cafadc4df3ac
--- /dev/null
+++ b/sys/alpha/tlsb/dwlpxreg.h
@@ -0,0 +1,237 @@
+/* $NetBSD: dwlpxreg.h,v 1.9 1998/03/21 22:02:42 mjacob Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Taken from combinations of:
+ *
+ * ``DWLPA and DWLPB PCI Adapter Technical Manual,
+ * Order Number: EK-DWLPX-TM.A01''
+ *
+ * and
+ *
+ * ``AlphaServer 8200/8400 System Technical Manual,
+ * Order Number EK-T8030-TM. A01''
+ */
+
+#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r))
+
+/*
+ * There are (potentially) 4 I/O hoses, and there are three
+ * (electrically distinct) PCI busses per DWLPX (which appear
+ * as one logical PCI bus).
+ *
+ * A CPU to PCI Address Mapping looks (roughly) like this:
+ *
+ * 39 38........36 35.34 33.....32 31....................5 4.........3 2...0
+ * --------------------------------------------------------------------------
+ * |1| I/O NodeID |Hose#|PCI Space|Byte Aligned I/O <26:0>|Byte Length|0 0 0|
+ * --------------------------------------------------------------------------
+ *
+ * I/O Node is the TLSB Node ID minus 4. Don't ask.
+ */
+
+#define NHPC 3
+
+/*
+ * Address Space Cookies
+ *
+ * (lacking I/O Node ID and Hose Numbers)
+ */
+
+#define DWLPX_PCI_DENSE 0x000000000LL
+#define DWLPX_PCI_SPARSE 0x100000000LL
+#define DWLPX_PCI_IOSPACE 0x200000000LL
+#define DWLPX_PCI_CONF 0x300000000LL
+
+/*
+ * PCIA Interface Adapter Register Addresses (Offsets from Node Address)
+ *
+ *
+ * Addresses are for Hose #0, PCI bus #0. Macros below will offset
+ * per bus. I/O Hose and TLSB Node I/D offsets must be added separately.
+ */
+
+#define _PCIA_CTL 0x380000000LL /* PCI 0 Bus Control */
+#define _PCIA_MRETRY 0x380000080LL /* PCI 0 Master Retry Limit */
+#define _PCIA_GPR 0x380000100LL /* PCI 0 General Purpose */
+#define _PCIA_ERR 0x380000180LL /* PCI 0 Error Summary */
+#define _PCIA_FADR 0x380000200LL /* PCI 0 Failing Address */
+#define _PCIA_IMASK 0x380000280LL /* PCI 0 Interrupt Mask */
+#define _PCIA_DIAG 0x380000300LL /* PCI 0 Diagnostic */
+#define _PCIA_IPEND 0x380000380LL /* PCI 0 Interrupt Pending */
+#define _PCIA_IPROG 0x380000400LL /* PCI 0 Interrupt in Progress */
+#define _PCIA_WMASK_A 0x380000480LL /* PCI 0 Window Mask A */
+#define _PCIA_WBASE_A 0x380000500LL /* PCI 0 Window Base A */
+#define _PCIA_TBASE_A 0x380000580LL /* PCI 0 Window Translated Base A */
+#define _PCIA_WMASK_B 0x380000600LL /* PCI 0 Window Mask B */
+#define _PCIA_WBASE_B 0x380000680LL /* PCI 0 Window Base B */
+#define _PCIA_TBASE_B 0x380000700LL /* PCI 0 Window Translated Base B */
+#define _PCIA_WMASK_C 0x380000780LL /* PCI 0 Window Mask C */
+#define _PCIA_WBASE_C 0x380000800LL /* PCI 0 Window Base C */
+#define _PCIA_TBASE_C 0x380000880LL /* PCI 0 Window Translated Base C */
+#define _PCIA_ERRVEC 0x380000900LL /* PCI 0 Error Interrupt Vector */
+#define _PCIA_DEVVEC 0x380001000LL /* PCI 0 Device Interrupt Vector */
+
+
+#define PCIA_CTL(hpc) (_PCIA_CTL + (0x200000 * (hpc)))
+#define PCIA_MRETRY(hpc) (_PCIA_MRETRY + (0x200000 * (hpc)))
+#define PCIA_GPR(hpc) (_PCIA_GPR + (0x200000 * (hpc)))
+#define PCIA_ERR(hpc) (_PCIA_ERR + (0x200000 * (hpc)))
+#define PCIA_FADR(hpc) (_PCIA_FADR + (0x200000 * (hpc)))
+#define PCIA_IMASK(hpc) (_PCIA_IMASK + (0x200000 * (hpc)))
+#define PCIA_DIAG(hpc) (_PCIA_DIAG + (0x200000 * (hpc)))
+#define PCIA_IPEND(hpc) (_PCIA_IPEND + (0x200000 * (hpc)))
+#define PCIA_IPROG(hpc) (_PCIA_IPROG + (0x200000 * (hpc)))
+#define PCIA_WMASK_A(hpc) (_PCIA_WMASK_A + (0x200000 * (hpc)))
+#define PCIA_WBASE_A(hpc) (_PCIA_WBASE_A + (0x200000 * (hpc)))
+#define PCIA_TBASE_A(hpc) (_PCIA_TBASE_A + (0x200000 * (hpc)))
+#define PCIA_WMASK_B(hpc) (_PCIA_WMASK_B + (0x200000 * (hpc)))
+#define PCIA_WBASE_B(hpc) (_PCIA_WBASE_B + (0x200000 * (hpc)))
+#define PCIA_TBASE_B(hpc) (_PCIA_TBASE_B + (0x200000 * (hpc)))
+#define PCIA_WMASK_C(hpc) (_PCIA_WMASK_C + (0x200000 * (hpc)))
+#define PCIA_WBASE_C(hpc) (_PCIA_WBASE_C + (0x200000 * (hpc)))
+#define PCIA_TBASE_C(hpc) (_PCIA_TBASE_C + (0x200000 * (hpc)))
+#define PCIA_ERRVEC(hpc) (_PCIA_ERRVEC + (0x200000 * (hpc)))
+
+#define PCIA_DEVVEC(hpc, subslot, ipin) \
+ (_PCIA_DEVVEC + (0x200000 * (hpc)) + ((subslot) * 0x200) + ((ipin-1) * 0x80))
+
+#define PCIA_SCYCLE 0x380002000LL /* PCI Special Cycle */
+#define PCIA_IACK 0x380002080LL /* PCI Interrupt Acknowledge */
+
+#define PCIA_PRESENT 0x380800000LL /* PCI Slot Present */
+#define PCIA_TBIT 0x380A00000LL /* PCI TBIT */
+#define PCIA_MCTL 0x380C00000LL /* PCI Module Control */
+#define PCIA_IBR 0x380E00000LL /* PCI Information Base Repair */
+
+/*
+ * Bits in PCIA_CTL register
+ */
+#define PCIA_CTL_SG32K (0<<25) /* 32K SGMAP entries */
+#define PCIA_CTL_SG64K (1<<25) /* 64K SGMAP entries */
+#define PCIA_CTL_SG128K (3<<25) /* 128K SGMAP entries */
+#define PCIA_CTL_SG0K (2<<25) /* disable SGMAP in HPC */
+#define PCIA_CTL_4UP (0<<23) /* 4 Up Hose buffers */
+#define PCIA_CTL_1UP (1<<23) /* 1 "" */
+#define PCIA_CTL_2UP (2<<23) /* 2 "" */
+#define PCIA_CTL_3UP (3<<23) /* 3 "" (normal) */
+#define PCIA_CTL_RMM4X (1<<22) /* Read Multiple 2X -> 4X */
+#define PCIA_CTL_RMMENA (1<<21) /* Read Multiple Enable */
+#define PCIA_CTL_RMMARB (1<<20) /* RMM Multiple Arb */
+#define PCIA_CTL_HAEDIS (1<<19) /* Hardware Address Ext. Disable */
+#define PCIA_CTL_MHAE(x) ((x&0x1f)<<14) /* Memory Hardware Address Extension */
+#define PCIA_CTL_IHAE(x) ((x&0x1f)<<9) /* I/O Hardware Address Extension */
+#define PCIA_CTL_CUTENA (1<<8) /* PCI Cut Through */
+#define PCIA_CTL_CUT(x) ((x&0x7)<<4) /* PCI Cut Through Size */
+#define PCIA_CTL_PRESET (1<<3) /* PCI Reset */
+#define PCIA_CTL_DTHROT (1<<2) /* DMA downthrottle */
+#define PCIA_CTL_T1CYC (1<<0) /* Type 1 Configuration Cycle */
+
+/*
+ * Bits in PCIA_ERR. All are "Write 1 to clear".
+ */
+#define PCIA_ERR_SERR_L (1<<18) /* PCI device asserted SERR_L */
+#define PCIA_ERR_ILAT (1<<17) /* Incremental Latency Exceeded */
+#define PCIA_ERR_SGPRTY (1<<16) /* CPU access of SG RAM Parity Error */
+#define PCIA_ERR_ILLCSR (1<<15) /* Illegal CSR Address Error */
+#define PCIA_ERR_PCINXM (1<<14) /* Nonexistent PCI Address Error */
+#define PCIA_ERR_DSCERR (1<<13) /* PCI Target Disconnect Error */
+#define PCIA_ERR_ABRT (1<<12) /* PCI Target Abort Error */
+#define PCIA_ERR_WPRTY (1<<11) /* PCI Write Parity Error */
+#define PCIA_ERR_DPERR (1<<10) /* PCI Data Parity Error */
+#define PCIA_ERR_APERR (1<<9) /* PCI Address Parity Error */
+#define PCIA_ERR_DFLT (1<<8) /* SG Map RAM Invalid Entry Error */
+#define PCIA_ERR_DPRTY (1<<7) /* DMA access of SG RAM Parity Error */
+#define PCIA_ERR_DRPERR (1<<6) /* DMA Read Return Parity Error */
+#define PCIA_ERR_MABRT (1<<5) /* PCI Master Abort Error */
+#define PCIA_ERR_CPRTY (1<<4) /* CSR Parity Error */
+#define PCIA_ERR_COVR (1<<3) /* CSR Overrun Error */
+#define PCIA_ERR_MBPERR (1<<2) /* Mailbox Parity Error */
+#define PCIA_ERR_MBILI (1<<1) /* Mailbox Illegal Length Error */
+#define PCIA_ERR_ERROR (1<<0) /* Summary Error */
+#define PCIA_ERR_ALLERR ((1<<19) - 1)
+
+/*
+ * Bits in PCIA_PRESENT.
+ */
+#define PCIA_PRESENT_REVSHIFT 25 /* shift by this to get revision */
+#define PCIA_PRESENT_REVMASK 0xf
+#define PCIA_PRESENT_STDIO 0x01000000 /* STD I/O bridge present */
+#define PCIA_PRESENT_SLOTSHIFT(hpc, slot) \
+ (((hpc) << 3) + ((slot) << 1))
+#define PCIA_PRESENT_SLOT_MASK 0x3
+#define PCIA_PRESENT_SLOT_NONE 0x0
+#define PCIA_PRESENT_SLOT_25W 0x1
+#define PCIA_PRESENT_SLOT_15W 0x2
+#define PCIA_PRESENT_SLOW_7W 0x3
+
+/*
+ * Location of the DWLPx SGMAP page table SRAM.
+ */
+#define PCIA_SGMAP_PT 0x381000000UL
+
+/*
+ * Values for PCIA_WMASK_x
+ */
+#define PCIA_WMASK_MASK 0xffff0000 /* mask of valid bits */
+#define PCIA_WMASK_64K 0x00000000
+#define PCIA_WMASK_128K 0x00010000
+#define PCIA_WMASK_256K 0x00030000
+#define PCIA_WMASK_512K 0x00070000
+#define PCIA_WMASK_1M 0x000f0000
+#define PCIA_WMASK_2M 0x001f0000
+#define PCIA_WMASK_4M 0x003f0000
+#define PCIA_WMASK_8M 0x007f0000
+#define PCIA_WMASK_16M 0x00ff0000
+#define PCIA_WMASK_32M 0x01ff0000
+#define PCIA_WMASK_64M 0x03ff0000
+#define PCIA_WMASK_128M 0x07ff0000
+#define PCIA_WMASK_256M 0x0fff0000
+#define PCIA_WMASK_512M 0x1fff0000
+#define PCIA_WMASK_1G 0x3fff0000
+#define PCIA_WMASK_2G 0x7fff0000
+#define PCIA_WMASK_4G 0xffff0000
+
+/*
+ * Values for PCIA_WBASE_x
+ */
+#define PCIA_WBASE_MASK 0xffff0000 /* mask of valid bits in address */
+#define PCIA_WBASE_W_EN 0x00000002 /* window enable */
+#define PCIA_WBASE_SG_EN 0x00000001 /* SGMAP enable */
+
+/*
+ * Values for PCIA_TBASE_x
+ *
+ * NOTE: Translated Base is only used on direct-mapped DMA on the DWLPx!!
+ */
+#define PCIA_TBASE_MASK 0x00fffffe
+#define PCIA_TBASE_SHIFT 15
diff --git a/sys/alpha/tlsb/gbus.c b/sys/alpha/tlsb/gbus.c
new file mode 100644
index 000000000000..523528439b7f
--- /dev/null
+++ b/sys/alpha/tlsb/gbus.c
@@ -0,0 +1,155 @@
+/* $Id */
+/* $NetBSD: gbus.c,v 1.8 1998/05/13 22:13:35 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Autoconfiguration and support routines for the Gbus: the internal
+ * bus on AlphaServer CPU modules.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/rpb.h>
+#include <machine/pte.h>
+
+#include <alpha/tlsb/gbusreg.h>
+#include <alpha/tlsb/gbusvar.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+extern int cputype;
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+/*
+ * The structure used to attach devices to the Gbus.
+ */
+struct gbus_device {
+ const char* gd_name;
+ int gd_offset;
+};
+
+#define DEVTOGBUS(dev) ((struct gbus_device*) device_get_ivars(dev))
+
+struct gbus_device gbus_children[] = {
+ { "zsc", GBUS_DUART0_OFFSET },
+/* { "zsc", GBUS_DUART1_OFFSET },*/
+ { "mcclock", GBUS_CLOCK_OFFSET },
+ { NULL, 0 },
+};
+
+static devclass_t gbus_devclass;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t gbus_print_device;
+static bus_read_ivar_t gbus_read_ivar;
+
+static bus_ops_t gbus_bus_ops = {
+ gbus_print_device,
+ gbus_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static void
+gbus_print_device(bus_t bus, device_t dev)
+{
+ struct gbus_device* gdev = DEVTOGBUS(dev);
+ device_t gbusdev = bus_get_device(bus);
+
+ printf(" at %s%d offset 0x%lx",
+ device_get_name(gbusdev), device_get_unit(gbusdev),
+ gdev->gd_offset);
+}
+
+static int
+gbus_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct gbus_device* gdev = DEVTOGBUS(dev);
+
+ switch (index) {
+ case GBUS_IVAR_OFFSET:
+ *result = gdev->gd_offset;
+ break;
+ }
+ return ENOENT;
+}
+
+static driver_probe_t gbus_bus_probe;
+
+static driver_t gbus_bus_driver = {
+ "gbus",
+ gbus_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct bus),
+ NULL,
+};
+
+/*
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
+ */
+static int
+gbus_bus_probe(bus_t parent, device_t dev)
+{
+ bus_t bus = device_get_softc(dev);
+ struct gbus_device *gdev;
+
+ /*
+ * Make sure we're looking for a Gbus.
+ * Right now, only Gbus could be a
+ * child of a TLSB CPU Node.
+ */
+ if (!TLDEV_ISCPU(tlsb_get_dtype(dev)))
+ return ENXIO;
+
+ bus_init(bus, dev, &gbus_bus_ops);
+
+ for (gdev = gbus_children; gdev->gd_name; gdev++)
+ bus_add_device(bus, gdev->gd_name, -1, gdev);
+
+ return 0;
+}
+
+DRIVER_MODULE(gbus, tlsb, gbus_bus_driver, gbus_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/gbusreg.h b/sys/alpha/tlsb/gbusreg.h
new file mode 100644
index 000000000000..4e758549df83
--- /dev/null
+++ b/sys/alpha/tlsb/gbusreg.h
@@ -0,0 +1,46 @@
+/* $NetBSD: gbusreg.h,v 1.1 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Register definitions for the Gbus found on TurboLaser CPU modules.
+ */
+
+#define GBUS_DUART0_OFFSET 0x10000000 /* duart 0 */
+#define GBUS_DUART1_OFFSET 0x11000000 /* duart 1 */
+#define GBUS_CLOCK_OFFSET 0x20000000 /* clock */
diff --git a/sys/alpha/tlsb/gbusvar.h b/sys/alpha/tlsb/gbusvar.h
new file mode 100644
index 000000000000..16526192c969
--- /dev/null
+++ b/sys/alpha/tlsb/gbusvar.h
@@ -0,0 +1,64 @@
+/* $NetBSD: gbusvar.h,v 1.1 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 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.
+ */
+
+/*
+ * Autoconfiguration definitions for the Gbus found on TurboLaser CPU modules.
+ */
+
+/* #include <machine/bus.h> */
+
+enum gbus_device_ivars {
+ GBUS_IVAR_OFFSET /* offset from Gbus base */
+};
+
+/*
+ * Simplified accessors for gbus devices
+ */
+
+#define GBUS_ACCESSOR(A, B, T) \
+ \
+static __inline T gbus_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, GBUS_IVAR_ ## B, &v); \
+ return (T) v; \
+}
+
+GBUS_ACCESSOR(offset, OFFSET, u_int32_t)
+
diff --git a/sys/alpha/tlsb/kftxx.c b/sys/alpha/tlsb/kftxx.c
new file mode 100644
index 000000000000..9f41b623ce01
--- /dev/null
+++ b/sys/alpha/tlsb/kftxx.c
@@ -0,0 +1,192 @@
+/* $Id$ */
+/* $NetBSD: kftxx.c,v 1.9 1998/05/14 00:01:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * KFTIA and KFTHA Bus Adapter Node for I/O hoses
+ * found on AlphaServer 8200 and 8400 systems.
+ *
+ * i.e., handler for all TLSB I/O nodes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/rpb.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+#include <alpha/tlsb/kftxxreg.h>
+#include <alpha/tlsb/kftxxvar.h>
+
+struct kft_softc {
+ struct bus sc_bus; /* bus common */
+ int sc_node; /* TLSB node */
+ u_int16_t sc_dtype; /* device type */
+};
+
+/*
+ * Instance variables for kft devices.
+ */
+struct kft_device {
+ char * kd_name; /* name */
+ int kd_node; /* node number */
+ u_int16_t kd_dtype; /* device type */
+ u_int16_t kd_hosenum; /* hose number */
+};
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+static devclass_t kft_devclass;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t kft_print_device;
+static bus_read_ivar_t kft_read_ivar;
+
+static bus_ops_t kft_bus_ops = {
+ kft_print_device,
+ kft_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static void
+kft_print_device(bus_t bus, device_t dev)
+{
+ struct kft_device *kd = (struct kft_device*) device_get_ivars(dev);
+ device_t busdev = bus_get_device(bus);
+
+ printf(" at %s%d hose %d",
+ device_get_name(busdev), device_get_unit(busdev),
+ kd->kd_hosenum);
+}
+
+static int
+kft_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct kft_device *kd = (struct kft_device*) device_get_ivars(dev);
+
+ switch (index) {
+ case KFT_IVAR_NAME:
+ *result = (u_long) kd->kd_name;
+ return 0;
+
+ case KFT_IVAR_NODE:
+ *result = (u_long) kd->kd_node;
+ return 0;
+
+ case KFT_IVAR_DTYPE:
+ *result = (u_long) kd->kd_dtype;
+ return 0;
+
+ case KFT_IVAR_HOSENUM:
+ *result = (u_long) kd->kd_hosenum;
+ return 0;
+
+ default:
+ return ENOENT;
+ }
+}
+
+static driver_probe_t kft_bus_probe;
+
+static driver_t kft_bus_driver = {
+ "kft",
+ kft_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct kft_softc),
+ NULL,
+};
+
+static int
+kft_bus_probe(bus_t parent, device_t dev)
+{
+ struct kft_softc *sc = (struct kft_softc *) device_get_softc(dev);
+ struct kft_device* kd;
+ int hoseno;
+
+ if (!TLDEV_ISIOPORT(tlsb_get_dtype(dev)))
+ return ENXIO;
+
+ bus_init(&sc->sc_bus, dev, &kft_bus_ops);
+
+ sc->sc_node = tlsb_get_node(dev);
+ sc->sc_dtype = tlsb_get_dtype(dev);
+
+ for (hoseno = 0; hoseno < MAXHOSE; hoseno++) {
+ u_int32_t value =
+ TLSB_GET_NODEREG(sc->sc_node, KFT_IDPNSEX(hoseno));
+ if (value & 0x0E000000) {
+ printf("%s%d: Hose %d IDPNSE has %x\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+ if ((value & 0x1) != 0x0) {
+ printf("%s%d: Hose %d has a Bad Cable (0x%x)\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+ if ((value & 0x6) != 0x6) {
+ if (value)
+ printf("%s%d: Hose %d is missing PWROK (0x%x)\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+
+ kd = (struct kft_device*) malloc(sizeof(struct kft_device),
+ M_DEVBUF, M_NOWAIT);
+ if (!kd) continue;
+
+ kd->kd_name = "dwlpx";
+ kd->kd_node = sc->sc_node;
+ kd->kd_dtype = sc->sc_dtype;
+ kd->kd_hosenum = hoseno;
+ bus_add_device(&sc->sc_bus, kd->kd_name, -1, kd);
+ }
+
+ return 0;
+}
+
+DRIVER_MODULE(kft, tlsb, kft_bus_driver, kft_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/kftxxreg.h b/sys/alpha/tlsb/kftxxreg.h
new file mode 100644
index 000000000000..0f45fdd5e1ce
--- /dev/null
+++ b/sys/alpha/tlsb/kftxxreg.h
@@ -0,0 +1,74 @@
+/* $NetBSD: kftxxreg.h,v 1.4 1997/06/04 01:47:15 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Registers and values specific to KFTIA or KFTHA nodes.
+ */
+
+/*
+ * Taken from combinations of:
+ *
+ * ``DWLPA and DWLPB PCI Adapter Technical Manual,
+ * Order Number: EK-DWLPX-TM.A01''
+ *
+ * and
+ *
+ * ``AlphaServer 8200/8400 System Technical Manual,
+ * Order Number EK-T8030-TM. A01''
+ */
+
+#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r))
+
+/*
+ * There are (potentially) 4 I/O hoses per I/O node.
+ *
+ * A CPU to Hose Address Mapping looks (roughly) like this:
+ *
+ * 39 38........36 35.34 33.................0
+ * -------------------------------------------
+ * |1|TLSB NodeID |Hose#|Hose Module Specific|
+ * -------------------------------------------
+ *
+ */
+
+#define HOSE_SIZE 0x400000000L
+
+#define MAXHOSE 4
+/*
+ * Hose Specific I/O registers (offsets from base of I/O Board)
+ */
+
+#define KFT_IDPNSEX(hose) ((hose)? (0x2040 + (0x100 * (hose))) : 0x2A40)
+
+#define KFT_ICCNSE 0x2040
+#define KFT_ICCWTR 0x2100
+#define KFT_IDPMSR 0x2B80
diff --git a/sys/alpha/tlsb/kftxxvar.h b/sys/alpha/tlsb/kftxxvar.h
new file mode 100644
index 000000000000..d0b3f40cc834
--- /dev/null
+++ b/sys/alpha/tlsb/kftxxvar.h
@@ -0,0 +1,59 @@
+/* $NetBSD: kftxxvar.h,v 1.3 1997/04/06 20:08:38 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Instance vars for children of a KFTIA or KFTHA node.
+ */
+enum kft_dev_ivars {
+ KFT_IVAR_NAME,
+ KFT_IVAR_NODE,
+ KFT_IVAR_DTYPE,
+ KFT_IVAR_HOSENUM
+};
+
+/*
+ * Simplified accessors for kft devices
+ */
+
+#define KFT_ACCESSOR(A, B, T) \
+ \
+static __inline T kft_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, KFT_IVAR_ ## B, &v); \
+ return (T) v; \
+}
+
+KFT_ACCESSOR(name, NAME, const char*)
+KFT_ACCESSOR(node, NODE, int)
+KFT_ACCESSOR(dtype, DTYPE, u_int16_t)
+KFT_ACCESSOR(hosenum, HOSENUM, u_int16_t)
diff --git a/sys/alpha/tlsb/mcclock_tlsb.c b/sys/alpha/tlsb/mcclock_tlsb.c
new file mode 100644
index 000000000000..15974fc878b7
--- /dev/null
+++ b/sys/alpha/tlsb/mcclock_tlsb.c
@@ -0,0 +1,126 @@
+/* $Id$ */
+/* $NetBSD: mcclock_tlsb.c,v 1.8 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <dev/dec/clockvar.h>
+#include <dev/dec/mcclockvar.h>
+
+#include <alpha/tlsb/gbusvar.h>
+
+#include <alpha/tlsb/tlsbreg.h> /* XXX */
+
+#include <dev/dec/mc146818reg.h>
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+/*
+ * Registers are 64 bytes apart (and 1 byte wide)
+ */
+#define REGSHIFT 6
+
+struct mcclock_tlsb_softc {
+ struct mcclock_softc sc_mcclock;
+ unsigned long regbase;
+};
+
+static int mcclock_tlsb_probe(bus_t, device_t);
+static int mcclock_tlsb_attach(bus_t, device_t);
+
+static devclass_t mcclock_devclass;
+
+driver_t mcclock_tlsb_driver = {
+ "mcclock",
+ mcclock_tlsb_probe,
+ mcclock_tlsb_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct mcclock_tlsb_softc),
+ NULL,
+};
+
+static void mcclock_tlsb_write __P((struct mcclock_softc *, u_int, u_int));
+static u_int mcclock_tlsb_read __P((struct mcclock_softc *, u_int));
+
+const struct mcclock_busfns mcclock_tlsb_busfns = {
+ mcclock_tlsb_write, mcclock_tlsb_read,
+};
+
+int
+mcclock_tlsb_probe(bus_t bus, device_t dev)
+{
+ device_set_desc(dev, "MC146818A real time clock");
+ return 0;
+}
+
+int
+mcclock_tlsb_attach(bus_t bus, device_t dev)
+{
+ struct mcclock_tlsb_softc *sc = device_get_softc(dev);
+
+ /* XXX Should be bus.h'd, so we can accomodate the kn7aa. */
+
+ sc->sc_mcclock.sc_dev = dev;
+ sc->regbase = TLSB_GBUS_BASE + gbus_get_offset(dev);
+
+ mcclock_attach(&sc->sc_mcclock, &mcclock_tlsb_busfns);
+ return 0;
+}
+
+static void
+mcclock_tlsb_write(mcsc, reg, val)
+ struct mcclock_softc *mcsc;
+ u_int reg, val;
+{
+ struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
+ unsigned char *ptr = (unsigned char *)
+ KV(sc->regbase + (reg << REGSHIFT));
+ *ptr = val;
+}
+
+static u_int
+mcclock_tlsb_read(mcsc, reg)
+ struct mcclock_softc *mcsc;
+ u_int reg;
+{
+ struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
+ unsigned char *ptr = (unsigned char *)
+ KV(sc->regbase + (reg << REGSHIFT));
+ return *ptr;
+}
+
+DRIVER_MODULE(mcclock_tlsb, gbus, mcclock_tlsb_driver, mcclock_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/tlsb.c b/sys/alpha/tlsb/tlsb.c
new file mode 100644
index 000000000000..7b778ac0c546
--- /dev/null
+++ b/sys/alpha/tlsb/tlsb.c
@@ -0,0 +1,329 @@
+/* $Id */
+/* $NetBSD: tlsb.c,v 1.10 1998/05/14 00:01:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Autoconfiguration and support routines for the TurboLaser System Bus
+ * found on AlphaServer 8200 and 8400 systems.
+ */
+
+#include "opt_simos.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <machine/rpb.h>
+#include <machine/cpuconf.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+/* #include "locators.h" */
+
+extern int cputype;
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+/*
+ * The structure used to attach devices to the TurboLaser.
+ */
+struct tlsb_device {
+ int td_node; /* node number */
+ u_int16_t td_dtype; /* device type */
+ u_int8_t td_swrev; /* software revision */
+ u_int8_t td_hwrev; /* hardware revision */
+};
+#define DEVTOTLSB(dev) ((struct tlsb_device*) device_get_ivars(dev))
+
+struct intr_mapping {
+ STAILQ_ENTRY(intr_mapping) queue;
+ driver_intr_t* intr;
+ void* arg;
+};
+
+struct tlsb_softc {
+ struct bus bus;
+ STAILQ_HEAD(, intr_mapping) intr_handlers;
+};
+
+static char *tlsb_node_type_str(u_int32_t);
+static void tlsb_intr(void* frame, u_long vector);
+
+/* There can be only one. */
+static int tlsb_found;
+static struct tlsb_softc* tlsb0_softc;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t tlsb_print_device;
+static bus_read_ivar_t tlsb_read_ivar;
+static bus_map_intr_t tlsb_map_intr;
+
+static bus_ops_t tlsb_bus_ops = {
+ tlsb_print_device,
+ tlsb_read_ivar,
+ null_write_ivar,
+ tlsb_map_intr,
+};
+
+static void
+tlsb_print_device(bus_t bus, device_t dev)
+{
+ device_t busdev = bus_get_device(bus);
+ struct tlsb_device* tdev = DEVTOTLSB(dev);
+
+ printf(" at %s%d node %d",
+ device_get_name(busdev),
+ device_get_unit(busdev),
+ tdev->td_node);
+}
+
+static int
+tlsb_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct tlsb_device* tdev = DEVTOTLSB(dev);
+
+ switch (index) {
+ case TLSB_IVAR_NODE:
+ *result = tdev->td_node;
+ break;
+
+ case TLSB_IVAR_DTYPE:
+ *result = tdev->td_dtype;
+ break;
+
+ case TLSB_IVAR_SWREV:
+ *result = tdev->td_swrev;
+ break;
+
+ case TLSB_IVAR_HWREV:
+ *result = tdev->td_hwrev;
+ break;
+ }
+ return ENOENT;
+}
+
+static int
+tlsb_map_intr(bus_t bus, device_t dev, driver_intr_t *intr, void *arg)
+{
+ struct tlsb_softc* sc = (struct tlsb_softc*) bus;
+ struct intr_mapping* i;
+ i = malloc(sizeof(struct intr_mapping), M_DEVBUF, M_NOWAIT);
+ if (!i)
+ return ENOMEM;
+ i->intr = intr;
+ i->arg = arg;
+ STAILQ_INSERT_TAIL(&sc->intr_handlers, i, queue);
+
+ return 0;
+}
+
+static driver_probe_t tlsb_bus_probe;
+static devclass_t tlsb_devclass;
+
+static driver_t tlsb_bus_driver = {
+ "tlsb",
+ tlsb_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct tlsb_softc),
+ NULL,
+};
+
+/*
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
+ */
+static int
+tlsb_bus_probe(bus_t parent, device_t dev)
+{
+ struct tlsb_softc* sc = device_get_softc(dev);
+ struct tlsb_device *tdev;
+ u_int32_t tldev;
+ u_int8_t vid;
+ int node;
+ device_t subdev;
+
+ device_set_desc(dev, "TurboLaser bus");
+ bus_init(&sc->bus, dev, &tlsb_bus_ops);
+ STAILQ_INIT(&sc->intr_handlers);
+ tlsb0_softc = sc;
+
+ set_iointr(tlsb_intr);
+
+ printf("Probing for devices on the TurboLaser bus:\n");
+
+ tlsb_found = 1;
+
+ /*
+ * Attempt to find all devices on the bus, including
+ * CPUs, memory modules, and I/O modules.
+ */
+
+ /*
+ * Sigh. I would like to just start off nicely,
+ * but I need to treat I/O modules differently-
+ * The highest priority I/O node has to be in
+ * node #8, and I want to find it *first*, since
+ * it will have the primary disks (most likely)
+ * on it.
+ */
+ /*
+ * XXX dfr: I don't see why I need to do this
+ */
+ for (node = 0; node <= TLSB_NODE_MAX; ++node) {
+ /*
+ * Check for invalid address. This may not really
+ * be necessary, but what the heck...
+ */
+ if (badaddr(TLSB_NODE_REG_ADDR(node, TLDEV), sizeof(u_int32_t)))
+ continue;
+ tldev = TLSB_GET_NODEREG(node, TLDEV);
+#ifdef SIMOS
+ if (node != 0 && node != 8)
+ continue;
+#endif
+ if (tldev == 0) {
+ /* Nothing at this node. */
+ continue;
+ }
+#if 0
+ if (TLDEV_ISIOPORT(tldev))
+ continue; /* not interested right now */
+#endif
+
+ tdev = (struct tlsb_device*)
+ malloc(sizeof(struct tlsb_device),
+ M_DEVBUF, M_NOWAIT);
+
+ if (!tdev)
+ continue;
+
+ tdev->td_node = node;
+#ifdef SIMOS
+ if (node == 0)
+ tdev->td_dtype = TLDEV_DTYPE_SCPU4;
+ else if (node == 8)
+ tdev->td_dtype = TLDEV_DTYPE_KFTIA;
+#else
+ tdev->td_dtype = TLDEV_DTYPE(tldev);
+#endif
+ tdev->td_swrev = TLDEV_SWREV(tldev);
+ tdev->td_hwrev = TLDEV_HWREV(tldev);
+
+ subdev = bus_add_device(&sc->bus, NULL, -1, tdev);
+ device_set_desc(subdev, tlsb_node_type_str(tdev->td_dtype));
+
+ /*
+ * Deal with hooking CPU instances to TurboLaser nodes.
+ */
+ if (TLDEV_ISCPU(tldev)) {
+ printf("%s%d node %d: %s",
+ device_get_name(dev), device_get_unit(dev),
+ node, tlsb_node_type_str(tldev));
+
+ /*
+ * Hook in the first CPU unit.
+ */
+ vid = (TLSB_GET_NODEREG(node, TLVID) &
+ TLVID_VIDA_MASK) >> TLVID_VIDA_SHIFT;
+ printf(", VID %d\n", vid);
+ TLSB_PUT_NODEREG(node, TLCPUMASK, (1<<vid));
+ }
+ }
+
+ return 0;
+}
+
+static void
+tlsb_intr(void* frame, u_long vector)
+{
+ struct tlsb_softc* sc = tlsb0_softc;
+ struct intr_mapping* i;
+
+ /*
+ * XXX for SimOS, broadcast the interrupt. A real implementation
+ * will decode the vector to extract node and host etc.
+ */
+ for (i = STAILQ_FIRST(&sc->intr_handlers);
+ i; i = STAILQ_NEXT(i, queue))
+ i->intr(i->arg);
+}
+
+DRIVER_MODULE(tlsb, root, tlsb_bus_driver, tlsb_devclass, 0, 0);
+
+static char *
+tlsb_node_type_str(u_int32_t dtype)
+{
+ static char tlsb_line[64];
+
+ switch (dtype & TLDEV_DTYPE_MASK) {
+ case TLDEV_DTYPE_KFTHA:
+ return ("KFTHA I/O interface");
+
+ case TLDEV_DTYPE_KFTIA:
+ return ("KFTIA I/O interface");
+
+ case TLDEV_DTYPE_MS7CC:
+ return ("MS7CC Memory Module");
+
+ case TLDEV_DTYPE_SCPU4:
+ return ("Single CPU, 4MB cache");
+
+ case TLDEV_DTYPE_SCPU16:
+ return ("Single CPU, 16MB cache");
+
+ case TLDEV_DTYPE_DCPU4:
+ return ("Dual CPU, 4MB cache");
+
+ case TLDEV_DTYPE_DCPU16:
+ return ("Dual CPU, 16MB cache");
+
+ default:
+ bzero(tlsb_line, sizeof(tlsb_line));
+ sprintf(tlsb_line, "unknown, dtype 0x%x", dtype);
+ return (tlsb_line);
+ }
+ /* NOTREACHED */
+}
diff --git a/sys/alpha/tlsb/tlsbmem.c b/sys/alpha/tlsb/tlsbmem.c
new file mode 100644
index 000000000000..c46306c80031
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbmem.c
@@ -0,0 +1,91 @@
+/* $NetBSD: tlsbmem.c,v 1.6 1998/01/12 10:21:25 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Dummy Node for TLSB Memory Modules found on
+ * AlphaServer 8200 and 8400 systems.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: tlsbmem.c,v 1.6 1998/01/12 10:21:25 thorpej Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/autoconf.h>
+#include <machine/rpb.h>
+#include <machine/pte.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+struct tlsbmem_softc {
+ struct device sc_dv;
+ int sc_node; /* TLSB node */
+ u_int16_t sc_dtype; /* device type */
+};
+
+static int tlsbmemmatch __P((struct device *, struct cfdata *, void *));
+static void tlsbmemattach __P((struct device *, struct device *, void *));
+struct cfattach tlsbmem_ca = {
+ sizeof (struct tlsbmem_softc), tlsbmemmatch, tlsbmemattach
+};
+
+static int
+tlsbmemmatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct tlsb_dev_attach_args *ta = aux;
+ if (TLDEV_ISMEM(ta->ta_dtype))
+ return (1);
+ return (0);
+}
+
+static void
+tlsbmemattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct tlsb_dev_attach_args *ta = aux;
+ struct tlsbmem_softc *sc = (struct tlsbmem_softc *)self;
+
+ sc->sc_node = ta->ta_node;
+ sc->sc_dtype = ta->ta_dtype;
+
+ printf("\n");
+}
diff --git a/sys/alpha/tlsb/tlsbreg.h b/sys/alpha/tlsb/tlsbreg.h
new file mode 100644
index 000000000000..37b58de6dfdf
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbreg.h
@@ -0,0 +1,318 @@
+/* $NetBSD: tlsbreg.h,v 1.3 1997/04/06 20:08:40 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Definitions for the TurboLaser System Bus found on
+ * AlphaServer 8200/8400 systems.
+ */
+
+/*
+ * There are 9 TurboLaser nodes, 0 though 8. Their uses are defined as
+ * follows:
+ *
+ * Node Module
+ * ---- ------
+ * 0 CPU, Memory
+ * 1 CPU, Memory
+ * 2 CPU, Memory
+ * 3 CPU, Memory
+ * 4 CPU, Memory, I/O
+ * 5 CPU, Memory, I/O
+ * 6 CPU, Memory, I/O
+ * 7 CPU, Memory, I/O
+ * 8 I/O
+ *
+ * A node occurs every 0x00400000 bytes.
+ *
+ * Note, the AlphaServer 8200 only has nodes 4 though 8.
+ */
+
+#define TLSB_NODE_BASE 0x000000ff88000000 /* Dense */
+#define TLSB_NODE_SIZE 0x00400000
+#define TLSB_NODE_MAX 8
+
+/* Translate a node number to an address. */
+#define TLSB_NODE_ADDR(_node) \
+ (long)(TLSB_NODE_BASE + ((_node) * TLSB_NODE_SIZE))
+
+#define TLSB_NODE_REG_ADDR(_node, _reg) \
+ KV((long)TLSB_NODE_ADDR((_node)) + (_reg))
+
+/* Access the specified register on the specified node. */
+#define TLSB_GET_NODEREG(_node, _reg) \
+ *(volatile u_int32_t *)(TLSB_NODE_REG_ADDR((_node), (_reg)))
+#define TLSB_PUT_NODEREG(_node, _reg, _val) \
+ *(volatile u_int32_t *)(TLSB_NODE_REG_ADDR((_node), (_reg))) = (_val)
+
+/*
+ * Some registers are shared by all TurboLaser nodes, and appear in
+ * the TurboLaser Broadcast space.
+ */
+#define TLSB_BCAST_BASE 0x000000ff8e000000 /* Dense */
+
+#define TLSB_BCAST_REG_ADDR(_reg) KV((long)(TLSB_BCASE_BASE + (_reg)))
+
+/* Access the specified register in the broadcast space. */
+#define TLSB_GET_BCASTREG(_reg) \
+ *(volatile u_int32_t *)(TLSB_BCAST_REG_ADDR + (_reg))
+#define TLSB_PUT_BCASTREG(_reg, _val) \
+ *(volatile u_int32_t *)(TLSB_BCAST_REG_ADDR + (_reg)) = (_val)
+
+/*
+ * Location of the Gbus, the per-CPU bus containing the clock and
+ * console hardware.
+ */
+#define TLSB_GBUS_BASE 0x000000ff90000000 /* Dense */
+
+/*
+ * Note that not every module type supports each TurboLaser register.
+ * The following defines the keys used to denote module support for
+ * a given register:
+ *
+ * C Supported by CPU module
+ * M Supported by Memory module
+ * I Supported by I/O module
+ */
+
+/*
+ * Per-node TurboLaser System Bus registers, offsets from the
+ * base of the node.
+ */
+#define TLDEV 0x0000 /* CMI: Device Register */
+#define TLBER 0x0040 /* CMI: Bus Error Register */
+#define TLCNR 0x0080 /* CMI: Congfiguration Register */
+#define TLVID 0x00c0 /* CM: Virtual ID Register */
+#define TLMMR0 0x0200 /* CM: Memory Mapping Register 0 */
+#define TLMMR1 0x0240 /* CM: Memory Mapping Register 1 */
+#define TLMMR2 0x0280 /* CM: Memory Mapping Register 2 */
+#define TLMMR3 0x02c0 /* CM: Memory Mapping Register 3 */
+#define TLMMR4 0x0300 /* CM: Memory Mapping Register 4 */
+#define TLMMR5 0x0340 /* CM: Memory Mapping Register 5 */
+#define TLMMR6 0x0380 /* CM: Memory Mapping Register 6 */
+#define TLMMR7 0x03c0 /* CM: Memory Mapping Register 7 */
+#define TLFADR0 0x0600 /* MI: Failing Address Register 0 */
+#define TLFADR1 0x0640 /* MI: Failing Address Register 1 */
+#define TLESR0 0x0680 /* CMI: Error Syndrome Register 0 */
+#define TLESR1 0x06c0 /* CMI: Error Syndrome Register 1 */
+#define TLESR2 0x0700 /* CMI: Error Syndrome Register 2 */
+#define TLESR3 0x0740 /* CMI: Error Syndrome Register 3 */
+#define TLILID0 0x0a00 /* I: Int. Level 0 IDENT Register */
+#define TLILID1 0x0a40 /* I: Int. Level 1 IDENT Register */
+#define TLILID2 0x0a80 /* I: Int. Level 2 IDENT Register */
+#define TLILID3 0x0ac0 /* I: Int. Level 3 IDENT Register */
+#define TLCPUMASK 0x0b00 /* I: CPU Interrupt Mask Register */
+#define TLMBPTR 0x0c00 /* I: Mailbox Pointer Register */
+#define TLEPAERR 0x1500 /* C: ADG error register */
+
+/*
+ * Registers shared between TurboLaser nodes, offsets from the
+ * TurboLaser Broadcast Base.
+ */
+#define TLPRIVATE 0x0000 /* CMI: private "global" space */
+#define TLIPINTR 0x0040 /* C: Interprocessor Int. Register */
+#define TLIOINTR4 0x0100 /* C: I/O Interrupt Register 4 */
+#define TLIOINTR5 0x0140 /* C: I/O Interrupt Register 5 */
+#define TLIOINTR6 0x0180 /* C: I/O Interrupt Register 6 */
+#define TLIOINTR7 0x01c0 /* C: I/O Interrupt Register 7 */
+#define TLIOINTR8 0x0200 /* C: I/O Interrupt Register 8 */
+#define TLWSDQR4 0x0400 /* C: Win Spc Dcr Que Ctr Reg 4 */
+#define TLWSDQR5 0x0440 /* C: Win Spc Dcr Que Ctr Reg 5 */
+#define TLWSDQR6 0x0480 /* C: Win Spc Dcr Que Ctr Reg 6 */
+#define TLWSDQR7 0x04c0 /* C: Win Spc Dcr Que Ctr Reg 7 */
+#define TLWSDQR8 0x0500 /* C: Win Spc Dcr Que Ctr Reg 8 */
+#define TLRMDQRX 0x0600 /* C: Mem Chan Dcr Que Ctr Reg X */
+#define TLRMDQR8 0x0640 /* C: Mem Chan Dcr Que Ctr Reg 8 */
+#define TLRDRD 0x0800 /* C: CSR Read Data Rtn Data Reg */
+#define TLRDRE 0x0840 /* C: CSR Read Data Rtn Error Reg */
+#define TLMCR 0x1880 /* M: Memory Control Register */
+
+/*
+ * TLDEV - Device Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * Register is loaded during initialization with information
+ * that identifies a node. A zero value indicates a non-initialized
+ * (slot empty) node.
+ *
+ * Bits 0-15 contain the hardware device type, bits 16-23
+ * the board's software revision, and bits 24-31 the board's
+ * hardware revision.
+ *
+ * The device type portion is laid out as follows:
+ *
+ * Bit 15: identifies a CPU
+ * Bit 14: identifies a memory board
+ * Bit 13: identifies an I/O board
+ * Bits 0-7: specify the ID of a node type
+ */
+#define TLDEV_DTYPE_MASK 0x0000ffff
+#define TLDEV_DTYPE_KFTHA 0x2000 /* KFTHA board, I/O */
+#define TLDEV_DTYPE_KFTIA 0x2020 /* KFTIA board, I/O */
+#define TLDEV_DTYPE_MS7CC 0x5000 /* Memory board */
+#define TLDEV_DTYPE_SCPU4 0x8011 /* 1 CPU, 4mb cache */
+#define TLDEV_DTYPE_SCPU16 0x8012 /* 1 CPU, 16mb cache */
+#define TLDEV_DTYPE_DCPU4 0x8014 /* 2 CPU, 4mb cache */
+#define TLDEV_DTYPE_DCPU16 0x8015 /* 2 CPU, 16mb cache */
+
+#define TLDEV_DTYPE(_val) ((_val) & TLDEV_DTYPE_MASK)
+# define TLDEV_ISCPU(_val) (TLDEV_DTYPE(_val) & 0x8000)
+# define TLDEV_ISMEM(_val) (TLDEV_DTYPE(_val) & 0x4000)
+# define TLDEV_ISIOPORT(_val) (TLDEV_DTYPE(_val) & 0x2000)
+#define TLDEV_SWREV(_val) (((_val) >> 16) & 0xff)
+#define TLDEV_HWREV(_val) (((_val) >> 24) & 0xff)
+
+/*
+ * TLBER - Bus Error Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * This register contains information about TLSB errors detected by
+ * nodes on the TLSB. The register will become locked when:
+ *
+ * * Any error occurs and the "lock on first error"
+ * bit of the Configuration Register is set.
+ *
+ * * Any bit other than 20-23 (DS0-DS3) becomes set.
+ *
+ * and will remain locked until either:
+ *
+ * * All bits in the TLBER are cleared.
+ *
+ * * The "lock on first error" bit is cleared.
+ *
+ * TLBER locking is intended for diagnosic purposes only, and
+ * not for general use.
+ */
+#define TLBER_ATCE 0x00000001 /* Addr Transmit Ck Error */
+#define TLBER_APE 0x00000002 /* Addr Parity Error */
+#define TLBER_BAE 0x00000004 /* Bank Avail Violation Error */
+#define TLBER_LKTO 0x00000008 /* Bank Lock Timeout */
+#define TLBER_NAE 0x00000010 /* No Ack Error */
+#define TLBER_RTCE 0x00000020 /* Read Transmit Ck Error */
+#define TLBER_ACKTCE 0x00000040 /* Ack Transmit Ck Error */
+#define TLBER_MMRE 0x00000080 /* Mem Mapping Register Error */
+#define TLBER_FNAE 0x00000100 /* Fatal No Ack Error */
+#define TLBER_REQDE 0x00000200 /* Request Deassertion Error */
+#define TLBER_ATDE 0x00000400 /* Addredd Transmitter During Error */
+#define TLBER_UDE 0x00010000 /* Uncorrectable Data Error */
+#define TLBER_CWDE 0x00020000 /* Correctable Write Data Error */
+#define TLBER_CRDE 0x00040000 /* Correctable Read Data Error */
+#define TLBER_CRDE2 0x00080000 /* ...ditto... */
+#define TLBER_DS0 0x00100000 /* Data Synd 0 */
+#define TLBER_DS1 0x00200000 /* Data Synd 1 */
+#define TLBER_DS2 0x00400000 /* Data Synd 2 */
+#define TLBER_DS3 0x00800000 /* Data Synd 3 */
+#define TLBER_DTDE 0x01000000 /* Data Transmitter During Error */
+#define TLBER_FDTCE 0x02000000 /* Fatal Data Transmit Ck Error */
+#define TLBER_UACKE 0x04000000 /* Unexpected Ack Error */
+#define TLBER_ABTCE 0x08000000 /* Addr Bus Transmit Error */
+#define TLBER_DCTCE 0x10000000 /* Data Control Transmit Ck Error */
+#define TLBER_SEQE 0x20000000 /* Sequence Error */
+#define TLBER_DSE 0x40000000 /* Data Status Error */
+#define TLBER_DTO 0x80000000 /* Data Timeout Error */
+
+/*
+ * TLCNR - Configuration Register
+ *
+ * Access: R/W
+ */
+#define TLCNR_CWDD 0x00000001 /* Corr Write Data Err INTR Dis */
+#define TLCNR_CRDD 0x00000002 /* Corr Read Data Err INTR Dis */
+#define TLCNR_LKTOD 0x00000004 /* Bank Lock Timeout Disable */
+#define TLCNR_DTOD 0x00000008 /* Data Timeout Disable */
+#define TLCNR_STF_A 0x00001000 /* Self-Test Fail A */
+#define TLCNR_STF_B 0x00002000 /* Self-Test Fail B */
+#define TLCNR_HALT_A 0x00100000 /* Halt A */
+#define TLCNR_HALT_B 0x00200000 /* Halt B */
+#define TLCNR_RSTSTAT 0x10000000 /* Reset Status */
+#define TLCNR_NRST 0x40000000 /* Node Reset */
+#define TLCNR_LOFE 0x80000000 /* Lock On First Error */
+
+#define TLCNR_NODE_MASK 0x000000f0 /* Node ID mask */
+#define TLCNR_NODE_SHIFT 4
+
+#define TLCNR_VCNT_MASK 0x00000f00 /* VCNT mask */
+#define TLCNR_VCNT_SHIFT 8
+
+/*
+ * TLVID - Virtual ID Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * Virtual units can be CPUs or Memory boards. The units are
+ * are addressed using virtual IDs. These virtual IDs are assigned
+ * by writing to the TLVID register. The upper 24 bits of this
+ * register are reserved and must be written as `0'.
+ */
+#define TLVID_VIDA_MASK 0x0000000f /* Virtual ID for unit 0 */
+#define TLVID_VIDA_SHIFT 0
+
+#define TLVID_VIDB_MASK 0x000000f0 /* Virtual ID for unit 1 */
+#define TLVID_VIDB_SHIFT 4
+
+/*
+ * TLMMRn - Memory Mapping Registers
+ *
+ * Access: W
+ *
+ * Notes:
+ * Contains mapping information for doing a bank-decode.
+ */
+#define TLMMR_INTMASK 0x00000003 /* Valid bits in Interleave */
+#define TLMMR_ADRMASK 0x000000f0 /* Valid bits in Address */
+#define TLMMR_SBANK 0x00000800 /* Single-bank indicator */
+#define TLMMR_VALID 0x80000000 /* Indicated mapping is valid */
+
+#define TLMMR_INTLV_MASK 0x00000700 /* Mask for interleave value */
+#define TLMMR_INTLV_SHIFT 8
+
+#define TLMMR_ADDRESS_MASK 0x03fff000 /* Mask for address value */
+#define TLMMR_ADDRESS_SHIFT 12
+
+/*
+ * TLFADRn - Failing Address Registers
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * These registers contain status information for a failed address.
+ * Not all nodes preserve this information. The validation bits
+ * indicate the validity of a given field.
+ */
+
diff --git a/sys/alpha/tlsb/tlsbvar.h b/sys/alpha/tlsb/tlsbvar.h
new file mode 100644
index 000000000000..bfb24ed4557e
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbvar.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+/* $NetBSD: tlsbvar.h,v 1.5 1998/05/13 23:23:23 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Definitions for the TurboLaser System Bus found on
+ * AlphaServer 8200/8400 systems.
+ */
+
+enum tlsb_device_instvars {
+ TLSB_IVAR_NODE,
+ TLSB_IVAR_DTYPE,
+ TLSB_IVAR_SWREV,
+ TLSB_IVAR_HWREV
+};
+
+/*
+ * Simplified accessors for turbolaser devices
+ */
+
+#define TLSB_ACCESSOR(A, B, T) \
+ \
+static __inline T tlsb_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, TLSB_IVAR_ ## B, &v); \
+ return v; \
+}
+
+TLSB_ACCESSOR(node, NODE, int)
+TLSB_ACCESSOR(dtype, DTYPE, u_int16_t)
+TLSB_ACCESSOR(hwrev, HWREV, u_int8_t)
+TLSB_ACCESSOR(swrev, SWREV, u_int8_t)
+
+/*
+ * Bus-dependent structure for CPUs. This is dynamically allocated
+ * for each CPU on the TurboLaser, and glued into the cpu_softc
+ * as sc_busdep (when there is a cpu_softc to do this to).
+ */
+struct tlsb_cpu_busdep {
+ u_int8_t tcpu_vid; /* virtual ID of CPU */
+ int tcpu_node; /* TurboLaser node */
+};
diff --git a/sys/alpha/tlsb/zs_tlsb.c b/sys/alpha/tlsb/zs_tlsb.c
new file mode 100644
index 000000000000..8532ed33e05f
--- /dev/null
+++ b/sys/alpha/tlsb/zs_tlsb.c
@@ -0,0 +1,473 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+/*
+ * This driver is a hopeless hack to get the SimOS console working. A real
+ * driver would use the zs driver source from NetBSD.
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/ucred.h>
+#include <machine/cons.h>
+#include <machine/clock.h>
+
+#include <alpha/tlsb/gbusvar.h>
+#include <alpha/tlsb/tlsbreg.h> /* XXX */
+#include <alpha/tlsb/zsreg.h>
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+static int zsc_get_channel(device_t dev);
+static caddr_t zsc_get_base(device_t dev);
+
+struct zs_softc {
+ struct tty tty;
+ int channel;
+ caddr_t base;
+};
+#define ZS_SOFTC(unit) \
+ ((struct zs_softc*)devclass_get_softc(zs_devclass, (unit)))
+
+static d_open_t zsopen;
+static d_close_t zsclose;
+static d_read_t zsread;
+static d_write_t zswrite;
+static d_ioctl_t zsioctl;
+static d_stop_t zsstop;
+static d_devtotty_t zsdevtotty;
+
+#define CDEV_MAJOR 97
+static struct cdevsw zs_cdevsw = {
+ zsopen, zsclose, zsread, zswrite,
+ zsioctl, zsstop, noreset, zsdevtotty,
+ ttpoll, nommap, NULL, "zs",
+ NULL, -1,
+};
+
+static void zsstart __P((struct tty *));
+static int zsparam __P((struct tty *, struct termios *));
+
+/*
+ * Helpers for console support.
+ */
+
+static int zs_cngetc __P((dev_t));
+static void zs_cnputc __P((dev_t, int));
+static void zs_cnpollc __P((dev_t, int));
+
+struct consdev zs_cons = {
+ NULL, NULL, zs_cngetc, NULL, zs_cnputc,
+ NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
+};
+
+static caddr_t zs_console_addr;
+static int zs_console;
+
+static int zs_probe(bus_t, device_t);
+static int zs_attach(bus_t, device_t);
+
+static devclass_t zs_devclass;
+static devclass_t zsc_devclass;
+
+driver_t zs_driver = {
+ "zs",
+ zs_probe,
+ zs_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct zs_softc),
+ NULL,
+};
+
+static int
+zs_probe(bus_t bus, device_t dev)
+{
+ return 0;
+}
+
+static int
+zs_attach(bus_t bus, device_t dev)
+{
+ struct zs_softc *sc = device_get_softc(dev);
+
+ sc->channel = zsc_get_channel(dev);
+ sc->base = zsc_get_base(dev);
+
+ return 0;
+}
+
+static int
+zs_get_status(caddr_t base)
+{
+ return (*(u_int32_t*) (base + ZSC_STATUS)) & 0xff;
+}
+
+static void
+zs_put_status(caddr_t base, int v)
+{
+ *(u_int32_t*) (base + ZSC_STATUS) = v;
+ alpha_mb();
+}
+
+static int
+zs_get_rr3(caddr_t base)
+{
+ zs_put_status(base, 3);
+ return zs_get_status(base);
+}
+
+static int
+zs_get_data(caddr_t base)
+{
+ return (*(u_int32_t*) (base + ZSC_DATA)) & 0xff;
+}
+
+static void
+zs_put_data(caddr_t base, int v)
+{
+ *(u_int32_t*) (base + ZSC_DATA) = v;
+ alpha_mb();
+}
+
+static int
+zs_getc(caddr_t base)
+{
+ while (!(zs_get_status(base) & 1))
+ DELAY(5);
+ return zs_get_data(base);
+}
+
+static void
+zs_putc(caddr_t base, int c)
+{
+ while (!(zs_get_status(base) & 4))
+ DELAY(5);
+ zs_put_data(base, c);
+}
+
+extern struct consdev* cn_tab;
+
+int
+zs_cnattach(vm_offset_t base, vm_offset_t offset)
+{
+ zs_console_addr = (caddr_t) ALPHA_PHYS_TO_K0SEG(base + offset);
+ zs_console = 1;
+
+ cn_tab = &zs_cons;
+ return 0;
+}
+
+static int
+zs_cngetc(dev_t dev)
+{
+ int s = spltty();
+ int c = zs_getc(zs_console_addr);
+ splx(s);
+ return c;
+}
+
+static void
+zs_cnputc(dev_t dev, int c)
+{
+ int s = spltty();
+ zs_putc(zs_console_addr, c);
+ splx(s);
+}
+
+static void
+zs_cnpollc(dev_t dev, int onoff)
+{
+}
+
+
+static int
+zsopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct zs_softc* sc = ZS_SOFTC(minor(dev));
+ struct tty *tp;
+ int s;
+ int error = 0;
+
+ if (!sc)
+ return ENXIO;
+
+ s = spltty();
+
+ tp = &sc->tty;
+
+ tp->t_oproc = zsstart;
+ tp->t_param = zsparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_CARR_ON;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = 9600;
+ ttsetwater(tp);
+ } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return EBUSY;
+ }
+
+ splx(s);
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+
+ return error;
+}
+
+static int
+zsclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return 0;
+}
+
+static int
+zsread(dev_t dev, struct uio *uio, int flag)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+static int
+zswrite(dev_t dev, struct uio *uio, int flag)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+static int
+zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ int error;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+ if (error != ENOIOCTL)
+ return error;
+
+ return ENOTTY;
+}
+
+static int
+zsparam(struct tty *tp, struct termios *t)
+{
+
+ return 0;
+}
+
+static void
+zsstart(struct tty *tp)
+{
+ struct zs_softc* sc = (struct zs_softc*) tp;
+ int s;
+
+ s = spltty();
+
+ if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
+ ttwwakeup(tp);
+ splx(s);
+ return;
+ }
+
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0)
+ zs_putc(sc->base, getc(&tp->t_outq));
+ tp->t_state &= ~TS_BUSY;
+
+ ttwwakeup(tp);
+ splx(s);
+}
+
+/*
+ * Stop output on a line.
+ */
+static void
+zsstop(struct tty *tp, int flag)
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY)
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ splx(s);
+}
+
+static struct tty *
+zsdevtotty(dev_t dev)
+{
+ struct zs_softc* sc = ZS_SOFTC(minor(dev));
+ if (!sc)
+ return (NULL);
+ return (&sc->tty);
+}
+
+CDEV_DRIVER_MODULE(zs, zsc, zs_driver, zs_devclass,
+ CDEV_MAJOR, zs_cdevsw, 0, 0);
+
+/*
+ * The zsc bus holds two zs devices, one for channel A, one for channel B.
+ */
+
+struct zsc_softc {
+ struct bus bus;
+ caddr_t base;
+ struct zs_softc* sc_a;
+ struct zs_softc* sc_b;
+};
+
+static driver_probe_t zsc_tlsb_probe;
+static driver_attach_t zsc_tlsb_attach;
+static driver_intr_t zsc_tlsb_intr;
+static bus_print_device_t zsc_tlsb_print_device;
+
+driver_t zsc_tlsb_driver = {
+ "zsc",
+ zsc_tlsb_probe,
+ zsc_tlsb_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct zsc_softc),
+ NULL,
+};
+
+
+static bus_ops_t zsc_tlsb_ops = {
+ zsc_tlsb_print_device,
+ null_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static int
+zsc_get_channel(device_t dev)
+{
+ return (long) device_get_ivars(dev);
+}
+
+static caddr_t
+zsc_get_base(device_t dev)
+{
+ device_t busdev = bus_get_device(device_get_parent(dev));
+ struct zsc_softc* sc = device_get_softc(busdev);
+ return sc->base;
+}
+
+static void
+zsc_tlsb_print_device(bus_t bus, device_t dev)
+{
+ device_t busdev = bus_get_device(bus);
+
+ printf(" at %s%d channel %c",
+ device_get_name(busdev), device_get_unit(busdev),
+ 'A' + (device_get_unit(dev) & 1));
+}
+
+static int
+zsc_tlsb_probe(bus_t parent, device_t dev)
+{
+ struct zsc_softc* sc = device_get_softc(dev);
+
+ device_set_desc(dev, "Z8530 uart");
+
+ bus_init(&sc->bus, dev, &zsc_tlsb_ops);
+
+ sc->base = (caddr_t) ALPHA_PHYS_TO_K0SEG(TLSB_GBUS_BASE
+ + gbus_get_offset(dev));
+
+ /*
+ * Add channel A for now.
+ */
+ bus_add_device(&sc->bus, "zs", -1, (void*) 0);
+
+ return 0;
+}
+
+static int
+zsc_tlsb_attach(bus_t parent, device_t dev)
+{
+ struct zsc_softc* sc = device_get_softc(dev);
+
+ bus_generic_attach(parent, dev);
+
+ /* XXX */
+ sc->sc_a = ZS_SOFTC(0);
+
+ bus_map_intr(parent, dev, zsc_tlsb_intr, sc);
+
+ return 0;
+}
+
+
+static void
+zsc_tlsb_intr(void* arg)
+{
+ struct zsc_softc* sc = arg;
+ caddr_t base = sc->base;
+
+ /* XXX only allow for zs0 at zsc0 */
+ int rr3 = zs_get_rr3(base);
+ if (rr3 & 0x20) {
+ struct tty* tp = &sc->sc_a->tty;
+ int c;
+
+ while (zs_get_status(base) & 1) {
+ c = zs_get_data(base);
+#ifdef DDB
+ if (c == CTRL('\\'))
+ Debugger("manual escape to debugger");
+#endif
+ if (tp->t_state & TS_ISOPEN)
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ DELAY(5);
+ }
+ }
+}
+
+DRIVER_MODULE(zsc_tlsb, gbus, zsc_tlsb_driver, zsc_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/zsreg.h b/sys/alpha/tlsb/zsreg.h
new file mode 100644
index 000000000000..68e567d7087b
--- /dev/null
+++ b/sys/alpha/tlsb/zsreg.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#define ZSC_STATUS 0x80
+#define ZSC_DATA 0xc0
diff --git a/sys/conf/Makefile.alpha b/sys/conf/Makefile.alpha
new file mode 100644
index 000000000000..ecc9daa7235d
--- /dev/null
+++ b/sys/conf/Makefile.alpha
@@ -0,0 +1,272 @@
+# Makefile.alpha -- with config changes.
+# Copyright 1990 W. Jolitz
+# from: @(#)Makefile.alpha 7.1 5/10/91
+# $Id: Makefile.alpha,v 1.109 1998/04/17 07:51:36 dima Exp $
+#
+# Makefile for FreeBSD
+#
+# This makefile is constructed from a machine description:
+# config machineid
+# Most changes should be made in the machine description
+# /sys/alpha/conf/``machineid''
+# after which you should do
+# config machineid
+# Generic makefile changes should be made in
+# /sys/alpha/conf/Makefile.alpha
+# after which config should be rerun for all machines.
+#
+
+# Which version of config(8) is required.
+%VERSREQ= 300003
+
+BINFORMAT?= elf
+
+STD8X16FONT?= iso
+
+.if exists(./@/.)
+S= ./@
+.else
+S= ../..
+.endif
+ALPHA= ${S}/alpha
+
+COPTFLAGS?=-O
+INCLUDES= -nostdinc -I- -I. -I$S
+# This hack is to allow kernel compiles to succeed on machines w/out srcdist
+.if exists($S/../include)
+INCLUDES+= -I$S/../include
+.else
+INCLUDES+= -I/usr/include
+.endif
+COPTS= ${INCLUDES} ${IDENT} -DKERNEL -include opt_global.h
+CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS} -mno-fp-regs
+LOAD_ADDRESS?= 0xfffffc0000230000
+DEFINED_PROF= ${PROF}
+.if defined(PROF)
+CFLAGS+= -malign-functions=4
+.if ${PROFLEVEL} >= 2
+IDENT+= -DGPROF4 -DGUPROF
+PROF+= -mprofiler-epilogue
+.endif
+.endif
+
+NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} $<
+NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+# XXX LOCORE means "don't declare C stuff" not "for locore.s".
+NORMAL_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
+DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
+DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+DRIVER_S= ${CC} -c -x assembler-with-cpp -DLOCORE ${COPTS} $<
+PROFILE_C= ${CC} -c ${CFLAGS} ${PARAM} $<
+
+# ${ALPHA}/alpha/setdef0.c and ${ALPHA}/alpha/setdef1.c are intentionally
+# omitted from SYSTEM_CFILES. They depend on setdefs.h, a header which
+# is generated from all of ${OBJS}. We don't want to have to compile
+# everything just to do a make depend.
+SYSTEM_CFILES= ioconf.c param.c vnode_if.c config.c
+SYSTEM_SFILES= ${ALPHA}/alpha/locore.s
+SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
+.if ${CFLAGS:M-g} == ""
+SYMORDER_EXCLUDE=-x symbols.exclude
+.endif
+SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
+.if ${BINFORMAT} == elf
+SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} ioconf.o param.o config.o \
+ setdef1.o
+SYSTEM_LD= @${LD} -Bstatic -N -Ttext ${LOAD_ADDRESS} -e locorestart -defsym _DYNAMIC=0 \
+ -o $@ -X ${SYSTEM_OBJS} vers.o
+SYSTEM_LD_TAIL= @size $@; chmod 755 $@
+.endif
+
+%BEFORE_DEPEND
+
+%OBJS
+
+%CFILES
+
+%SFILES
+
+%LOAD
+
+%CLEAN
+
+clean:
+ rm -f *.o *.s eddep errs genassym gensetdefs kernel linterrs \
+ makelinks param.c setdefs.h symbols.exclude symbols.sort tags \
+ vers.c vnode_if.c vnode_if.h ${CLEAN}
+
+#lint: /tmp param.c
+# @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} \
+# ${ALPHA}/alpha/Locore.c ${CFILES} ioconf.c param.c | \
+# grep -v 'struct/union .* never defined' | \
+# grep -v 'possible pointer alignment problem'
+
+symbols.exclude: Makefile
+ echo "gcc2_compiled." >symbols.exclude
+ echo "___gnu_compiled_c" >>symbols.exclude
+
+symbols.sort: ${ALPHA}/alpha/symbols.raw
+ grep -v '^#' ${ALPHA}/alpha/symbols.raw \
+ | sed 's/^ //' | sort -u > symbols.sort
+
+locore.o: ${ALPHA}/alpha/locore.s assym.s
+ ${NORMAL_S}
+
+setdef0.o: ${ALPHA}/alpha/setdef0.c setdefs.h
+ ${NORMAL_C}
+
+setdef1.o: ${ALPHA}/alpha/setdef1.c setdefs.h
+ ${NORMAL_C}
+
+setdefs.h: gensetdefs ${OBJS}
+ @echo Generating kernel linker sets
+ @./gensetdefs ${OBJS} >setdefs.h
+
+gensetdefs: gensetdefs.o
+ ${CC} ${CFLAGS} gensetdefs.o -o $@
+
+gensetdefs.o: ${ALPHA}/alpha/gensetdefs.c
+ ${CC} -c ${CFLAGS} ${ALPHA}/alpha/gensetdefs.c
+
+# everything potentially depends on the Makefile since everything potentially
+# depends on the options. Some things are more dependent on the Makefile for
+# historical reasons.
+machdep.o: Makefile
+
+# the following is necessary because autoconf.o depends on #if GENERIC
+autoconf.o: Makefile
+
+# XXX - may no longer be needed
+locore.o: Makefile
+
+# depends on KDB (cons.o also depends on GENERIC)
+trap.o cons.o: Makefile
+
+# this rule stops ./assym.s in .depend from causing problems
+./assym.s: assym.s
+
+assym.s: genassym
+ ./genassym >assym.s
+
+# Some of the defines that genassym outputs may well depend on the
+# value of kernel options.
+genassym.o: ${ALPHA}/alpha/genassym.c Makefile opt_global.h
+ ${CC} -c ${CFLAGS} ${PARAM} -UKERNEL ${ALPHA}/alpha/genassym.c
+
+genassym: genassym.o
+ ${CC} ${CFLAGS} ${PARAM} genassym.o -o $@
+
+SYSTEM_OBJS+= __divqu.o __divq.o __divlu.o __divl.o
+SYSTEM_OBJS+= __remqu.o __remq.o __remlu.o __reml.o
+CLEAN+= __divqu.S __divq.S __divlu.S __divl.S
+CLEAN+= __remqu.S __remq.S __remlu.S __reml.S
+
+__divqu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divqu')define(OP,\`div')define(S,\`false')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divq.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divq')define(OP,\`div')define(S,\`true')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divlu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divlu')define(OP,\`div')define(S,\`false')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__divl.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__divl')define(OP,\`div')define(S,\`true')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remqu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remqu')define(OP,\`rem')define(S,\`false')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remq.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remq')define(OP,\`rem')define(S,\`true')"; \
+ echo "define(WORDSIZE,64)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__remlu.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__remlu')define(OP,\`rem')define(S,\`false')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+__reml.S: ${S}/alpha/alpha/divrem.m4
+ @echo 'building ${.TARGET} from ${.ALLSRC}'
+ @(echo "define(NAME,\`__reml')define(OP,\`rem')define(S,\`true')"; \
+ echo "define(WORDSIZE,32)"; cat ${.ALLSRC}) | m4 > ${.TARGET}
+
+
+${OBJS}: opt_global.h
+
+# XXX this assumes that the options for NORMAL_C* and DRIVER_C* are identical.
+depend: assym.s param.c vnode_if.h ${BEFORE_DEPEND}
+ rm -f .newdep
+ mkdep -a -f .newdep ${COPTS} ${CFILES} ${SYSTEM_CFILES}
+ mkdep -a -f .newdep ${COPTS} ${PARAM} -UKERNEL ${ALPHA}/alpha/genassym.c
+ MKDEP_CPP="${CC} -E -x assembler-with-cpp" ; export MKDEP_CPP ; \
+ mkdep -a -f .newdep -DLOCORE ${COPTS} ${SFILES} ${SYSTEM_SFILES}
+ rm -f .depend
+ mv -f .newdep .depend
+
+cleandepend:
+ rm -f .depend
+
+links:
+ egrep '#if' ${CFILES:Nswapkernel.c} | sed -f $S/conf/defines | \
+ sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
+ echo ${CFILES:Nswapkernel.c} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
+ sort -u | comm -23 - dontlink | \
+ sed 's,../.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks
+ sh makelinks && rm -f dontlink
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+install:
+ @if [ ! -f kernel ] ; then \
+ echo "You must first build your kernel before trying to install." ; \
+ exit 1 ; \
+ fi
+.if exists(${DESTDIR}/kernel)
+ chflags noschg ${DESTDIR}/kernel
+ mv ${DESTDIR}/kernel ${DESTDIR}/kernel.old
+.endif
+ PATH=$${PATH}:/sbin:/usr/sbin; \
+ if [ `sysctl -n kern.bootfile` = ${DESTDIR}/kernel ] ; then \
+ sysctl -w kern.bootfile=${DESTDIR}/kernel.old ; \
+ if [ -f /var/db/kvm_kernel.db ] ; then \
+ mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
+ fi \
+ fi
+ install -c -m 555 -o root -g wheel -fschg kernel ${DESTDIR}/
+
+ioconf.o: ioconf.c $S/sys/param.h $S/sys/buf.h
+ ${CC} -c ${CFLAGS} ioconf.c
+
+param.c: $S/conf/param.c
+ -rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${CC} -c ${CFLAGS} ${PARAM} param.c
+
+vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh ${KERN_IDENT} ${IDENT}
+ ${CC} ${CFLAGS} -c vers.c
+
+vnode_if.c: $S/kern/vnode_if.sh $S/kern/vnode_if.src
+ sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src
+ sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+
+.include <bsd.kern.mk>
+
+%RULES
+
+# DO NOT DELETE THIS LINE -- make depend uses it
diff --git a/sys/conf/files b/sys/conf/files
index 74e85534e8e7..bc9694b22f47 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,6 +1,6 @@
aicasm optional ahc device-driver \
dependency "$S/dev/aic7xxx/*.[chyl]" \
- compile-with "make -f $S/dev/aic7xxx/Makefile MAKESRCPATH=$S/dev/aic7xxx" \
+ compile-with "${MAKE} -f $S/dev/aic7xxx/Makefile MAKESRCPATH=$S/dev/aic7xxx" \
no-obj no-implicit-rule \
clean "aicasm"
#
@@ -86,7 +86,7 @@ kern/inflate.c optional gzip
kern/init_main.c standard
kern/init_sysent.c standard
kern/init_sysvec.c standard
-kern/kern_intr.c standard
+#kern/kern_intr.c standard
kern/kern_module.c standard
kern/kern_linker.c standard
kern/link_aout.c standard
@@ -403,6 +403,7 @@ pci/pci_compat.c optional pci
pci/pcisupport.c optional pci
pci/tek390.c optional amd device-driver
pci/wdc_p.c optional wdc device-driver
+pci/simos.c optional simos device-driver
pci/xrpu.c optional xrpu device-driver
posix4/posix4_mib.c standard
posix4/p1003_1b.c standard
diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha
new file mode 100644
index 000000000000..04e5410ad8b4
--- /dev/null
+++ b/sys/conf/files.alpha
@@ -0,0 +1,80 @@
+# This file tells config what files go into building a kernel,
+# files marked standard are always included.
+#
+# $Id$
+#
+# The long compile-with and dependency lines are required because of
+# limitations in config: backslash-newline doesn't work in strings, and
+# dependency lines other than the first are silently ignored.
+#
+#
+font8x16.o optional std8x16font \
+ compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
+ no-implicit-rule before-depend \
+ clean "${STD8X16FONT}-8x16 font8x16.c"
+
+#
+alpha/alpha/autoconf.c standard device-driver
+alpha/alpha/cpuconf.c standard
+alpha/alpha/dec_kn8ae.c optional dec_kn8ae
+alpha/alpha/mountroot.c optional slice
+alpha/alpha/ipl_funcs.c standard
+alpha/alpha/pal.s standard
+alpha/alpha/cons.c standard
+alpha/alpha/prom.c standard
+alpha/alpha/prom_disp.s standard
+alpha/alpha/db_disasm.c optional ddb
+alpha/alpha/db_interface.c optional ddb
+alpha/alpha/db_trace.c optional ddb
+alpha/alpha/exception.s standard
+alpha/alpha/in_cksum.c optional inet
+# locore.s needs to be handled in Makefile to put it first. Otherwise it's
+# now normal.
+# alpha/alpha/locore.s standard
+alpha/alpha/machdep.c standard
+alpha/alpha/math_emulate.c optional math_emulate
+alpha/alpha/mem.c standard
+alpha/alpha/mp_machdep.c optional smp
+alpha/alpha/perfmon.c optional perfmon profiling-routine
+alpha/alpha/perfmon.c optional perfmon
+alpha/alpha/pmap.c standard
+alpha/alpha/procfs_machdep.c standard
+alpha/alpha/simplelock.s optional smp
+alpha/alpha/support.s standard
+alpha/alpha/swtch.s standard
+alpha/alpha/sys_machdep.c standard
+alpha/alpha/trap.c standard
+alpha/alpha/interrupt.c standard
+alpha/alpha/userconfig.c optional userconfig
+alpha/alpha/vm_machdep.c standard
+alpha/alpha/clock.c standard
+alpha/alpha/diskslice_machdep.c standard
+alpha/tlsb/tlsb.c optional tlsb
+alpha/tlsb/gbus.c optional gbus
+alpha/tlsb/kftxx.c optional kft
+alpha/tlsb/mcclock_tlsb.c optional gbus
+alpha/tlsb/zs_tlsb.c optional gbus
+alpha/tlsb/dwlpx.c optional dwlpx
+dev/dec/mcclock.c optional gbus
+alpha/pci/pcibus.c optional pci
+kern/subr_bus.c standard
+libkern/bcd.c standard
+libkern/bcmp.c standard
+libkern/ffs.c standard
+libkern/inet_ntoa.c standard
+libkern/index.c standard
+libkern/mcount.c optional profiling-routine
+libkern/qsort.c standard
+libkern/random.c standard
+libkern/scanc.c standard
+libkern/skpc.c standard
+libkern/strcat.c standard
+libkern/strcmp.c standard
+libkern/strcpy.c standard
+libkern/strlen.c standard
+libkern/strncmp.c standard
+libkern/strncpy.c standard
+libkern/alpha/htonl.S standard
+libkern/alpha/htons.S standard
+libkern/alpha/ntohl.S standard
+libkern/alpha/ntohs.S standard
diff --git a/sys/conf/options.alpha b/sys/conf/options.alpha
new file mode 100644
index 000000000000..666e7f77eff6
--- /dev/null
+++ b/sys/conf/options.alpha
@@ -0,0 +1,18 @@
+# $Id$
+
+EV5 opt_global.h
+DEC_KN8AE opt_cpu.h
+
+ATAPI opt_atapi.h
+ATAPI_STATIC opt_atapi.h
+
+CMD640 opt_wd.h
+
+SHOW_BUSYBUFS
+PANIC_REBOOT_WAIT_TIME opt_panic.h
+
+AHC_TAGENABLE opt_aic7xxx.h
+AHC_SCBPAGING_ENABLE opt_aic7xxx.h
+AHC_ALLOW_MEMIO opt_aic7xxx.h
+AHC_SHARE_SCBS opt_aic7xxx.h
+
diff --git a/sys/ddb/db_examine.c b/sys/ddb/db_examine.c
index a848ac77db09..08538913e8c0 100644
--- a/sys/ddb/db_examine.c
+++ b/sys/ddb/db_examine.c
@@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: db_examine.c,v 1.18 1998/06/07 17:09:37 dfr Exp $
+ * $Id: db_examine.c,v 1.19 1998/06/08 08:43:19 dfr Exp $
*/
/*
@@ -257,7 +257,7 @@ db_search_cmd(dummy1, dummy2, dummy3, dummy4)
int size;
db_expr_t value;
db_expr_t mask;
- unsigned int count;
+ db_expr_t count;
t = db_read_token();
if (t == tSLASH) {
diff --git a/sys/ddb/db_print.c b/sys/ddb/db_print.c
index 114cf00a9d51..78404965af12 100644
--- a/sys/ddb/db_print.c
+++ b/sys/ddb/db_print.c
@@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: db_print.c,v 1.18 1998/06/07 17:09:37 dfr Exp $
+ * $Id: db_print.c,v 1.19 1998/06/08 02:15:37 bde Exp $
*/
/*
@@ -53,7 +53,7 @@ db_show_regs(dummy1, dummy2, dummy3, dummy4)
for (regp = db_regs; regp < db_eregs; regp++) {
db_read_variable(regp, &value);
- db_printf("%-12s%#10n", regp->name, value);
+ db_printf("%-12s%#10ln", regp->name, value);
db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset);
if (name != 0 && offset <= db_maxoff && offset != value) {
db_printf("\t%s", name);
diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c
index 40f365187f37..5caf478af7ee 100644
--- a/sys/ddb/db_sym.c
+++ b/sys/ddb/db_sym.c
@@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: db_sym.c,v 1.20 1997/06/30 23:54:49 bde Exp $
+ * $Id: db_sym.c,v 1.21 1998/06/07 17:09:38 dfr Exp $
*/
/*
@@ -300,11 +300,11 @@ db_printsym(off, strategy)
if (name == 0)
value = off;
if (value >= DB_SMALL_VALUE_MIN && value <= DB_SMALL_VALUE_MAX) {
- db_printf("%+#n", off);
+ db_printf("%+#ln", off);
return;
}
if (name == 0 || d >= db_maxoff) {
- db_printf("%#n", off);
+ db_printf("%#ln", off);
return;
}
db_printf("%s", name);
diff --git a/sys/dev/dec/clockvar.h b/sys/dev/dec/clockvar.h
new file mode 100644
index 000000000000..920d1627a830
--- /dev/null
+++ b/sys/dev/dec/clockvar.h
@@ -0,0 +1,62 @@
+/* $NetBSD: clockvar.h,v 1.4 1997/06/22 08:02:18 jonathan Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Definitions for cpu-independent clock handling for the alpha and pmax.
+ */
+
+/*
+ * clocktime structure:
+ *
+ * structure passed to TOY clocks when setting them. broken out this
+ * way, so that the time_t -> field conversion can be shared.
+ */
+struct clocktime {
+ int year; /* year - 1900 */
+ int mon; /* month (1 - 12) */
+ int day; /* day (1 - 31) */
+ int hour; /* hour (0 - 23) */
+ int min; /* minute (0 - 59) */
+ int sec; /* second (0 - 59) */
+ int dow; /* day of week (0 - 6; 0 = Sunday) */
+};
+
+/*
+ * clockfns structure:
+ *
+ * function switch used by chip-independent clock code, to access
+ * chip-dependent routines.
+ */
+struct clockfns {
+ void (*cf_init) __P((struct device *));
+ void (*cf_get) __P((struct device *, time_t, struct clocktime *));
+ void (*cf_set) __P((struct device *, struct clocktime *));
+};
+
+void clockattach __P((device_t, const struct clockfns *));
diff --git a/sys/dev/dec/mc146818reg.h b/sys/dev/dec/mc146818reg.h
new file mode 100644
index 000000000000..95c3ccfa5a29
--- /dev/null
+++ b/sys/dev/dec/mc146818reg.h
@@ -0,0 +1,194 @@
+/* $NetBSD: mc146818reg.h,v 1.2 1997/03/12 06:53:42 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Definitions for the Motorola MC146818A Real Time Clock.
+ * They also apply for the (compatible) Dallas Semicontuctor DS1287A RTC.
+ *
+ * Though there are undoubtedly other (better) sources, this material was
+ * culled from the DEC "KN121 System Module Programmer's Reference
+ * Information."
+ *
+ * The MC146818A has 16 registers. The first 10 contain time-of-year
+ * and alarm data. The rest contain various control and status bits.
+ *
+ * To read or write the registers, one writes the register number to
+ * the RTC's control port, then either reads from or writes the new
+ * data to the RTC's data port. Since the locations of these ports
+ * and the method used to access them can be machine-dependent, the
+ * low-level details of reading and writing the RTC's registers are
+ * handled by machine-specific functions.
+ *
+ * The time-of-year and alarm data can be expressed in either binary
+ * or BCD, and they are selected by a bit in register B.
+ *
+ * The "hour" time-of-year and alarm fields can either be expressed in
+ * AM/PM format, or in 24-hour format. If AM/PM format is chosen, the
+ * hour fields can have the values: 1-12 and 81-92 (the latter being
+ * PM). If the 24-hour format is chosen, they can have the values
+ * 0-24. The hour format is selectable by a bit in register B.
+ * (XXX IS AM/PM MODE DESCRIPTION CORRECT?)
+ *
+ * It is assumed the if systems are going to use BCD (rather than
+ * binary) mode, or AM/PM hour format, they'll do the appropriate
+ * conversions in machine-dependent code. Also, if the clock is
+ * switched between BCD and binary mode, or between AM/PM mode and
+ * 24-hour mode, the time-of-day and alarm registers are NOT
+ * automatically reset; they must be reprogrammed with correct values.
+ */
+
+/*
+ * The registers, and the bits within each register.
+ */
+
+#define MC_SEC 0x0 /* Time of year: seconds (0-59) */
+#define MC_ASEC 0x1 /* Alarm: seconds */
+#define MC_MIN 0x2 /* Time of year: minutes (0-59) */
+#define MC_AMIN 0x3 /* Alarm: minutes */
+#define MC_HOUR 0x4 /* Time of year: hour (see above) */
+#define MC_AHOUR 0x5 /* Alarm: hour */
+#define MC_DOW 0x6 /* Time of year: day of week (1-7) */
+#define MC_DOM 0x7 /* Time of year: day of month (1-31) */
+#define MC_MONTH 0x8 /* Time of year: month (1-12) */
+#define MC_YEAR 0x9 /* Time of year: year in century (0-99) */
+
+#define MC_REGA 0xa /* Control register A */
+
+#define MC_REGA_RSMASK 0x0f /* Interrupt rate select mask (see below) */
+#define MC_REGA_DVMASK 0x70 /* Divisor select mask (see below) */
+#define MC_REGA_UIP 0x80 /* Update in progress; read only. */
+
+#define MC_REGB 0xb /* Control register B */
+
+#define MC_REGB_DSE 0x01 /* Daylight Savings Enable */
+#define MC_REGB_24HR 0x02 /* 24-hour mode (AM/PM mode when clear) */
+#define MC_REGB_BINARY 0x04 /* Binary mode (BCD mode when clear) */
+#define MC_REGB_SQWE 0x08 /* Square Wave Enable */
+#define MC_REGB_UIE 0x10 /* Update End interrupt enable */
+#define MC_REGB_AIE 0x20 /* Alarm interrupt enable */
+#define MC_REGB_PIE 0x40 /* Periodic interrupt enable */
+#define MC_REGB_SET 0x80 /* Allow time to be set; stops updates */
+
+#define MC_REGC 0xc /* Control register C */
+
+/* MC_REGC_UNUSED 0x0f UNUSED */
+#define MC_REGC_UF 0x10 /* Update End interrupt flag */
+#define MC_REGC_AF 0x20 /* Alarm interrupt flag */
+#define MC_REGC_PF 0x40 /* Periodic interrupt flag */
+#define MC_REGC_IRQF 0x80 /* Interrupt request pending flag */
+
+#define MC_REGD 0xd /* Control register D */
+
+/* MC_REGD_UNUSED 0x7f UNUSED */
+#define MC_REGD_VRT 0x80 /* Valid RAM and Time bit */
+
+
+#define MC_NREGS 0xe /* 14 registers; CMOS follows */
+#define MC_NTODREGS 0xa /* 10 of those regs are for TOD and alarm */
+
+#define MC_NVRAM_START 0xe /* start of NVRAM: offset 14 */
+#define MC_NVRAM_SIZE 50 /* 50 bytes of NVRAM */
+
+/*
+ * Periodic Interrupt Rate Select constants (Control register A)
+ */
+#define MC_RATE_NONE 0x0 /* No periodic interrupt */
+#define MC_RATE_1 0x1 /* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */
+#define MC_RATE_2 0x2 /* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */
+#define MC_RATE_8192_Hz 0x3 /* 122.070 us period */
+#define MC_RATE_4096_Hz 0x4 /* 244.141 us period */
+#define MC_RATE_2048_Hz 0x5 /* 488.281 us period */
+#define MC_RATE_1024_Hz 0x6 /* 976.562 us period */
+#define MC_RATE_512_Hz 0x7 /* 1.953125 ms period */
+#define MC_RATE_256_Hz 0x8 /* 3.90625 ms period */
+#define MC_RATE_128_Hz 0x9 /* 7.8125 ms period */
+#define MC_RATE_64_Hz 0xa /* 15.625 ms period */
+#define MC_RATE_32_Hz 0xb /* 31.25 ms period */
+#define MC_RATE_16_Hz 0xc /* 62.5 ms period */
+#define MC_RATE_8_Hz 0xd /* 125 ms period */
+#define MC_RATE_4_Hz 0xe /* 250 ms period */
+#define MC_RATE_2_Hz 0xf /* 500 ms period */
+
+/*
+ * Time base (divisor select) constants (Control register A)
+ */
+#define MC_BASE_4_MHz 0x00 /* 4MHz crystal */
+#define MC_BASE_1_MHz 0x10 /* 1MHz crystal */
+#define MC_BASE_32_KHz 0x20 /* 32KHz crystal */
+#define MC_BASE_NONE 0x60 /* actually, both of these reset */
+#define MC_BASE_RESET 0x70
+
+
+/*
+ * RTC register/NVRAM read and write functions -- machine-dependent.
+ * Appropriately manipulate RTC registers to get/put data values.
+ */
+u_int mc146818_read __P((void *sc, u_int reg));
+void mc146818_write __P((void *sc, u_int reg, u_int datum));
+
+/*
+ * A collection of TOD/Alarm registers.
+ */
+typedef u_int mc_todregs[MC_NTODREGS];
+
+/*
+ * Get all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define MC146818_GETTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* update in progress; spin loop */ \
+ while (mc146818_read(sc, MC_REGA) & MC_REGA_UIP) \
+ ; \
+ \
+ /* read all of the tod/alarm regs */ \
+ for (i = 0; i < MC_NTODREGS; i++) \
+ (*regs)[i] = mc146818_read(sc, i); \
+ } while (0);
+
+/*
+ * Set all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define MC146818_PUTTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* stop updates while setting */ \
+ mc146818_write(sc, MC_REGB, \
+ mc146818_read(sc, MC_REGB) | MC_REGB_SET); \
+ \
+ /* write all of the tod/alarm regs */ \
+ for (i = 0; i < MC_NTODREGS; i++) \
+ mc146818_write(sc, i, (*regs)[i]); \
+ \
+ /* reenable updates */ \
+ mc146818_write(sc, MC_REGB, \
+ mc146818_read(sc, MC_REGB) & ~MC_REGB_SET); \
+ } while (0);
diff --git a/sys/dev/dec/mcclock.c b/sys/dev/dec/mcclock.c
new file mode 100644
index 000000000000..76e3805ef785
--- /dev/null
+++ b/sys/dev/dec/mcclock.c
@@ -0,0 +1,141 @@
+/* $Id$ */
+/* $NetBSD: mcclock.c,v 1.11 1998/04/19 07:50:25 jonathan Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <dev/dec/clockvar.h>
+#include <dev/dec/mcclockvar.h>
+#include <dev/dec/mc146818reg.h>
+
+/*
+ * XXX rate is machine-dependent.
+ */
+#ifdef __alpha__
+#define MC_DEFAULTRATE MC_RATE_1024_Hz
+#endif
+#ifdef __pmax__
+#define MC_DEFAULTRATE MC_RATE_256_Hz
+#endif
+
+
+void mcclock_init __P((struct device *));
+void mcclock_get __P((struct device *, time_t, struct clocktime *));
+void mcclock_set __P((struct device *, struct clocktime *));
+
+const struct clockfns mcclock_clockfns = {
+ mcclock_init, mcclock_get, mcclock_set,
+};
+
+#define mc146818_write(dev, reg, datum) \
+ (*(dev)->sc_busfns->mc_bf_write)(dev, reg, datum)
+#define mc146818_read(dev, reg) \
+ (*(dev)->sc_busfns->mc_bf_read)(dev, reg)
+
+void
+mcclock_attach(sc, busfns)
+ struct mcclock_softc *sc;
+ const struct mcclock_busfns *busfns;
+{
+ sc->sc_busfns = busfns;
+
+ /* Turn interrupts off, just in case. */
+ mc146818_write(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
+
+ clockattach(sc->sc_dev, &mcclock_clockfns);
+}
+
+void
+mcclock_init(dev)
+ device_t dev;
+{
+ struct mcclock_softc *sc = device_get_softc(dev);
+
+ mc146818_write(sc, MC_REGA, MC_BASE_32_KHz | MC_DEFAULTRATE);
+ mc146818_write(sc, MC_REGB,
+ MC_REGB_PIE | MC_REGB_SQWE | MC_REGB_BINARY | MC_REGB_24HR);
+}
+
+/*
+ * Get the time of day, based on the clock's value and/or the base value.
+ */
+void
+mcclock_get(dev, base, ct)
+ struct device *dev;
+ time_t base;
+ struct clocktime *ct;
+{
+ struct mcclock_softc *sc = device_get_softc(dev);
+ mc_todregs regs;
+ int s;
+
+ s = splclock();
+ MC146818_GETTOD(sc, &regs)
+ splx(s);
+
+ ct->sec = regs[MC_SEC];
+ ct->min = regs[MC_MIN];
+ ct->hour = regs[MC_HOUR];
+ ct->dow = regs[MC_DOW];
+ ct->day = regs[MC_DOM];
+ ct->mon = regs[MC_MONTH];
+ ct->year = regs[MC_YEAR];
+}
+
+/*
+ * Reset the TODR based on the time value.
+ */
+void
+mcclock_set(dev, ct)
+ struct device *dev;
+ struct clocktime *ct;
+{
+ struct mcclock_softc *sc = device_get_softc(dev);
+ mc_todregs regs;
+ int s;
+
+ s = splclock();
+ MC146818_GETTOD(sc, &regs);
+ splx(s);
+
+ regs[MC_SEC] = ct->sec;
+ regs[MC_MIN] = ct->min;
+ regs[MC_HOUR] = ct->hour;
+ regs[MC_DOW] = ct->dow;
+ regs[MC_DOM] = ct->day;
+ regs[MC_MONTH] = ct->mon;
+ regs[MC_YEAR] = ct->year;
+
+ s = splclock();
+ MC146818_PUTTOD(sc, &regs);
+ splx(s);
+}
diff --git a/sys/dev/dec/mcclockvar.h b/sys/dev/dec/mcclockvar.h
new file mode 100644
index 000000000000..d2c0ac82e9bf
--- /dev/null
+++ b/sys/dev/dec/mcclockvar.h
@@ -0,0 +1,41 @@
+/* $NetBSD: mcclockvar.h,v 1.4 1997/06/22 08:02:19 jonathan Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+struct mcclock_softc {
+ device_t sc_dev;
+ const struct mcclock_busfns *sc_busfns;
+};
+
+struct mcclock_busfns {
+ void (*mc_bf_write) __P((struct mcclock_softc *, u_int, u_int));
+ u_int (*mc_bf_read) __P((struct mcclock_softc *, u_int));
+};
+
+void mcclock_attach __P((struct mcclock_softc *,
+ const struct mcclock_busfns *));
diff --git a/sys/dev/mc146818/mc146818reg.h b/sys/dev/mc146818/mc146818reg.h
new file mode 100644
index 000000000000..95c3ccfa5a29
--- /dev/null
+++ b/sys/dev/mc146818/mc146818reg.h
@@ -0,0 +1,194 @@
+/* $NetBSD: mc146818reg.h,v 1.2 1997/03/12 06:53:42 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Definitions for the Motorola MC146818A Real Time Clock.
+ * They also apply for the (compatible) Dallas Semicontuctor DS1287A RTC.
+ *
+ * Though there are undoubtedly other (better) sources, this material was
+ * culled from the DEC "KN121 System Module Programmer's Reference
+ * Information."
+ *
+ * The MC146818A has 16 registers. The first 10 contain time-of-year
+ * and alarm data. The rest contain various control and status bits.
+ *
+ * To read or write the registers, one writes the register number to
+ * the RTC's control port, then either reads from or writes the new
+ * data to the RTC's data port. Since the locations of these ports
+ * and the method used to access them can be machine-dependent, the
+ * low-level details of reading and writing the RTC's registers are
+ * handled by machine-specific functions.
+ *
+ * The time-of-year and alarm data can be expressed in either binary
+ * or BCD, and they are selected by a bit in register B.
+ *
+ * The "hour" time-of-year and alarm fields can either be expressed in
+ * AM/PM format, or in 24-hour format. If AM/PM format is chosen, the
+ * hour fields can have the values: 1-12 and 81-92 (the latter being
+ * PM). If the 24-hour format is chosen, they can have the values
+ * 0-24. The hour format is selectable by a bit in register B.
+ * (XXX IS AM/PM MODE DESCRIPTION CORRECT?)
+ *
+ * It is assumed the if systems are going to use BCD (rather than
+ * binary) mode, or AM/PM hour format, they'll do the appropriate
+ * conversions in machine-dependent code. Also, if the clock is
+ * switched between BCD and binary mode, or between AM/PM mode and
+ * 24-hour mode, the time-of-day and alarm registers are NOT
+ * automatically reset; they must be reprogrammed with correct values.
+ */
+
+/*
+ * The registers, and the bits within each register.
+ */
+
+#define MC_SEC 0x0 /* Time of year: seconds (0-59) */
+#define MC_ASEC 0x1 /* Alarm: seconds */
+#define MC_MIN 0x2 /* Time of year: minutes (0-59) */
+#define MC_AMIN 0x3 /* Alarm: minutes */
+#define MC_HOUR 0x4 /* Time of year: hour (see above) */
+#define MC_AHOUR 0x5 /* Alarm: hour */
+#define MC_DOW 0x6 /* Time of year: day of week (1-7) */
+#define MC_DOM 0x7 /* Time of year: day of month (1-31) */
+#define MC_MONTH 0x8 /* Time of year: month (1-12) */
+#define MC_YEAR 0x9 /* Time of year: year in century (0-99) */
+
+#define MC_REGA 0xa /* Control register A */
+
+#define MC_REGA_RSMASK 0x0f /* Interrupt rate select mask (see below) */
+#define MC_REGA_DVMASK 0x70 /* Divisor select mask (see below) */
+#define MC_REGA_UIP 0x80 /* Update in progress; read only. */
+
+#define MC_REGB 0xb /* Control register B */
+
+#define MC_REGB_DSE 0x01 /* Daylight Savings Enable */
+#define MC_REGB_24HR 0x02 /* 24-hour mode (AM/PM mode when clear) */
+#define MC_REGB_BINARY 0x04 /* Binary mode (BCD mode when clear) */
+#define MC_REGB_SQWE 0x08 /* Square Wave Enable */
+#define MC_REGB_UIE 0x10 /* Update End interrupt enable */
+#define MC_REGB_AIE 0x20 /* Alarm interrupt enable */
+#define MC_REGB_PIE 0x40 /* Periodic interrupt enable */
+#define MC_REGB_SET 0x80 /* Allow time to be set; stops updates */
+
+#define MC_REGC 0xc /* Control register C */
+
+/* MC_REGC_UNUSED 0x0f UNUSED */
+#define MC_REGC_UF 0x10 /* Update End interrupt flag */
+#define MC_REGC_AF 0x20 /* Alarm interrupt flag */
+#define MC_REGC_PF 0x40 /* Periodic interrupt flag */
+#define MC_REGC_IRQF 0x80 /* Interrupt request pending flag */
+
+#define MC_REGD 0xd /* Control register D */
+
+/* MC_REGD_UNUSED 0x7f UNUSED */
+#define MC_REGD_VRT 0x80 /* Valid RAM and Time bit */
+
+
+#define MC_NREGS 0xe /* 14 registers; CMOS follows */
+#define MC_NTODREGS 0xa /* 10 of those regs are for TOD and alarm */
+
+#define MC_NVRAM_START 0xe /* start of NVRAM: offset 14 */
+#define MC_NVRAM_SIZE 50 /* 50 bytes of NVRAM */
+
+/*
+ * Periodic Interrupt Rate Select constants (Control register A)
+ */
+#define MC_RATE_NONE 0x0 /* No periodic interrupt */
+#define MC_RATE_1 0x1 /* 256 Hz if MC_BASE_32_KHz, else 32768 Hz */
+#define MC_RATE_2 0x2 /* 128 Hz if MC_BASE_32_KHz, else 16384 Hz */
+#define MC_RATE_8192_Hz 0x3 /* 122.070 us period */
+#define MC_RATE_4096_Hz 0x4 /* 244.141 us period */
+#define MC_RATE_2048_Hz 0x5 /* 488.281 us period */
+#define MC_RATE_1024_Hz 0x6 /* 976.562 us period */
+#define MC_RATE_512_Hz 0x7 /* 1.953125 ms period */
+#define MC_RATE_256_Hz 0x8 /* 3.90625 ms period */
+#define MC_RATE_128_Hz 0x9 /* 7.8125 ms period */
+#define MC_RATE_64_Hz 0xa /* 15.625 ms period */
+#define MC_RATE_32_Hz 0xb /* 31.25 ms period */
+#define MC_RATE_16_Hz 0xc /* 62.5 ms period */
+#define MC_RATE_8_Hz 0xd /* 125 ms period */
+#define MC_RATE_4_Hz 0xe /* 250 ms period */
+#define MC_RATE_2_Hz 0xf /* 500 ms period */
+
+/*
+ * Time base (divisor select) constants (Control register A)
+ */
+#define MC_BASE_4_MHz 0x00 /* 4MHz crystal */
+#define MC_BASE_1_MHz 0x10 /* 1MHz crystal */
+#define MC_BASE_32_KHz 0x20 /* 32KHz crystal */
+#define MC_BASE_NONE 0x60 /* actually, both of these reset */
+#define MC_BASE_RESET 0x70
+
+
+/*
+ * RTC register/NVRAM read and write functions -- machine-dependent.
+ * Appropriately manipulate RTC registers to get/put data values.
+ */
+u_int mc146818_read __P((void *sc, u_int reg));
+void mc146818_write __P((void *sc, u_int reg, u_int datum));
+
+/*
+ * A collection of TOD/Alarm registers.
+ */
+typedef u_int mc_todregs[MC_NTODREGS];
+
+/*
+ * Get all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define MC146818_GETTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* update in progress; spin loop */ \
+ while (mc146818_read(sc, MC_REGA) & MC_REGA_UIP) \
+ ; \
+ \
+ /* read all of the tod/alarm regs */ \
+ for (i = 0; i < MC_NTODREGS; i++) \
+ (*regs)[i] = mc146818_read(sc, i); \
+ } while (0);
+
+/*
+ * Set all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define MC146818_PUTTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* stop updates while setting */ \
+ mc146818_write(sc, MC_REGB, \
+ mc146818_read(sc, MC_REGB) | MC_REGB_SET); \
+ \
+ /* write all of the tod/alarm regs */ \
+ for (i = 0; i < MC_NTODREGS; i++) \
+ mc146818_write(sc, i, (*regs)[i]); \
+ \
+ /* reenable updates */ \
+ mc146818_write(sc, MC_REGB, \
+ mc146818_read(sc, MC_REGB) & ~MC_REGB_SET); \
+ } while (0);
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
new file mode 100644
index 000000000000..883666d88353
--- /dev/null
+++ b/sys/kern/subr_bus.c
@@ -0,0 +1,854 @@
+/*-
+ * Copyright (c) 1997 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus_private.h>
+#include <sys/systm.h>
+
+device_t
+bus_get_device(bus_t bus)
+{
+ return bus->dev;
+}
+
+void
+bus_print_device(bus_t bus, device_t dev)
+{
+ printf("%s%d", device_get_name(dev), device_get_unit(dev));
+ if (device_is_alive(dev)) {
+ if (device_get_desc(dev))
+ printf(": <%s>", device_get_desc(dev));
+ bus->ops->print_device(bus, dev);
+ } else
+ printf(" not found");
+ printf("\n");
+}
+
+int
+bus_read_ivar(bus_t bus, device_t dev,
+ int index, u_long *result)
+{
+ return bus->ops->read_ivar(bus, dev, index, result);
+}
+
+int
+bus_write_ivar(bus_t bus, device_t dev,
+ int index, u_long value)
+{
+ return bus->ops->write_ivar(bus, dev, index, value);
+}
+
+int
+bus_map_intr(bus_t bus, device_t dev, driver_intr_t *intr, void *arg)
+{
+ return bus->ops->map_intr(bus, dev, intr, arg);
+}
+
+static devclass_list_t devclasses;
+
+static void
+devclass_init(void)
+{
+ TAILQ_INIT(&devclasses);
+}
+
+static devclass_t
+devclass_find_internal(const char *classname, int create)
+{
+ devclass_t dc;
+
+ for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link))
+ if (!strcmp(dc->name, classname))
+ return dc;
+
+ if (create) {
+ dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
+ M_DEVBUF, M_NOWAIT);
+ if (!dc)
+ return NULL;
+ dc->name = (char*) (dc + 1);
+ strcpy(dc->name, classname);
+ dc->devices = NULL;
+ dc->maxunit = 0;
+ dc->nextunit = 0;
+ TAILQ_INIT(&dc->drivers);
+ TAILQ_INSERT_TAIL(&devclasses, dc, link);
+ }
+
+ return dc;
+}
+
+devclass_t
+devclass_find(const char *classname)
+{
+ return devclass_find_internal(classname, FALSE);
+}
+
+int
+devclass_add_driver(devclass_t dc, driver_t *driver)
+{
+ /*
+ * Make sure the devclass which the driver is implementing exists.
+ */
+ devclass_find_internal(driver->name, TRUE);
+
+ TAILQ_INSERT_TAIL(&dc->drivers, driver, link);
+
+ return 0;
+}
+
+int
+devclass_delete_driver(devclass_t dc, driver_t *driver)
+{
+ bus_t bus;
+ device_t dev;
+ int i;
+ int error;
+
+ /*
+ * Disassociate from any devices. We iterate through all the
+ * devices attached to any bus in this class.
+ */
+ for (i = 0; i < dc->maxunit; i++) {
+ if (dc->devices[i]) {
+ bus = dc->devices[i]->softc;
+ for (dev = TAILQ_FIRST(&bus->devices); dev;
+ dev = TAILQ_NEXT(dev, link))
+ if (dev->driver == driver) {
+ if (error = device_detach(dev))
+ return error;
+ device_set_driver(dev, NULL);
+ }
+ }
+ }
+
+ TAILQ_REMOVE(&dc->drivers, driver, link);
+ return 0;
+}
+
+driver_t *
+devclass_find_driver(devclass_t dc, const char *classname)
+{
+ driver_t *driver;
+
+ for (driver = TAILQ_FIRST(&dc->drivers); driver;
+ driver = TAILQ_NEXT(driver, link))
+ if (!strcmp(driver->name, classname))
+ return driver;
+
+ return NULL;
+}
+
+const char *
+devclass_get_name(devclass_t dc)
+{
+ return dc->name;
+}
+
+device_t
+devclass_get_device(devclass_t dc, int unit)
+{
+ if (unit < 0 || unit >= dc->maxunit)
+ return NULL;
+ return dc->devices[unit];
+}
+
+void *
+devclass_get_softc(devclass_t dc, int unit)
+{
+ device_t dev;
+
+ if (unit < 0 || unit >= dc->maxunit)
+ return NULL;
+ dev = dc->devices[unit];
+ if (!dev || dev->state < DS_ATTACHED)
+ return NULL;
+ return dev->softc;
+}
+
+int
+devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
+{
+ int i;
+ int count;
+ device_t dev;
+ device_t *list;
+
+ count = 0;
+ for (i = 0; i < dc->maxunit; i++)
+ if (dc->devices[i])
+ count++;
+
+ list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
+ if (!list)
+ return ENOMEM;
+
+ count = 0;
+ for (i = 0; i < dc->maxunit; i++)
+ if (dc->devices[i]) {
+ list[count] = dc->devices[i];
+ count++;
+ }
+
+ *devlistp = list;
+ *devcountp = count;
+
+ return 0;
+}
+
+int
+devclass_get_maxunit(devclass_t dc)
+{
+ return dc->maxunit;
+}
+
+static int
+devclass_alloc_unit(devclass_t dc, int *unitp)
+{
+ int unit = *unitp;
+
+ /*
+ * If we have been given a wired unit number, check for existing
+ * device.
+ */
+ if (unit != -1) {
+ device_t dev;
+ dev = devclass_get_device(dc, unit);
+ if (dev) {
+ printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit);
+ unit = -1;
+ }
+ }
+
+ if (unit == -1) {
+ unit = dc->nextunit;
+ dc->nextunit++;
+ } else if (dc->nextunit <= unit)
+ dc->nextunit = unit + 1;
+
+ if (unit >= dc->maxunit) {
+ device_t *newlist;
+ int newsize;
+
+ newsize = (dc->maxunit ? 2 * dc->maxunit
+ : MINALLOCSIZE / sizeof(device_t));
+ newlist = malloc(sizeof(device_t) * newsize, M_DEVBUF, M_NOWAIT);
+ if (!newlist)
+ return ENOMEM;
+ bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit);
+ bzero(newlist + dc->maxunit,
+ sizeof(device_t) * (newsize - dc->maxunit));
+ if (dc->devices)
+ free(dc->devices, M_DEVBUF);
+ dc->devices = newlist;
+ dc->maxunit = newsize;
+ }
+
+ *unitp = unit;
+ return 0;
+}
+
+static int
+devclass_add_device(devclass_t dc, device_t dev)
+{
+ int error;
+
+ if (error = devclass_alloc_unit(dc, &dev->unit))
+ return error;
+ dc->devices[dev->unit] = dev;
+ dev->devclass = dc;
+ return 0;
+}
+
+static int
+devclass_delete_device(devclass_t dc, device_t dev)
+{
+ if (dev->devclass != dc
+ || dc->devices[dev->unit] != dev)
+ panic("devclass_delete_device: inconsistent device class");
+ dc->devices[dev->unit] = NULL;
+ if (dev->flags & DF_WILDCARD)
+ dev->unit = -1;
+ dev->devclass = NULL;
+ while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL)
+ dc->nextunit--;
+ return 0;
+}
+
+static device_t
+make_device(bus_t bus, const char *name,
+ int unit, void *ivars)
+{
+ driver_t *driver;
+ device_t dev;
+ devclass_t dc;
+ int error;
+
+ if (name) {
+ dc = devclass_find_internal(name, TRUE);
+ if (!dc) {
+ printf("make_device: can't find device class %s\n", name);
+ return NULL;
+ }
+
+ if (error = devclass_alloc_unit(dc, &unit))
+ return NULL;
+ } else
+ dc = NULL;
+
+ dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT);
+ if (!dev)
+ return 0;
+
+ dev->parent = bus;
+ dev->driver = NULL;
+ dev->devclass = dc;
+ dev->unit = unit;
+ dev->desc = NULL;
+ dev->busy = 0;
+ dev->flags = DF_ENABLED;
+ if (unit == -1)
+ dev->flags |= DF_WILDCARD;
+ if (name)
+ dev->flags |= DF_FIXEDCLASS;
+ dev->ivars = ivars;
+ dev->softc = NULL;
+
+ if (dc)
+ dc->devices[unit] = dev;
+
+ dev->state = DS_NOTPRESENT;
+
+ return dev;
+}
+
+void
+bus_init(bus_t bus, device_t dev, bus_ops_t *ops)
+{
+ bus->ops = ops;
+ bus->dev = dev;
+ TAILQ_INIT(&bus->devices);
+}
+
+device_t
+bus_add_device(bus_t bus, const char *name, int unit, void *ivars)
+{
+ device_t dev;
+
+ dev = make_device(bus, name, unit, ivars);
+
+ TAILQ_INSERT_TAIL(&bus->devices, dev, link);
+
+ return dev;
+}
+
+device_t
+bus_add_device_after(bus_t bus, device_t place, const char *name,
+ int unit, void *ivars)
+{
+ device_t dev;
+
+ dev = make_device(bus, name, unit, ivars);
+
+ if (place) {
+ TAILQ_INSERT_AFTER(&bus->devices, place, dev, link);
+ } else {
+ TAILQ_INSERT_HEAD(&bus->devices, dev, link);
+ }
+
+ return dev;
+}
+
+int
+bus_delete_device(bus_t bus, device_t dev)
+{
+ int error;
+
+ if (error = device_detach(dev))
+ return error;
+ if (dev->devclass)
+ devclass_delete_device(dev->devclass, dev);
+ TAILQ_REMOVE(&bus->devices, dev, link);
+ free(dev, M_DEVBUF);
+
+ return 0;
+}
+
+/*
+ * Find only devices attached to this bus.
+ */
+device_t
+bus_find_device(bus_t bus, const char *classname, int unit)
+{
+ devclass_t dc;
+ device_t dev;
+
+ dc = devclass_find(classname);
+ if (!dc)
+ return NULL;
+
+ dev = devclass_get_device(dc, unit);
+ if (dev && dev->parent == bus)
+ return dev;
+ return NULL;
+}
+
+static driver_t *
+first_matching_driver(devclass_t dc, device_t dev)
+{
+ if (dev->devclass)
+ return devclass_find_driver(dc, dev->devclass->name);
+ else
+ return TAILQ_FIRST(&dc->drivers);
+}
+
+static driver_t *
+next_matching_driver(devclass_t dc, device_t dev, driver_t *last)
+{
+ if (dev->devclass) {
+ driver_t *driver;
+ for (driver = TAILQ_NEXT(last, link); driver;
+ driver = TAILQ_NEXT(driver, link))
+ if (!strcmp(dev->devclass->name, driver->name))
+ return driver;
+ return NULL;
+ } else
+ return TAILQ_NEXT(last, link);
+}
+
+static int
+bus_probe_device(bus_t bus, device_t dev)
+{
+ devclass_t dc;
+ driver_t *driver;
+ void *softc;
+
+ dc = bus->dev->devclass;
+ if (dc == NULL)
+ panic("bus_probe_device: bus' device has no devclass");
+
+ if (dev->state == DS_ALIVE)
+ return 0;
+
+ for (driver = first_matching_driver(dc, dev);
+ driver;
+ driver = next_matching_driver(dc, dev, driver)) {
+ device_set_driver(dev, driver);
+ if (driver->probe(bus, dev) == 0) {
+ if (!dev->devclass)
+ device_set_devclass(dev, driver->name);
+ dev->state = DS_ALIVE;
+ return 0;
+ }
+ }
+
+ return ENXIO;
+}
+
+int
+bus_generic_attach(bus_t parent, device_t busdev)
+{
+ bus_t bus = busdev->softc;
+ device_t dev;
+ int error;
+
+ for (dev = TAILQ_FIRST(&bus->devices);
+ dev; dev = TAILQ_NEXT(dev, link))
+ device_probe_and_attach(dev);
+
+ return 0;
+}
+
+int
+bus_generic_detach(bus_t parent, device_t busdev)
+{
+ bus_t bus = busdev->softc;
+ device_t dev;
+ int error;
+
+ if (busdev->state != DS_ATTACHED)
+ return EBUSY;
+
+ for (dev = TAILQ_FIRST(&bus->devices);
+ dev; dev = TAILQ_NEXT(dev, link))
+ device_detach(dev);
+
+ return 0;
+}
+
+int
+bus_generic_shutdown(bus_t parent, device_t busdev)
+{
+ bus_t bus = busdev->softc;
+ device_t dev;
+
+ for (dev = TAILQ_FIRST(&bus->devices);
+ dev; dev = TAILQ_NEXT(dev, link))
+ device_shutdown(dev);
+
+ return 0;
+}
+
+bus_t
+device_get_parent(device_t dev)
+{
+ return dev->parent;
+}
+
+driver_t *
+device_get_driver(device_t dev)
+{
+ return dev->driver;
+}
+
+devclass_t
+device_get_devclass(device_t dev)
+{
+ return dev->devclass;
+}
+
+const char *
+device_get_name(device_t dev)
+{
+ if (dev->devclass)
+ return devclass_get_name(dev->devclass);
+ return NULL;
+}
+
+int
+device_get_unit(device_t dev)
+{
+ return dev->unit;
+}
+
+const char *
+device_get_desc(device_t dev)
+{
+ return dev->desc;
+}
+
+void
+device_set_desc(device_t dev, const char* desc)
+{
+ dev->desc = desc;
+}
+
+void *
+device_get_softc(device_t dev)
+{
+ return dev->softc;
+}
+
+void *
+device_get_ivars(device_t dev)
+{
+ return dev->ivars;
+}
+
+device_state_t
+device_get_state(device_t dev)
+{
+ return dev->state;
+}
+
+void
+device_enable(device_t dev)
+{
+ dev->flags |= DF_ENABLED;
+}
+
+void
+device_disable(device_t dev)
+{
+ dev->flags &= ~DF_ENABLED;
+}
+
+void
+device_busy(device_t dev)
+{
+ if (dev->state < DS_ATTACHED)
+ panic("device_busy: called for unattached device");
+ if (dev->busy == 0 && dev->parent)
+ device_busy(dev->parent->dev);
+ dev->busy++;
+ dev->state = DS_BUSY;
+}
+
+void
+device_unbusy(device_t dev)
+{
+ if (dev->state != DS_BUSY)
+ panic("device_unbusy: called for non-busy device");
+ dev->busy--;
+ if (dev->busy == 0) {
+ if (dev->parent->dev)
+ device_unbusy(dev->parent->dev);
+ dev->state = DS_ATTACHED;
+ }
+}
+
+int
+device_is_enabled(device_t dev)
+{
+ return (dev->flags & DF_ENABLED) != 0;
+}
+
+int
+device_is_alive(device_t dev)
+{
+ return dev->state >= DS_ALIVE;
+}
+
+int
+device_set_devclass(device_t dev, const char *classname)
+{
+ devclass_t dc;
+
+ if (dev->devclass) {
+ printf("device_set_devclass: device class already set\n");
+ return EINVAL;
+ }
+
+ dc = devclass_find_internal(classname, TRUE);
+ if (!dc)
+ return ENOMEM;
+
+ return devclass_add_device(dc, dev);
+}
+
+int
+device_set_driver(device_t dev, driver_t *driver)
+{
+ if (dev->state >= DS_ATTACHED)
+ return EBUSY;
+
+ if (dev->driver == driver)
+ return 0;
+
+ if (dev->softc) {
+ free(dev->softc, M_DEVBUF);
+ dev->softc = NULL;
+ }
+ dev->driver = driver;
+ if (driver) {
+ dev->softc = malloc(driver->softc, M_DEVBUF, M_NOWAIT);
+ bzero(dev->softc, driver->softc);
+ }
+ return 0;
+}
+
+int
+device_probe_and_attach(device_t dev)
+{
+ bus_t bus = dev->parent;
+ int error;
+
+ if (dev->state >= DS_ALIVE)
+ return 0;
+
+ if (dev->flags & DF_ENABLED) {
+ bus_probe_device(bus, dev);
+ bus_print_device(bus, dev);
+ if (dev->state == DS_ALIVE) {
+ error = dev->driver->attach(bus, dev);
+ if (!error)
+ dev->state = DS_ATTACHED;
+ else {
+ printf("device_probe_and_attach: %s%n attach returned %d\n",
+ dev->driver->name, dev->unit, error);
+ device_set_driver(dev, NULL);
+ dev->state = DS_NOTPRESENT;
+ }
+ }
+ } else
+ printf("%s%d: disabled, not probed.\n",
+ dev->devclass->name, dev->unit);
+
+ return 0;
+}
+
+int
+device_detach(device_t dev)
+{
+ int error;
+
+ if (dev->state == DS_BUSY)
+ return EBUSY;
+ if (dev->state != DS_ATTACHED)
+ return 0;
+
+ if (dev->driver->detach) {
+ if (error = dev->driver->detach(dev->parent, dev))
+ return error;
+ } else
+ return EBUSY;
+
+ if (!(dev->flags & DF_FIXEDCLASS))
+ devclass_delete_device(dev->devclass, dev);
+
+ dev->state = DS_NOTPRESENT;
+ device_set_driver(dev, NULL);
+
+ return 0;
+}
+
+int
+device_shutdown(device_t dev)
+{
+ if (dev->state < DS_ATTACHED)
+ return 0;
+ if (dev->driver->shutdown)
+ return dev->driver->shutdown(dev->parent, dev);
+ else
+ return 0;
+}
+
+void
+null_print_device(bus_t bus, device_t dev)
+{
+}
+
+int
+null_read_ivar(bus_t bus, device_t dev, int index, u_long* result)
+{
+ return ENOENT;
+}
+
+int
+null_write_ivar(bus_t bus, device_t dev, int index, u_long value)
+{
+ return ENOENT;
+}
+
+int
+null_map_intr(bus_t bus, device_t dev, driver_intr_t *intr, void *arg)
+{
+ /* Propagate up the bus hierarchy until someone handles it. */
+ if (bus->dev)
+ return bus_map_intr(bus->dev->parent, bus->dev, intr, arg);
+ else
+ return EINVAL;
+}
+
+bus_ops_t null_bus_ops = {
+ null_print_device,
+ null_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static void
+root_bus_print_device(bus_t bus, device_t dev)
+{
+}
+
+static int root_bus_map_intr(bus_t bus, device_t dev,
+ driver_intr_t *intr, void *arg)
+{
+ return EINVAL;
+}
+
+static bus_ops_t root_bus_ops = {
+ root_bus_print_device,
+ null_read_ivar,
+ null_write_ivar,
+ root_bus_map_intr,
+};
+
+static struct bus the_root_bus;
+bus_t root_bus = &the_root_bus;
+device_t root_device;
+devclass_t root_devclass;
+
+static int
+root_bus_module_handler(module_t mod, modeventtype_t what, void* arg)
+{
+ switch (what) {
+ case MOD_LOAD:
+ devclass_init();
+ root_device = make_device(NULL, "root", 0, NULL);
+ root_device->state = DS_ATTACHED;
+ bus_init(root_bus, root_device, &root_bus_ops);
+ root_devclass = devclass_find("root");
+ return 0;
+ }
+
+ return 0;
+}
+
+static moduledata_t root_bus_mod = {
+ "rootbus",
+ root_bus_module_handler,
+ 0
+};
+DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
+
+void
+root_bus_configure()
+{
+ device_t dev;
+ int error;
+
+ for (dev = TAILQ_FIRST(&root_bus->devices); dev;
+ dev = TAILQ_NEXT(dev, link)) {
+ device_probe_and_attach(dev);
+ }
+}
+
+int
+driver_module_handler(module_t mod, modeventtype_t what, void* arg)
+{
+ struct driver_module_data* data = (struct driver_module_data*) arg;
+ devclass_t bus_devclass = devclass_find_internal(data->busname, TRUE);
+ int error;
+
+ switch (what) {
+ case MOD_LOAD:
+ if (error = devclass_add_driver(bus_devclass,
+ data->driver))
+ return error;
+ *data->devclass =
+ devclass_find_internal(data->driver->name, TRUE);
+ break;
+
+ case MOD_UNLOAD:
+ if (error = devclass_delete_driver(bus_devclass,
+ data->driver))
+ return error;
+ break;
+ }
+
+ if (data->chainevh)
+ return data->chainevh(mod, what, data->chainarg);
+ else
+ return 0;
+}
diff --git a/sys/libkern/alpha/byte_swap_2.S b/sys/libkern/alpha/byte_swap_2.S
new file mode 100644
index 000000000000..fab3c58d8471
--- /dev/null
+++ b/sys/libkern/alpha/byte_swap_2.S
@@ -0,0 +1,47 @@
+/* $NetBSD: byte_swap_2.S,v 1.2 1996/10/17 03:08:08 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+#ifndef NAME
+#define NAME byte_swap_2
+#endif
+
+/*
+ * Byte-swap a 2-byte quantity. (Convert 0x0123 to 0x2301.)
+ *
+ * Argument is an unsigned 2-byte integer (u_int16_t).
+ */
+LEAF(NAME, 1) /* a0 contains 0x0123 */
+ extbl a0, 0, t0 /* t0 = 0x 23 */
+ extbl a0, 1, t1 /* t1 = 0x 01 */
+ sll t0, 8, t0 /* t1 = 0x23 */
+ or t0, t1, v0 /* v0 = 0x2301 */
+ RET
+END(NAME)
diff --git a/sys/libkern/alpha/byte_swap_4.S b/sys/libkern/alpha/byte_swap_4.S
new file mode 100644
index 000000000000..8dbb83ca2484
--- /dev/null
+++ b/sys/libkern/alpha/byte_swap_4.S
@@ -0,0 +1,53 @@
+/* $NetBSD: byte_swap_4.S,v 1.2 1996/10/17 03:08:09 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+#ifndef NAME
+#define NAME byte_swap_4
+#endif
+
+/*
+ * Byte-swap a 4-byte quantity. (Convert 0x01234567 to 0x67452301.)
+ *
+ * Argument is an unsigned 4-byte integer (u_int32_t).
+ */
+LEAF(NAME, 1) /* a0 contains 0x01234567 */
+ extbl a0, 0, t0 /* t0 = 0x 67 */
+ extbl a0, 1, t1 /* t1 = 0x 45 */
+ extbl a0, 2, t2 /* t2 = 0x 23 */
+ extbl a0, 3, t3 /* t3 = 0x 01 */
+ sll t0, 24, t0 /* t0 = 0x67 */
+ sll t1, 16, t1 /* t1 = 0x 45 */
+ sll t2, 8, t2 /* t2 = 0x 23 */
+ or t3, t0, v0 /* v0 = 0x67 01 */
+ or t1, t2, t1 /* t1 = 0x 4523 */
+ or t1, v0, v0 /* v0 = 0x67452301 */
+ RET
+END(NAME)
diff --git a/sys/libkern/alpha/htonl.S b/sys/libkern/alpha/htonl.S
new file mode 100644
index 000000000000..7fab6f922b30
--- /dev/null
+++ b/sys/libkern/alpha/htonl.S
@@ -0,0 +1,32 @@
+/* $NetBSD: htonl.S,v 1.1 1996/04/17 22:36:52 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME htonl
+
+#include <libkern/alpha/byte_swap_4.S>
diff --git a/sys/libkern/alpha/htons.S b/sys/libkern/alpha/htons.S
new file mode 100644
index 000000000000..392578c5786b
--- /dev/null
+++ b/sys/libkern/alpha/htons.S
@@ -0,0 +1,32 @@
+/* $NetBSD: htons.S,v 1.1 1996/04/17 22:36:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME htons
+
+#include <libkern/alpha/byte_swap_2.S>
diff --git a/sys/libkern/alpha/ntohl.S b/sys/libkern/alpha/ntohl.S
new file mode 100644
index 000000000000..370848abd968
--- /dev/null
+++ b/sys/libkern/alpha/ntohl.S
@@ -0,0 +1,32 @@
+/* $NetBSD: ntohl.S,v 1.1 1996/04/17 22:36:57 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME ntohl
+
+#include <libkern/alpha/byte_swap_4.S>
diff --git a/sys/libkern/alpha/ntohs.S b/sys/libkern/alpha/ntohs.S
new file mode 100644
index 000000000000..80be3f8d15cd
--- /dev/null
+++ b/sys/libkern/alpha/ntohs.S
@@ -0,0 +1,32 @@
+/* $NetBSD: ntohs.S,v 1.1 1996/04/17 22:37:02 cgd Exp $ */
+
+/*
+ * Copyright (c) 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define NAME ntohs
+
+#include <libkern/alpha/byte_swap_2.S>
diff --git a/sys/pci/simos.c b/sys/pci/simos.c
new file mode 100644
index 000000000000..4e84edd6a12a
--- /dev/null
+++ b/sys/pci/simos.c
@@ -0,0 +1,312 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_debug.h>
+
+#include <machine/clock.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <sys/kernel.h>
+
+#include <pci/simos.h>
+
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+
+#include <machine/alpha_cpu.h>
+
+#define MAX_SIZE (64*1024)
+
+struct simos_softc {
+ int sc_unit;
+ struct scsi_link sc_link;
+ SimOS_SCSI* sc_regs;
+ int sc_busy;
+ struct scsi_xfer* sc_head;
+ struct scsi_xfer* sc_tail;
+};
+
+struct simos_softc* simosp[10];
+
+static u_long simos_unit;
+
+static char *simos_probe __P((pcici_t tag, pcidi_t type));
+static void simos_attach __P((pcici_t config_d, int unit));
+
+struct pci_device simos_driver = {
+ "simos",
+ simos_probe,
+ simos_attach,
+ &simos_unit,
+ NULL
+};
+DATA_SET (pcidevice_set, simos_driver);
+
+static int32_t simos_start(struct scsi_xfer * xp);
+static void simos_min_phys (struct buf *bp);
+static u_int32_t simos_info(int unit);
+
+static struct scsi_adapter simos_switch =
+{
+ simos_start,
+ simos_min_phys,
+ 0,
+ 0,
+ simos_info,
+ "simos"
+};
+
+static struct scsi_device simos_dev =
+{
+ NULL, /* Use default error handler */
+ NULL, /* have a queue, served by this */
+ NULL, /* have no async handler */
+ NULL, /* Use default 'done' routine */
+ "simos",
+};
+
+static char *
+simos_probe(pcici_t tag, pcidi_t type)
+{
+ switch (type) {
+ case 0x1291|(0x1291<<16):
+ return "SimOS SCSI";
+ default:
+ return NULL;
+ }
+
+}
+
+static void
+simos_attach(pcici_t config_id, int unit)
+{
+ struct simos_softc* sc;
+ struct scsibus_data* scbus;
+
+ sc = malloc(sizeof(struct simos_softc), M_DEVBUF, M_WAITOK);
+ simosp[unit] = sc;
+ bzero(sc, sizeof *sc);
+
+ sc->sc_unit = unit;
+ sc->sc_regs = (SimOS_SCSI*) SIMOS_SCSI_ADDR;
+ sc->sc_busy = 0;
+ sc->sc_head = 0;
+ sc->sc_tail = 0;
+
+ sc->sc_link.adapter_unit = unit;
+ sc->sc_link.adapter_softc = sc;
+ sc->sc_link.adapter_targ = SIMOS_SCSI_MAXTARG-1;
+ sc->sc_link.fordriver = 0;
+ sc->sc_link.adapter = &simos_switch;
+ sc->sc_link.device = &simos_dev;
+ sc->sc_link.flags = 0;
+
+ scbus = scsi_alloc_bus();
+ scbus->adapter_link = &sc->sc_link;
+ scbus->maxtarg = 1;
+ scbus->maxlun = 0;
+ scsi_attachdevs(scbus);
+ scbus = 0;
+}
+
+static void
+simos_enqueue(struct simos_softc* sc, struct scsi_xfer* xp)
+{
+ if (sc->sc_tail) {
+ sc->sc_tail->next = xp;
+ } else {
+ sc->sc_head = sc->sc_tail = xp;
+ }
+ xp->next = 0;
+}
+
+static void
+simos_start_transfer(struct simos_softc* sc)
+{
+ struct scsi_xfer* xp = sc->sc_head;
+ u_int8_t* p;
+ int i, count, target;
+ vm_offset_t va;
+ vm_size_t size;
+
+ if (sc->sc_busy || !xp)
+ return;
+
+ sc->sc_busy = TRUE;
+
+ target = xp->sc_link->target;
+
+ /*
+ * Copy the command into SimOS' buffer
+ */
+ p = (u_int8_t*) xp->cmd;
+ count = xp->cmdlen;
+ for (i = 0; i < count; i++)
+ sc->sc_regs->cmd[i] = *p++;
+ sc->sc_regs->length = count;
+ sc->sc_regs->target = target;
+ sc->sc_regs->lun = xp->sc_link->lun;
+
+ /*
+ * Setup the segment descriptors.
+ */
+ va = (vm_offset_t) xp->data;
+ size = xp->datalen;
+ i = 0;
+ while (size > 0) {
+ vm_size_t len = PAGE_SIZE - (va & PAGE_MASK);
+ if (len > size)
+ len = size;
+ sc->sc_regs->sgMap[i].pAddr = vtophys(va);
+ sc->sc_regs->sgMap[i].len = len;
+ size -= len;
+ va += len;
+ i++;
+ }
+ sc->sc_regs->sgLen = i;
+
+ /*
+ * Start the i/o.
+ */
+ alpha_wmb();
+ sc->sc_regs->startIO = 1;
+ alpha_wmb();
+}
+
+static void
+simos_done(struct simos_softc* sc)
+{
+ struct scsi_xfer* xp;
+ int done;
+
+ if (!sc->sc_busy)
+ return;
+
+ xp = sc->sc_head;
+
+ /*
+ * Spurious interrupt caused by my bogus interrupt broadcasting.
+ */
+ if (!sc->sc_regs->done[xp->sc_link->target])
+ return;
+
+ sc->sc_head = xp->next;
+ if (!sc->sc_head)
+ sc->sc_tail = 0;
+
+ sc->sc_busy = FALSE;
+
+ done = sc->sc_regs->done[xp->sc_link->target];
+ if (done >> 16) {
+ /* Error detected */
+ xp->error = XS_TIMEOUT;
+ }
+ xp->flags |= ITSDONE;
+
+ sc->sc_regs->done[xp->sc_link->target] = 1;
+ alpha_wmb();
+
+ if (!(xp->flags & SCSI_NOMASK))
+ scsi_done(xp);
+
+ if (sc->sc_head)
+ simos_start_transfer(sc);
+}
+
+static int32_t
+simos_start(struct scsi_xfer * xp)
+{
+ struct simos_softc* sc;
+ int flags = xp->flags;
+ int retval = 0;
+ int s;
+
+ sc = xp->sc_link->adapter_softc;
+
+ /*
+ * Reset (chortle) the adapter.
+ */
+ if (flags & SCSI_RESET)
+ return COMPLETE;
+
+ /*
+ * Simos doesn't understand some commands
+ */
+ if (xp->cmd->opcode == START_STOP || xp->cmd->opcode == PREVENT_ALLOW)
+ return COMPLETE;
+
+ s = splbio();
+
+ simos_enqueue(sc, xp);
+ simos_start_transfer(sc);
+
+ if (flags & SCSI_NOMASK) {
+ /*
+ * Poll for result
+ */
+ while (!sc->sc_regs->done[xp->sc_link->target])
+ ;
+
+ simos_done(sc);
+ retval = COMPLETE;
+ } else
+ retval = SUCCESSFULLY_QUEUED;
+
+ splx(s);
+
+ return retval;
+}
+
+static void
+simos_min_phys (struct buf *bp)
+{
+ if ((unsigned long)bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE;
+}
+
+static u_int32_t
+simos_info(int unit)
+{
+ return 1;
+}
+
+void
+simos_intr(int unit)
+{
+ /* XXX bogus */
+ struct simos_softc* sc = simosp[unit];
+
+ simos_done(sc);
+}
diff --git a/sys/pci/simos.h b/sys/pci/simos.h
new file mode 100644
index 000000000000..46093547cf0d
--- /dev/null
+++ b/sys/pci/simos.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * Copyright (C) 1998 by the Board of Trustees
+ * of Leland Stanford Junior University.
+ * Copyright (C) 1998 Digital Equipment Corporation
+ *
+ * This file is part of the SimOS distribution.
+ * See LICENSE file for terms of the license.
+ *
+ */
+
+
+
+
+#ifndef _SIMOS_SCSI_H
+#define _SIMOS_SCSI_H
+
+#define SIMOS_SCSI_ADDR 0xfffffcc500000000
+#define SIMOS_SCSI_ADDR_32 0xffffffffa5000000
+#define SIMOS_SCSI_MAXDMA_LEN 128
+#define SIMOS_SCSI_MAXTARG 16
+#define SIMOS_SCSI_MAXLUN 16
+
+#define SIMOS_SCSI_REGS ((struct SimOS_SCSI *)SIMOS_SCSI_ADDR)
+#define SIMOS_SCSI_REGS_32 ((struct SimOS_SCSI *)SIMOS_SCSI_ADDR_32)
+
+typedef unsigned long SCSIReg;
+
+
+typedef struct SimOS_SCSI {
+ SCSIReg startIO; /* write-only */
+ SCSIReg done[SIMOS_SCSI_MAXTARG]; /* read-write (write=ack) */
+
+ SCSIReg target; /* data fields */
+ SCSIReg lun;
+ SCSIReg cmd[12];
+ SCSIReg length;
+ SCSIReg sgLen;
+ struct {
+ SCSIReg pAddr;
+ SCSIReg len;
+ } sgMap[SIMOS_SCSI_MAXDMA_LEN];
+
+
+} SimOS_SCSI;
+
+#endif
diff --git a/sys/powerpc/include/bootinfo.h b/sys/powerpc/include/bootinfo.h
new file mode 100644
index 000000000000..36b394323d29
--- /dev/null
+++ b/sys/powerpc/include/bootinfo.h
@@ -0,0 +1,21 @@
+/*
+ * Kernel-internal structure used to hold important bits of boot
+ * information. NOT to be used by boot blocks.
+ *
+ * Note that not all of the fields from the bootinfo struct(s)
+ * passed by the boot blocks aren't here (because they're not currently
+ * used by the kernel!). Fields here which aren't supplied by the
+ * bootinfo structure passed by the boot blocks are supposed to be
+ * filled in at startup with sane contents.
+ */
+struct bootinfo_kernel {
+ u_long ssym; /* start of syms */
+ u_long esym; /* end of syms */
+ u_long hwrpb_phys; /* hwrpb physical address */
+ u_long hwrpb_size; /* size of hwrpb data */
+ char boot_flags[64]; /* boot flags */
+ char booted_kernel[64]; /* name of booted kernel */
+ char booted_dev[64]; /* name of booted device */
+};
+
+extern struct bootinfo_kernel bootinfo;
diff --git a/sys/powerpc/include/clock.h b/sys/powerpc/include/clock.h
new file mode 100644
index 000000000000..95c160fed890
--- /dev/null
+++ b/sys/powerpc/include/clock.h
@@ -0,0 +1,22 @@
+/*
+ * Kernel interface to machine-dependent clock driver.
+ * Garrett Wollman, September 1994.
+ * This file is in the public domain.
+ *
+ * $Id: clock.h,v 1.34 1998/03/05 21:45:42 tegge Exp $
+ */
+
+#ifndef _MACHINE_CLOCK_H_
+#define _MACHINE_CLOCK_H_
+
+#ifdef KERNEL
+
+extern int wall_cmos_clock;
+extern int adjkerntz;
+
+void DELAY __P((int usec));
+int sysbeep __P((int pitch, int period));
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_CLOCK_H_ */
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
new file mode 100644
index 000000000000..d70c1dabf2d7
--- /dev/null
+++ b/sys/powerpc/include/md_var.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_MD_VAR_H_
+#define _MACHINE_MD_VAR_H_
+
+/*
+ * Miscellaneous machine-dependent declarations.
+ */
+
+extern char sigcode[];
+extern int szsigcode;
+extern int Maxmem;
+extern void (*netisrs[32]) __P((void));
+
+void cpu_power_down __P((void));
+void cpu_halt __P((void));
+void cpu_reset __P((void));
+int is_physical_memory __P((vm_offset_t addr));
+void swi_vm __P((void));
+int vm_page_zero_idle __P((void));
+int fill_regs __P((struct proc *, struct reg *));
+int set_regs __P((struct proc *, struct reg *));
+
+#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c
new file mode 100644
index 000000000000..520bd41384ee
--- /dev/null
+++ b/sys/powerpc/powerpc/genassym.c
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 1982, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
+ * $Id: genassym.c,v 1.54 1998/04/06 18:59:14 peter Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/errno.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <machine/frame.h>
+#include <sys/vmmeter.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#define KERNEL /* XXX avoid user headers */
+#include <sys/user.h>
+#undef KERNEL
+#include <net/if.h>
+#include <netinet/in.h>
+#include <nfs/nfsv2.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfs.h>
+#include <nfs/nfsdiskless.h>
+
+int main __P((void));
+int printf __P((const char *, ...));
+
+#define P(name, val) \
+ printf(val > 999 ? "#define\t%s 0x%lx\n" : "#define\t%s %ld\n", name, val)
+
+/* XXX Danger Will Robinson */
+struct prochd {
+ struct proc *ph_link; /* Linked list of running processes. */
+ struct proc *ph_rlink;
+};
+
+#define OFF(name, type, elem) P(#name, (long)&((type*)0)->elem)
+#define CONST2(name, val) P(#name, val)
+#define CONST1(name) P(#name, name)
+
+int
+main()
+{
+ OFF(P_FORW, struct proc, p_procq.tqe_next);
+ OFF(P_BACK, struct proc, p_procq.tqe_prev);
+ OFF(P_VMSPACE, struct proc, p_vmspace);
+ OFF(P_ADDR, struct proc, p_addr);
+ OFF(P_PRI, struct proc, p_priority);
+ OFF(P_RTPRIO_TYPE, struct proc, p_rtprio.type);
+ OFF(P_RTPRIO_PRIO, struct proc, p_rtprio.prio);
+ OFF(P_STAT, struct proc, p_stat);
+ OFF(P_WCHAN, struct proc, p_wchan);
+ OFF(P_FLAG, struct proc, p_flag);
+ OFF(P_PID, struct proc, p_pid);
+ OFF(P_RUNTIME, struct proc, p_runtime);
+ OFF(P_MD_PCBPADDR, struct proc, p_md.md_pcbpaddr);
+
+ OFF(PH_LINK, struct prochd, ph_link);
+ OFF(PH_RLINK, struct prochd, ph_rlink);
+
+ CONST1(SSLEEP);
+ CONST1(SRUN);
+
+ OFF(VM_PMAP, struct vmspace, vm_pmap);
+ OFF(V_TRAP, struct vmmeter, v_trap);
+ OFF(V_SYSCALL, struct vmmeter, v_trap);
+ OFF(V_INTR, struct vmmeter, v_trap);
+
+ CONST1(UPAGES);
+ CONST1(PAGE_SIZE);
+ CONST1(PAGE_SHIFT);
+ CONST1(PAGE_MASK);
+ CONST1(USRSTACK);
+ CONST1(VM_MAXUSER_ADDRESS);
+ CONST1(KERNBASE);
+ CONST1(PTLEV1I);
+ CONST1(PTESIZE);
+
+ OFF(U_PCB_ONFAULT, struct user, u_pcb.pcb_onfault);
+ OFF(U_PCB_HWPCB_KSP, struct user, u_pcb.pcb_hw.apcb_ksp);
+ OFF(U_PCB_CONTEXT, struct user, u_pcb.pcb_context);
+ OFF(U_PROFSCALE, struct user, u_stats.p_prof.pr_scale);
+
+ OFF(PR_BASE, struct uprof, pr_base);
+ OFF(PR_SIZE, struct uprof, pr_size);
+ OFF(PR_OFF, struct uprof, pr_off);
+ OFF(PR_SCALE, struct uprof, pr_scale);
+
+ OFF(RU_MINFLT, struct rusage, ru_minflt);
+
+ OFF(PCB_HW, struct pcb, pcb_hw);
+ OFF(PCB_CONTEXT, struct pcb, pcb_context);
+ OFF(PCB_FP, struct pcb, pcb_fp);
+ OFF(PCB_ONFAULT, struct pcb, pcb_onfault);
+ OFF(PCB_ACCESSADDR, struct pcb, pcb_accessaddr);
+
+ OFF(FPREG_FPR_REGS, struct fpreg, fpr_regs);
+ OFF(FPREG_FPR_CR, struct fpreg, fpr_cr);
+
+ CONST1(B_READ);
+ CONST1(ENOENT);
+ CONST1(EFAULT);
+ CONST1(ENAMETOOLONG);
+ CONST1(MAXPATHLEN);
+
+ /* Register offsets, for stack frames. */
+ CONST1(FRAME_V0),
+ CONST1(FRAME_T0),
+ CONST1(FRAME_T1),
+ CONST1(FRAME_T2),
+ CONST1(FRAME_T3),
+ CONST1(FRAME_T4),
+ CONST1(FRAME_T5),
+ CONST1(FRAME_T6),
+ CONST1(FRAME_T7),
+ CONST1(FRAME_S0),
+ CONST1(FRAME_S1),
+ CONST1(FRAME_S2),
+ CONST1(FRAME_S3),
+ CONST1(FRAME_S4),
+ CONST1(FRAME_S5),
+ CONST1(FRAME_S6),
+ CONST1(FRAME_A3),
+ CONST1(FRAME_A4),
+ CONST1(FRAME_A5),
+ CONST1(FRAME_T8),
+ CONST1(FRAME_T9),
+ CONST1(FRAME_T10),
+ CONST1(FRAME_T11),
+ CONST1(FRAME_RA),
+ CONST1(FRAME_T12),
+ CONST1(FRAME_AT),
+ CONST1(FRAME_SP),
+
+ CONST1(FRAME_SW_SIZE),
+
+ CONST1(FRAME_PS),
+ CONST1(FRAME_PC),
+ CONST1(FRAME_GP),
+ CONST1(FRAME_A0),
+ CONST1(FRAME_A1),
+ CONST1(FRAME_A2),
+
+ CONST1(FRAME_SIZE),
+
+ /* bits of the PS register */
+ CONST1(ALPHA_PSL_USERMODE);
+ CONST1(ALPHA_PSL_IPL_MASK);
+ CONST1(ALPHA_PSL_IPL_0);
+ CONST1(ALPHA_PSL_IPL_SOFT);
+ CONST1(ALPHA_PSL_IPL_HIGH);
+
+ /* pte bits */
+ CONST1(ALPHA_L1SHIFT);
+ CONST1(ALPHA_L2SHIFT);
+ CONST1(ALPHA_L3SHIFT);
+ CONST1(ALPHA_K1SEG_BASE);
+ CONST1(ALPHA_PTE_VALID);
+ CONST1(ALPHA_PTE_ASM);
+ CONST1(ALPHA_PTE_KR);
+ CONST1(ALPHA_PTE_KW);
+
+ /* Kernel entries */
+ CONST1(ALPHA_KENTRY_ARITH);
+ CONST1(ALPHA_KENTRY_MM);
+
+ CONST1(ALPHA_KENTRY_IF);
+ CONST1(ALPHA_KENTRY_UNA);
+
+ CONST1(VPTBASE);
+
+ return (0);
+}
diff --git a/sys/powerpc/powerpc/procfs_machdep.c b/sys/powerpc/powerpc/procfs_machdep.c
new file mode 100644
index 000000000000..11898d0cf3cb
--- /dev/null
+++ b/sys/powerpc/powerpc/procfs_machdep.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1993 Jan-Simon Pendry
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * 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.
+ *
+ * @(#)procfs_machdep.c 8.3 (Berkeley) 1/27/94
+ *
+ * From:
+ * $Id: procfs_machdep.c,v 1.10 1997/07/20 08:37:22 bde Exp $
+ */
+
+/*
+ * Functions to be implemented here are:
+ *
+ * procfs_read_regs(proc, regs)
+ * Get the current user-visible register set from the process
+ * and copy it into the regs structure (<machine/reg.h>).
+ * The process is stopped at the time read_regs is called.
+ *
+ * procfs_write_regs(proc, regs)
+ * Update the current register set from the passed in regs
+ * structure. Take care to avoid clobbering special CPU
+ * registers or privileged bits in the PSL.
+ * Depending on the architecture this may have fix-up work to do,
+ * especially if the IAR or PCW are modified.
+ * The process is stopped at the time write_regs is called.
+ *
+ * procfs_read_fpregs, procfs_write_fpregs
+ * deal with the floating point register set, otherwise as above.
+ *
+ * procfs_sstep(proc)
+ * Arrange for the process to trap after executing a single instruction.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/vnode.h>
+#include <machine/reg.h>
+#include <machine/md_var.h>
+#include <miscfs/procfs/procfs.h>
+
+#include <vm/vm.h>
+#include <sys/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+#include <sys/user.h>
+
+int
+procfs_read_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+ return (fill_regs(p, regs));
+}
+
+int
+procfs_write_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+ return (set_regs(p, regs));
+}
+
+/*
+ * Ptrace doesn't support fpregs at all, and there are no security holes
+ * or translations for fpregs, so we can just copy them.
+ */
+
+int
+procfs_read_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ if (p == fpcurproc) {
+ alpha_pal_wrfen(1);
+ savefpstate(&p->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+ }
+
+ bcopy(&p->p_addr->u_pcb.pcb_fp, fpregs, sizeof *fpregs);
+ return (0);
+}
+
+int
+procfs_write_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ if (p == fpcurproc)
+ fpcurproc = NULL;
+
+ bcopy(fpregs, &p->p_addr->u_pcb.pcb_fp, sizeof *fpregs);
+ return (0);
+}
+
+int
+procfs_sstep(p)
+ struct proc *p;
+{
+ return (EINVAL);
+}
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
new file mode 100644
index 000000000000..54ca3d155519
--- /dev/null
+++ b/sys/sys/bus.h
@@ -0,0 +1,229 @@
+/*-
+ * Copyright (c) 1997 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _SYS_BUS_H_
+#define _SYS_BUS_H_
+
+#ifdef KERNEL
+
+/*
+ * Forward declarations
+ */
+typedef struct bus *bus_t;
+typedef struct device *device_t;
+typedef struct driver driver_t;
+typedef struct devclass *devclass_t;
+
+typedef int driver_probe_t(bus_t bus, device_t dev);
+typedef int driver_attach_t(bus_t bus, device_t dev);
+typedef int driver_detach_t(bus_t bus, device_t dev);
+typedef int driver_shutdown_t(bus_t bus, device_t dev);
+typedef void driver_intr_t(void*);
+
+typedef enum driver_type {
+ DRIVER_TYPE_TTY,
+ DRIVER_TYPE_BIO,
+ DRIVER_TYPE_NET,
+ DRIVER_TYPE_MISC,
+ MAX_DRIVER_TYPE
+} driver_type_t;
+
+struct driver {
+ const char *name;
+ driver_probe_t *probe;
+ driver_attach_t *attach;
+ driver_detach_t *detach;
+ driver_shutdown_t *shutdown;
+ driver_type_t type;
+ size_t softc; /* size of device softc struct */
+ TAILQ_ENTRY(driver) link; /* list of devices on bus */
+ void *buspriv; /* private data for the owning bus */
+};
+
+typedef enum device_state device_state_t;
+enum device_state {
+ DS_NOTPRESENT, /* not probed or probe failed */
+ DS_ALIVE, /* probe succeeded */
+ DS_ATTACHED, /* attach method called */
+ DS_BUSY /* device is open */
+};
+
+/*
+ * Busses - containers of devices.
+ */
+typedef void bus_print_device_t(bus_t bus, device_t dev);
+typedef int bus_read_ivar_t(bus_t bus, device_t dev,
+ int index, u_long *result);
+typedef int bus_write_ivar_t(bus_t bus, device_t dev,
+ int index, u_long value);
+typedef int bus_map_intr_t(bus_t bus, device_t dev,
+ driver_intr_t *intr, void *arg);
+
+typedef struct bus_ops {
+ bus_print_device_t *print_device;
+ bus_read_ivar_t *read_ivar;
+ bus_write_ivar_t *write_ivar;
+ bus_map_intr_t *map_intr;
+} bus_ops_t;
+
+typedef TAILQ_HEAD(device_list, device) device_list_t;
+
+struct bus {
+ bus_ops_t *ops;
+ device_t dev; /* device instance in parent bus */
+ device_list_t devices;
+};
+
+/*
+ * Bus priorities. This determines the order in which busses are probed.
+ */
+#define BUS_PRIORITY_HIGH 1
+#define BUS_PRIORITY_MEDIUM 2
+#define BUS_PRIORITY_LOW 3
+
+/*
+ * The root bus, to which all top-level busses are attached.
+ */
+extern bus_t root_bus;
+extern devclass_t root_devclass;
+void root_bus_configure(void);
+
+/*
+ * Access functions for bus.
+ */
+device_t bus_get_device(bus_t bus);
+void bus_print_device(bus_t bus, device_t dev);
+int bus_read_ivar(bus_t bus, device_t dev,
+ int index, u_long *result);
+int bus_write_ivar(bus_t bus, device_t dev,
+ int index, u_long value);
+int bus_map_intr(bus_t bus, device_t dev, driver_intr_t *intr, void *arg);
+device_t bus_add_device(bus_t bus, const char *name,
+ int unit, void *ivars);
+device_t bus_add_device_after(bus_t bus, device_t place, const char *name,
+ int unit, void *ivars);
+int bus_delete_device(bus_t bus, device_t dev);
+device_t bus_find_device(bus_t bus, const char *classname, int unit);
+
+/*
+ * Useful functions for implementing busses.
+ */
+void bus_init(bus_t bus, device_t dev, bus_ops_t *ops);
+driver_attach_t bus_generic_attach;
+driver_detach_t bus_generic_detach;
+driver_shutdown_t bus_generic_shutdown;
+bus_print_device_t null_print_device;
+bus_read_ivar_t null_read_ivar;
+bus_write_ivar_t null_write_ivar;
+bus_map_intr_t null_map_intr;
+extern bus_ops_t null_bus_ops;
+
+/*
+ * Access functions for device.
+ */
+bus_t device_get_parent(device_t dev);
+driver_t *device_get_driver(device_t dev);
+devclass_t device_get_devclass(device_t dev);
+int device_set_devclass(device_t dev, const char *classname);
+int device_set_driver(device_t dev, driver_t *driver);
+void device_set_desc(device_t dev, const char* desc);
+const char* device_get_desc(device_t dev);
+const char* device_get_name(device_t dev);
+int device_get_unit(device_t dev);
+void *device_get_softc(device_t dev);
+void *device_get_ivars(device_t dev);
+device_state_t device_get_state(device_t dev);
+void device_enable(device_t dev);
+void device_disable(device_t dev);
+void device_busy(device_t dev);
+void device_unbusy(device_t dev);
+int device_is_enabled(device_t dev);
+int device_is_alive(device_t dev); /* did probe succeed? */
+int device_probe_and_attach(device_t dev);
+int device_detach(device_t dev);
+int device_shutdown(device_t dev);
+
+/*
+ * Access functions for devclass.
+ */
+devclass_t devclass_find(const char *classname);
+int devclass_add_driver(devclass_t dc, driver_t *driver);
+int devclass_delete_driver(devclass_t dc, driver_t *driver);
+driver_t *devclass_find_driver(devclass_t dc, const char *classname);
+const char *devclass_get_name(devclass_t dc);
+device_t devclass_get_device(devclass_t dc, int unit);
+void *devclass_get_softc(devclass_t dc, int unit);
+int devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp);
+int devclass_get_maxunit(devclass_t dc);
+
+#ifdef _SYS_MODULE_H_
+
+/*
+ * Module support for automatically adding drivers to busses.
+ */
+struct driver_module_data {
+ modeventhand_t chainevh;
+ void* chainarg;
+ const char* busname;
+ driver_t* driver;
+ devclass_t* devclass;
+};
+
+int driver_module_handler __P((module_t, modeventtype_t, void*));
+
+#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
+ \
+static struct driver_module_data name##_driver_mod = { \
+ evh, arg, \
+ #busname, \
+ &driver, \
+ &devclass, \
+}; \
+ \
+static moduledata_t name##_mod = { \
+ #name, \
+ driver_module_handler, \
+ &name##_driver_mod \
+}; \
+DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
+
+#define CDEV_DRIVER_MODULE(name, busname, driver, devclass, \
+ major, devsw, evh, arg) \
+ \
+static struct cdevsw_module_data name##_cdevsw_mod = { \
+ evh, arg, makedev(major, 0), &devsw \
+}; \
+ \
+DRIVER_MODULE(name, busname, driver, devclass, \
+ cdevsw_module_handler, &name##_cdevsw_mod)
+
+#endif
+
+#endif /* KERNEL */
+
+#endif /* !_SYS_BUS_H_ */
diff --git a/sys/sys/bus_private.h b/sys/sys/bus_private.h
new file mode 100644
index 000000000000..5a9fba96e50a
--- /dev/null
+++ b/sys/sys/bus_private.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1997 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _SYS_BUS_PRIVATE_H_
+#define _SYS_BUS_PRIVATE_H_
+
+#include <sys/bus.h>
+
+/*
+ * Forward declarations
+ */
+typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
+typedef TAILQ_HEAD(driver_list, driver) driver_list_t;
+
+struct devclass {
+ TAILQ_ENTRY(devclass) link;
+ driver_list_t drivers; /* bus devclasses store drivers for bus */
+ char *name;
+ device_t *devices; /* array of devices indexed by unit */
+ int maxunit; /* size of devices array */
+ int nextunit; /* next unused unit number */
+};
+
+/*
+ * Implementation of device.
+ */
+struct device {
+ TAILQ_ENTRY(device) link; /* list of devices on a bus */
+ bus_t parent;
+ driver_t *driver;
+ devclass_t devclass; /* device class which we are in */
+ int unit;
+ const char* desc; /* driver specific description */
+ int busy; /* count of calls to device_busy() */
+ device_state_t state;
+ int flags;
+#define DF_ENABLED 1 /* device should be probed/attached */
+#define DF_FIXEDCLASS 2 /* devclass specified at create time */
+#define DF_WILDCARD 4 /* unit was originally wildcard */
+ void *ivars;
+ void *softc;
+};
+
+
+
+#endif /* !_SYS_BUS_PRIVATE_H_ */
diff --git a/sys/sys/elf64.h b/sys/sys/elf64.h
new file mode 100644
index 000000000000..a17f082bffd6
--- /dev/null
+++ b/sys/sys/elf64.h
@@ -0,0 +1,312 @@
+/*-
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: elf64.h,v 1.2 1997/08/30 18:58:31 peter Exp $
+ */
+
+#ifndef _SYS_ELF64_H_
+#define _SYS_ELF64_H_ 1
+
+/*
+ * ELF definitions common to all 64-bit architectures.
+ */
+
+typedef u_int64_t Elf64_Addr;
+typedef u_int16_t Elf64_Half;
+typedef u_int64_t Elf64_Off;
+typedef int32_t Elf64_Sword;
+typedef u_int32_t Elf64_Word;
+typedef u_int64_t Elf64_Size;
+
+/*
+ * ELF header.
+ */
+
+#define EI_NIDENT 16 /* Size of e_ident array. */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf64_Half e_type; /* File type. */
+ Elf64_Half e_machine; /* Machine architecture. */
+ Elf64_Word e_version; /* ELF format version. */
+ Elf64_Addr e_entry; /* Entry point. */
+ Elf64_Off e_phoff; /* Program header file offset. */
+ Elf64_Off e_shoff; /* Section header file offset. */
+ Elf64_Word e_flags; /* Architecture-specific flags. */
+ Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf64_Half e_phentsize; /* Size of program header entry. */
+ Elf64_Half e_phnum; /* Number of program header entries. */
+ Elf64_Half e_shentsize; /* Size of section header entry. */
+ Elf64_Half e_shnum; /* Number of section header entries. */
+ Elf64_Half e_shstrndx; /* Section name strings section. */
+} Elf64_Ehdr;
+
+/* Indexes into the e_ident array. */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_PAD 7 /* Start of padding (per SVR4 ABI). */
+#define EI_BRAND 8 /* Start of architecture identification. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+
+/* Values for e_machine. */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M64 1 /* AT&T WE64100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_486 6 /* Intel i486. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
+
+/* Extensions */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */
+#define EM_PARISC 15 /* HPPA */
+#define EM_PPC 20 /* PowerPC */
+#define EM_ALPHA 0x9026 /* Alpha */
+
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf64_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf64_Word sh_type; /* Section type. */
+ Elf64_Size sh_flags; /* Section flags. */
+ Elf64_Addr sh_addr; /* Address in memory image. */
+ Elf64_Off sh_offset; /* Offset in file. */
+ Elf64_Word sh_size; /* Size in bytes. */
+ Elf64_Word sh_link; /* Index of a related section. */
+ Elf64_Word sh_info; /* Depends on section type. */
+ Elf64_Size sh_addralign; /* Alignment in bytes. */
+ Elf64_Size sh_entsize; /* Size of each entry in section. */
+} Elf64_Shdr;
+
+/* Special section indexes. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends*/
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relation section without addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
+
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf64_Word p_type; /* Entry type. */
+ Elf64_Word p_flags; /* Access permission flags. */
+ Elf64_Off p_offset; /* File offset of contents. */
+ Elf64_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf64_Addr p_paddr; /* Physical address (not used). */
+ Elf64_Size p_filesz; /* Size of contents in file. */
+ Elf64_Size p_memsz; /* Size of contents in memory. */
+ Elf64_Size p_align; /* Alignment in memory and file. */
+} Elf64_Phdr;
+
+/* Values for p_type. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
+
+#define PT_COUNT 7 /* Number of defined p_type values. */
+
+/* Values for p_flags. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf64_Size d_tag; /* Entry type. */
+ union {
+ Elf64_Size d_val; /* Integer value. */
+ Elf64_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf64_Dyn;
+
+/* Values for d_tag. */
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
+ library. */
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of Elf64_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of Elf64_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each Elf64_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
+ name. */
+#define DT_RPATH 15 /* String table offset of library path. */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. */
+#define DT_REL 17 /* Address of Elf64_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of Elf64_Rel relocations. */
+#define DT_RELENT 19 /* Size of each Elf64_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
+ non-writable segments. */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
+
+#define DT_COUNT 24 /* Number of defined d_tag values. */
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Size r_info; /* Relocation type and symbol index. */
+} Elf64_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Size r_info; /* Relocation type and symbol index. */
+ Elf64_Off r_addend; /* Addend. */
+} Elf64_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF64_R_SYM(info) ((info) >> 8)
+#define ELF64_R_TYPE(info) ((unsigned char)(info))
+
+/* Macro for constructing r_info from field values. */
+#define ELF64_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf64_Word st_name; /* String table index of name. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf64_Half st_shndx; /* Section index of symbol. */
+ Elf64_Addr st_value; /* Symbol value. */
+ Elf64_Size st_size; /* Size of associated object. */
+} Elf64_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Symbol Binding - ELF64_ST_BIND - st_info */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific symbol bindings */
+
+/* Symbol type - ELF64_ST_TYPE - st_info */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_LOPROC 13 /* reserved range for processor */
+#define STT_HIPROC 15 /* specific symbol types */
+
+/* Special symbol table indexes. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
+
+#endif /* !_SYS_ELF64_H_ */
diff --git a/sys/sys/module.h b/sys/sys/module.h
index fe54185e5010..7553a777c258 100644
--- a/sys/sys/module.h
+++ b/sys/sys/module.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: module.h,v 1.1 1997/05/07 16:05:45 dfr Exp $
+ * $Id: module.h,v 1.2 1997/10/24 05:29:07 jmg Exp $
*/
#ifndef _SYS_MODULE_H_
@@ -52,7 +52,8 @@ typedef struct moduledata {
} moduledata_t;
#define DECLARE_MODULE(name, data, sub, order) \
-SYSINIT(name##module, sub, order, module_register_init, &data)
+SYSINIT(name##module, sub, order, module_register_init, &data) \
+struct __hack
void module_register_init(void *data);
int module_register(const char *name, modeventhand_t callback, void *arg);